Hovercraft.prototype = new Layer();
Hovercraft.prototype.constructor = Hovercraft;
Hovercraft.superclass = Layer.prototype;

function Hovercraft(id, images, startImage, scale)
{
	//alert("Hovercraft::Constructor");
	this.SetId(id);
	
	//------ Create element -----------
	var elem = document.createElement("div");
	
	var attr_Id = document.createAttribute("id");
	attr_Id.value = this.GetId();
	elem.setAttributeNode(attr_Id);	
		
	var attr_Style = document.createAttribute("style");
	attr_Style.value = "position:absolute; visibility: hidden";
	elem.setAttributeNode(attr_Style);
	
	var attr_Align = document.createAttribute("align");
	attr_Align.value = "center";
	elem.setAttributeNode(attr_Align);
	
	elem.innerHTML = "<img id=\"" + id + "_image\">";
	
	document.body.appendChild(elem);
	//-----------------------------------
	
	this.scale = scale ? scale : 1;
	
	this._images = images;
	this._currImgIndex = null;
	this._object = elem;
	this._imageElem = document.getElementById(id + "_image");
	var _this = this;
	this._imageElem.GetThis = function() { return _this; }; //See use in e.g. OnMouseDown //FIXME: DELETE
	
	this._defaultZIndex = 200;
	
	//---- Floating variables -----
	this._yPos = null;
	this._xPos = null;
	this._stepLength = 3;
	this._yDir = null;
	this._xDir = null;
	this._speed = null;
	this._floatTimer = null;
	this._newDirTimer = null;
	this._rect = null;
	this._insideX = true;	//Tells whether inside rect
	this._insideY = true;	
	
	//---- Moving with mouse variables ----
	this._isMouseMove = false;
	this._isMouseDown = false;
	this._mouseDownPosX = null;
	this._mouseDownPosY = null;
	var _this = this;
	this._funcPtrOnMouseMove = function(e) { _this.OnMouseMove(e) };
	this._funcPtrOnMouseUp = function() { _this.OnMouseUp() };	
	
	
	//Check if all images are loaded, they should be
	var ok = true;
	for (var i = 0; i < this._images.length; ++i)
		if (!this._images[i].image.complete)
		{
			alert("Hovercraft::Constructor: Error: Image: " + this._images[i].GetSrc() + " is not loaded!");
			ok = false;
		}
	if (ok)	
		this.SetImage(startImage);
		
	//---- Collision Detection ----
	this._cdCollidables = null;
	this._cdCurrCollidable = null;
	this._cdEnabled = true;		
}

Hovercraft.prototype.ClassName = function()
{
	return "Hovercraft";
}

//____ Functions_____
Hovercraft.prototype.SetDefaultZIndex = function(defZIndex)
{
	if (isNaN(defZIndex))
		alert("Howercraft::SetDefaultZIndex: value is not a number.");
	else
		this._defaultZIndex = defZIndex;
}

Hovercraft.prototype.SetImage = function(imageIndex)
{	
	//alert("Hovercraft::SetImage");
	if (isNaN(parseInt(imageIndex)))
	{
		alert("Hovercraft::SetImage: Invalid image index. " + this.GetId());
		return;
	}
	
	if (imageIndex < 0 || imageIndex >= this._images.length)
	{
		alert("Hovercraft::SetImage: Image index: " + imageIndex + " out of range");
		return;
	}
	this._currImgIndex = imageIndex;	

	//this._object.style.backgroundImage = "url('" + this._images[this._currImgIndex].GetSrc() + "')";
	
		
	var width = this._images[this._currImgIndex].GetWidth() * this.scale;
	var height = this._images[this._currImgIndex].GetHeight() * this.scale;
	
	//alert(width +" "+ height);
	
	this._imageElem.src = this._images[this._currImgIndex].GetSrc();
    
    this._imageElem.style.width = width + "px";
    //this._imageElem.height = height + "px";
    
    //alert(width + " "+ this._imageElem.width);
    
	this.SetWidth(width); //this._images[this._currImgIndex].GetWidth());
	this.SetHeight(height);//this._images[this._currImgIndex].GetHeight());
	this.SetZIndex(this._defaultZIndex);
}

