/* c-basic-offset: 2; tab-width: 2; indent-tabs-mode: nil
 * vi: set shiftwidth=2 tabstop=2 expandtab:
 * :indentSize=2:tabSize=2:noTabs=true:
 */

#include "Game.h"
#include "MousePointer.h"
#include "GameButton.h"
#include "game_utils.h"
#include "GameObject.h"

/*
 * This file, as the rest of the project is under MIT license.
 * see http://opensource.org/licenses/MIT
 *
 * Author Gustav Hartvigsson <gustav.hartvigsson _at_ gmail.com> 2014
 */

void quit (int rc) {
  SDL_Quit();
  exit(rc);
}

void game_button_my_callback_hover (GameButton * self, void * data);
void game_button_my_callback_stop_hover (GameButton * self, void * data);
void game_button_my_callback_clicked (GameButton * self, void * data);

Game * game_new () {
  if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
    fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
    quit (1);
  }
  
  Game * self = malloc (sizeof (Game));
  fprintf (stdout, "Creating Game: address: %ld\n", (long) self);
  
  self->window = SDL_CreateWindow ("Hello World",
                             SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
                             640, 480, SDL_WINDOW_SHOWN);
  
  if (!self->window) {
    fprintf(stderr, "Couldn't create 640x480 window: %s\n",
            SDL_GetError());
    quit (2);
  }
  
  SDL_ShowCursor(0);
  
  self->renderer = SDL_CreateRenderer (self->window,
          -1, /* initialize the first one supporting the requested flags */
          SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
  
  if (!self->renderer) {
    fprintf(stderr, "Couldn't create renderer object: %s\n", SDL_GetError());
    quit (3);
  }
  
  self->game_controller = SDL_GameControllerOpen(0);
  if (!self->game_controller) {
    fprintf(stderr, "Couldn't open controller: %s\n", SDL_GetError());
  } else {
    fprintf (stdout, "Could open controller %s\n",
             SDL_GameControllerName (self->game_controller));
  }
  
  self->bg_colour_toggle = false;
  self->background_colour = game_color_create_color (0,0,0,255);
  
  self->button = game_button_new (50,50, 50, 100);
  game_button_set_callback (self->button, "hover", game_button_my_callback_hover, NULL);
  game_button_set_callback (self->button, "stop_hover", game_button_my_callback_stop_hover, NULL);
  game_button_set_callback (self->button, "clicked", game_button_my_callback_clicked, self);
  
  self->done = 0;
  
  self->mouse_delta.x = 0;
  self->mouse_delta.y = 0;
  self->mouse = mouse_pointer_new (640,480);
  
  return self;
} /* game_new */

void game_main_loop (Game * self) {
  while (!self->done) {
    game_process_events (self);
    game_draw (self);
  }
  fprintf (stdout, "Exiting main loop!\n");
}

void game_process_events (Game * self) {
  while (SDL_PollEvent(&self->event)) {
    switch (self->event.type) {
        case SDL_QUIT: 
        self->done = 1;
        break;
      case SDL_CONTROLLERAXISMOTION:
        if (self->event.caxis.axis == SDL_CONTROLLER_AXIS_LEFTX) {
         self->mouse_delta.x = self->event.caxis.value / J_SCALE_FACTOR;
        }
        if (self->event.caxis.axis == SDL_CONTROLLER_AXIS_LEFTY) {
         self->mouse_delta.y = self->event.caxis.value / J_SCALE_FACTOR;
        }
        break;
      case SDL_MOUSEBUTTONDOWN:
      case SDL_CONTROLLERBUTTONDOWN:
        if(self->event.cbutton.button == SDL_CONTROLLER_BUTTON_A) {
          fprintf (stdout,"Button A was Pressed!\n");
          self->mouse->pressed = true;
        }
        break;
      case SDL_MOUSEBUTTONUP:
      case SDL_CONTROLLERBUTTONUP:
        if(self->event.cbutton.button == SDL_CONTROLLER_BUTTON_A) {
          fprintf (stdout,"Button A was Relised!\n");
          self->mouse->pressed = false;
        }
        break;
      case SDL_MOUSEMOTION:
        mouse_pointer_move_to (self->mouse,
          self->event.motion.x + self->event.motion.xrel,
          self->event.motion.y + self->event.motion.yrel);
        break;
    }
  }
  game_button_check_clicked (self->button, self->mouse);
  game_button_check_hover (self->button, self->mouse);
  mouse_pointer_move (self->mouse, self->mouse_delta.x, self->mouse_delta.y);
}

void game_draw (Game * self) {
  game_color_set_draw_color (self->renderer, self->background_colour);
  
  SDL_RenderClear(self->renderer);
  
  game_button_draw (self->button, self->renderer);
  
  mouse_pointer_draw (self->mouse, self->renderer);
  
  SDL_RenderPresent (self->renderer);
}

void game_free (Game * self) {
  fprintf (stdout, "Freeing Game: address: %ld\n", (long) self);
  SDL_DestroyRenderer (self->renderer);
  SDL_DestroyWindow (self->window);
  game_button_free (self->button);
  mouse_pointer_free (self->mouse);
  free (self);
  SDL_Quit ();
}


/* CALLBACKS */

void game_button_my_callback_hover (GameButton * self, void * data) {
  fprintf (stdout, "Hover callback is triggered! @ time: %d\n", SDL_GetTicks());
  game_button_set_fill (self, true);
}

void game_button_my_callback_stop_hover (GameButton * self, void * data) {
  fprintf (stdout, "Stop Hover callback is triggered! @ time: %d\n", SDL_GetTicks());
  game_button_set_fill (self, false);
}

void game_button_my_callback_clicked (GameButton * self, void * data){
  Game * game = (Game *) data;
  if (game->bg_colour_toggle) {
    game->bg_colour_toggle = false;
    game->background_colour = game_color_create_color (0,0,0,255);
  } else {
    game->bg_colour_toggle = true;
    game->background_colour = game_color_create_color (55,55,55,255);
  }
}



/* MOO! */
