/* man.c */

#include "graphics.h"
#include "key.h"
#include "man.h"
#include "map.h"
#include "scrn.h"

man_status man_condition;

/* His position in map */
int man_mapx,man_mapy;

/* Position on screen */
int man_screenx,man_screeny;

/* Map position he's aiming for */
int man_newx,man_newy;

/* Whether man is pushing bomb or has detonator */
BOOL man_pushing,man_detonator;

/* Directions */
#define dir_LEFT 0
#define dir_RIGHT 1
#define dir_UP 2
#define dir_DOWN 3

int man_face_dir;

/* Submoves left to go before man is aligned to a map square */
int man_submoves;

/* See whether player wants to and can move either horizontally or
   vertically and if so do it
 */
BOOL man_try_horiz(void);
BOOL man_try_vert(void);

void man_init_pos(int x,int y)
{
  man_mapx = x;
  man_mapy = y;
  man_screenx = x << MAPPIX;
  man_screeny = y << MAPPIX;
  man_face_dir = dir_UP;
  man_submoves = 0;
  man_pushing = man_detonator = FALSE;
  man_condition = status_PLAYING;
}

void man_draw(int vga)
{
  (*scrn_slow_plotter)(&graphics_pool[graphic_LEFT + man_face_dir],
  	    	       man_screenx,man_screeny,vga);
  if (man_pushing)
  {
    register int x,y;

    switch (man_face_dir)
    {
      case dir_LEFT:
        x = man_screenx - 16;
        y = man_screeny;
        break;
      case dir_RIGHT:
        x = man_screenx + 16;
        y = man_screeny;
        break;
      case dir_UP:
        x = man_screenx;
        y = man_screeny - 16;
        break;
      case dir_DOWN:
        x = man_screenx;
        y = man_screeny + 16;
        break;
    }
    (*scrn_slow_plotter)(&graphics_pool[graphic_BOMBOFF],x,y,vga);
  }
}

man_status man_move()
{
  if (pressing_esc())
    return status_ESC;

  if (!man_submoves)
  {
    man_pushing = FALSE;
    switch (man_face_dir)
    {
      case dir_LEFT:
      case dir_RIGHT:
        if (!man_try_vert())
          man_try_horiz();
        break;
      case dir_UP:
      case dir_DOWN:
        if (!man_try_horiz())
          man_try_vert();
        break;
    }
  }

  if (man_submoves)
  {
    switch (man_face_dir)
    {
      case dir_LEFT:
        man_screenx -= 2;
        break;
      case dir_RIGHT:
        man_screenx += 2;
        break;
      case dir_UP:
        man_screeny -= 2;
        break;
      case dir_DOWN:
        man_screeny += 2;
        break;
    }
    if (!(--man_submoves))
    {
      man_mapx = man_newx;
      man_mapy = man_newy;
      map_place_item(man_mapx,man_mapy,map_BLANK);
      if (man_pushing)
      {
        int x,y;

        switch (man_face_dir)
        {
          case dir_LEFT:
            x = man_mapx - 1;
            y = man_mapy;
            break;
          case dir_RIGHT:
            x = man_mapx + 1;
            y = man_mapy;
            break;
          case dir_UP:
            x = man_mapx;
            y = man_mapy - 1;
            break;
          case dir_DOWN:
            x = man_mapx;
            y = man_mapy + 1;
            break;
        }
        map_place_item(x,y,map_BOMBOFF);
      }
    }
  }

  return man_condition;
}

BOOL man_try_horiz()
{
  if (pressing_left())
  {
    man_newx = man_mapx - 1;
    man_newy = man_mapy;
    if (map_loc_free(man_newx,man_newy,-1,0,TRUE,
    		     &man_condition,&man_pushing,&man_detonator))
    {
      man_face_dir = dir_LEFT;
      man_submoves = 8;
      return TRUE;
    }
  }
  if (pressing_right())
  {
    man_newx = man_mapx + 1;
    man_newy = man_mapy;
    if (map_loc_free(man_newx,man_newy,1,0,TRUE,
    		     &man_condition,&man_pushing,&man_detonator))
    {
      man_face_dir = dir_RIGHT;
      man_submoves = 8;
      return TRUE;
    }
  }
  return FALSE;
}

BOOL man_try_vert()
{
  if (pressing_up())
  {
    man_newx = man_mapx;
    man_newy = man_mapy - 1;
    if (map_loc_free(man_newx,man_newy,0,-1,TRUE,
    		     &man_condition,&man_pushing,&man_detonator))
    {
      man_face_dir = dir_UP;
      man_submoves = 8;
      return TRUE;
    }
  }
  if (pressing_down())
  {
    man_newx = man_mapx;
    man_newy = man_mapy + 1;
    if (map_loc_free(man_newx,man_newy,0,1,TRUE,
    		     &man_condition,&man_pushing,&man_detonator))
    {
      man_face_dir = dir_DOWN;
      man_submoves = 8;
      return TRUE;
    }
  }
  return FALSE;
}
