"use strict";

var EN_CretaceousHam = function(){
	this.sprite = new Sprite(EN_CretaceousHam.spriteSheet,"CretaceousHam");
	this.sprite.game_object = this; // no longer a generic GO

	this._basicInit(EN_CretaceousHam.params);

	//-----

	this.sprite.collision_flags |= (DEFINE_SPRITE_COLLISION_FLAGS.GROUND);

	this.controls = new Controls(); // ground-runner; easier to just patch in standard controls


	this.direction = 1;

	this.grounded = false;
	this.in_water_cache = false;
	this.horizontal_move_index = 0;
	this.jump_index = 0;
	this.fall_index = 0;

	this.meli = null;
	this.meliFind=false; // she probably won't be in the map when we init; hopefully when we update


	this.anim_state = this.ANIM_STATES.stand;
	this.frame_timer=0;

	this.behavior_state = this.BEHAVIOR_STATES.curious;
	this.behavior_timer = 0;
	this.leftward_move_land = this.leftward_walk_land;
	this.rightward_move_land = this.rightward_walk_land;
	this.charge_level = 0;

	this.blocks = [];
	this.age = 0;
	this.damaged = false;
};
EN_CretaceousHam.spriteImg = SDS_Load_Image("art/sheets/sprite/cretaceous_ham.png");
EN_CretaceousHam.spriteSheet = new TileSheet(6, 5, 1, 3, EN_CretaceousHam.spriteImg);
EN_CretaceousHam.params = {
	name: "CretaceousHam",
	box: [10,8,53,31], // left, top, right, bottom
	max_step: 3,
	hp: 600,
	infection: 3,
};

