/**
 * @author bruno DA SILVA
 * @license GPL V3
 * 
 * 
 
 	This file is part of weukerDefense.js

    weukerDefense.js is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    weukerDefense.js is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with weukerDefense.js.  If not, see <http://www.gnu.org/licenses/>.

 */

var Config = Class.create({
	nbWeuk : 20
	, GameWidth : 800
	, GameHeight : 600
	, pathWidth : 30
	, getPathCoords : function() {
		var paths = new Array();
		paths.push({startX:0  , startY: 0	, endX : 50, endY:0});
		paths.push({startX:50, startY: 0	, endX : 50, endY:200});
		paths.push({startX:50, startY: 200	, endX : 200, endY:200});
		paths.push({startX:200, startY: 200	, endX : 200, endY:250});
		paths.push({startX:200, startY: 250	, endX : 300, endY:250});
		paths.push({startX:300, startY: 250	, endX : 300, endY:300});
		paths.push({startX:300, startY: 300	, endX : 400, endY:300});
		paths.push({startX:400, startY: 300	, endX : 400, endY:420});
		paths.push({startX:400, startY: 420	, endX : 480, endY:420});
		paths.push({startX:480, startY: 420	, endX : 480, endY:this.GameHeight - 20});
		paths.push({startX:480, startY: this.GameHeight - 20	, endX : this.GameWidth - 20, endY:this.GameHeight - 20 } );
		return paths;
	}
	//init modif des param en fonction de la page
	, init: function() {
		
	}, getDelayBetweenWeuk: function(vagueNumber) {
		return 1.5 - parseInt(vagueNumber/2) * 0.1
	}, getWeukPerVague: function(vagueNumber) {
		return 9 + parseInt(vagueNumber * vagueNumber * 5) 
	}, getWeukSpeed: function(vagueNumber, distance) {
		return 1000/distance + parseInt(vagueNumber / 3) * 0.2;
	}, getWeukMoveVelocity: function(targetPos, currPos) {
		if (targetPos == undefined) {
			return {
				x: 0,
				y: 0
			};
		} else {
			return {
				x: this.getMaxifiedDiff(targetPos.end.x, currPos.x, 1, 0),
				y: this.getMaxifiedDiff(targetPos.end.y, currPos.y, 1, 0)
			};
		}
	}, getWeukMoveRefreshSpeed: function() {
		return 0.1;
	}, getMaxifiedDiff: function(a, b, max, min) {
		if (Math.abs(a - b) < max) {
			if (Math.abs(a - b) > min) {
				return min;
			} else {
				return a - b;
			}
		} if (a < b) {
			return -max;
		} else {
			return max;
		}
	}, getMinDelayBetweenVague: function() {
		return 15;
	},gold: 0
	, getGold: function() {
		return this.gold;
	}, addGold: function(gold) {
		this.gold = parseInt(this.gold) + parseInt(gold);
		$('nbGold').update(this.gold + ' Golds');
	}
	 
});




var Shoot = Class.create({
	initialize : function(weukId, towerId, initialCoord, specialClass) {
		var cssClass 	= 'shoot '+weukId+' '+towerId+' '+specialClass;
		var cssId 		= 'shoot-'+weukId+'-'+towerId
		
		var div = new Element('div', { 
			class: cssClass
			, id: cssId
		}).setStyle({
		  top: initialCoord.y+'px',
		  left: initialCoord.x +'px'
		});
		
		$("gameContent").appendChild(div);
	}
});

var Path = Class.create({
	initialize : function(start, end, index) {
		this.start 	= start;
		this.end 	= end;
		this.index	= index;
		var elmt = new Element('div', { 
			'class': this.toCssClass()
			, 'id': this.toCssId()
		});	
		$("gameContent").appendChild(elmt);
	}, toCssClass : function() {
		return 'path '+this.index
	}, toCssId : function() {
		return 'path_'+this.index
	}, toWidth : function() {
		return (Math.abs(this.start.x - this.end.x)<10?10:Math.abs(this.start.x - this.end.x));
	}, toHeight : function() {
		return (Math.abs(this.start.y - this.end.y)<10?10:Math.abs(this.start.y - this.end.y));
	}, init : function() {
		new Effect.Morph(this.toCssId(), {
				style: 'top:'+this.start.y+'px; left:'+this.start.x+'px;width:'+this.toWidth()+'px; height: '+this.toHeight()+'px'
				, duration: 3 
		});
	}
});

