//
// gamehandler.h
//
// "in-game" program mode
//
//
// Author: Tomi Belan <tomi.belan@gmail.com>, (C) 2006
//
// Copyright: See COPYING file that comes with this distribution
//
//

#include <iostream> // @debug

#include "gamehandler.h"
#include "playership.h"
#include "bullet.h"
#include "barrier.h"
#include "mainmenu.h"
#include "music.h"
#include "main.h"

GameHandler::GameHandler()
{
  Music::play(2+random()%2);
  
  world = createSurface(1300, 1300);
  background = createSurface(world->w, world->h);
  
  SDL_FillRect(background, NULL, SDL_MapRGB(background->format, 0, 0, 255));
  SDL_Surface *water = imagePool["voda.png"];
  int tmp = (world->w/water->w)+1;
  for(int x = 0; x < tmp; x++) {
    for(int y = 0; y < tmp; y++) {
      SDL_Rect offset; set_rect_pos(offset, x*water->w, y*water->h);
      SDL_Rect clip; set_rect(clip, 0, 0, world->w-offset.x, world->h-offset.y);
      if(clip.w > water->w) clip.w = water->w;
      if(clip.h > water->h) clip.h = water->h;
      if(clip.w > 0 && clip.h > 0)
        SDL_BlitSurface(water, &clip, background, &offset);
    }
  }
  
  set_rect(viewportSize, 0, 0, 390, 490);
  set_rect_pos(viewport1Pos, 5, 5);
  set_rect_pos(viewport2Pos, 405, 5);
  
  shipType1 = 0;
  shipType2 = 1;
  
  int i;
  for(i = 0; i < 1; i++)
    objects.push_back((GameObject*) new Barrier(this, 0));
  for(i = 0; i < 3; i++)
    objects.push_back((GameObject*) new Barrier(this, 1));
  for(i = 0; i < 9; i++)
    objects.push_back((GameObject*) new Barrier(this, 2));
  
  bullet1 = new Bullet(this, 1); objects.push_back((GameObject*)bullet1);
  bullet2 = new Bullet(this, 2); objects.push_back((GameObject*)bullet2);
  
  ship1 = new PlayerShip(this, 1); objects.push_back((GameObject*)ship1);
  ship2 = new PlayerShip(this, 2); objects.push_back((GameObject*)ship2);
  
  bullet1->shipsWereInitialized();
  bullet2->shipsWereInitialized();
  
  if(ship1->rect.x == ship2->rect.x || ship1->rect.y == ship2->rect.y)
    ship2->relocate();
  
}

GameHandler::~GameHandler()
{
  for(int i = 0; i < objects.size(); i++)
    delete objects[i];
  
  SDL_FreeSurface(world);
  SDL_FreeSurface(background);
}

int GameHandler::mapWorldRGB(Uint8 r, Uint8 g, Uint8 b)
{
  // I have *no idea* why this workaround is needed
  world->format->palette = NULL;
  return SDL_MapRGB(world->format, r, g, b);
}

void GameHandler::activate()
{
  SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0, 0, 0));
  moveViewport(1);
  moveViewport(2);
}

void GameHandler::event(SDL_Event *e)
{
  if(e->type == SDL_KEYDOWN) {
    if(e->key.keysym.sym == SDLK_ESCAPE)
      newProgramMode = new MainMenu();
  }
}

void GameHandler::update()
{
  SDL_BlitSurface(background, &background->clip_rect, world, &background->clip_rect);
  for(int i = 0; i < objects.size(); i++) {
    objects[i]->update(world);
  }
  
  set_rect_dim(viewport1, viewportSize.w, viewportSize.h);
  set_rect_dim(viewport2, viewportSize.w, viewportSize.h);
  set_rect_pos(viewport2Pos, 405, 5);
  SDL_BlitSurface(world, &viewport1, screen, &viewport1Pos);
  SDL_BlitSurface(world, &viewport2, screen, &viewport2Pos);
  SDL_Flip(screen);
}

void GameHandler::cleanUp()
{
}

void GameHandler::moveViewport(int viewportId)
{
  SDL_Rect shipPos = (viewportId == 1 ? ship1 : ship2)->rect;
  set_rect(shipPos, shipPos.x+shipPos.w/2-viewportSize.w/2, shipPos.y+shipPos.h/2-viewportSize.h/2, viewportSize.w, viewportSize.h);
  if(shipPos.x < 0) shipPos.x = 0;
  if(shipPos.y < 0) shipPos.y = 0;
  if(shipPos.x + shipPos.w >= world->w) shipPos.x = world->w - shipPos.w - 1;
  if(shipPos.y + shipPos.h >= world->h) shipPos.y = world->h - shipPos.h - 1;
  if(viewportId == 1)
    set_rect_pos(viewport1, shipPos.x, shipPos.y);
  else
    set_rect_pos(viewport2, shipPos.x, shipPos.y);
}

bool GameHandler::collidesWithBarriers(SDL_Rect rect1)
{
  for(int i = 0; i < barriers.size(); i++)
    if(rectanglesCollide(rect1, barriers[i]->rect))
      return true;
  return false;
}