EN_CretaceousHam.prototype = new GO_Enemy();

	EN_CretaceousHam.prototype.interactions = GO_Enemy.prototype.interactions |
			DEFINE_GAMEOBJECT_INTERACTIONS.CONTROL;
	
	// NPC walk controls
	EN_CretaceousHam.prototype.leftward_walk_land = [0,-1,-2];
	EN_CretaceousHam.prototype.rightward_walk_land = [0,1,2];
	EN_CretaceousHam.prototype.leftward_charge_land = [
		[0,-1,-2,-3],
		[0,-1,-2,-3,-4],
		[0,-1,-2,-3,-4,-5],
	];
	EN_CretaceousHam.prototype.rightward_charge_land = [
		[0,1,2,3],
		[0,1,2,3,4],
		[0,1,2,3,4,5],
	];
	EN_CretaceousHam.prototype.leftward_move_water = [0,-1,-2];
	EN_CretaceousHam.prototype.rightward_move_water = [0,1,2];
	EN_CretaceousHam.prototype.jump_rise_air = [ //27px = 1.75 blocks
		-4,-4,-4,-4,
		-3,-3, 
		-2,-2,
		-1,
		0, 0];
	EN_CretaceousHam.prototype.fall_air = [ 
		1, 
		2, 2, 2, 
		3, 3, 3, 
		4, 4, 4, 4, 4, 4, 
		5, 5, 5, 5, 5, 5,
		6, 6, 6, 6, 6, 6,
		7, 7, 7, 7, 7, 7, 
		8];
	EN_CretaceousHam.prototype.jump_rise_water = [ //8px = .5 blocks
		-2, -2, -2, 
		-1, -1, 
		0]; // maybe a bird; not a duck.
	EN_CretaceousHam.prototype.fall_water = [ 
		-1]; // naturally buoyant; "fall" towards surface

	EN_CretaceousHam.prototype.ANIM_STATES = {
		"stand" : 0,
		"walk" : 1,
		"jump" : 2,
		"fall" : 3,
		"stun" : 4,
	};
	EN_CretaceousHam.prototype.anim_frames = [
		[0], //"stand" : 
		[0,1,0,2], //"walk" : 
		[1], //"jump" : 
		[2], //"fall" :
		[3] // "stun" :
	];

	EN_CretaceousHam.prototype.BEHAVIOR_STATES = {
		"curious" : 0,
		"walk" : 1,
		"charge" : 2,
		"bonk" : 3,
		"stun" : 4,
		"dead" : 5
	};

	EN_CretaceousHam.prototype.BLOCK_SCRAMBLE = [
		//6,7,8,9,10,11,12,13,14,15,16,17,18,19,

		6,9,13,16,19,
		7,10,15,17,
		8,12,14,18,
		11, 0,0,
	];


	EN_CretaceousHam.prototype.checkEvent = function(sourceGO){
		if (this.behavior_state!=this.BEHAVIOR_STATES.dead) return "";// jic
		return "Ground_Ham";
	}

	EN_CretaceousHam.prototype.ai = function(){
		if (!this.meli && !this.meliFind){
			this.meli = this.manager.getNamedObject("Meli");
			this.meliFind = true;
		}

		this._heap.oldAnimState=this.anim_state;

		++this.age;
		this.age &= 15;
		++this.behavior_timer;
		switch (this.behavior_state){
			case this.BEHAVIOR_STATES.curious:
				this.controls.unpress(this.controls,"left");
				this.controls.unpress(this.controls,"right");

				this._heap.seenMeli = this.meli && 
					(this.meli.sprite.y+this.meli.sprite.box_bottom>this.sprite.y+this.sprite.box_top) && 
					(this.meli.sprite.y+this.meli.sprite.box_top<this.sprite.y+this.sprite.box_bottom);
				this._heap.seenMeli &= this.meli &&
					((this.direction<0 && this.meli.sprite.x+this.meli.sprite.box_left < this.sprite.x+this.sprite.box_left) ||
					(this.direction>0 && this.meli.sprite.x+this.meli.sprite.box_right > this.sprite.x+this.sprite.box_right));	
				this._heap.seenMeli &= this.behavior_timer>=30;
				
				if (!this._heap.seenMeli && (this.behavior_timer&15)==0){
					this.direction*=-1;
				}

				if (this._heap.seenMeli || this.behavior_timer>=90){
					this.behavior_timer=0;
					this.behavior_state = (this.infection>0) ? this.BEHAVIOR_STATES.charge : this.BEHAVIOR_STATES.walk;
					this.charge_level = Math.min(
						Math.abs((this.meli.sprite.x+this.meli.sprite.center.x) - (this.sprite.x+this.sprite.center.x))>>6,
						this.leftward_charge_land.length-1
					);
				}
			break;

			case this.BEHAVIOR_STATES.walk:
				this.leftward_move_land = this.leftward_walk_land;
				this.rightward_move_land = this.rightward_walk_land;
				this.controls.press(this.controls,this.direction<0 ? "left" : "right");
				this.controls.unpress(this.controls,this.direction<0 ? "right" : "left");
			break;
			case this.BEHAVIOR_STATES.charge:
				this.leftward_move_land = this.leftward_charge_land[this.charge_level];
				this.rightward_move_land = this.rightward_charge_land[this.charge_level];
				this.controls.press(this.controls,this.direction<0 ? "left" : "right");
				this.controls.unpress(this.controls,this.direction<0 ? "right" : "left");
			break;

			case this.BEHAVIOR_STATES.bonk:
				this.controls.unpress(this.controls,"left");
				this.controls.unpress(this.controls,"right");
				// manual override motion
				this._heap.dx = -this.direction;
				this._heap.dy = this.behavior_timer<7 ? -1 : this.behavior_timer>8 ? 1 : 0
				this.sprite.move(this._heap.dx,this._heap.dy,  this._heap.spriteMoveRes);
				if (this.behavior_timer>=15){
					this.behavior_timer=0;
					this.behavior_state = this.BEHAVIOR_STATES.stun;
				}
			break;

			case this.BEHAVIOR_STATES.stun:
				this.controls.unpress(this.controls,"left");
				this.controls.unpress(this.controls,"right");
				if (this.behavior_timer>=15*(this.charge_level+1)){
					this.behavior_timer=0;
					this.behavior_state = this.BEHAVIOR_STATES.curious;
				}
			break;

			case this.BEHAVIOR_STATES.dead:
				this.controls.unpress(this.controls,"left");
				this.controls.unpress(this.controls,"right");
				this.behavior_timer=0;
			break;

		}

		
		if (this.behavior_state !== this.BEHAVIOR_STATES.bonk) this.NPCWalk();

		if (this._heap.spriteMoveRes.flags & DEFINE_SPRITE_MOVE_RESULT_FLAGS.EJECTED_H){
			if (this.behavior_state===this.BEHAVIOR_STATES.charge){
				//this.damage(this,0);
				this.behavior_timer=0;
				this.behavior_state=this.BEHAVIOR_STATES.bonk;
				
				if (this.sfx) this.sfx.stop();
				this.sfx = new Chiptune("FX_fallcrash",SDS.sfxchip);
				this.sfx.play(false);

				if (this.meli){
					this.meli.sprite.move(-this.direction,-2,  this.meli._heap.spriteMoveRes);
					this.meli.grounded = false;
				}

				// fall existing fallblocks, spawn new ones
				for (this._heap.i=0; this._heap.i<this.blocks.length; ++this._heap.i){
					this.blocks[this._heap.i].drop_block = false;
					this.blocks[this._heap.i].fall_counter = Math.min(this.blocks[this._heap.i].fall_counter,0);
				}
				this.blocks.length = 0;
				for (this._heap.i=0; this._heap.i<this.charge_level+1; ++this._heap.i){
					this._heap.x = ((this.meli?this.meli.sprite.x:this.sprite.x) + this.age + this._heap.i)%16;
					this._heap.x = this.BLOCK_SCRAMBLE[this._heap.x];
					if (this._heap.x){
						this._heap.block = new GO_Fallblock(16,true);
						this._heap.block.sprite.x = this._heap.x<<4;
						this._heap.block.sprite.y = 15<<4;

						this._heap.block.addToRoom(this.sprite.map_room);
						this.manager.add(this._heap.block);
						this.blocks.push(this._heap.block);

						this._heap.poof = new GO_Poof();
						this._heap.poof.spawnOnSprite(this._heap.block.sprite,this.manager);
						this._heap.poof = null;

						while(this._heap.block.sprite.isTouchingSprite(this.meli.sprite)){
							this.meli.takedamage({hp:1,chi:0});
							// don't _love_ this custom zip logic, but it's in a controlled space
							// and will be better than instadeath due to unseen spawn
							this.meli.sprite.y += (this.meli.sprite.y & 15 < 8) ? -1 : 1;
						}

						this._heap.block = null;
					}
				}
			}
			else if (this.behavior_state===this.BEHAVIOR_STATES.walk) this.behavior_state=this.BEHAVIOR_STATES.curious;
			this._heap.spriteMoveRes.flags &= ~DEFINE_SPRITE_MOVE_RESULT_FLAGS.EJECTED_H; // because _heap is shared by all instances, and thus if another instance moves and we don't, we get its _moveRes :P
		}
		

		this.toggleInteractionsStd();

		if (this.behavior_state===this.BEHAVIOR_STATES.bonk || 
			this.behavior_state===this.BEHAVIOR_STATES.stun ||
			this.behavior_state===this.BEHAVIOR_STATES.dead){
			this.anim_state = this.ANIM_STATES.stun;
		}
		// else it will be stand/walk/fall as appropriate

		if (this._heap.oldAnimState != this.anim_state){
			this.frame_timer=0;
		}
		this.frame_timer++;
		this._heap.aniFrame = (this.frame_timer>>(this.infection ? 2 : 3)) % this.anim_frames[this.anim_state].length;

		this.sprite.frame = this.anim_frames[this.anim_state][this._heap.aniFrame];

		this.sprite.frame = this.sprite.frame & 7;

		//if (this.infection>0) this.sprite.frame+=8;
		if (this.damaged){
			this.damaged=false;
			this.sprite.frame+=8;
		}
		if (this.direction<0) this.sprite.frame+=4;
	};
	EN_CretaceousHam.prototype.damage = function(source,points){
		if (points>0){
			this.hp-=points;
			this.damaged = true;
		}
		
		// bonk back the right way from attack
		if (source!=this){
			if (source.sprite.x + (source.sprite.box_left+source.sprite.box_right)>>1 < this.sprite.x + (this.sprite.box_left+this.sprite.box_right)>>1){
				this.direction = -1;
			}
			else{
				this.direction = 1;
			}
			if (points>0){
				this.sprite.move(-this.direction<<1,0);
			}
		}

		/*
		this._heap.cough = new GO_Smoke();
		this._heap.cough.sprite.x = this.sprite.x + ((this.direction>0) ? 16 : 0);
		this._heap.cough.sprite.y = this.sprite.y;
		this._heap.cough.launch_dir.x=0;
		this._heap.cough.launch_dir.y=-1;
		this._heap.cough.host_obj = this;

		this.sprite.map_room.addSprite(this._heap.cough.sprite);
		this.manager.add(this._heap.cough);

		this._heap.cough = null;

		this.infection--;
		*/

		if (this.behavior_state===this.BEHAVIOR_STATES.charge && points>25){
			this.behavior_timer=0;
			this.behavior_state=this.BEHAVIOR_STATES.bonk;
		}

		if (this.hp<=0){
			// TODO: event get ham
			this.infection=0;
			this.hp=1;
			this.behavior_state=this.BEHAVIOR_STATES.dead;
			this.interactions = this.interactions | DEFINE_GAMEOBJECT_INTERACTIONS.CHECK;

			return true;
		}
		return false;
		//return (this.hp<=0);
		
	};
	EN_CretaceousHam.prototype._inflictVal = {hp:3, chi:0};
	EN_CretaceousHam.prototype.inflict = function(){
		return this._inflictVal;
	};
	EN_CretaceousHam.prototype.drop = function(){
		return null;
	};


