/**
 * Map
 * @classDescription  
 * @dependence        Mootools (http://www.mootools.net)
 * @author            Aken.li (http://www.kxbd.com)
 * @created           2009-11-25
 */
var Map = new Class({

	Implements: [Options,Events],
	
	options:{
		snowMax:20,
		snowInit:5,
		snowInterval:400,
		ladderMax:12,
		ladderInit:6,
		ladderInterval:300,
		moveInterval:30,
		bouncePower:20,
		hitTestDistance:20,
		hitInterval:30,
		starsMax:10
	},
	
	initialize:function(pId, options){
		this.setOptions(options);
		this.y = 0;
		this.arrSnow = [];
		this.arrLadder = [];
		this.score = 0;
		this.map = $(pId);
		this.scene = this.map.getParent();
		
		this.player = this.playerCreate();
		this.snowInit();
		this.ladderInit();
		this.attachEvent();
	},

	playerCreate:function(){
		return new Player(this.map);
	},

	attachEvent:function(){
		this.moveTimer = this.move.periodical(this.options.moveInterval,this);
		this.hitTimer = this.checkHit.periodical(this.options.hitInterval,this);
		this.startPlay = this.player.jump.bind(this.player);
		this.map.addEvent('click', this.startPlay);
		this.player.addEvent('gameOver', this.gameOver.bind(this));
		$('playAgain').addEvent('click', this.playAgain.bind(this));
	},

	ladderCreate:function(){
		if (this.arrLadder.length < this.options.ladderMax) {
			if (this.arrLadder.length >= 1) {
				var _y = this.arrLadder[this.arrLadder.length - 1].y;
			}
			var _ladder = new Ladder(30 + 660 * Math.random(), _y - 100 || 0, this.map);
			this.arrLadder.push(_ladder);
			_ladder.addEvent('ladderRemove', this.ladderRemoveArr.bind(this));
		}
	},
	
	ladderInit:function(){
		for (var i= 0; i < this.options.ladderInit; i++) {
			this.ladderCreate();
		}
		this.ladderTimer = this.ladderCreate.periodical(this.options.ladderInterval,this);
	},

	ladderRemoveArr:function(elt){
		this.arrLadder.splice(this.arrLadder.indexOf(elt), 1);
	},

	ladderRemove:function(){
		for (var i = 0; i < this.arrLadder.length; i++) {
			var _ladder = this.arrLadder[i];
			if (_ladder.y> this.player.y + 400) {
				_ladder.remove();
			}
		}
	},

	snowCreate:function(isInit){
		if (this.arrSnow.length < this.options.snowMax) {
			var _y = (isInit == true)?200:50;
			var s = new Snow(750*Math.random(), (this.player.y-480)+_y*Math.random(), this.map, {
				rangeX: 1 + 2*Math.random(),
				speedY: 1.5+Math.random(),
				scale: parseInt(10 + Math.random() * 10)
			});
			this.arrSnow.push(s);
			s.addEvent('snowRemove', this.snowRemoveArr.bind(this));
		}
	},

	snowInit:function(){
		for (var i = 0; i < this.options.snowInit; i++) {
			this.snowCreate(true);
		}
		this.snowTimer = this.snowCreate.periodical(this.options.snowInterval,this);
	},

	snowRemoveArr:function(elt){
		this.arrSnow.splice(this.arrSnow.indexOf(elt), 1);
	},

	snowRemove:function(){
		for (var i = 0; i < this.arrSnow.length; i++) {
			var _s = this.arrSnow[i];
			if (_s.y> this.player.y + 400) {
				_s.remove();
			}
		}
	},

	move:function(){
		if (this.player.y < 250) {
			this.y = this.y -(this.player.y - 250 + this.y)*0.15 ;
		}else {
			this.y -= this.y*.3;
		}
		this.render();

		this.ladderRemove();
		this.snowRemove();
	},

	render:function(){
		this.map.setStyle('top',this.y);
	},

	checkHit:function(){
		for (var i = 0; i < this.arrLadder.length; i++) {
			var _ladder = this.arrLadder[i];
			if (!_ladder.isHited && this.hitTest(this.player, _ladder)) {
				if (this.player.isLiving == false) {
					this.player.isLiving = true;
					//dispatchEvent(new Event('gameStart'));
				}
				this.player.speedY = this.options.bouncePower;
				this.score += _ladder.score;
				this.showScore(_ladder.score, _ladder.x, _ladder.y);
				this.showEffect(_ladder.x, _ladder.y);
				_ladder.isHited = true;
				_ladder.remove();
			};
		}
	},

	hitTest:function(elt1, elt2){
		var _dis = this.options.hitTestDistance;
		var _disX = Math.abs(elt2.x+elt2.width*0.5-elt1.x-elt1.width*0.5);
		var _disY = Math.abs(elt2.y+elt2.height*0.5-elt1.y-elt1.height*0.5);
		if(_disX<_dis&&_disY<_dis){
			return true;
		}else{
			return false;
		}
	},

	showScore:function(pScore,pX,pY){
		$('score').set('text', 'Score: '+ this.score);
		var _score = new ScoreText(pX, pY, this.map);
	},
	
	showEffect:function(pX, pY){
		for (var i = 0; i < this.options.starsMax; i++) {
			var _s = new Star(pX, pY, Math.PI*2*i/this.options.starsMax, this.map);
		}
	},

	gameOver:function(){
		this.snowTimer = $clear(this.snowTimer);
		for (var i = 0, _len= this.arrSnow.length; i < _len; i++) {
			this.arrSnow[0].remove();
		}

		this.ladderTimer = $clear(this.ladderTimer);
		for (i = 0, _len=this.arrLadder.length; i < _len; i++) {
			this.arrLadder[0].remove();
		}
		this.y = 0;
		this.render();

		this.map.removeEvent('click', this.startPlay);

		this.showGameOver();
		
	},

	showGameOver:function(){
		var _high = Cookie.read("IntoTheSky")||0;
		$('gameOver').setStyle('display','block');
		$('yourScore').set('text', this.score);
		if(this.score>_high){
			$('highScore').set('text', this.score);
			Cookie.write("IntoTheSky", this.score)
		}else{
			$('highScore').set('text', _high);
		}
		
	},

	playAgain:function(){
		$('gameOver').setStyle('display','none');
		this.score = 0;
		$('score').set('text','Score: '+0);
		this.snowInit();
		this.ladderInit();
		this.map.addEvent('click', this.startPlay);
	}

});

