function Player()
{
    this.x = 640;
    this.y = 360;
    this.width = 42;
    this.height = 42;
    this.speed = 100;
    this.b_attack = false;
    this.swordAngle = 0;
    this.swordDamage = 50;
    this.swordRange = 100;
    this.damageInvulnerability = 0;
    this.maxhp = 5;
    this.hp = this.maxhp;
    this.attackCooldown = 0;
    this.attackCooldownStat = 2;
}



Player.prototype.update = function( dt )
{
    var dx = 0;
    var dy = 0;
    if ( keyState.up )
    {
        dy = -1;
    }
    else if ( keyState.down )
    {
        dy = 1;
    }
    if ( keyState.left )
    {
        dx = -1;
    }
    else if ( keyState.right )
    {
        dx = 1;
    }

    if ( dx != 0 && dy != 0 )
    {
        // 
        this.x += dx * dt * this.speed * 0.70710678118;
        this.y += dy * dt * this.speed * 0.70710678118;
    }
    else if ( dx != 0 && dy == 0 )
    {
        this.x += dx * dt * this.speed;
    }
    else if ( dy != 0 && dx == 0 )
    {
        this.y += dy * dt * this.speed;
    }

    if ( this.x < this.width/2 ) this.x = this.width/2;
    else if ( this.x > 1280-this.width/2 ) this.x = 1280-this.width/2;
    if ( this.y < this.height/2 ) this.y = this.height/2;
    else if ( this.y > 720-this.height/2 ) this.y = 720-this.height/2;

    if ( this.b_attack )
    {
        this.swordAngle += Math.PI*dt*5;
        if ( this.swordAngle >= Math.PI*2 )
        {
            this.b_attack = false;
        }
    }

    this.damageInvulnerability -= dt;
    this.attackCooldown -= dt;

    for ( let i = 0 ; i < game.upgrades.length ; ++i )
    {
        if ( game.upgrades[i].isTouchingPlayer() )
        {
            game.upgrades[i].apply();
        }
    }
}



Player.prototype.attack = function()
{
    if ( this.attackCooldown <= 0 )
    {
        this.b_attack = true;
        this.swordAngle = 0;
        for ( let i = 0 ; i < game.enemies.length ; ++i )
        {
            if ( game.enemies[i].isInSwordRange() )
            {
                game.enemies[i].damage( this.swordDamage );
            }
        }
        this.attackCooldown = this.attackCooldownStat;
        swordSound.play();
    }
}



Player.prototype.damage = function( damage )
{
    if ( this.damageInvulnerability <= 0 )
    {
        this.hp -= damage;
        this.damageInvulnerability = 1;
        playerHurtSound.play();
        if ( this.hp <= 0 )
        {
            this.hp = 0;
            game.state = GAMESTATE_GAMEOVER;
            gameOverSound.play();
        }
    }
}



Player.prototype.draw = function( ctx )
{
    ctx.drawImage( playerImage , this.x-this.width/2 , this.y-this.height/2 , this.width , this.height );

    ctx.fillStyle = "#555555";
    ctx.fillRect( this.x-this.width/2 , this.y+this.height/2+3 , this.width , 5 );
    ctx.fillStyle = "#aaaaaa";
    var percent = (this.attackCooldownStat-this.attackCooldown)/this.attackCooldownStat;
    if ( percent > 1.0 ) percent = 1.0;
    ctx.fillRect( this.x-this.width/2 , this.y+this.height/2+3 , percent*40 , 5 );

    if ( this.b_attack )
    {
        ctx.save();
        ctx.translate( this.x , this.y );
        ctx.rotate( this.swordAngle );
        ctx.fillStyle = "rgba( 255 , 0 , 0 , 0.3 )";
        ctx.fillRect( 20 , -10 , this.swordRange , 20 );
        ctx.drawImage( swordImage , 20 , -10 , 100 , 20 );
        ctx.restore();
    }

    ctx.font = "16px serif";
    ctx.fillStyle = "#ffffff";
    ctx.fillText( "Speed: "+Math.floor(this.speed) , 10 , 60 );
    ctx.fillText( "Damage: "+Math.floor(this.swordDamage) , 10 , 80 );
    ctx.fillText( "Attack Speed: "+Math.floor(this.attackCooldownStat*100)/100.0+"s" , 10 , 100 );
    ctx.fillText( "Range: "+Math.floor(this.swordRange) , 10 , 120 );
}