/* hatch.m,
 *
 * Bunkers for tanks and stuff.  Good for keeping units safe until
 * they activate.
 */

#include <allegro.h>
#include <math.h>
#include "common.h"
#include "map.h"
#include "seborrhea/seborrhea.h"
#include "unit-mapextras.h"
#include "units/all-units.h"
#include "units/hatch.h"


static SebFile *hatch_sebum;
static SebAnimation *open_anim;


@implementation Hatch
        /* Initialization. */
+ (BOOL) loadData
{
    if (hatch_sebum)		/* Don't load twice. */
	return YES;

    hatch_sebum = [SebFile new];
    if (not [hatch_sebum loadSebumDirectory:"data/hatch"])
	return NO;

    open_anim = (SebAnimation *)[hatch_sebum getSebumByName:"open-anim"];
    return YES;
}

+ (void) shutdown
{
    FREE_SEBFILE(hatch_sebum);
    open_anim = nil;
}

- init
{
    [super init];

    anim.anim  = open_anim;
    anim.frame = 0;
    anim.delay = anim.tics = 6;
    anim.loop  = NO;

    sprite = [anim.anim getFrame:0];
    w = [sprite width];
    h = [sprite height];

    spawnee = nil;

    flags |= FLAG_INVINCIBLE;	/* Don't get found by find_closest_unit. */
    return self;
}

	/* Update. */
- (void) spawnUnit
{
    [spawn_unit(spawnee, x, y, ACTIVE_GROUND_LIST, NO) setAngle:angle];
    spawnee = nil;
}

- (int) update
{
    /* If all players are dead, don't open the hatch unless we have
       already begun. */
    if (!(game_flags & FLAG_PLAYERS_ALIVE) && anim.frame == 0) 
	return THING_NORMAL;

    if (spawnee && (y + activate_y >= offsetY)) {
	if (animate(&anim)) {
	    sprite = [anim.anim getFrame:anim.frame];

	    if (anim.frame == [open_anim numFrames]-1)
		[self spawnUnit];
	}

	alpha = 255 * (anim.frame * anim.delay + 6-anim.tics) / ([open_anim numFrames] * anim.delay);
    }

    return [super update];
}

	/* Collisions. */
- (int) collisionLists { return 0; }

	/* For use in map editor only! */
- (void) drawMapEditorExtras:(BITMAP *)dest
{
    [super drawMapEditorExtras:dest];
    draw_activation_line(dest, x, y, activate_y);
}

	/* Protocol stuff. */
- derive_setActivationLine;
- derive_importUnitPropertiesWithVariableActivationLine;
- derive_exportUnitPropertiesWithVariableActivationLine;
@end

/*------------------------------------------------------------*/

@implementation HatchWithVariableTravelRange
- (void) spawnUnit
{
    [[spawn_unit(spawnee, x, y, ACTIVE_GROUND_LIST, NO)
		setAngle:angle]
	setTravelRange:travel_range];
    spawnee = nil;
}

	/* Load/Save.  Format: travel_range;activate_y;x;y;a[;flags] */
- (void) importUnitProperties:(char *)str
{
    char str2[1024];
    sscanf(str, "%d;%s", &travel_range, str2);
    [super importUnitProperties:str2];
}

- (char *) exportUnitProperties:(char *)str
{
    char str2[1024] = "\0";

    [super exportUnitProperties:str2];
    snprintf(str, sizeof(str2), "%d;%s", travel_range, str2);
    return str;
}

	/* For use in map editor only! */
- (void) drawMapEditorExtras:(BITMAP *)dest
{
    [super drawMapEditorExtras:dest];
    draw_travel_range(dest, x, y, angle, travel_range);
}

	/* Protocol stuff. */
- derive_setTravelRange(travel_range);

	/* Data sharing tweaks. */
+ (BOOL) loadData { return LOAD_UNIT_DATA_FOR(Hatch, NO); }
+ (void) shutdown {}
@end
