/*
 ===================================================
 Main ingame layer, where all gameplay events happen 
 ===================================================
 */

var GameLayer = cc.Layer.extend({
	_levelBG:null,
	_level:null,
	_HUD:null,
	_ItemsBatch:null,
	_ItemsList:null,
	_manager:null,
	_timer:null,
	_roundLabel:null,
	_scoreLabel:null,
	_bonusLabel:null,
	_winSize:null,
	_resultsWindow:null,
	_score:0,
	_deltaFrame:0,
	_streakCounter:0,
	_clickLocation:null,
	_itemClickAction:null,
	_hintParticle:null,
	_anticlicker:null,
	_oldDistance:null,
	_previousTouchLocation:null,
	_touchEnded:true,
	_multiTouchEnded:true,
	_invisibleCanvasLayer:null, //used for moving BG, items and hint particles during
								//zooming-dragging routines
	_checkList:null,
	_bezier:null,
	pickedItems:null,
	
	ctor:function () {
		this._super();
		this.init();
	},

	init:function () {
		this._winSize = cc.director.getWinSize();
		this._manager = GameManager.getInstance();
		this._manager.setGameState(SS.GAME_STATE.PLAYING);
		this._level  = GameManager.getInstance().getSelectedLevel();
		this._deltaFrame = cc.director.getTotalFrames();
		this.pickedItems = new Array();
		//======HINT===
		this._hintParticle = new Hint();	
		this.addChild(this._hintParticle,FOREGROUND);	
	
		//======HUD=========
		this._HUD = new HUDLayer();
		this.addChild(this._HUD, FOREGROUND);
		//=====TIMER======
		if(this._manager.getGameMode() == SS.GAME_MODE.HARDCORE){
			this._timer = new Timer();
			this.addChild(this._timer,FOREGROUND,99);
		}
		//====Score Label====		
		if(this._manager.getGameMode() == SS.GAME_MODE.HARDCORE){
			this._scoreLabel = new cc.LabelTTF("Score:" + this._score.toString(10), "Old English Text MT", 40);
			this._scoreLabel.color = cc.color(253, 211,129);
			this._scoreLabel.setOpacity(180);
			this.addChild(this._scoreLabel,FOREGROUND);
			this._scoreLabel.attr({
				x:10,
				y:710,
				anchorX:0,
				anchorY:0,
			})
		}
		//====Bonus Label====
		this._bonusLabel = new cc.LabelTTF("", "Old English Text MT", 50);
		this._bonusLabel.color = cc.color(253, 211,129);
		this._bonusLabel.attr({
			x:this._winSize.width/2,
			y:this._winSize.height/1.5
		})
		this.addChild(this._bonusLabel,FOREGROUND);
		//====Round Label====
		if(this._manager.getGameMode() == SS.GAME_MODE.HARDCORE){
			var round = this._manager.getCurrentRound();
			var str = sprintf("Round %d", round.ID);
			this._roundLabel = new cc.LabelTTF(str, "Old English Text MT", 100);
			this._roundLabel.setScale(0.2);
			this._roundLabel.color = cc.color(253, 211,129);
			this._roundLabel.attr({
				x:this._winSize.width/2,
				y:this._winSize.height/2
			})
			this.addChild(this._roundLabel,FOREGROUND);
			
			var actionTo = cc.scaleTo(0.2, 1);
			var action2 = cc.fadeOut(1.0);
			
			this._roundLabel.runAction(cc.sequence(cc.delayTime(0.5),actionTo, cc.delayTime(0.5),action2));
		}
		//======ItemsList========
		this._ItemsList = new ItemsList();
		this.addChild(this._ItemsList,FOREGROUND);
		this._checkList = this._ItemsList.getItems().slice();
		//=======Invisible Canvas Layer=====
		this._invisibleCanvasLayer = new cc.Layer();
		this.addChild(this._invisibleCanvasLayer, BACKGROUND);
		this._invisibleCanvasLayer.attr({
			anchorX:0,
			anchorY:0
		});
		//=======Background========
		this._levelBG = new cc.Sprite(this._level.SpritePath);
		this._levelBG.attr({
			anchorX:0,
			anchorY:0
		});
		this._invisibleCanvasLayer.addChild(this._levelBG, BACKGROUND);	
		//=======ItemBatch========
		cc.spriteFrameCache.addSpriteFrames(this._level.AtlasPlist);
		var batch = cc.textureCache.addImage(this._level.AtlasPNG);
		this._ItemsBatch = new cc.SpriteBatchNode(batch);
		this._ItemsBatch.attr({
			x:0,
			y:0,
			anchorX:0,
			anchorY:0
		})
		this._invisibleCanvasLayer.addChild(this._ItemsBatch, FOREGROUND);
		//=======Items' sprites========
		var itemNode = null;
		var zOrder = this._level.ItemsCount;
		var Tag = this._level.ItemsCount;
		for(var item in this._level.Items){
			itemNode = new Item(cc.spriteFrameCache.getSpriteFrame(this._level.Items[item].SpritePath));
			itemNode.setAnchorPoint(cc.p(0.5,0.5));
			itemNode.setPosition(this._level.Items[item].Position);
			this._ItemsBatch.addChild(itemNode, zOrder--, Tag--);
			
			itemNode.setTitle(this._level.Items[item].Title);
		}
		//======Mouse Events=====
		this.initEvents();
		//======Anticlicker===
		this._anticlicker = new Anticlicker();
		this.addChild(this._anticlicker, FOREGROUND);
		
		this.scheduleUpdate();
	},

	onCallback:function(dic){	
		this._ItemsList.removeItem(dic["label"], 1);	
		dic["item"].removeFromParent(true);	
	},
	
	update:function () {		
		if( this._manager.getGameMode() == SS.GAME_MODE.RELAX ){
			if(this._manager.getGameState() == SS.GAME_STATE.ROUND_END) {
				this.showResults();
			}
		}
		else{
			if(this._manager.getGameState() == SS.GAME_STATE.ROUND_END){
				if( !this._manager.setNextRound() ) {		
					this.showResults();
				}
				
				else {
					this._ItemsList.init();
					this.resetGame();
				}
			}
			else if(this._manager.getGameState() == SS.GAME_STATE.GAME_OVER)this.showResults();
		}
		if(this.pickedItems.length){
			for(var i = 0 ; i < this.pickedItems.length; i++){		
				var oldpos  = this.pickedItems[i].prevPosition ? this.pickedItems[i].prevPosition
						: this.pickedItems[i].getPosition();
				var newpos  = this.pickedItems[i].getPosition();
				this.pickedItems[i].prevPosition = newpos;
				var angle = Math.atan2(-newpos.y + oldpos.y, newpos.x - oldpos.x) * 180 / Math.PI;
				this.pickedItems[i].setRotation(angle);
			}
		}
	},
	
	
	//---------Here you put your bonus calculating logic---------	
	calculateScore:function(){
		if(this._manager.getGameMode() == SS.GAME_MODE.RELAX) return;
		var string = "";
		this._score += ITEM_SCORE;
		var deltaScore = ITEM_SCORE;
		var df = cc.director.getTotalFrames();
		if(df - this._deltaFrame <= 120){
			this._score += ITEM_SPEED_BONUS;
			deltaScore += ITEM_SPEED_BONUS;
			this._streakCounter++;
			string = "Speed Streak!";	
		}else{
			this._streakCounter = 0;
		}
		if(this._streakCounter >= 2){
			this._score += ITEM_STREAK_BONUS_3;
			deltaScore += ITEM_STREAK_BONUS_3;
			string = "Speed Streak x3!";	
		}
		if(this._streakCounter >= 4){
			this._score += ITEM_STREAK_BONUS_5;
			deltaScore += ITEM_STREAK_BONUS_5;
			string = "Speed Streak x5!";	
		}
		if(this._streakCounter >= 6){
			this._score += ITEM_STREAK_BONUS_7;
			deltaScore += ITEM_STREAK_BONUS_7;
			string = "Speed Streak x7!";	
		}
		this._deltaFrame = df;
		var scoreTTF = new cc.LabelTTF(deltaScore.toString(), "Old English Text MT", 30);
		scoreTTF.color = cc.color(253, 211,129);
		scoreTTF.runAction(cc.fadeOut(1.0));
		scoreTTF.setPositionX(this._clickLocation.x);
		scoreTTF.setPositionY(this._clickLocation.y + 20);
		this.addChild(scoreTTF, FOREGROUND);
		
		var s = this._bonusLabel.getString();
		if(	this._streakCounter){
			if(this._bonusLabel.getString() != string || this._bonusLabel.getOpacity() <100 ){
				this._bonusLabel.setString(string);	
				this._bonusLabel.stopAllActions();
				this._bonusLabel.setOpacity(255);
				this._bonusLabel.runAction(cc.fadeOut(2) );
			}
		}
		this._scoreLabel.setString("Score:" + this._score.toString(10));
	},
	
	BonusCallback:function(){
		this._bonusLabel.setString("");
	},
	
	initEvents:function(){
		cc.eventManager.addListener({
			event: cc.EventListener.TOUCH_ONE_BY_ONE,

			onTouchBegan: function (touch, event) {	
				var target = event.getCurrentTarget();
				if(GameManager.getInstance().getGameState() == SS.GAME_STATE.FROZEN
						||!target._touchEnded) return false;				

				var locationInNode = target._clickLocation = target.convertToNodeSpace(touch.getLocation());
				var locationInBatchNode = target._ItemsBatch.convertToNodeSpace(touch.getLocation());

				var childrenBatch = target._ItemsBatch.getChildren();
				var s = null;
				var rect = null;

				var List = target._ItemsList.getItems();

				for(var i = 0; i < childrenBatch.length; i++){
					s = childrenBatch[i].getContentSize();
					var Pos = target._ItemsBatch.convertToWorldSpace(cc.p(childrenBatch[i].getPositionX()-s.width/2, 
							childrenBatch[i].getPositionY()-s.height/2));
					var x = childrenBatch[i].getPositionX()-s.width/2;
					var y = childrenBatch[i].getPositionY()-s.height/2;

					var scale = target._invisibleCanvasLayer.getScale();
					rect = cc.rect( Pos.x, 
							Pos.y, 
							s.width*scale, 
							s.height*scale);	

					var flag = 0;
					if (cc.rectContainsPoint(rect, locationInNode)) {  
						for(var j = 0; j< target._checkList.length;j++){
							var o = target._checkList[j].getString();
							if( childrenBatch[i].getTitle() == target._checkList[j].getString() ){	
								for(var n = 0; n < List.length;n++){
									if( List[n].getString() == target._checkList[j].getString() ){
									
										target._ItemsBatch.reorderChild(childrenBatch[i], childrenBatch.length);
										target.pickupAnimation(target, childrenBatch[i], List[n]);
										target._checkList.splice(j,1);
											
										cc.audioEngine.playEffect(res.pickup_mp3);			
									
										target.calculateScore();
										flag = 1;
										break;
									}
								}
							}
						}

					}
					if(flag) break;
				}
				if(!target._checkList.length){
					target._manager.setGameState(SS.GAME_STATE.ROUND_END);
				}	

				if(!flag) {					
					cc.audioEngine.playEffect(res.wrong_click_mp3);								
				}
				target._anticlicker.checkClick(flag);
				target._touchEnded = false;
				return true;
			},

			onTouchMoved: function (touch, event) {	
				var target = event.getCurrentTarget();
				if(GameManager.getInstance().getGameState() == SS.GAME_STATE.FROZEN
						||!target._multiTouchEnded
						||  GameManager.getInstance().getGameState() == SS.GAME_STATE.FALLING_ITEM) return;						
				var locationInNode = target._clickLocation = target.convertToNodeSpace(touch.getLocation());
				var scale = target._invisibleCanvasLayer.getScale();
				if(!target._previousTouchLocation)
					target._previousTouchLocation = target._clickLocation;

				var deltaPoint = cc.pSub(target._clickLocation, target._previousTouchLocation);
				var newLevelBGPosition = cc.pAdd(target._invisibleCanvasLayer.getPosition(), deltaPoint);
				var levelBGContentSize = target._levelBG.getContentSize();
				levelBGContentSize.width  *= scale;
				levelBGContentSize.height *= scale;

				if(newLevelBGPosition.x > 0)newLevelBGPosition.x = 0;					
				if(newLevelBGPosition.y > 0)newLevelBGPosition.y = 0;
				if(newLevelBGPosition.y + levelBGContentSize.height < target._winSize.height)
					newLevelBGPosition.y = target._winSize.height - levelBGContentSize.height;					
				if(newLevelBGPosition.x + levelBGContentSize.width < target._winSize.width)
					newLevelBGPosition.x = target._winSize.width  - levelBGContentSize.width;

				deltaPoint = cc.pSub(newLevelBGPosition,target._invisibleCanvasLayer.getPosition());

				target._invisibleCanvasLayer.setPosition(newLevelBGPosition);
				target._previousTouchLocation = target._clickLocation;
			},
			onTouchEnded: function (touch, event) {	
				var target = event.getCurrentTarget();
				target._previousTouchLocation = null;
				target._touchEnded = true;
			}			
		}, this);

		//=======MULTITOUCH=====
			cc.eventManager.addListener({
				event: cc.EventListener.TOUCH_ALL_AT_ONCE,

				onTouchesBegan: function (touches, event) {						
					if(GameManager.getInstance().getGameState() == SS.GAME_STATE.FROZEN
						||  GameManager.getInstance().getGameState() == SS.GAME_STATE.FALLING_ITEM) return;
					if(touches.length != 2) return;

					var target = event.getCurrentTarget();				
					var touch1 = touches[0];
					var touch2 = touches[1];

					var touch1_locationInNode = target.convertToNodeSpace(touch1.getLocation());
					var touch2_locationInNode = target.convertToNodeSpace(touch2.getLocation());

					target._oldDistance = cc.pDistance(touch1_locationInNode, touch2_locationInNode);
					var childrenBatch = target._ItemsBatch.getChildren();
					target._multiTouchEnded = false;
				},

				onTouchesMoved: function (touches, event) {
					if(GameManager.getInstance().getGameState() == SS.GAME_STATE.FROZEN
							||  GameManager.getInstance().getGameState() == SS.GAME_STATE.FALLING_ITEM) return;
					if(touches.length != 2) return;

					var target = event.getCurrentTarget();
					var touch1 = touches[0];
					var touch2 = touches[1];

					var touch1_locationInNode = target.convertToNodeSpace(touch1.getLocation());
					var touch2_locationInNode = target.convertToNodeSpace(touch2.getLocation());

					var distance = cc.pDistance(touch1_locationInNode, touch2_locationInNode);

					var childrenBatch = target._ItemsBatch.getChildren();

					if(!target._oldDistance) target._oldDistance = distance;
					if(target._oldDistance <= distance){

						var s = Math.abs(target._oldDistance - distance)/500;
						var scale = target._invisibleCanvasLayer.getScale() + s;
						if(scale > 1.7) scale  = 1.7;
						target._invisibleCanvasLayer.setScale(scale);
					}else{
						var s = Math.abs(target._oldDistance - distance)/500;
						var scale = target._invisibleCanvasLayer.getScale() - s;
						if(scale < 1) scale  = 1;
						target._invisibleCanvasLayer.setScale(scale);
					}

					var levelBGContentSize = target._levelBG.getContentSize();
					levelBGContentSize.width  *= scale;
					levelBGContentSize.height *= scale;
					var newPosition = target._invisibleCanvasLayer.getPosition();
					if(newPosition.x > 0)newPosition.x = 0;					
					if(newPosition.y > 0)newPosition.y = 0;
					if(newPosition.y + levelBGContentSize.height < target._winSize.height)
						newPosition.y = target._winSize.height - levelBGContentSize.height;					
					if(newPosition.x + levelBGContentSize.width < target._winSize.width)
						newPosition.x = target._winSize.width  - levelBGContentSize.width;
					target._invisibleCanvasLayer.setPosition(newPosition);

					target._oldDistance = distance;
				},

				onTouchesEnded: function (touches, event) {	
					var target = event.getCurrentTarget();
					target._oldDistance = 0;
					target._multiTouchEnded = true;
				}

			}, this);

	},
	
	pickupAnimation:function(target, item, label){
		target.retain();
		item.retain();
		label.retain();
		//particle
		label.color = cc.color(100, 100, 100);
		var emitter = new cc.ParticleGalaxy();
		emitter.texture = cc.textureCache.addImage("res/fire.png");
		if (emitter.setShapeType)
			emitter.setShapeType(cc.ParticleSystem.BALL_SHAPE);
		emitter.setPosition(item.getPosition());
		emitter.setDuration(2);		
		emitter.setLife(0.5);
		emitter.setLifeVar(0.5);
		this._invisibleCanvasLayer.addChild(emitter, 10);
		//positions
		var labelPosition = target._ItemsList.getItemPositionAndMoveList(label);
		var itemPosition = item.getPosition();
		var point = this._invisibleCanvasLayer.convertToNodeSpace(cc.p(labelPosition, label.getPositionY()));
		//check scale
		var oldPosition = this._invisibleCanvasLayer.getPosition();	
		var scale = this._invisibleCanvasLayer.getScale();	
		if(this._invisibleCanvasLayer.getScale() > 1){						
			var screenCenter = cc.p(this._winSize.width/2,this._winSize.height/2);
			var deltaCenter = cc.pSub(screenCenter,oldPosition);			
		}

		var minX =  this._winSize.width/4/scale - oldPosition.x;
		var maxX =  this._winSize.width/2/scale  + this._winSize.width/4/scale   - oldPosition.x;
		var minY =  this._winSize.height/2.5/scale   - oldPosition.y;
		var maxY =  this._winSize.height/2/scale  + this._winSize.height/4/scale   - oldPosition.y;

		var middlePointX = Math.floor(Math.random() * (maxX - minX + 1)) + minX;
		var middlePointY = Math.floor(Math.random() * (maxY - minY + 1)) + minY;

		var supportX = Math.floor(Math.random() * this._winSize.width/5 - this._winSize.width/10) + middlePointX;
		var supportY = middlePointY - this._winSize.height/5;

		var points = [itemPosition, 
		              cc.p(middlePointX, middlePointY),
		              point];

		var action1 = cc.cardinalSplineTo(2, points,4);
		var action2 = cc.cardinalSplineTo(2, points,4);

		var scale = cc.ScaleBy.create(1.5, 0.3 );

		var seq = cc.Sequence.create( cc.callFunc(function(){		
			if(target._manager.getGameState() != SS.GAME_STATE.ROUND_END){
				target._manager.setGameState(SS.GAME_STATE.FALLING_ITEM); 
			}
			target.pickedItems.push(item);
		} ),
		action2, 
		cc.callFunc(function(){
			target.pickedItems.splice(0,1);
			target._ItemsList.removeItem(label, 1);	
			item.removeFromParent(true);
			target._manager.setGameState(SS.GAME_STATE.PLAYING); 
		} ));

		if(!this.pickedItems)
			this.pickedItems = new Array();

		item.runAction(	seq );	
		item.runAction( scale );

		emitter.runAction( cc.sequence( action1, 
				cc.callFunc( function(){emitter.stopSystem();}),
				cc.delayTime(0.5), 
				cc.callFunc( function(){emitter.removeFromParent(true);})));

	},
	
	
	resetGame:function(){
		this._ItemsBatch.removeAllChildren(true);
		this.removeChildByTag(99);
		this._timer = new Timer();
		this.addChild(this._timer, FOREGROUND,99);
		this._checkList = [];
		this._checkList = this._ItemsList.getItems().slice();
		
		if(this._manager.getGameMode() == SS.GAME_MODE.HARDCORE){
			var round = this._manager.getCurrentRound();
			var str = sprintf("Round %d", round.ID);
			this._roundLabel = new cc.LabelTTF(str, "Old English Text MT", 100);
			this._roundLabel.setScale(0.2);
			this._roundLabel.color = cc.color(253, 211,129);
			this._roundLabel.attr({
				x:this._winSize.width/2,
				y:this._winSize.height/2
			})
			this.addChild(this._roundLabel,FOREGROUND);
			
			var actionTo = cc.scaleTo(0.2, 1);
			var action2 = cc.fadeOut(1.0);
			this._roundLabel.runAction(cc.sequence(actionTo, cc.delayTime(0.5),action2));
		}
		//=======Items' sprites========
		var itemNode = null;
		var zOrder = this._level.ItemsCount;
		var Tag = this._level.ItemsCount;
		for(var item in this._level.Items){
			itemNode = new Item(cc.spriteFrameCache.getSpriteFrame(this._level.Items[item].SpritePath));
			itemNode.setAnchorPoint(cc.p(0.5,0.5));
			itemNode.setPosition(this._level.Items[item].Position);
			this._ItemsBatch.addChild(itemNode, zOrder--, Tag--);

			itemNode.setTitle(this._level.Items[item].Title);
		}
		this._manager.setGameState(SS.GAME_STATE.PLAYING);
	},
	
	showResults:function(){
		if(this._manager.getGameMode() == SS.GAME_MODE.RELAX) this._score = BRONZE_SCORE;
		cc.eventManager.removeAllListeners();
		if(this._manager.getGameState() != SS.GAME_STATE.GAME_OVER)
			this._manager.setGameState(SS.GAME_STATE.RESULTS);
		//======RESULTS WINDOW=====
		this._resultsWindow = new ResultsLayer(this._score);
		this.addChild(this._resultsWindow, FOREGROUND);
		this.unscheduleUpdate();
	},
	
	performHint:function(){
		if(!this._hintParticle.isReady()) return;
		var List = this._checkList;
		var childrenBatch = this._ItemsBatch.getChildren();
		var index = Math.floor(( Math.random() * (List.length ) ));
		for(var i = 0; i< childrenBatch.length;i++){
			if( childrenBatch[i].getTitle() == List[index].getString() ){	
				var oldItemPosition = childrenBatch[i].getPosition();
				if(this._invisibleCanvasLayer.getScale() > 1){
					var scale = this._invisibleCanvasLayer.getScale();
					var oldPosition = this._invisibleCanvasLayer.getPosition();					
					var itemPosiotion = this._ItemsBatch.convertToWorldSpace( childrenBatch[i].getPosition());
					var screenCenter = cc.p(this._winSize.width/2,this._winSize.height/2);
					var deltaCenter = cc.pSub(screenCenter,itemPosiotion);

					var newPosition = cc.pAdd(oldPosition,deltaCenter);			
					var contentSize = this._levelBG.getContentSize();
					contentSize.height *= scale;
					contentSize.width  *= scale;

					if(newPosition.x > 0)newPosition.x = 0;					
					if(newPosition.y > 0)newPosition.y = 0;
					if(newPosition.y + contentSize.height < this._winSize.height)
						newPosition.y = this._winSize.height - contentSize.height;					
					if(newPosition.x + contentSize.width < this._winSize.width)
						newPosition.x = this._winSize.width  - contentSize.width;
				}
				var moveTo = new cc.MoveTo(0.3, newPosition);
				var callFunc = new cc.CallFunc(this.createEmitterSelector, this, oldItemPosition);
				var seq = new cc.Sequence(moveTo, callFunc);
				this._invisibleCanvasLayer.runAction(seq);
				this._hintParticle.initEmitter();
				cc.audioEngine.playEffect(res.hint_on_mp3);
				cc.audioEngine.playEffect(res.hint_fly_mp3);							
			}
		}		
	},	
	
	createEmitterSelector:function(target, position){
		var emitter = new cc.ParticleFlower();
		var myTexture = cc.textureCache.addImage("res/stars.png");
		emitter.texture = myTexture;		
		emitter.shapeType = cc.ParticleSystem.BALL_SHAPE;
		emitter.setEmitterMode(cc.ParticleSystem.MODE_RADIUS);
		emitter.lifeVar = 0;
		emitter.life = 3;
		emitter.endRadiusVar = 0;
		emitter.startRadiusVar =30;
		emitter.startRadius =100;
		emitter.rotatePerSVar = 50;
		emitter.emissionRate = 100;
		emitter.setEndRadius(0);
		emitter.setPosition(position);
		emitter.setPositionType(cc.ParticleSystem.TYPE_RELATIVE);
		emitter.setDuration(3);
		emitter.setAutoRemoveOnFinish(true);
		this._invisibleCanvasLayer.addChild(emitter,FOREGROUND);
	}
});

GameLayer.scene = function () {
	var scene = new cc.Scene();
	var layer = new GameLayer();
	scene.addChild(layer);
	return scene;
};

