/*
    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 "WRMS_include.h"

typedef enum WRMS_visualizer_states
{ VISUALIZER_DISABLED =
    0, BULLET_VISUALIZE, DAMAGES_VISUALIZE,
    WAITING_FOR_LEAVE } WRMS_visualizer_states;

/* the visualizer object */
typedef struct WRMS_visualizer
{
  int active_p;			/* is the visualizer active? */
  WRMS_visualizer_states vstate;

  SPRITE *visualizer;		/* sprite unvisible object */

  SPRITE *bullet;		/* bullet which our camera is tracking */
  LIST *worms;			/* list of worms */
  LIST *damages;		/* damages got to worms until last explosion */

} WRMS_visualizer;

static WRMS_visualizer _visualizer = { 0, 0, NULL, NULL, NULL, NULL };

void
WRMS_visualizer_init ()
{
  memset (&_visualizer, 0, sizeof (WRMS_visualizer));
}

static void
damage_msg_life (SPRITE * msg)
{
  int *lifetime = MG_get_key (msg, "time_left");
  *lifetime -= MG_get_system_dt ();
  if (*lifetime <= 0)
    {
      free (lifetime);
      WRMS_visualizer_leave ();
      MG_remove_sprite (msg);
    }
}

static int
show_damage (SPRITE * worm)
{
  if (!worm || WRMS_worm_health (worm) <= 0)
    return 0;

  int damage = WRMS_rules_get_damage (worm);

  if (damage <= 0)
    return damage;

  POINT mid = sprite_mid (worm);
  char dmg[10];
  sprintf (dmg, "-%d", damage);
  SDL_Color c = WRMS_worm_team (worm)->c;
  SPRITE *msg = WRMS_text (dmg, c, 10, WRMS_FONT);
  MG_set_key (msg, "time_left", make_int (4000));
  MG_install_callback (msg, "on_iter", damage_msg_life);

  POINT msg_mid = sprite_mid (msg);
  MG_move_sprite (msg, mid.x - msg_mid.x, mid.y - msg_mid.y - 44);

  return damage;
}

static void
visualizer_redraw (SPRITE * self)
{
  LIST *it = WRMS_rules_worms ();
  SPRITE *worm;
  PHYSICS p;
  int dmg = 0;
  int *ticks;

  switch (_visualizer.vstate)
    {
    case BULLET_VISUALIZE:
      /* Track camera when scrollable */
      WRMS_controll_camera (sprite_mid (_visualizer.bullet), 0);
      break;

    case DAMAGES_VISUALIZE:
      /* Show to user how much damage worms got,
         only when all worms are not moving */

      /* wait a while */
      ticks = MG_get_key (self, "ticks");
      if (*ticks > 0)
	{
	  *ticks -= MG_get_system_dt ();
	  return;
	}

      /* check if nobody is moving */
      while (it)
	{
	  worm = (SPRITE *) it->value;
	  p = worm->physics;

	  if (!WRMS_worm_fixed_p (worm))
	    {
	      return;		/* worm is still moving ... wait */
	    }

	  it = it->node;
	}

      /* Nice all worms are not moving */
      /* Let show not zero damages */
      /* draw texts with damage above worms */

      it = WRMS_rules_worms ();
      dmg = 0;

      while (it)
	{
	  SPRITE *worm = it->value;

	  if (worm)
	    dmg += show_damage (worm);

	  it = it->node;
	}

      WRMS_rules_update_worms_health ();

      /* no damage was given, so leave visualizer */
      if (!dmg)
	WRMS_visualizer_leave ();
      else
	_visualizer.vstate = WAITING_FOR_LEAVE;

      break;
    case WAITING_FOR_LEAVE:
      break;
    default:
      return;
      break;
    }
}

void
WRMS_visualizer_enter ()
{
  SPRITE *vis;
  memset (&_visualizer, 0, sizeof (WRMS_visualizer));
  _visualizer.active_p = 1;
  _visualizer.visualizer = MG_make_sprite (NULL, NULL);

  vis = _visualizer.visualizer;
  MG_install_callback (vis, "on_iter", visualizer_redraw);
}

void
WRMS_visualizer_leave ()
{
  if (_visualizer.visualizer)
    {
      free (MG_get_key (_visualizer.visualizer, "ticks"));
      MG_remove_sprite (_visualizer.visualizer);
    }

  memset (&_visualizer, 0, sizeof (WRMS_visualizer));

  MG_send_msg (WRMS_hud (), "on_turn");
  SPRITE *active_worm = WRMS_rules_active_worm ();
  if (active_worm)
    {
      SDL_WarpMouse (MG_get_machine ()->screen->w / 2,
		     MG_get_machine ()->screen->h / 2);
      WRMS_controll_camera (sprite_mid (active_worm), 0);
    }

  WRMS_arrow_set (WRMS_rules_active_worm ());
}

void
WRMS_visualize_bullet (SPRITE * bullet)
{
  _visualizer.bullet = bullet;
  _visualizer.vstate = BULLET_VISUALIZE;
}

int
WRMS_visualizer_active_p ()
{
  return _visualizer.active_p;
}

void
WRMS_visualizer_damages ()
{
  _visualizer.bullet = NULL;
  _visualizer.worms = WRMS_rules_worms ();
  _visualizer.damages = NULL;

  _visualizer.vstate = DAMAGES_VISUALIZE;
  MG_set_key (_visualizer.visualizer, "ticks", make_int (1000));
}
