
var Hero = new Class({
	Extends: DynaObject,
	initialize: function(type){
            if($defined(type))
		this.parent(type);
            else
                this.parent(GAMEUNITTYPE.HERO);
        this.currentDirection=null;
        this.sense=0;
        this.cuanta=2;
        //these should be the same as in the css file : div.hero
        this.width=game.standardWidth;
        this.height=game.standardHeight;
        this.hitWorldBoundary=false;
        this.hitTheWall=false;
        this.bombExplosionLength=1;
        this.numberOfBombs=1;
        this.currentSpriteFrame = {x: 0 ,y: 0};
        this.spriteAnimationSpeed = 5;
        this.spriteAnimationIndex = 0;
        this.score = 0;
        this.canFlyOverFakeWalls = false;
        this.life=1;
	},
	setExplosionLength: function(explosionLength){
    	this.bombExplosionLength = explosionLength;
    },
        processKeyPressedInput: function(keyCode){
            if(keyCode==39){
                this.currentDirection='left';
                this.sense=1;
                this.spriteY = 50;
            }
            if(keyCode==37){
                this.currentDirection='left';
                this.sense=-1;
                this.spriteY = 100;
            }
            if(keyCode==40){
                this.currentDirection='top';
                this.sense=1;
                this.spriteY = 200;
            }
            if(keyCode==38){
                this.currentDirection='top';
                this.sense=-1;
                this.spriteY = 150;
            }
        },
        processKeyUpInput: function(keyCode){
            	this.sense=0;
                this.spriteY = 1;
                this.updateHeroSprite();
        },
        processKeyDownInput: function(keyCode){
            this.processKeyPressedInput(keyCode);
        },
        launchBomb: function(){
                if(this.numberOfBombs>0){
                    this.bombLaunched=true;
                  this.numberOfBombs--;
                  var bomb=new Bomb(this.x,this.y,this);
                  bomb.setExplosionLength(this.bombExplosionLength);
                }
        },
        returnBomb: function(){
            this.bombLaunched=false;
            this.numberOfBombs++;
        },
        setNumberOfBombs: function(noBombs){
            this.numberOfBombs=noBombs;
        },
        updateHeroSprite: function(){
            if(this.spriteAnimationIndex>=this.spriteAnimationSpeed){
                this.spriteAnimationIndex = 0;
            } else {
                this.spriteAnimationIndex++;
                return;
            }
              if(this.currentSpriteFrame.y!=this.spriteY){
                  this.currentSpriteFrame.y=this.spriteY;
                  this.spriteX = game.standardWidth;
              }
              else {
                  this.spriteX += game.standardWidth;
                  if(this.spriteX>=250)
                      this.spriteX = game.standardWidth;
                  this.currentSpriteFrame.x = this.spriteX;
              }
              //this.HTMLIncarnation.setStyle('background-position',this.spriteX+'px '+this.spriteY+'px');
              this.HTMLIncarnation.style.backgroundPosition=this.spriteX+'px '+this.spriteY+'px';
        },
        moveAlongDirection: function(){
            if(this.sense==0)
              return;
            var currentPosition=0;
            var newPosition=0;
            if(this.currentDirection=='left'){
                currentPosition = this.x;
                newPosition = currentPosition+(this.sense*this.cuanta);
                if((newPosition<0 && this.sense<0) || (this.sense>0 && newPosition>game.worldWidth-game.standardWidth)){
                    this.hitWorldBoundary=true;
                    return;
                }
            }
            if(this.currentDirection=='top'){
                currentPosition = this.y;
                newPosition = currentPosition+(this.sense*this.cuanta);
                if((this.sense<0 && newPosition<0) || (this.sense>0 && newPosition>game.worldHeight-game.standardHeight)){
                    this.hitWorldBoundary=true;
                    return;
                }
            }
            
            var repositionedX=this.x;
            var repositionedY=this.y;
            
            //// this is when , for example, you are going down and you stop to turn the direction
            //// but you do not stop right in the spot where your coordinate allow you not to hit a wall
            //// so if you donot hit it in the middle , this code below adjust your coordinate
            //// so you don't hit it.
            if(this.currentDirection =='left'){
        		repositionedY=util.rePositionCoordinate(this.y,game.standardHeight);
        		if(repositionedY!=this.y){
                    this.y=repositionedY;
                    //this.HTMLIncarnation.setStyle('top',this.y);
                    this.HTMLIncarnation.style.top=this.y+'px';
                }
            }
        	if(this.currentDirection =='top'){
        		repositionedX=util.rePositionCoordinate(this.x,game.standardWidth);
        		if(repositionedX!=this.x){
                    this.x=repositionedX;
                    //this.HTMLIncarnation.setStyle('left',this.x);
                    this.HTMLIncarnation.style.left=this.x+'px';
                }
        	}
            if(!this.canFlyOverFakeWalls)
                this.hitTheWall=this.world.checkForCollisionWithWalls(this,(this.currentDirection=='left')?newPosition:repositionedX,(this.currentDirection=='top')?newPosition:repositionedY,this.currentDirection);
            else
                this.hitTheWall=false;
            if(!this.hitTheWall){
                // the hero could have hit the EXIT , and now it is reborn in another level
                if(this.reborn){
                    this.reborn=false;
                    return;
                }
                  if(this.currentDirection=='left'){
                    this.x=newPosition;
                    //this.HTMLIncarnation.setStyle(this.currentDirection,newPosition);
                    this.HTMLIncarnation.style.left=newPosition+'px';
                  }
                  if(this.currentDirection=='top'){
                    this.y=newPosition;
                    //this.HTMLIncarnation.setStyle(this.currentDirection,newPosition);
                    this.HTMLIncarnation.style.top=newPosition+'px';
                  }
                  //this.HTMLIncarnation.setStyle(this.currentDirection,newPosition);
            } else {
                if(this.currentDirection=='left'){
                  ///////// this is because when you are 1 pixel close to the wall , and try to touch it
                  ///////// the collision detection method doesn't allow you to get any closer
                  //////// so we are here because we hit the wall [else from !this.hitTheWall] and direction = left 
                  //////// and x is 1-2-3... pixels close to the wall
                  var wallposition = this.x%game.standardWidth;
                  if(wallposition != 0){
                      if(wallposition < game.standardWidth/2)
                        this.x-=wallposition;
                      else
                        this.x+=game.standardWidth-wallposition;
                      //this.HTMLIncarnation.setStyle('left',this.x);
                      this.HTMLIncarnation.style.left=this.x+'px';
                  }
                  ////////// end adjusting from 1pixelCloseToWall issue
                }
                if(this.currentDirection=='top'){
                   var wallposition = this.y%game.standardHeight;
                   if(wallposition!=0){
                      if(wallposition < game.standardHeight/2)
                        this.y-=wallposition;
                      else
                        this.y+=game.standardHeight-wallposition;
                      //this.HTMLIncarnation.setStyle('top',this.y);
                      this.HTMLIncarnation.style.top=this.y+'px';
                   }
                }
            }
            if(this.x<0)
                this.x=0;
            if(this.y<0)
                this.y=0;
            this.updateHeroSprite();
            var newZone=util.getZoneAtPoint(this.x,this.y);
            if(newZone!=this.myZone){
                if(this.canFlyOverFakeWalls){
                    newZone.addElement(this);
                    this.myZone.removeElement(this);
                    this.myZone=newZone;
                } else {
                    if(newZone.isWalkable()){
                          newZone.addElement(this);
                          this.myZone.removeElement(this);
                          this.myZone=newZone;
                    } else {
                        if((newZone.hasType(GAMEUNITTYPE.WALL) || newZone.hasType(GAMEUNITTYPE.FAKEWALL)) && game.debug==0 && !this.canFlyOverFakeWalls){
                            debugger;
                            //alert(this.type+' entered into a wall');
                        }
                    }
                }
            }
        },
        assimilateGoody: function(zone){
        	var elements = zone.getElements();
        	var goody = null;
        	for(var i=0;i<elements.length;i++){
        		if(elements[i].type==GAMEUNITTYPE.GOODY){
        			goody=elements[i];
        			break;
        		}
        	}
                if(goody.subtype==GOODYSUBTYPE.EXIT){
                    if(game.heroes.length==0){
                      this.reborn=true;
                      goody.terminate();
                      generateNextLevel();
                    }
                } else {
                  if(goody.subtype==GOODYSUBTYPE.LIFE){
                          this.life++;
                  }
                  if(goody.subtype==GOODYSUBTYPE.SPEED){
                          this.cuanta++;
                  }
                  if(goody.subtype==GOODYSUBTYPE.BOMB){
                          this.numberOfBombs++;
                  }
                  // more to be implemented here
                  goody.terminate();
                }
       },
        terminate: function(){
            this.life--;
            if(this.life>0)
                return;
            this.parent();
            this.scream();
            this.die();
        },
        die: function(){
            var bombExplosionLength = this.bombExplosionLength;
            var numberOfBombs = this.numberOfBombs;
            var speed = this.cuanta;
            if($defined(this.bombLaunched) && this.bombLaunched)
                numberOfBombs++;
            $('score').set('text','0');
            this.score=0;
            game.hero=null;
            restartLevel(speed,bombExplosionLength,numberOfBombs);
        },
        addPointsToScore: function(points){
            this.score += points;
            $('score').set('text',this.score);
        },
        scream: function(){
            var soundSuffix=1+Math.round(Math.random()*3);
            game.sound.playSound('scream'+soundSuffix);
        }
});