Hovercraft.prototype.WhenToBeginFloating = function(maxTimeSec, speed, rect)
{
	if (isNaN(maxTimeSec))
	{
		alert("Howercraft::WhenToBeginFloating: maxTimeSec is not a number.");
		return;
	}
	this._rect = rect;
	
	//Init position
	//this._yPos = Math.floor(Math.random() * (document.body.clientHeight - this.GetHeight()) );
	//this._xPos = Math.floor(Math.random() * (document.body.clientWidth - this.GetWidth()) );
	this._yPos = Math.floor(Math.random() * (this._rect.GetBottom() - this._rect.GetTop() - this.GetHeight()) ) + this._rect.GetTop();
	this._xPos = Math.floor(Math.random() * (this._rect.GetRight() - this._rect.GetLeft() - this.GetWidth()) ) + this._rect.GetLeft();
	
	//alert(this._xPos + " " + this._yPos);
	
	this._object.style.top = this._yPos + "px";
	this._object.style.left = this._xPos + "px";
	
	var _this = this;
	setTimeout( function() { _this.BeginFloating(speed) }, Math.round(Math.random()*maxTimeSec+1) * 1000 );	
}

Hovercraft.prototype.BeginFloating = function(speed)
{
	if (this._rect == null)
	{
		alert("Hovercraft::BeginFloating: Error: A rect is not set.");
		return;
	}
	//alert("Hovercraft::BeginFloating");
	this._speed = speed;
	
	var _this = this;
	//this._newDirTimer = setInterval(function() { _this.NewDirection() }, Math.round(Math.random()*20+1) * 1000 ); //1 to 20 sek
	
	this._newDirTimer = setTimeout(function() { _this.NewDirection() }, 200 );
	this._floatTimer = setInterval( function() { _this.Float() }, this._speed );	

	this.Fade(0.1, 20);
}

Hovercraft.prototype.StopFloating = function()
{
	clearInterval(this._floatTimer);
}

Hovercraft.prototype.Float = function()
{
//	alert("Hovercraft::Float");
	this._yPos = Math.round(this._yPos + this._stepLength * this._yDir);
	this._xPos = Math.round(this._xPos + this._stepLength * this._xDir);		
		
	//------- If outside the rect, float into it -----------
	
	//Check x
	//If left of rect, go right 
	if (this._xPos < this._rect.GetLeft())
	{
		//window.status = "left";
		clearTimeout(this._newDirTimer);
		this._newDirTimer = null;
		this._insideX = false;
		this._xDir = 1;
		this.SetCorrectImage();
	}
	//If right of rect, go left 
	else if ((this._xPos + this.GetWidth()) > this._rect.GetRight())
	{
		//window.status = "right";
		clearTimeout(this._newDirTimer);
		this._newDirTimer = null;
		this._insideX = false;
		this._xDir = -1;
		this.SetCorrectImage();
	}
	//If inside set _insideX so that the newDirTimer interval is set
	else
	{
		//window.status = "";
		this._insideX = true;
	}
	
	//Check y
	//If over of rect, go down 		
	if (this._yPos < this._rect.GetTop())
	{
		//window.status = "top";
		clearTimeout(this._newDirTimer);
		this._newDirTimer = null;
		this._insideY = false;		
		this._yDir = 1;
		this.SetCorrectImage();
	}
	//If under rect, go up
	else if ((this._yPos + this.GetHeight()) > this._rect.GetBottom())
	{
		//window.status = "bottom";
		clearTimeout(this._newDirTimer);
		this._newDirTimer = null;
		this._insideY = false;		
		this._yDir = -1;
		this.SetCorrectImage();
	}	
	//If inside set _insideY so that the newDirTimer interval is set
	else
	{
		//window.status = "";
		this._insideY = true;	
	}
	
	//Check _newDirTimer == null so that the timeout only is set one time	
	if (this._insideY && this._insideX && this._newDirTimer == null)
	{		
		var _this = this;
		this._newDirTimer = setTimeout(function() { _this.NewDirection() }, Math.round(Math.random()*20+1) * 1000 ); //1 to 20 sek
	}
	
	// ----------------------------------------------------------

	// --- move	---
	this.CDSetPos(this._xPos, this._yPos); //... with regard to collison detection
	//this._object.style.top = this._yPos;
	//this._object.style.left = this._xPos;
	
}

