//
// playership.cpp
//
// game player's ship
//
//
// Author: Tomi Belan <tomi.belan@gmail.com>, (C) 2006
//
// Copyright: See COPYING file that comes with this distribution
//
//

#include <iostream> // @debug
#include <math.h>

#include "main.h"
#include "keyboard.h"
#include "bullet.h"
#include "gameover.h"
#include "gamehandler.h"
#include "playership.h"

#define byShip(a,b) (playerId==1?(a):(b))

PlayerShip::PlayerShip(GameHandler *handler, int playerId)
{
  this->playerId = playerId;
  this->handler = handler;
  maxReloading = 1;
  reloading = 0;
  maxhp = 50;
  hp = maxhp;
  velocity = 0;
  teleportRecharge = 0;
  teleportCounter = 3;
  direction = (rand()%20)/5.0;
  shipSpeed = byShip(6,5);
  relocate();
}

PlayerShip::~PlayerShip()
{
}

void PlayerShip::relocate()
{
  set_rect(rect, 100+100*(int)(rand()%7), 100+100*(int)(rand()%7), 100, 100);
  if(handler->collidesWithBarriers(rect))
    relocate();
}

int PlayerShip::getPhase()
{
//  double tmpdir = 4.711 - direction;
  double tmpdir = 4.911 - direction;
  while(tmpdir < 0) tmpdir += 6.282;
  while(tmpdir >= 6.282) tmpdir -= 6.282;
  return (int) (tmpdir * 36 / 6.282);
}

void PlayerShip::update(SDL_Surface *where)
{
  // process input
  keyboard();
  
  // do things
  move();
  
  if(reloading)
    reloading--;
  if(teleportRecharge)
    teleportRecharge--;
  
  // draw output
  
  SDL_Surface *ship = imagePool["lod1.png"];
  int phase = getPhase();
  SDL_Rect tmp, tmp2; set_rect(tmp, 100*(phase%6), 100*(phase/6), 100, 100);
  SDL_BlitSurface(ship, &tmp, where, &rect);
  
  set_rect_pos(tmp, byShip(0, 400), 500);
  SDL_BlitSurface(byShip(imagePool["bar1.png"],imagePool["bar2.png"]), NULL, screen, &tmp);
  
  // hitpoints bar:
  set_rect(tmp, 0, 578, 396-(Sint16)(396.0*hp/maxhp), 22);
  tmp.x = byShip(396, 800) - tmp.w;
  SDL_FillRect(screen, &tmp, SDL_MapRGB(screen->format, 0, 0, 0));
  
  // weapon reload:
  phase = 40-(int)(40.*reloading/maxReloading);
  set_rect(tmp, 69*(phase/5), 69*(phase%5), 69, 69);
  set_rect_pos(tmp2, byShip(308, 712), 508);
  SDL_BlitSurface(imagePool["kruh.png"], &tmp, screen, &tmp2);
}

void PlayerShip::move()
{
  SDL_Rect oldrect = rect;
  
  rect.x += (Sint16) (velocity*sin(direction));
  rect.y += (Sint16) (velocity*cos(direction));
  
  if(rect.x < 0) rect.x = 0;
  if(rect.y < 0) rect.y = 0;
  if(rect.x+rect.w >= handler->world->w) rect.x = handler->world->w-rect.w;
  if(rect.y+rect.h >= handler->world->h) rect.y = handler->world->h-rect.h;
  
  if(velocity)
    handler->moveViewport(playerId);
  
  if(handler->collidesWithBarriers(rect)) {
    SDL_Rect test;
    test = rect; test.x = oldrect.x;
    if(!handler->collidesWithBarriers(test)) {
      rect = test; return;
    }
    test = rect; test.y = oldrect.y;
    if(!handler->collidesWithBarriers(test)) {
      rect = test; return;
    }
    rect = oldrect;
  }
}

void PlayerShip::keyboard()
{
  if(Keyboard::isPressed(byShip(SDLK_a,SDLK_LEFT)))
    direction += 0.05;
  else if(Keyboard::isPressed(byShip(SDLK_d,SDLK_RIGHT)))
    direction -= 0.05;
  else {
  }
  if(Keyboard::isPressed(byShip(SDLK_w,SDLK_UP))) {
//    velocity = shipSpeed;
    if(velocity < shipSpeed)
      velocity += .5;
  }
  else {
//    velocity = 0;
    if(velocity > 0)
      velocity -= .5;
  }
  if(byShip(Keyboard::isPressed(SDLK_TAB)||Keyboard::isPressed(SDLK_SPACE),Keyboard::isPressed(SDLK_RETURN)))
    shoot();
  if(Keyboard::isPressed(byShip(SDLK_z,SDLK_DELETE)))
    teleport();
}

SDL_Rect PlayerShip::myCollisionRect()
{
  SDL_Rect imageSize;
  int phase = getPhase();
  switch(phase % 9) {
    case 0: set_rect_dim(imageSize, 100, 40); break;
    case 1: set_rect_dim(imageSize, 95, 50); break;
    case 2: set_rect_dim(imageSize, 95, 60); break;
    case 3: set_rect_dim(imageSize, 90, 65); break;
    case 4: set_rect_dim(imageSize, 85, 75); break;
    case 5: set_rect_dim(imageSize, 75, 85); break;
    case 6: set_rect_dim(imageSize, 65, 90); break;
    case 7: set_rect_dim(imageSize, 60, 95); break;
    case 8: set_rect_dim(imageSize, 50, 95); break;
  }
  if((phase/9) % 2) {
    int w = imageSize.w; int h = imageSize.h;
    set_rect_dim(imageSize, h, w);
  }
  
  SDL_Rect collisionRect = imageSize;
  set_rect_pos(collisionRect, rect.x+rect.w/2-imageSize.w/2, rect.y+rect.h/2-imageSize.h/2);
  return collisionRect;
}

bool PlayerShip::collidesWith(SDL_Rect rect2)
{
  return rectanglesCollide(myCollisionRect(), rect2);
}

void PlayerShip::wasHit()
{
  hp -= 5;
  if(hp <= 0) {
    hp = 0;
    newProgramMode = new GameOver(playerId);
  }
}

void PlayerShip::setReloading(int n, int max)
{
  reloading = n;
  maxReloading = max == -1 ? n : max;
}

void PlayerShip::shoot()
{
  if(reloading)
    return;
  setReloading(120);
//  if(velocity)
//    return;
  Bullet *bullet = byShip(handler->bullet1,handler->bullet2);
  if(bullet->visible)
    bullet->visible = false;
  SDL_Rect bulletVelocity, bulletPos;
  double tmp = bullet->speed + velocity/2;
  set_rect_pos(bulletVelocity, (Sint16)(tmp*sin(direction)), (Sint16)(tmp*cos(direction)));
  set_rect(bulletPos, rect.x+rect.w/2, rect.y+rect.h/2, bullet->size.w, bullet->size.h);
  bulletPos.x -= bullet->size.w/2;
  bulletPos.y -= bullet->size.h/2;
  if(rectanglesCollide(byShip(handler->ship2,handler->ship1)->rect, bulletPos))
    return;
  bullet->show(bulletPos, bulletVelocity);
}

void PlayerShip::teleport()
{
  if(!teleportCounter) return;
  if(teleportRecharge) return;
  teleportCounter--;
  teleportRecharge = 900;
  setReloading(300);
  relocate();
  handler->moveViewport(playerId);
}


