ig.module('game.entities.player')
 .requires(
    'impact.entity',
    'impact.input',
    'game.movement',
    'game.entities.window',
    'game.config',
    'game.movement-style',
    'game.entities.score',
    'game.behavior',
    'game.level'
 )
 .defines(function () {
     "use strict"
     ig.global.EntityPlayer = ig.Entity.extend({
         //load the default animSheet, this is the one for movement
         //note: faces right by default
         animSheet: new ig.AnimationSheet(IMG.PREFIX + 'player.png', IMG.SIZE(201), IMG.SIZE(205)),
         winSheet: new ig.AnimationSheet(IMG.PREFIX + 'FelixWin.png', IMG.SIZE(145), IMG.SIZE(240)),
         size: { x: IMG.SIZE(100), y: IMG.SIZE(205) },
         maxVel: { x: 1000, y: 1000 },
         gravityFactor: 0,
         zIndex: 3,
         scoreMultiple: 1,
         //speed player movement
         //this is how long it takes to get from one tile
         //to the next
         speed: 0.2,
         //the number of lives that we have at the moment
         lives: 3,
         //are we currently moving
         isMoving: false,
         invincible: false,
         lock: false,
         updateLock: false,
         gridPosition: { floor: 0, window: 0 },
         collides: ig.Entity.COLLIDES.NONE,
         checkAgainst: ig.Entity.TYPE.A,
         type: ig.Entity.TYPE.B,
         init: function (x, y, settings) {
             //setup all of our animations
             this.addAnim('idle', 0.2, [0]);
             this.addAnim('respawn', 0.25, [7, 0]);
             this.addAnim('move', 0.2, [1]);
             this.addAnim('fall', 0.2, [3]);
             this.addAnim('fix', 0.07, [1, 2, 0], true);
             this.addAnim('die', 0.5, [11, 15, 15, 15, 16, 16], true);
             this.winAnim = new ig.Animation(this.winSheet, 0.1, [0, 1]);
             var realx = ig.game.level.getPosition(x, y).x;
             var realy = ig.game.level.getPosition(x, y).y;
             this.gridPosition = { floor: y, window: x };
             this.parent(realx, realy, settings);
             //this.size = EntityPlayer.size;
         },
         getWindowUnder: function () {
             var retval = [];
             var ents = ig.game.getEntitiesByType(EntityWindow);

             for (var i = 0; i < ents.length; ++i) {
                 if (this.touches(ents[i])) {
                     retval.push(ents[i]);
                 }
             }
             if (retval.length === 0) {
                 //we did not find anything
                 return undefined;
             } else {
                 //we are going to ignore all but the first window we found
                 //but we are going to log the fact that we found more than one window if we did in fact
                 //find more than one window
                 if (retval.length > 1) {
                     console.log("WARNING: found more than one window");
                 }
                 return retval[0];
             }
         },
         //go through and flip all of the animations
         flipAllAnims: function (flip) {
             //terminateing condition
             for (var i in this.anims) {
                 if ("flip" in this.anims[i]) {
                     this.anims[i].flip.x = flip;
                 }
             }

             //since invincibility animations are constructed
             //on-the-fly our current animation may not be in
             //this.anims, thus we should
             if ("flip" in this.currentAnim) {
                 this.currentAnim.flip.x = flip;
             }

         },
         update: function () {
             //dont update if we are locked out
             if (!this.lock && !this.updateLock) {
                 //if we have a behavior do it, lock out everything else
                 if ("behavior" in this) {
                     this.behavior(this);
                     //| we want to lock out input while the player is moving
                     //TODO: remov ethis code and use behaviors instead
                 } else if (!("movement" in this)) {
                     var dir = UI.Stick.lastDirection;
                     var direction = UI.Stick.getStickDirection(dir.x, dir.y);
                     if (direction) {
                         simKey(direction.code);
                     }
                     if (ig.input.pressed('right')) {
                         this.handleMove("right");
                     } else if (ig.input.pressed('left')) {
                         this.handleMove("left");
                     } else if (ig.input.pressed('up')) {
                         this.handleMove("up");
                     } else if (ig.input.pressed('down')) {
                         this.handleMove("down")
                     } else if (ig.input.pressed('fix')) {
                         this.handleFix();
                     }
                 }
                 if ("movement" in this) {
                     //update our position based on the movvement property
                     this.pos = this.movement.getPosition();
                     if (this.movement.isDone()) {
                         delete this.movement;
                         this.currentAnim = this.anims.idle;
                     }
                 }
                 this.parent();
             }
         },
         draw: function () {
             if (!this.lock) {
                 this.parent();
             }
         },
         //called when the player presses space
         //or taps/clicks the fix button
         handleFix: function () {
             if (!this.lock) {

                 var curWindow = ig.game.level.getWindow(this.gridPosition);
                 if (!curWindow.isRepairing()) {
                     this.currentAnim = this.anims.fix.rewind();
                 }
                 //we want to only fix windows that are not fixed or fixing
                 //we dont want to be able to spam the fix button to increase our score
                 if (curWindow !== undefined && !curWindow.isFixed() && !curWindow.isRepairing()) {

                     //check if we have already created the score entity
                     //and if not created, otherwise use it
                     if (ig.game.scoreEnt === undefined) {
                         //we want to get score every time we fix a part of a window, not
                         //just when we are done
                         var score = ig.game.spawnEntity(EntityScore, this.pos.x, this.pos.y, this.scoreMultiple);
                     } else {
                         ig.game.scoreEnt.start(this.pos.x, this.pos.y, this.scoreMultiple);
                     }
                     curWindow.repairWindow();
                 } else {
                    // ig.game.soundFixButton.play();
                    ig.game.playHammerSound();
                 }
             }
         },
         //handle movement in some particular direction,
         //the code to get this direction is in update
         handleMove: function (direction) {
             //the reason we check for behavior here is because
             //this method is called when the player moves the onscreen stick
             //annoyingly impact's input class does not allow for 
             //firing an action by calling a method
             if (!("movement" in this)) {
                 //handle movement related input
                 var moveStyle = {
                     x: MovementStyle.linear,
                     y: function (t) { return IMG.SIZE(-50) * MovementStyle.sin(t); }
                 };
                 switch (direction) {
                     case "up":
                         this.gridPosition = ig.game.level.getNewIndex(this.gridPosition, Utils.directionsEnum.UP);
                         this.movement = new Movement(this.pos, ig.game.level.getPosition(this.gridPosition), this.speed, moveStyle);
                         this.currentAnim = this.anims.move;
                         break;
                     case "down":
                         this.gridPosition = ig.game.level.getNewIndex(this.gridPosition, Utils.directionsEnum.DOWN);
                         this.movement = new Movement(this.pos, ig.game.level.getPosition(this.gridPosition), this.speed, moveStyle);
                         this.currentAnim = this.anims.move;
                         break;
                     case "left":
                         this.gridPosition = ig.game.level.getNewIndex(this.gridPosition, Utils.directionsEnum.LEFT);
                         this.movement = new Movement(this.pos, ig.game.level.getPosition(this.gridPosition), this.speed, moveStyle);
                         this.currentAnim = this.anims.move;
                         this.flipAllAnims(true);
                         break;
                     case "right":
                         this.gridPosition = ig.game.level.getNewIndex(this.gridPosition, Utils.directionsEnum.RIGHT);
                         this.movement = new Movement(this.pos, ig.game.level.getPosition(this.gridPosition), this.speed, moveStyle);
                         this.currentAnim = this.anims.move;
                         this.flipAllAnims(false);
                         break;
                 }
             }
         },
         //override the receive damage function so that
         //we dont receive damage if we are invinible
         receiveDamage: function (amount, from) {
             if (!this.invincible) {
                 UI.updateLivesBar(this.lives);
                 this.currentAnim = this.anims.fall;
                 this.vel = { x: 0, y: 100 };
                 this.parent(amount, from);
             }
         },

	 addLife: function(){
		
		if(this.lives<3){

		 this.lives += 1; 
                 UI.updateLivesBar(this.lives);

		}
	 
	 },

         check: function (other) {

             //only do things if we are not already in the death
             //state
             if (!this.isDieing && !this.invincible) {
                 ig.game.soundBrick.play();
                 this.lives -= 1;
                 this.isDieing = true;
		 console.log("Basile Log:check Function lives: "  + this.lives)
                 UI.updateLivesBar(this.lives);
                 if (this.lives === 0) {
                     if (this.movement) {
                         delete this.movement;
                     }
                     this.currentAnim = this.anims.die;
                     this.behavior = Behavior.Player.gameOver.bind(window, new ig.Timer(), this, function () {
                         UI.showGameOver();
                         ig.game.pauseCount += 1;
                     });
                 } else {
                     this.behavior = Behavior.playerDie.bind(window, new ig.Timer());
                 }
             }
             this.parent(other);
         }
     });
 });
