ig.module( 
	'game.sheep-game' 
)
.requires(
	'impact.game',
	'impact.font',
	'impact.animation',
	
	'game.camera',
	'game.joystick',
	
	// Entities
	'game.entities.player',
	'game.entities.button',
	'game.entities.checkpoint',
	'game.entities.lava',
	'game.entities.coin',
	'game.entities.saw',
	'game.entities.finish',
	'game.entities.debris',
	'game.entities.earthquake',
	'game.entities.trigger',
	'game.entities.mover',
	'game.entities.void',
	
	// Levels
	'game.levels.main'
)
.defines(function(){

SheepGame = ig.Game.extend({
	
	// Load a font
	font: new ig.Font( 'media/font-calypso.png' ),
	font2: new ig.Font( 'media/font-calypso-x2.png' ),
	
	clearColor: '#18182A',
	gravity: 240,
	
	// Custom
	lastCheckpoint: null,
	playerSpawnPos: {
		x: 0,
      	y: 0
   	},
   	liveCount: 0,
   	coinCount: 0,
   	totalScore: 0,
   	camera: null,
   	showFPS: false,
   	
   	_lavaAnimSheet: new ig.AnimationSheet( 'media/sprites/lava4.png', 576, 32 ),
   	_lavaAnimation: null,
   	
   	distanceShow: false,
   	distanceTimeout: null,
   	_arrowRight: new ig.Image( 'media/sprites/arrow-right.png' ),
   	
   	gameOver: false,
	
	_frameCount: 0,
	_lastFps: 0,
	
	_live: new ig.Image( 'media/sprites/sheep-live.png' ),
	_coin: new ig.Image( 'media/sprites/coin-ui.png' ),
	
	_gameOverTime: null,
	_fadeOutGameOver: 1000,
	_fadeOutCoinsScores: 1500,
	_fadeOutLivesScores: 2000,
	_fadeOutTotalScores: 2700,
	_fadeOutButtons: 3500,
	
	joystick: null,
	
	init: function() {
		this.parent();
		
		if (!SheepGame.initialized)
		{
			ig.input.bind(ig.KEY.LEFT_ARROW, 'left');
	        ig.input.bind(ig.KEY.RIGHT_ARROW, 'right');
	        ig.input.bind(ig.KEY.UP_ARROW, 'jump');
	        
	        ig.input.bind(ig.KEY.A, 'left');
	        ig.input.bind(ig.KEY.D, 'right');
	        ig.input.bind(ig.KEY.W, 'jump');
			
			// Background Animation
			// An object, specifying the animated tiles for particular tileset. Note that you have to set this before loading a level through .loadLevel().
			// This sets two tiles (tile 0 and tile 5) of any background map with 
			// the 'media/tiles.png' tileset to be animated.
			/*var as = new ig.AnimationSheet( 'media/sprites/lava2.png', 64, 64 );
			this.backgroundAnims = {
			    'media/sprites/lava2.png': {
			        0: new ig.Animation( as, 0.15, [0,1,2,3,4,5] ),
			    }
			};*/

			SheepGame.initialized = true;
		}
		
		// FPS Meter
		if (this.showFPS) {
			setInterval(function(){
  				this._lastFps = this._frameCount;
  				this._frameCount = 0;
			}.bind(this), 1000);
		}
		
		// if (Title.joystickState)
		// {
			this.joystick = new Joystick();
			this.joystick.x = ig.system.width - this.joystick.width - 7;
			this.joystick.y = ig.system.height - this.joystick.height - 7;
		// }
		
		this.camera = new Camera(ig.system.width / 4, ig.system.height / 3, 5);
     	this.camera.trap.size.x = ig.system.width / 10;
      	this.camera.trap.size.y = ig.system.height / 3;
      	this.camera.lookAhead.x = 0;//ig.ua.mobile ? ig.system.width / 6 : 0;
		
		this.loadLevel(LevelMain);
		
		try {
        	Playtomic.Log.Play();
		} catch (e) { }
	},
	
	loadLevel: function (level) {
        /*if (ig.ua.iPhone4 || ig.ua.android) {
            for (var i = 0; i < level.layer.length; i++) {
                if (level.layer[i].name == 'background') {
                    level.layer.erase(level.layer[i]);
                }
            }
        }*/
        
        this._loadLevel(level);
        
        this.player = this.getEntitiesByType(EntityPlayer)[0];
        
        /*this.player.pos.x = 6000;
        this.player.pos.y = 50;
        this.getEntityByName('saw').visible = true;*/
        
        this.player.panic = false; // На всякий случай
        this.lastCheckpoint = null;
        this.playerSpawnPos = {
            x: this.player.pos.x,
            y: this.player.pos.y
        };
        this.liveCount = 3;
        this.coinCount = 0;
        this.totalScore = 0;
        
        this.gameOver = false;
        
        this.camera.min.x = 0;
        this.camera.min.y = 0;
        this.camera.max.x = this.collisionMap.width * this.collisionMap.tilesize - ig.system.width;
        this.camera.max.y = this.collisionMap.height * this.collisionMap.tilesize - ig.system.height;
        this.camera.set(this.player);
        
        this._lavaAnimation = new ig.Animation( this._lavaAnimSheet, 0.15, [0, 1, 2, 3, 4, 5] );
        
        for (var i = 0; i < this.backgroundMaps.length; i++) {
        	this.backgroundMaps[i].preRender = true;
        }
        
        this.blinkDistance();
        
        if (ig.music.currentIndex != 0)
			ig.music.playTrack(0);

		ig.localyticsSession.tagScreen("Play");
		ig.localyticsSession.upload();
    },
    
    _loadLevel: function( data ) {
		this.screen = {x: 0, y: 0};

		// Entities
		this.entities = [];
		this.namedEntities = {};
		for( var i = 0; i < data.entities.length; i++ ) {
			var ent = data.entities[i];
			if (ig.ua.mobile && ent.settings && ent.settings.count) {
				ent.settings.count = Math.round(ent.settings.count / 3);
			}
			// if (ent.settings && (ent.settings.name == 'lava' || ent.settings.name == 'player' || ent.settings.name == 'finish' || ent.settings.name == 'trigger1' || ent.settings.name == 'saw'))
				this.spawnEntity( ent.type, ent.x, ent.y, ent.settings );
		}
		this.sortEntities();
		
		// Map Layer
		this.collisionMap = null;
		this.backgroundMaps = [];
		for( var i = 0; i < data.layer.length; i++ ) {
			var ld = data.layer[i];
			if( ld.name == 'collision' ) {
				this.collisionMap = new ig.CollisionMap(ld.tilesize, ld.data );
			}
			else {
				var newMap = new ig.BackgroundMap(ld.tilesize, ld.data, ld.tilesetName);
				newMap.anims = this.backgroundAnims[ld.tilesetName] || {};
				newMap.repeat = ld.repeat;
				newMap.distance = ld.distance;
				this.backgroundMaps.push( newMap );
			}
		}
	},
    
    reachFinish: function() {
    	if (this.gameOver)
    		return;
    	
		this.gameOver = true;
		this._gameOverTime = Date.now();
			
		this.totalScore = this.coinCount * 500 + this.liveCount * 5000;
    },
    
    respawnDeferred: function(x, y) {
		this.respawnTime = 2;
    },
    
    respawnPlayerAtLastCheckpoint: function () {
    	this.liveCount--;
    	
    	if (this.liveCount == 0)
		{
			this.gameOver = true;
			this._gameOverTime = Date.now();
			
			this.totalScore = this.coinCount * 500 + this.liveCount * 5000;
			
			return;
		}
    	
        var pos = this.playerSpawnPos;
        
        if (this.lastCheckpoint) {
            pos = this.lastCheckpoint.getSpawnPos();
            this.lastCheckpoint.currentAnim = this.lastCheckpoint.anims.respawn.rewind();  
        }
        else {
			pos.x += 50;
        }
        
        this.getEntityByName('saw').pos.x = Math.max(0, pos.x - 200);
        
        var panic = this.player.panic;
	    this.player = this.spawnEntity(EntityPlayer, pos.x, pos.y, { name: "player" });
	    this.player.panic = panic;
	    this.player.currentAnim = this.player.anims.spawn.rewind();
    },
	
	update: function() {
        /*if (ig.input.pressed('respawn')) {
        	this.respawnPlayerAtLastCheckpoint();
        }*/
        
        if (this.player && this.player.pos.x < this.camera.min.x + 7)
        	this.player.pos.x = this.camera.min.x + 7;
        
        var maxX = this.collisionMap.width * this.collisionMap.tilesize;
        if (this.player && this.player.pos.x > maxX - 15)
        	this.player.pos.x = maxX - 15;
        	
        if (this.joystick)
			this.joystick.update();
		
		// this.parent();
		// ----- parent update
		
		// load new level?
		if( this._levelToLoad ) {
			this.loadLevel( this._levelToLoad );
			this._levelToLoad = null;
		}
		
		// entities
		for( var i = 0; i < this.entities.length; i++ ) {
			var ent = this.entities[i];
			if( !ent._killed ) {
				ent.update();
			}
		}
		this.checkEntities();
		
		// remove all killed entities
		for( var i = 0; i < this._deferredKill.length; i++ ) {
			this.entities.erase( this._deferredKill[i] );
		}
		this._deferredKill = [];		
		
		// ----------
		
		if (this.respawnTime > 0)
        {
        	this.respawnTime -= ig.system.tick;
        	
        	if (this.respawnTime <= 0)
        	{
				this.respawnPlayerAtLastCheckpoint();
        	}
		}
		
		this._updateCamera();
		
		// --- earthquake
		
		if (this.earthquake) {
			this.screen.x += this.earthquake.x || 0;
			this.screen.y += this.earthquake.y || 0;
			
			this.earthquake.x = 0;
			this.earthquake.y = 0;
		}
		
		// ----------
		
		// background
		for( var tileset in this.backgroundAnims ) {
			var anims = this.backgroundAnims[tileset];
			for( var a in anims ) {
				anims[a].update();
			}
		}
		for( var i = 0; i < this.backgroundMaps.length; i++ ) {
			this.backgroundMaps[i].setScreenPos( this.screen.x, this.screen.y);
		}
		
		// -----
		
		
	},
	
	_updateCamera: function() {
		this.camera.min.x = this.getEntityByName('saw').pos.x + 1;
		this.camera.follow(this.player);
	},
	
	draw: function() {
		// Parent draw()
		ig.system.clear( this.clearColor );
		
		// Layer "Help"
		this.backgroundMaps[0].draw();
		
		for( var i = 0; i < this.entities.length; i++ ) {
			if (this.entities[i] instanceof EntityButton)
				continue;
			
			this.entities[i].draw();
		}
		
		// Layer "Main"
		this.backgroundMaps[1].draw();
			
		this._lavaAnimation.update();
		this._lavaAnimation.draw(-ig.game.screen.x % 64, -ig.game.screen.y + 320 - 32);
		if (ig.system.width < this._lavaAnimSheet.width) {
			this._lavaAnimation.draw(-ig.game.screen.x % 64 + this._lavaAnimSheet.width, -ig.game.screen.y + 320 - 32);
		}
			
		// Layer "Exit"
		this.backgroundMaps[2].draw();
		
		//
		this.camera.draw();
		
		if (this.showFPS)
			this.font.draw('FPS: ' + this._lastFps, 2, 2);
		
		if (!this.gameOver)
		{
			if (this.joystick)
				this.joystick.draw();
			
			if (this.distanceShow)
			{
				var from = this.player.pos.x;
				var to = this.getEntityByName('finish').pos.x;
				
				var beginFrom = this.getEntityByName('trigger1').pos.x;
				
				this.distance = Math.floor((to - from) / 64);
				
				if (this.player.pos.x > beginFrom || this.getEntityByName('saw').visible)
				{
					if (this.distance > 0)
					{
						var x = ig.system.width - 40;
						
						this.font.draw(this.distance + 'm', x, 40, ig.Font.ALIGN.RIGHT);
						this._arrowRight.draw(x - this._arrowRight.width, 60);
					}
				}
			}
			
			for (var i = 0; i < this.liveCount; i++)
			{
				this._live.draw(ig.system.width - 120 - i * 27, (32 - this._live.height) / 2);
			}
			
			var coins = this.coinCount + "";
			while (coins.length < 3)
        		coins = '0' + coins;
			
			this._coin.draw(ig.system.width - 69, (32 - this._coin.height) / 2);
			this.font.draw(coins, ig.system.width - 17, 7, ig.Font.ALIGN.RIGHT);
		}
		else
		{
			var oy = -50;
			
			var t = Date.now() - this._gameOverTime;
			var alpha = t.map( 0, this._fadeOutGameOver, 0, 1);
			var text = this.liveCount > 0 ? 'CONGRATULATIONS!' : 'GAME OVER';
			this.font2.draw(text, ig.system.width / 2, ig.system.height / 2 - 40 + oy, ig.Font.ALIGN.CENTER, alpha);
			
			if (t > this._fadeOutGameOver)
			{
				alpha = t.map(this._fadeOutGameOver, this._fadeOutCoinsScores, 0, 1);
				this.font.draw('Coins: ' + this.coinCount + ' x 500', ig.system.width / 2, ig.system.height / 2 + 20 + oy, ig.Font.ALIGN.CENTER, alpha);
				
			}
			
			if (t > this._fadeOutCoinsScores)
			{
				alpha = t.map(this._fadeOutCoinsScores, this._fadeOutLivesScores, 0, 1);
				this.font.draw('Lives: ' + this.liveCount + ' x 5000', ig.system.width / 2, ig.system.height / 2 + 45 + oy, ig.Font.ALIGN.CENTER, alpha);
			}
			
			if (t > this._fadeOutLivesScores)
			{
				alpha = t.map(this._fadeOutLivesScores, this._fadeOutTotalScores, 0, 1);
				this.font.draw('Total score: ' + this.totalScore, ig.system.width / 2, ig.system.height / 2 + 70 + oy, ig.Font.ALIGN.CENTER, alpha);
			}
			
			if (t > this._fadeOutTotalScores)
			{
				if (!this.getEntitiesByType(SheepGameEntityButtonMenu).length)
				{
					try {
						if (!Playtomic)
							throw("Playtomic not loaded");
						
						this.spawnEntity( SheepGameEntityButtonMenu, 0, 0 );
						this.spawnEntity( SheepGameEntityButtonSubmit, 0, 0 );
					} catch (e) {
						this.spawnEntity( SheepGameEntityButtonMenu, 0, 0 );
					}

					ig.localyticsSession.tagEvent("Play: Game Over", { "Score": ig.localyticsSession.createRangedAttribute2(this.totalScore, 0, 100000, 5000), "Coins": ig.localyticsSession.createRangedAttribute2(this.coinCount, 0, 100, 5), "Lives": this.liveCount });
				}
				
				var btn = this.getEntitiesByType(SheepGameEntityButtonMenu)[0];
				try {
					if (!Playtomic)
						throw("Playtomic not loaded");
				
					btn.pos.x = (ig.system.width / 2 - 50);
					btn.pos.y = (ig.system.height / 2 + 125 + oy);
					btn.alignToCenter();
					btn.draw();
					
					btn = this.getEntitiesByType(SheepGameEntityButtonSubmit)[0];
					btn.pos.x = (ig.system.width / 2 + 40);
					btn.pos.y = (ig.system.height / 2 + 125 + oy);
					btn.alignToCenter();
					btn.draw();
				} catch (e) {
					btn.pos.x = (ig.system.width / 2);
					btn.pos.y = (ig.system.height / 2 + 125 + oy);
					btn.alignToCenter();
					btn.draw();
				}
			}
		}
		
      	this._frameCount++;
	},
	
	blinkDistance: function() {
		if (this.distanceTimeout)
			clearTimeout(this.distanceTimeout);
		
		this.distanceShow = !this.distanceShow;
		
		this.distanceTimeout = setTimeout(this.blinkDistance.bind(this), this.distanceShow ? 1500 : 1000);
	}
});

SheepGameEntityButtonMenu = EntityButton.extend({
	name: "menu",
	animSheet: new ig.AnimationSheet( 'media/sprites/button-menu.png', 56, 38 ),
	
	init: function( x, y, settings ) {
		this.parent(x, y, settings);
		
		this.alignToCenter();
	},
	
	clicked: function() {
		ig.system.switchGame(Title);

		ig.localyticsSession.tagEvent("Play: Click Menu Button");
	}
});

SheepGameEntityButtonSubmit = EntityButton.extend({
	name: "submit",
	animSheet: new ig.AnimationSheet( 'media/sprites/button-submit.png', 75, 38 ),
	
	init: function( x, y, settings ) {
		this.parent(x, y, settings);
		
		this.alignToCenter();
	},
	
	clicked: function() {
		ScoresSubmit.lastScore = ig.game.totalScore;
		
		if (ScoresSubmit.lastScore)
		{
			ig.system.switchGame(ScoresSubmit);
		}
		else
		{
			ig.system.switchGame(Scores);
		}

		ig.localyticsSession.tagEvent("Play: Click Submit Button");
	}
});

});