var reWord=/(\S+)/g
var reSpace=/\s+$/
var oFloatFragment;
var aSpans=[];
var aOptWords=[]

var iDx, iDy;

var aStack=[]
aStack.add=function(obj){
	return this.push(obj) - 1;
}

/* Some useful prototypes */

String.prototype.IsWhiteSpace=function(){
	return !(this.valueOf().replace(/\s+/g, ''));
}

Number.prototype.good_coeff=function(){
	return (Math.abs(this.valueOf()) - .02) > 0;
}

/* Word functions */

function TextScanner(){
	var oParent=document.getElementById('content');
	NodeScan(oParent);
	
	var oSpan=oParent.getElementsByTagName('span');
	for(var i=0; i<oSpan.length; i++){
		if(oSpan[i].className == 'float-word')
			aSpans.push(new FloatWordClass(oSpan[i]));
	}
	OptimizeWords();
}

function NodeScan(oNode){
	var oSpan, sText;
	if(oNode.hasChildNodes()){
		for(var i=0; i<oNode.childNodes.length; i++){
			NodeScan(oNode.childNodes[i]);
		}
	}
	else if(oNode.nodeType == 3 && AllowedNode(oNode.parentNode) && !oNode.nodeValue.IsWhiteSpace()){
		oSpan=document.createElement('span');
		oSpan.innerHTML=oNode.nodeValue.replace(reWord, '<span class="float-word">$1</span>');
		oNode.parentNode.replaceChild(oSpan, oNode);
	}
}

function OptimizeWords(){
	aOptWords=[];
	var y1=Boat.oShape.y;
	var y2=y1+Boat.oShape.h;
	var s;
	for(var i=0; i<aSpans.length; i++){
		s=aSpans[i].oShape;
		if(y2 >= s.y && y1 <= s.y+s.h)
			aOptWords.push(aSpans[i]);
	}
}

function AllowedNode(oNode){
	return (oNode.nodeName!='SCRIPT' && oNode.nodeName!='BUTTON');
}

/* Animation functions */

function getAbsolutePos(oElem){
	var _x=0;
	var _y=0;
	if(oElem){
		do{
			_x+=oElem.offsetLeft;
			_y+=oElem.offsetTop;
		}while( (oElem=oElem.offsetParent) )
	}
	
	return {x: _x, y: _y};
}

function anim(){
	var v=0;
	Boat.MoveX(Boat.oShape.x+2);
	for(var i=0; i<aOptWords.length; i++){
		if((v=Boat.HitTest(aOptWords[i])))
			aOptWords[i].bounce(10, v);
		if(aOptWords[i].play)
			aOptWords[i].bounce_anim();
	}
	
	if(Boat.oShape.x > 3000)
		clearInterval(idInterval);
}

