/* swarm-missile.m,
 *
 * Swarm missiles are enemy's semi-tracking missiles.  They are really
 * more like toothpaste than missiles.
 */

#include <allegro.h>
#include <assert.h>
#include <math.h>
#include "common.h"
#include "linklist.h"
#include "map.h"
#include "pregen-circles.h"
#include "projectiles/swarm-missile.h"
#include "seborrhea/seborrhea.h"
#include "unit.h"
#include "unit-seeking.h"


#define INITIAL_TRAIL_HEALTH	8
#define SWARM_MISSILE_STEPS	35


@implementation SwarmMissile
+ initialize { REGISTER_PROJECTILE(self); return self; }

- init
{
    [super init];

    sprite = (Sebum<SebImage> *)[base_sebum getSebumByName:"weapon/homing"];
    w = 14;
    h = 14;
    rotatable_sprite = YES;

    speed = 8.0;

    return self;
}

- free 
{
    FREE_SPLINE(the_path);
    return [super free];
}

- (int) update
{
    if (health <= 0)
	return THING_DEAD;

    if (path_progress == 0) {
	Unit *target = find_closest_unit(x, y, ALLY_LIST);

	if (target) {
	    double dest_x, dest_y;
	    [target getX:&dest_x Y:&dest_y];
	
	    {
		List *list = [LIST_NEW];
		ControlPoint *cp1 = [ControlPoint new];
		ControlPoint *cp2 = [ControlPoint new];
		assert(list && cp1 && cp2);

		[[cp1 setX:x Y:y steps:SWARM_MISSILE_STEPS]
		    setControlPoint:1 X:x-dest_x Y:(dest_y-y)*0.75];
		[[cp2 setX:dest_x Y:dest_y]
		    setControlPoint:0 X:0 Y:0];

		[list insertItem:cp2];
		[list insertItem:cp1];

		the_path = articulate_spline(list);
		list = [list free];
	    }
	    path_progress++;
	    return THING_NORMAL;
	}
	else {
	    /* Move, otherwise it looks weird. */
	    spawn_debris([SwarmMissileTrail class], x, y, HIGH_LAYER);
	    return [super update];
	}
    }

    spawn_debris([SwarmMissileTrail class], x, y, HIGH_LAYER);
    /* Ignore the last 10 steps. */
    if (path_progress < SWARM_MISSILE_STEPS - 10) {
	x = the_path[path_progress].x;
	y = the_path[path_progress].y;
	path_progress++;

	if (path_progress >= SWARM_MISSILE_STEPS - 10) {
	    /* Prepare to go straight. */
	    double deltay = the_path[path_progress-2].y - the_path[path_progress-1].y;
	    double deltax = the_path[path_progress-1].x - the_path[path_progress-2].x;
	    angle = atan2(deltay, deltax);
	}
    }
    else
	[super update];

    return THING_NORMAL;
}
@end

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

@implementation SwarmMissileTrail
- init
{
    [super init];
    health = INITIAL_TRAIL_HEALTH;
    return self;
}

- (void) draw:(BITMAP *)dest
{
    int alpha = 0xff * health/INITIAL_TRAIL_HEALTH;
    pregen_circlefill_add(dest, x, y-offsetY,
	    4 * health/INITIAL_TRAIL_HEALTH,
	    makecol(0xd0, 0xa0, 0xff), alpha);
}

- (int) update
{
    if (--health < 0)
        return THING_DEAD;
    return [super update];
}
@end
