/*
* A simple medium-sized rock.  Meli can push, carry, and throw it.
*/
"use strict";

var GO_Boulder = function(boulderType){
	this.sprite = new Sprite(boulderType.spriteSheet,"Boulder");
	this.sprite.collision_flags = 
		DEFINE_SPRITE_COLLISION_FLAGS.GROUND | 
		DEFINE_SPRITE_COLLISION_FLAGS.SPRITES_ACTIVE |
		DEFINE_SPRITE_COLLISION_FLAGS.SPRITES_PASSIVE |
		DEFINE_SPRITE_COLLISION_FLAGS.SOLID;
	this.sprite.setBoundingBox(
		boulderType.box[0],
		boulderType.box[1],
		boulderType.box[2],
		boulderType.box[3]);
	//sprite.constraints=constraints;
	this.sprite.max_step = 0;
	this.sprite.game_object = this; // no longer a generic GO

	this.gravity_index = 0;

	this.alreadyHit = []; // things we hit while falling; don't process them again

	this.resistance = boulderType.resistance;
	this.push_counter = 0;

	this.impact=boulderType.impact; // if hit an enemy while airborne
	this.passive_impact=boulderType.passive_impact; // if enemy/button WITHOUT collision flag SPRITES_ACTIVE touched this while it was grounded; -1 for no eval
	if (boulderType.weight) this.weight = boulderType.weight;

	this.seen_push = 0;

	this.held=false;

};

GO_Boulder.TYPES = {
	BOULDER : {
		image:"boulder", 
		size: {x:4, y:4}, 
		box:[0,0,15,15], 
		resistance:1, 
		impact:3,
		passive_impact:3 // mainly for the legacy Guy quickkill
	}, // A simple medium-sized rock.
	L_SHRINEBLOCK : {
		image:"shrineblock_light", 
		size: {x:4, y:4}, 
		box:[0,0,15,15], 
		resistance:2, 
		impact:3,
		passive_impact:2
	}, // A hollow dislodged block; harder to push
	SHRINEBLOCK : {
		image:"shrineblock", 
		size: {x:4, y:4}, 
		box:[0,0,15,15], 
		resistance:4, 
		impact:4,
		passive_impact:2
	}, // A dislodged block; very heavy
	NUT : {
		image:"nut", 
		size: {x:4, y:4}, 
		box:[0,0,15,15], 
		weight: DEFINE_PROJECTILE_WEIGHT.LIGHT,
		resistance:1, 
		impact:1,
		passive_impact:-1
	}, // a very large nut from a very large tree
	SKYBLOCK : {
		image:"skyshrineblock", 
		size: {x:4, y:4}, 
		box:[0,0,15,15], 
		resistance:4, 
		impact:2,
		passive_impact:-1
	}, // from the chutes in the Boss Room
	FALLBLOCK : {
		image:"mountainblock", 
		size: {x:4, y:4}, 
		box:[0,2,15,15], 
		weight: DEFINE_PROJECTILE_WEIGHT.HEAVY,
		resistance:10, 
		impact:50,
		passive_impact:25 // main Cretaceous Ham damage mechanic
	}, // from certain falling platforms
}
for (var type in GO_Boulder.TYPES){
	var boulderType = GO_Boulder.TYPES[type];
	boulderType.spriteImg = SDS_Load_Image("art/sheets/sprite/"+boulderType.image+".png");
	boulderType.spriteSheet = new TileSheet(boulderType.size.x, boulderType.size.y, 0, 0, boulderType.spriteImg);
}

