/*
    Bazoo_worms the game
    Copyright (C) 2011  Pavel Prochazka

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "MG_lib.h"
#include "WRMS_include.h"
#include "WRMS_utils.h"
#include "stages.h"
#include "gui.h"

static SPRITE *yesno_d = NULL;

static void
leave_game (SPRITE * self)
{
  WRMS_visualizer_leave ();
  WRMS_enter_stage (STAGE_MENU);
  yesno_d = NULL;
}

static void
do_null (SPRITE * self)
{
  yesno_d = NULL;
}

static SPRITE *
yesno_dialog ()
{
  if (yesno_d)
    return yesno_d;

  /*if( WRMS_visualizer_active_p() ) // is it cool?
     return NULL; */

  SPRITE *dialog =
    WRMS_dialog_yesno (".: RETURN TO MENU ? :.", "Are you sure?");
  MG_install_callback (dialog, "on_yes", leave_game);
  MG_install_callback (dialog, "on_no", do_null);
  MACHINE *m = MG_get_machine ();
  SDL_Rect w_pos = m->view_rect;

  MG_move_sprite (dialog, w_pos.x + (w_pos.w / 2) - (dialog->dest.w / 2),
		  w_pos.y + (w_pos.h / 2) - (dialog->dest.h / 2));
  yesno_d = dialog;
  return dialog;
}

void
WRMS_controll_camera (POINT camera_mid, int mouse_p)
{
  if (yesno_d)
    return;

  SDL_Rect r = MG_get_machine ()->view_rect;
  SDL_Rect scr = WRMS_WORLD_SCREEN;

  POINT screen_mid = { r.x + (r.w / 2), r.y + (r.h / 2) };

  if (mouse_p)
    {
      VECTOR v = vector_from_points (screen_mid, camera_mid);
      double len = vector_length (v);

      if (len < 200)
	return;

      r.x += (v.x / 36.0f);
      r.y += (v.y / 36.0f);
    }
  else
    {
      /* just center */
      r.x = camera_mid.x - (r.w / 2);
      r.y = camera_mid.y - (r.h / 2);
    }

  SDL_Rect cut = MG_rects_cut (r, WRMS_WORLD_SCREEN);

  if (cut.x == 0)
    cut.w = r.w;

  if (cut.y == 0)
    cut.h = r.h;

  if (cut.w < r.w)
    {
      cut.x = scr.w - r.w;
      cut.w = r.w;
    }

  if (cut.h < r.h)
    {
      cut.y = scr.h - r.h;
      cut.h = r.h;
    }

  MG_sprite_set_position (WRMS_hud (), cut.x, cut.y);
  MG_set_view_rect (cut);
}

static void
game_hook (SPRITE * background)
{
  if (MG_key_down_p (SDLK_ESCAPE))
    {
      yesno_dialog ();
    }

  LIST *events = MG_get_machine ()->events;

  while (events)
    {
      SDL_Event *e = events->value;
      if (e->type == SDL_QUIT)
	{
	  yesno_dialog ();
	}
      events = events->node;
    }

  if (!WRMS_visualizer_active_p ())
    {
      WRMS_rules_refresh ();
      POINT mouse = { MG_get_mouse_x (), MG_get_mouse_y () };
      WRMS_controll_camera (mouse, 1);
    }

  if (WRMS_rules_game_done_p ())
    {
      char *team_win_str = NULL;

      WRMS_team *twin = WRMS_get_win_team ();
      if (twin)
	{
	  char *win_team = twin->team_name;
	  team_win_str =
	    (char *) malloc (sizeof (char) *
			     (strlen (TEAM_WIN_STR) + strlen (win_team) + 2));
	  sprintf (team_win_str, TEAM_WIN_STR, win_team);
	}
      else
	{
	  team_win_str = strdup ("Game draw!");
	}

      WRMS_stage_set_args (team_win_str);
      leave_game (NULL);
    }
}

static void
cloud_life (SPRITE * self)
{
  int orig_mid = (int) MG_get_key (self, "orig_y");
  POINT mid_current = sprite_mid (self);
  POINT mid_orig = mid_current;
  mid_orig.y = orig_mid;

  VECTOR speed = self->physics.v;
  VECTOR wind = WRMS_wind_get ();

  if ((speed.x < 0.0f ? -1.0f : 1.0f) != (wind.x < 0.0f ? -1.0f : 1.0f))
    {
      speed = vector (0.0f, 0.0f);
      MG_set_speed (self, &speed);
    }

  VECTOR v = vector_from_points (mid_current, mid_orig);
  v.y = (v.y / 10000.0f);
  v.x = wind.x / 2.0f;
  MG_set_power (self, &v);

  SDL_Rect world = WRMS_WORLD_SCREEN;
  SDL_Rect cut = MG_rects_cut (world, self->dest);

  if (MG_null_rect_p (cut))
    {
      if (self->dest.x > 0)
	MG_sprite_set_position (self, -self->dest.w + 1, self->dest.y);
      else
	MG_sprite_set_position (self, world.w - 1, self->dest.y);
    }
}

SPRITE *
WRMS_make_cloud ()
{
  SPRITE *out = MG_make_sprite (MG_get_img ("cloud.bmp"), NULL);
  MACHINE *m = MG_get_machine ();

  MG_sprite_set_position (out, -out->dest.w + 1,
			  (rand () % (m->game_world->h)) / 2);
  MG_install_callback (out, "on_iter", cloud_life);
  MG_set_weight (out, 8.0f);
  MG_set_key (out, "orig_y", (void *) (out->dest.y + out->dest.h / 2));

  VECTOR speed = vector (0.0f, 0.0f);
  MG_set_speed (out, &speed);

  return out;
}

SPRITE *
WRMS_set_background (const char *bckg)
{
#define BACKGROUND_ID 0x0
  SDL_Surface *s = MG_get_img (bckg);

  SPRITE *out = MG_make_sprite_nth (s, NULL, BACKGROUND_ID);

  out->type = BACKGROUND;
  MG_install_callback (out, "on_iter", game_hook);

  WRMS_make_cloud ();

  return out;
}