function InsidePolygon(aPolygon, p){
	var counter = 0;
	var i, xinters, p1, p2, l;
	p1 = aPolygon[0];
	l=aPolygon.length;
	for (i=1;i<=l;i++){
		p2 = aPolygon[i % l];
		if(
			(p.y > Math.min(p1.y,p2.y)) && 
			(p.y <= Math.max(p1.y,p2.y)) && 
			(p.x <= Math.max(p1.x,p2.x)) && 
			(p1.y != p2.y)
		){
			xinters = (p.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x;
			if (p1.x == p2.x || p.x <= xinters)
				counter++;
		}
		p1 = p2;
	}

    return !(counter % 2 == 0);
}

window.onresize=function(){
	for(var i=0; i<aSpans.length; i++){
		aSpans[i].RecalcPos();
	}
	OptimizeWords();
	Boat.CalcPos();
}

/* Classes */

function Rect(){
	if(arguments.length == 1){
		var oPos=getAbsolutePos(arguments[0]);
		this.x=oPos.x;
		this.y=oPos.y;
		this.w=arguments[0].offsetWidth;
		this.h=arguments[0].offsetHeight;
	}
	else if(arguments.length == 4){
		this.x=arguments[0];
		this.y=arguments[1];
		this.w=arguments[2];
		this.h=arguments[3];
	}
	else{
		return null;
	}
}

Rect.prototype.toString=function(){
	return 'x: '+this.x+', y: '+this.y+', width: '+this.w+', height: '+this.h;
}

function Point(x, y){
	this.x=x;
	this.y=y;
}

Point.prototype.toString=function(){
	return 'x: '+this.x+', y: '+this.y;
}

var Boat=function(){}

Boat.Init=function(){
	this.oPtr=document.getElementById('Boat');
	this.CalcPos();
	this.aUpCP=[new Point(140, 6), new Point(189, 14), new Point(227, 28), new Point(227, 50), new Point(17, 50), new Point(17, 30), new Point(24, 13)];
	this.aDownCP=[new Point(146, 54), new Point(191, 46), new Point(227, 28), new Point(227, 10), new Point(17, 10), new Point(17, 30), new Point(25, 47), new Point(104, 54)];
}

Boat.CalcPos=function(){
	this.oShape=new Rect(this.oPtr)
	this.iMiddle=this.oShape.y+30;
	this.oShape._y=this.oShape.y;
	this.oShape.h=56;
	this.oShape.dx=getAbsolutePos( document.getElementById('BoatWrap') ).x;
}

Boat.Move=function(x, y){
	this.MoveX(x);
	this.MoveY(y);
}

Boat.MoveX=function(x){
	this.oPtr.style.left=(x-this.oShape.dx)+'px';
	this.oShape.x=x;
}

Boat.MoveY=function(y){
	this.oPtr.style.top=y+'px';
	this.oShape.y=y;
	this.oShape._y=y;
}

Boat.HitTest=function(oWord){
	return ((oWord.oShape.y+oWord.oShape.h/2) > this.iMiddle) ? this._inDown(oWord) : this._inUp(oWord);
}

Boat._inUp=function(oWord){
	var p1, p2;
	var s=oWord.oShape;
	var t=this.oShape;
	var cx1=s.x-t.x;
	var cx2=cx1+s.w;
	var cy=s.y+s.h-t.y;
	
	if(InsidePolygon(this.aUpCP, new Point(cx1, cy)) || InsidePolygon(this.aUpCP, new Point(cx2, cy)))
		return -1;
	else
		return 0;
}

Boat._inDown=function(oWord){
	var p1, p2;
	var s=oWord.oShape;
	var t=this.oShape;
	var cx1=s.x-t.x;
	var cx2=cx1+s.w;
	var cy=s.y-t.y;
	
	if(InsidePolygon(this.aDownCP, new Point(cx1, cy)) || InsidePolygon(this.aDownCP, new Point(cx2, cy)))
		return 1;
	else
		return 0;
}

function FloatWordClass(oElem){
	this.Init(oElem);
}

FloatWordClass.prototype.Init=function(oElem){
	this.oElem=oElem;
	
	this.RecalcPos();
	
	this._a=.03;
	this._b=.039;
	this._d=.1;
	this.a=0;
	this.b=0;
}

FloatWordClass.prototype.RecalcPos=function(){
	this.oShape=new Rect(this.oElem);
	this.oShape._x=this.oShape.x;
	this.oShape._y=this.oShape.y;
}

FloatWordClass.prototype.bounce=function(vector, dir){
	if(this.a < Math.PI/2)
		this.a=Math.PI-this.a;
	this.d=vector*5;
	this.dir=dir;
	if(!this.play)
		this.b=Math.PI;
	this.play=1;
}

FloatWordClass.prototype.bounce_anim=function(){
	if(this.b > 0){
		var dx=Math.abs(Math.sin(this.b))*this.d;
		this.oElem.style.left=-dx+'px';
		this.oShape.x=this.oShape._x-dx;
		this.b-=this._b;
	}
	
	if(this.a.good_coeff() && this.d.good_coeff()){
		var dy=Math.abs(Math.sin(this.a))*this.d*this.dir;
		this.oElem.style.top=dy+'px';
		this.oShape.y=this.oShape._y+dy;
		this.a-=this._a;
		this.d-=this._d;
	}
	else{
		this.oElem.style.top='0px';
		this.oElem.style.left='0px';
		this.oShape.y=this.oShape._y;
		this.oShape.x=this.oShape._x;
		this.play=0;
	}
}