GO_Boulder.prototype = new GameObject(
	new Sprite(
		new TileSheet(
			4, 4, 0, 0, 
			SDS_Load_Image("art/sheets/sprite/boulder.png")
		),
		"Boulder"
	),
	"Boulder"
	);
	
	GO_Boulder.prototype.interactions = 
		DEFINE_GAMEOBJECT_INTERACTIONS.GRAB |
		DEFINE_GAMEOBJECT_INTERACTIONS.PUSH;

	GO_Boulder.prototype.gravity_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];
	GO_Boulder.prototype.gravity_water = [ 
		1, 
		1, 1, 1, 
		2, 2, 2, 
		3, 3, 3, 3, 3, 3,
		4, 4, 4, 4, 4, 4, 
		5, 5, 5, 5, 5, 5,
		6, 6, 6, 6, 6, 6, 
		7];

	GO_Boulder.prototype.weight = DEFINE_PROJECTILE_WEIGHT.MEDIUM;
	GO_Boulder.prototype.hoistpoint = [
		{'x':13, 'y':8}, // grab point when moving direction -1
		{'x':3, 'y':8} // grab point when moving direction 1
	];

	GO_Boulder.prototype.Update = function(){
		this._heap.gravityArray = (this.sprite.isTouchingTerrain(DEFINE_MAP_TERRAIN_TYPES.WATER)) ? this.gravity_water : this.gravity_air;

		if (this._heap.gravityArray[this.gravity_index] > 3){
			this.interactions |= DEFINE_GAMEOBJECT_INTERACTIONS.INFLICT;
			this.sprite.collision_flags &= ~DEFINE_SPRITE_COLLISION_FLAGS.SOLID;
		}
		else{
			this.interactions &= ~DEFINE_GAMEOBJECT_INTERACTIONS.INFLICT;
			this.sprite.collision_flags |= DEFINE_SPRITE_COLLISION_FLAGS.SOLID;
		}

		this.sprite.move(0,this._heap.gravityArray[this.gravity_index],  this._heap.spriteMoveRes);
		if (this._heap.spriteMoveRes.flags & DEFINE_SPRITE_MOVE_RESULT_EJECTED_V){
			if (this.gravity_index>4){
				if (this.sfx) this.sfx.stop();
				this.sfx = new Chiptune("FX_fallcrash",SDS.sfxchip);
				this.sfx.play(false);
			}

			this.gravity_index=0;
			this.alreadyHit.length=0;
		}
		else{
			this.gravity_index = Math.min(this.gravity_index+1,this._heap.gravityArray.length-1);
		}

		this._heap.broken = false;
		// can't have a pure gravity_index>0 check here or they won't hit switches.
		// hence new passive_impact param
		if ((this._heap.spriteMoveRes.flags & DEFINE_SPRITE_MOVE_RESULT_FLAGS.COLLIDING_S)){
			// apply damage to target
			for (var i=0; i<this._heap.spriteMoveRes.collisions.length; i++){
				if (this._heap.spriteMoveRes.collisions[i].game_object.interactions & DEFINE_GAMEOBJECT_INTERACTIONS.DAMAGE &&
					(this.gravity_index>0 || this.passive_impact>=0)){
					if (this.alreadyHit.indexOf(this._heap.spriteMoveRes.collisions[i])==-1){
						this._heap.broken = this._heap.broken || !this._heap.spriteMoveRes.collisions[i].game_object.damage(this,this.gravity_index>0 ? this.impact : this.passive_impact);
						this.alreadyHit.push(this._heap.spriteMoveRes.collisions[i]);
					}
				}
			}
			
		}

		this.seen_push--;
		if (this.seen_push<=0){
			this.seen_push=0;
			if (this.sfx && this.sfx.name=="FX_grind"){
				this.sfx.stop();
			}
		}
		

		if (this._heap.broken){
			if (this.sfx){
				this.sfx.stop();
			}

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

			this.sprite.map_room.removeSprite(this.sprite);
			this.manager.remove(this);
		}	
	};

	GO_Boulder.prototype.IndisposedUpdate = function(){
		
	};
	GO_Boulder.prototype.Unindispose = function(dx, dy, moveRes){
		if (moveRes.flags & (DEFINE_SPRITE_MOVE_RESULT_EJECTED_H | DEFINE_SPRITE_MOVE_RESULT_EJECTED_V)){
			if (Math.abs(dx)+Math.abs(dy) > 1){
				if (this.sfx) this.sfx.stop();
				this.sfx = new Chiptune("FX_fallcrash",SDS.sfxchip);
				this.sfx.play(false);
			}
		}
	};

	
	GO_Boulder.prototype.grab = function(){
		this.gravity_index=0;
		this.interactions &= ~DEFINE_GAMEOBJECT_INTERACTIONS.INFLICT;
		this.sprite.collision_flags |= DEFINE_SPRITE_COLLISION_FLAGS.SOLID;

		if (this.sfx && this.sfx.name=="FX_grind"){
			this.sfx.stop();
		}

		this.held=true;
	};
	GO_Boulder.prototype.drop = function(){
		this.gravity_index=0;
		this.held=false;
	};

	GO_Boulder.prototype.push = function(dx){
		this._heap.x = this.sprite.x;
		if (dx>=0){
			this.push_counter++;
		}
		else{
			this.push_counter--;
		}
		if (this.push_counter>=this.resistance){
			this.sprite.move(1,0);
			this.push_counter-=this.resistance;
		}
		else if (this.push_counter<=-this.resistance){
			this.sprite.move(-1,0);
			this.push_counter+=this.resistance;
		}

		if (this.gravity_index<2 && this.sprite.x!==this._heap.x) this.seen_push = 5; // 1 frame to catch up if it moves, 1 to account for update ordering, 3 to actually wait
		if (!this.sfx || this.sfx.name!="FX_grind"){
			this.sfx = new Chiptune("FX_grind",SDS.sfxchip);
		}
		if (!this.sfx.is_playing && !this.held){
			this.sfx.play(true);
		}
	};

	GO_Boulder.prototype.inflict = function(){
		return {hp:this.impact, chi:0};
	};