Hovercraft.prototype.IsInsideRect = function()
{
	//Left margin
	if (this._xPos < this._rect.GetLeft())
		return false;
	//Right margin
	else if ((this._xPos + this.GetWidth()) >  this._rect.GetRight())
		return false;	
	else if (this._yPos < this._rect.GetTop())
		return false;
	else if ((this._yPos + this.GetHeight()) >  this._rect.GetBottom())
		return false;			
		
	return true;
}

Hovercraft.prototype.NewDirection = function()
{
	//alert("Hovercraft::NewDirection");
	this._xDir = (Math.round( (Math.random()*2)*10 ) / 10) -1 ;  //A number between 1 and -1 rounded to 1 decimal point
	this._yDir = (Math.round( (Math.random()*2)*10 ) / 10) -1 ;
	this._xDir = Math.round(this._xDir*100)/100;  //Elmininate zero decimals
	this._yDir = Math.round(this._yDir*100)/100;

	//- Dont permit this movement, it makes things difficult with the rider
	//- xDir *= -1 has no effect (se Float())
	if(this._xDir == 0) 
		this._xDir += 0.1;	
	if(this._yDir == 0)
		this._yDir += 0.1;

	this.SetCorrectImage();
	var _this = this;
	//WclearTimeout(this._newDirTimer);
	this._newDirTimer = setTimeout(function() { _this.NewDirection() }, Math.round(Math.random()*20+1) * 1000 ); //1 to 20 sek
	//clearInterval(this._newDirTimer);
	//this._newDirTimer = setInterval(function() { _this.NewDirection() }, Math.round(Math.random()*20+1) * 1000 ); //1 to 20 sek
}

Hovercraft.prototype.SetCorrectImage = function()
{
	if(this._xDir > 0)
	{
		this.SetImage(1);
	}
	else if(this._xDir < 0)
	{
		this.SetImage(0);
	}
	
	//If rider
	if (this._cdCurrCollidable != null)
		this.CDSetColliderPos();
}

Hovercraft.prototype.SetMouseMove = function(mouseMove)
{
	var _this = this;
	if (mouseMove)
	{
		this._object.style.cursor = "move";

		//this._imageElem.addEventListener("mousemove", _this.OnMouseMove, false);
		this._imageElem.addEventListener("mousedown", function(e) { _this.OnMouseDown(e) }, false);
		//this._imageElem.addEventListener("mouseup", function() { _this.OnMouseUp() }, false);
	}
}

Hovercraft.prototype.OnMouseOver = function()
{
	
}

Hovercraft.prototype.OnMouseDown = function(e)
{
	//window.status = "Hovercraft::OnMouseDown: " + e.clientX;
	if (this.freezeZIndex == undefined || this.freezeZIndex == false)	
	    this.SetZIndex(1000);
	
	if (this._cdCurrCollidable != null)
		this._cdCurrCollidable.SetZIndex( this.GetZIndex() + 1);
	
	document.body.addEventListener('mousemove', this._funcPtrOnMouseMove, false);
	document.body.addEventListener('mouseup', this._funcPtrOnMouseUp, false);
	
	this._isMouseDown = true;	
	clearInterval(this._floatTimer);

	//Permitts draggin the hovercraft fast... ?
	e.preventDefault();
//	window.lastX=e.clientX;
	//window.lastY=e.clientY;
	
	//e.target = same as this.parentNode, i.e. the div layer
	this._mouseDownPosX = e.clientX - e.target.parentNode.offsetLeft; //offsetLeft gets/sets the number of pixels that the current element is offset to the left within the offsetParent node.
	this._mouseDownPosY = e.clientY - e.target.parentNode.offsetTop; //offsetTop returns the position of the current element relative to the top of the offsetParent node.
		
	//alert(thisHovercraft._mouseDownPosX + " " + thisHovercraft._mouseDownPosY);
			
	return false;  //Important
}

