function Ship() {
  
  this.x = 0;
  this.y = 0;
  
  this.ownSails = 0;
  this.ownHulls = 0;
  this.ownSpies = 0;
  this.ownCannon = 0;
  this.ownCannonballs = 0;
  this.ownSailors = 0;
  
  this.moveUp = false;
  this.moveRight = false;
  this.moveDown = false;
  this.moveLeft = false;
  
  this.canMove = false;
  
  this.speed = 0.3;
  this.acceleration = 0.002;
  
  this.velocity = 0.0;
  this.vector = { x : 0, y : 0 };
  
  this.direction = 2;
  
  this.shotInQueue = false;
  this.constantFire = false;
  
  this.shotVelocity = 0.194;
  this.damage = 9;
  
  this.coolDown = 12;
  this.coolDownProgress = 0;
  
  this.wake;
  
  this.atPort = false;
  
  this.hp = 100;
  this.maxHp = 100;
  this.healCounter = 0;
  
  this.gold = 200;
  
  this.numOfSpies = 0;
  
  this.damageCountdown = 0;
  
  
  this.init = function() {
    this.x = map.homePort.x + 1;
    this.y = map.homePort.y + 1;
    
    this.wake = new ParticleSystem();
    this.wake.setType(1);
    this.wake.setV(-0.2, 0.2, -0.1, 0.1);
    this.wake.setLife(25, 25);
    
    this.setUpdates();
    this.hp = this.maxHp;
  };
  
  
  this.setUpdates = function() {
    this.speed = Ship.sails[this.ownSails];
    this.maxHp = Ship.hulls[this.ownHulls];
    this.numOfSpies = Ship.spies[this.ownSpies];
    this.shotVelocity = Ship.cannon[this.ownCannon];
    this.damage = Ship.cannonballs[this.ownCannonballs];
    this.coolDown = Ship.sailors[this.ownSailors];
  };
  
  
  this.setPosition = function(x, y) {
    this.x = x;
    this.y = y;
  };  
  
  this.allowMovement = function() {
    this.canMove = true;
    mouse.registerDownArea("fireCannon", viewport.x, viewport.y, viewport.w, viewport.h, function() {
      ship.shotInQueue = true;
      ship.constantFire = true;
    });
    mouse.registerUpArea("fireCannon", viewport.x, viewport.y, viewport.w, viewport.h, function() {
      ship.constantFire = false;
    });
    keyboard.registerKeyUpHandler(Keyboard.SPACE_BAR, function() {
      panel.openUpgradeWindow();
    });
  };
  
  
  this.forbidMovement = function() {
    this.canMove = false;
    this.shotInQueue = false;
    this.constantFire = false;
    mouse.deleteDownArea("fireCannon");
    mouse.deleteUpArea("fireCannon");
    keyboard.deleteKeyUpHandler(Keyboard.SPACE_BAR);
  };
  
  
  this.update = function() {
    
    var lastX = this.x;
    var lastY = this.y;
    
    var accelerate = false;
    
    if(this.canMove) {
    
      var moveUpPressed = keyboard.isPressed(Keyboard.ARROW_UP) || keyboard.isPressed(Keyboard.W);
      var moveRightPressed = keyboard.isPressed(Keyboard.ARROW_RIGHT) || keyboard.isPressed(Keyboard.D);
      var moveDownPressed = keyboard.isPressed(Keyboard.ARROW_DOWN) || keyboard.isPressed(Keyboard.S);
      var moveLeftPressed = keyboard.isPressed(Keyboard.ARROW_LEFT) || keyboard.isPressed(Keyboard.A);
  
      
      var newVector = { x : 0.0, y : 0.0 };
      
      if(moveUpPressed && !moveDownPressed) {
        newVector.x -= 1.0;
        newVector.y -= 1.0;
        accelerate = true;
      } else if(moveDownPressed && !moveUpPressed) {
        newVector.x += 1.0;
        newVector.y += 1.0;
        accelerate = true;
      }
      if(moveRightPressed && !moveLeftPressed) {
        newVector.x += 1.0;
        newVector.y -= 1.0;
        accelerate = true;
      } else if(moveLeftPressed && !moveRightPressed) {
        newVector.x -= 1.0;
        newVector.y += 1.0;
        accelerate = true;
      }
      
      newVector = normalize(newVector);
      
      if(newVector.x != 0.0 || newVector.y != 0.0) {
        this.vector = newVector;
      }
    
    }
    
    if(accelerate) {
      if(this.velocity < this.speed) {
        this.velocity += this.acceleration;
        if(this.velocity > this.speed) {
          this.velocity = this.speed;
        }
      }
    } else {
      if(this.velocity > 0.0) {
        this.velocity -= this.acceleration;
        if(this.velocity < 0.0) {
          this.velocity = 0.0;
        }
      }
    }

    var newX = this.x + (this.vector.x * this.velocity);
    var newY = this.y + (this.vector.y * this.velocity);
    
    map.setFriendlyShipSpace(this.x, this.y, 0);
    
    if(map.isFreeForFriendlyShip(newX, newY)) {
      this.x = newX;
      this.y = newY;
    } else {
      if(this.vector.x != 0 && map.isFreeForFriendlyShip(newX, this.y)) {
        this.x = newX;
      } else if(this.vector.y != 0 && map.isFreeForFriendlyShip(this.x, newY)) {
        this.y = newY;
      } else {
        this.velocity = 0;
      }
    }
    
    map.setFriendlyShipSpace(this.x, this.y, 1);
    
    if(this.x < lastX && this.y < lastY) {
      this.direction = 0;
    } else if(this.x == lastX && this.y < lastY) {
      this.direction = 1;
    } else if(this.x > lastX && this.y < lastY) {
      this.direction = 2;
    } else if(this.x > lastX && this.y == lastY) {
      this.direction = 3;
    } else if(this.x > lastX && this.y > lastY) {
      this.direction = 4;
    } else if(this.x == lastX && this.y > lastY) {
      this.direction = 5;
    } else if(this.x < lastX && this.y > lastY) {
      this.direction = 6;
    } else if(this.x < lastX && this.y == lastY) {
      this.direction = 7;
    }
    
    var pos = map.transform(this.x, this.y);
    this.wake.setEmitter(pos.x, pos.y);
    viewport.setCamera(pos.x, pos.y);
    
    if(this.velocity > 0) {
      this.wake.on();
    } else {
      this.wake.off();
    }
    
    if(this.coolDownProgress > 0 && !map.paused) {
      this.coolDownProgress--;
    }
    if(this.shotInQueue || this.constantFire) {
      this.shotInQueue = false;
      
      if(this.coolDownProgress == 0) {
        this.coolDownProgress = this.coolDown;
        var mousePos = map.reverseTransform((mouse.x - viewport.x) - viewport.sceneX, (mouse.y - viewport.y) - viewport.sceneY);
        var cannonVelocity = { x : mousePos.x - this.x, y : mousePos.y - this.y };
        cannonVelocity = normalize(cannonVelocity);
        cannonVelocity.x *= this.shotVelocity;
        cannonVelocity.y *= this.shotVelocity;
        map.pushCannonball(true, this.x, this.y, cannonVelocity, this.damage);
      }
    }
    
    if(distance(this.x, this.y, map.homePort.x, map.homePort.y) < 2) {
      this.atPort = true;
    } else{
      this.atPort = false;
    }
    
    if(this.damageCountdown > 0 && !map.paused) {
      this.damageCountdown--;
    }
    if(this.atPort && this.hp < this.maxHp && !map.paused && this.damageCountdown == 0) {
      this.healCounter++;
      if(this.healCounter == 3) {
        this.healCounter = 0;
        this.hp++;
      }
    } else {
      this.healCounter = 0;
    }
    
  };
  
  
  this.dealDamage = function(damage) {
    this.hp -= damage;
    this.damageCountdown = 90;
    if(this.hp <= 0) {
      this.destroyed = true;
      this.hp = 0;
      panel.openInfoBox(4);
    }
  };
  
  
  this.isHit = function(x, y) {
    return distance(this.x, this.y, x, y) < 0.4;
  };
  
  
  this.draw = function() {
    var pos = map.transform(this.x, this.y);
    img.drawSprite("ship", pos.x - 60, pos.y - 90, 120, 120, this.direction, 0);
  };
  
  
  this.drawWake = function() {
    this.wake.draw();
  };
  
}


Ship.sails = [0.04, 0.048, 0.058, 0.07, 0.084, 0.101];
Ship.hulls = [50, 60, 72, 86, 104, 124];
Ship.spies = [0, 20, 40, 60, 80, 100];
Ship.cannon = [0.12, 0.132, 0.145, 0.16, 0.176, 0.194];
Ship.cannonballs = [5, 6, 7, 8, 10, 12];
Ship.sailors = [45, 36, 28, 22, 16, 12];

Ship.sailsCost = [0, 40, 50, 70, 90, 120];
Ship.hullsCost = [0, 25, 40, 60, 100, 150];
Ship.spiesCost = [0, 100, 150, 200, 250, 300];
Ship.cannonCost = [0, 30, 45, 60, 75, 90];
Ship.cannonballsCost = [0, 50, 80, 120, 180, 250];
Ship.sailorsCost = [0, 40, 60, 80, 100, 120];