/* unit-save.m,
 *
 * This file handles loading and saving of units.
 */

#include "common.h"
#include "unit.h"
#include "unit-intern.h"
#include "unit-save.h"
#include "units/all-units.h"


static void write_list(List *list, PACKFILE *fp)
{
    char str[1024];
    ListIterator *it;

    foreach(it, list) {
	Unit *unit = [it getItem];

        /* Write out the class of the unit, delimited by a newline. */
#if 0
	/* Cargo2Player and CargoHealth2Player are now relegated.
	   Just keep around for a bit, in case we want to read old files. */
	if (streq([unit name], "Cargo2Player"))
	    pack_fputs("Cargo", fp);
	else if (streq([unit name], "CargoHealth2Player"))
	    pack_fputs("CargoHealth", fp);
	else
#endif

	pack_fputs([unit name], fp);
        pack_putc('\n', fp);

        /* Store any properties the unit wants, ended by a newline. */
        pack_fputs([unit exportUnitProperties:str], fp);
	pack_putc('\n', fp);
    }
}

static void remove_stupid_from_list(List *list, BOOL air_unit)
{
    ListIterator *it, *nx;
    Unit *unit;

    foreach_nx (it, nx, list) {
	unit = [it getItem];
	nx = [it next];

	if (not find_class_by_name([unit name], air_unit))
	    destroy_unit(unit);
    }
}

void save_unit_lists(PACKFILE *fp)
{
    /* Remove any units that aren't in a class list. */
    remove_stupid_from_list(active_air_list, YES);
    remove_stupid_from_list(active_ground_list, NO);

    /* Write the number of air/ground units. */
    pack_iputw([active_air_list length], fp);
    pack_iputw([active_ground_list length], fp);

    /* Now write the individual unit data. */
    write_list(active_air_list, fp);
    write_list(active_ground_list, fp);
}

BOOL load_unit_lists(PACKFILE *fp, BOOL for_map_editor)
{
    Unit *unit;
    char class_name[1024], data[1024];
    int num_air_units, num_ground_units;
    Class class = nil;

    unit_reset();

    /* Get the number of air/ground units. */
    num_air_units = pack_igetw(fp);
    num_ground_units = pack_igetw(fp);

    /* Now read in the individual unit data. */
    /* The air units. */
    for (; num_air_units; num_air_units--) {
	/* Get name and data. */
	pack_fgets(class_name, 1024, fp);
	pack_fgets(data, 1024, fp);

	/* Find the class. */
	class = find_class_by_name(class_name, YES);
	if (not class) {	/* exit? */
	    fprintf(stderr, "Class %s not found!\n", class_name);
	    continue;
	}

	/* Load the class data if necessary. */
	if (not load_unit_data_for(class, YES))
	    goto errors;

	unit = [class new];
	[unit importUnitProperties:data];

	if (for_map_editor)
	    [active_air_list insertItemAtEnd:unit];
	else
	    [air_list insertItemAtEnd:unit];
    }

    /* The ground units. */
    for (; num_ground_units; num_ground_units--) {
	/* Get name and data. */
	pack_fgets(class_name, 1024, fp);
	pack_fgets(data, 1024, fp);

	/* Find the class. */
	class = find_class_by_name(class_name, NO);
	if (not class) {	/* exit? */
	    fprintf(stderr, "Class %s not found!\n", class_name);
	    continue;
	}

	/* Load the class data if necessary. */
	if (not load_unit_data_for(class, NO))
	    goto errors;

	unit = [class new];
	[unit importUnitProperties:data];

	if (for_map_editor)
	    [active_ground_list insertItemAtEnd:unit];
	else
	    [ground_list insertItemAtEnd:unit];
    }

    return YES;

 errors:
    return NO;
}