var Coord = Class.create({
	initialize : function(x, y) {
		this.x = x;
		this.y = y;
	}
});

var Game = Class.create({		
	init : function() {
		new Effect.Morph('gameContent', {
				style: 'background:#7BC4F4; width: '+conf.GameWidth+'px; height: '+conf.GameHeight+'px'
				, duration: 0.2 
		});
		this._initializePath();
		this._initializeTowerSelector();
		this._addMethods();
		this.vagueDeWeuks = new VagueDeWeuks(this.pathArray);
		this.vagueDeWeuks.startVague();
		this.towers = new TowerCollection();
		this.avance();
		conf.addGold(200);
	}
	, _initializePath : function() {
		this.pathArray = new Array();
		pathCoords = conf.getPathCoords();
		pathCoords.each(function(pathData, index) {
			path = new Path(  new Coord(pathData.startX, pathData.startY)
							, new Coord(pathData.endX, pathData.endY)
							, index
			);
			path.init();
			this.pathArray.push(path);
		}, this);
	}, _initializeTowerSelector : function() {
		Event.observe('toggleTowerContener', 'click', function(event) {
			game.toggleChoosedTowerType(event.target.identify());
		});
	}, toggleChoosedTowerType: function(towerType) {
		this.towers.toggleChoosedTowerType(towerType);
	}, avance: function() {
		var self = this;
		this.pe = new PeriodicalExecuter(function(pe) {
			self.vagueDeWeuks.avance();			
			self.towers.shoot(self.vagueDeWeuks);
			$$('.shoot').each(function(shootElmt, shootIndex) {
				shootElmt.shootAvance();
			});
			var now = new Date();
			if (self.vagueDeWeuks.weukActif == false) {
				self.vagueDeWeuks.reset();
				self.vagueDeWeuks.startVague();
			} else if (self.vagueDeWeuks.actif == false && Math.abs(self.vagueDeWeuks.StoppedDate.getSeconds() - now.getSeconds()) > conf.getMinDelayBetweenVague()) {
				self.vagueDeWeuks.startVague();
			}
			
		}, conf.getWeukMoveRefreshSpeed());
	}, _addMethods: function() {
		Element.addMethods('DIV', {
			shootAvance: function(self) {
				var data = self.identify().split(/-/);
				var weukId 	= data[1];
				var towerId	= data[2];
				var specialClass = data[3];
				var weukElmt = $(weukId);
				
				if (null == weukElmt || undefined == weukElmt) {
					self.shootExplode('', '', '');
					return;
				}
				
				var selfX = parseInt(self.getStyle('left').replace(/px/,''));
				var selfY = parseInt(self.getStyle('top').replace(/px/,''));
				
				var weukX = weukElmt.getStyle('left').replace(/px/,'');
				var weukY = weukElmt.getStyle('top').replace(/px/,'');
				
				
				var x = - conf.getMaxifiedDiff(selfX, weukX, 2, 0);
				var y = - conf.getMaxifiedDiff(selfY, weukY, 2, 0);

				
				if (x == 0 && y == 0) {
					self.shootExplode(weukId, towerId, specialClass);
				} else {
					self.setStyle({
					  left: (parseInt(selfX) + parseInt(x))+'px',
					  top: (parseInt(selfY) + parseInt(y))+'px'
					});
				}
				
			}, shootExplode: function(self, weukId, towerId, specialClass) {
				self.removeClassName('shoot');
				self.removeClassName('shoot').addClassName('explosion');
				
				//self.update('boom!');
				//Effect.Puff(self, { duration: 3, afterFinish:function(self){$(self).remove();} });
				self.remove();
				
				game.shootSuccessed(weukId, towerId, specialClass);
			}
		})
	}, shootSuccessed: function(weukId, towerId, specialClass) {
		var weuk = this.vagueDeWeuks.get(weukId);
		if (null != weuk) {
			weuk.shooted(specialClass);
		}
		var tower = this.towers.get(towerId);
		if (null != tower) {
			tower.shootSuccessed();
		}
	}
});
var conf = new Config();
var game = new Game();

Event.observe(window, 'load', function() {
	conf.init();
	game.init();
});