Hovercraft.prototype.OnMouseUp = function()
{
	//window.status = "Hovercraft::OnMouseUp";
	this.SetZIndex(this._defaultZIndex);
	if (this._cdCurrCollidable != null)
		this._cdCurrCollidable.SetZIndex( this.GetZIndex() + 1);	
	
	document.body.removeEventListener('mousemove', this._funcPtrOnMouseMove, false);
	document.body.removeEventListener('mouseup', this._funcPtrOnMouseUp, false);
	
	this._isMouseDown = false;
	var _this = this;
	clearInterval(this._floatTimer);
	this._floatTimer = setInterval( function() { _this.Float() }, this._speed );	
}

Hovercraft.prototype.OnMouseMove = function(e)
{
	//window.status = "Hovercraft::OnMouseMove: " + e.clientX;
	
	if(this._isMouseDown)
	{
				
		this._yPos = e.clientY - this._mouseDownPosY;
		this._xPos = e.clientX - this._mouseDownPosX;
		this.SetTop(this._yPos);
		this.SetLeft(this._xPos);
		
		//If rider
		if (this._cdCurrCollidable != null)
			this.CDSetColliderPos();		
	}
/*
	if(isMouseDown && !isPoleGuyRiding && isRidingPermitted &&
		parseInt(s.left) + parseInt(img.width) >= parseInt(boy.left) &&
     	parseInt(s.left) <= parseInt(boy.left) + parseInt(document.images["poleGuy"].width) &&
	//	parseInt(s.top) + parseInt(img.height) >= parseInt(document.all["smiley"].style.top) && //If s.bottom below guy top
		parseInt(s.top) >= parseInt(boy.top) + parseInt(document.images["poleGuy"].height)*0.7 && //If s.top below knees of guy (so he can jump up)
		parseInt(s.top) <= parseInt(boy.top) + parseInt(document.images["poleGuy"].height)*1.1 //If s.top above (*1.2 little under)bottom of guy
		)
	{
		isPoleGuyRiding = true;
		document.all["smiley"].style.zIndex = 101; //parseInt(s.zIndex)+1;
		changeImage();
		//UpdatePoleGuyRiding();
	}
	*/
	return false;  //Important
}

Hovercraft.prototype.OnResize = function()
{

}

Hovercraft.prototype.FreezeZIndex = function(freeze)
{
    this.freezeZIndex = freeze;
}

//------------ Collision Detection ------------------------------
Hovercraft.prototype.CDSetCollidables = function(collidables)
{
	this._cdCollidables = collidables;	
}

Hovercraft.prototype.CDSetCurrCollidable = function(currCollidable)
{
	this._cdCurrCollidable = currCollidable;
}

Hovercraft.prototype.CDSetPos = function(x,y)
{
	this.SetTop(y);
	this.SetLeft(x);
	
	if (this._cdEnabled)
	{
		if (this._cdCurrCollidable == null) 	//Only permit one rider
			this.CDCheck();
		else
			this.CDSetColliderPos();
	}
}

Hovercraft.prototype.CDCheck = function()
{
	if (this._cdCollidables == null || this._cdCollidables.length <= 0)
	{
		//alert("CDCheck: No collidables set");
		return;
	}
	
	/*	
	var x = this.GetLeft();
	var y = this.GetTop();
	var w = this.GetWidth();
	var h = this.GetHeight();
	
	var collX, collY, collW, collH;*/
	
	for (var i = 0; i < this._cdCollidables.length; i++)
	{
		/*
		collX = this._cdCollidables[i].GetLeft();
		collY = this._cdCollidables[i].GetTop();
		collW = this._cdCollidables[i].GetWidth();
		collH = this._cdCollidables[i].GetHeight();		*/
		
		//If collision
		if (this.CDCheckCitizen(this, this._cdCollidables[i]))
		{
			//Check if the citizen already rides another hovercraft
			//If it does, it should not ride on this one.
			if (this._cdCollidables[i].CDGetCurrCollidable() == null ||
				this._cdCollidables[i].CDGetCurrCollidable().ClassName() != "Hovercraft")
			{
				this._cdCurrCollidable = this._cdCollidables[i];			
				this._cdCurrCollidable.CDDisable(5000);  //Time before the citizen tries to jump to a pole

				//If the object is currently colliding
				/*
				if (this._cdCollidables[i].CDGetCurrCollidable() != null)
				{
					//Tell the obj which it collides with, that it is no longer colliding
					this._cdCurrCollidable.CDGetCurrCollidable().CDSetCurrCollidable(null);
				}*/
				
 				this._cdCurrCollidable.CDSetCurrCollidable(this);			
				this._cdCurrCollidable.DelMouseOverAction(this._cdCurrCollidable.JUMP(), this._cdCurrCollidable);
				
				this.CDSetColliderPos();
				break;
			}			
		}
	}
	
	/*window.status = "Num collidables: " + this._cdCollidables.length + 
					", " + this.GetId() + " (" + x + ", " + y + ", " + w + ", " + h + ")" +
					", Last checked collidable (" + collX + ", " + collY + ", " + collW +
					", " + collH + ")"; 
					//+ ", CDCheckAABB returned: " + this.CDCheckAABB(this, this._cdCollidables[0]) + " for collidable 0";																									   			
*/
}

Hovercraft.prototype.CDCheckCitizen = function(obj1, obj2)
{
	if ( (obj1.GetLeft() + 100) > (obj2.GetLeft() + obj2.GetWidth()) )
		return false;
	if ( (obj1.GetLeft() + obj1.GetWidth() - 100) < obj2.GetLeft() ) 
		return false;
	if ( obj1.GetTop() > (obj2.GetTop() + obj2.GetHeight() + 10) )
		return false
	if ( (obj1.GetTop() + obj1.GetHeight()) < (obj2.GetTop() + obj2.GetHeight() + 20) )
		return false;
		
	return true;	
}

Hovercraft.prototype.CDCheckAABB = function(obj1, obj2)
{
	if ( obj1.GetLeft() > (obj2.GetLeft() + obj2.GetWidth()) )
		return false;
	if ( (obj1.GetLeft() + obj1.GetWidth()) < obj2.GetLeft() ) 
		return false;
	if ( obj1.GetTop() > (obj2.GetTop() + obj2.GetHeight()) )
		return false
	if ( (obj1.GetTop() + obj1.GetHeight()) < obj2.GetTop() )
		return false;
		
	return true;	
}

Hovercraft.prototype.CDSetColliderPos = function()
{
	//window.status = "Hovercraft::CDSetColliderPos";
	if (this._cdCurrCollidable == null)
	{
		alert("Hovercraft::CDSetColliderPos: No current collider");
		return;
	}
	
	var imgIndex;
	if (this._xDir > 0)
		imgIndex = 3;
	else
		imgIndex = 2;
		
	this._cdCurrCollidable.SetImage(imgIndex);		
		
	this._cdCurrCollidable.SetZIndex( this.GetZIndex()+1 )		
	
	var x = parseInt(this.GetLeft()) + parseInt(this.GetWidth())/2 - parseInt(this._cdCurrCollidable.GetWidth())/2;
	var y =  parseInt(this.GetTop()) + this._cdCurrCollidable.GetImages()[imgIndex].GetBottomLine() - parseInt(this._cdCurrCollidable.GetHeight()); 
	
	this._cdCurrCollidable.CDSetPos(x,y);
}

Hovercraft.prototype.CDDisable = function(time)
{
	this._cdEnabled = false;
	var _this = this;
	setTimeout( function() { _this._cdEnabled = true; }, time);
}
