#include<stdlib.h>
#include<ctype.h>
#include<math.h>
#include"object.h"
#include"level.h"
#include"player.h"
#include"monster.h"
#include"io.h"
#include"fejs.h"

void
player_paint(struct player *p) {
  monster_paint(p->m);
}

void
player_look(struct player *p, tlevel *l) {
  int m, n, c, x1, y1, x2, y2;
  
  l->m[p->m->y][p->m->x].k = 1;

  if (p->m->x + p->m->l >= l->w)
    x2 = l->w - 1;
  else
    x2 = p->m->x + p->m->l;
  
  if (p->m->y + p->m->l / 2 >= l->h)
    y2 = l->h - 1;
  else
    y2 = p->m->y + p->m->l / 2;
  
  if (p->m->x - p->m->l < 0)
    x1 = 0;
  else
    x1 = p->m->x - p->m->l;
  
  if (p->m->y - p->m->l / 2 < 0)
    y1 = 0;
  else
    y1 = p->m->y - p->m->l / 2;
 
  for (m = x2; m >= p->m->x; m--) {
    for (n = y2; n >= p->m->y; n--) {
      c = (int) ceil(sqrt((double) (abs((p->m->x - m) * (p->m->x - m)) + abs((p->m->y - n) * (p->m->y - n)))));
      if (c <= p->m->l && ! l->m[n][m].k && trace_line(p->m->x, p->m->y, m, n, c, l))
	l->m[n][m].k = 1;
    }
  }
  
  for (m = x1; m <= p->m->x; m++) {
    for (n = y2; n >= p->m->y; n--) {
      c = (int) ceil(sqrt((double) (abs((p->m->x - m) * (p->m->x - m)) + abs((p->m->y - n) * (p->m->y - n)))));
      if (c <= p->m->l && ! l->m[n][m].k && trace_line(p->m->x, p->m->y, m, n, c, l))
	l->m[n][m].k = 1;
    }
  }
  
  for (m = x2; m >= p->m->x; m--) {
    for (n = y1; n <= p->m->y; n++) {
      c = (int) ceil(sqrt((double) (abs((p->m->x - m) * (p->m->x - m)) + abs((p->m->y - n) * (p->m->y - n)))));
      if (c <= p->m->l && ! l->m[n][m].k && trace_line(p->m->x, p->m->y, m, n, c, l))
	l->m[n][m].k = 1;
    }
  }
  
  for (m = x1; m <= p->m->x; m++) {
    for (n = y1; n <= p->m->y; n++) {
      c = (int) ceil(sqrt((double) (abs((p->m->x - m) * (p->m->x - m)) + abs((p->m->y - n) * (p->m->y - n)))));
      if (c <= p->m->l && ! l->m[n][m].k && trace_line(p->m->x, p->m->y, m, n, c, l))
	l->m[n][m].k = 1;
    }
  }  
}

int
player_move(struct player *p, signed short dx, signed short dy, tlevel *l) {
  int u = monster_move(p->m, dx, dy, l);
  
  if (l->m[p->m->y][p->m->x].o)
    object_notice(l->m[p->m->y][p->m->x].o);
  
  if (l->m[p->m->y][p->m->x].t == C_CDOOR)
    mwrite("Uh, oh, strange feeling to stay amidst closed door!");
  else
  if (l->m[p->m->y][p->m->x].t == C_WATER)
    mwrite("Bubble bubble... you are swimming amidst the might masses of water...");
  else
  if (l->m[p->m->y][p->m->x].t == C_WALL)
    mwrite("You are in the might stone and the compact rock! I cannot move! Let me out!");
  else
  if (l->m[p->m->y][p->m->x].t == C_FLOOR)
    ;
  else
    mwrite(terrains[l->m[p->m->y][p->m->x].t]);
  
  player_look(p, l);
  
  return u;
}

void
player_teleport(struct player *p, int x, int y, tlevel *l) {
  monster_teleport(p->m, x, y, l);
  player_look(p, l);
}

void
player_imenu(struct player *p, int a, tlevel *l) {
  unsigned long f = 0;
  tobj *o;
  char *acts[] = {"Drop an item", "Your equipment", }, ss[256],
       *cats[] = {"Head", "Neck", "Body", "Left hand", "Right hand", "Missile", "Boots", "Left ring", "Right ring", "Tool", };
  int allw[] = {3, 256, 256, -1, -1, 1, 256, 256, 256};
       
  mflush(1);
  pputstr(40 - strlen(acts[a]) / 2, 0, acts[a], C_YELLOW);
  pclear(2, 23);
  
  switch(a) {
    case 0: object_menu(p->m->i, p->m->il, &f, -1);
	    if (f + 1) {
	      o = p->m->i[f];
	      pclear(0, 25);
	      switch (a) {
		case 0: object_drop(l, p->m, o);
			break;
	      }
	    }
	    break;
	    
    case 1: while(1) {
	      unsigned long xi;
	      
	      pclear(2, 23);
	      sprintf(ss, "Choose letter [A-%c]  --  Type Z for quit  --  V for unequiped stuff", 'A' + W_S - 1);
	      pputstr(6, 24, ss, C_YELLOW);
	      
	      for (f = 0; f < W_S; f++) {
		pputch(2, f + 2, f + 'A', C_YELLOW);
		pputch(4, f + 2, '-', 0);
		sprintf(ss, "%s:", cats[f]);
		pputstr(6, f + 2, ss, C_BROWN);
		pputstr(20, f + 2, p->m->w[f]? pre_obj[p->m->w[f]->i].name: "-nothing-", 0);
	      }
	      f = toupper(getch());
	      
	      if (f >= 'A' && f < 'A' + W_S) {
		f -= 'A';
		if (p->m->w[f]) {
		  player_iget(p, p->m->w[f]);
		  p->m->w[f] = NULL;
		} else {
		  object_menu(p->m->i, p->m->il, &xi, allw[f]);
		  if (xi + 1) {
		    player_idrop(p, o = p->m->i[xi]);
		    p->m->w[f] = o;
		  }
		}
	      } else
	        switch (f) {
		  case '\033':
		  case 'Z'   : goto iout;
		  case 'V'   : f = 0;
			       object_menu(p->m->i, p->m->il, &f, 0);
			       break;
	        }
	    }
iout:	    
	    break;
  }
  
  pclear(0, 25);
}

void
player_iget(struct player *p, tobj *o) {
  monster_iget(p->m, o);
}

void
player_idrop(struct player *p, tobj *o) {
  monster_idrop(p->m, o);
}
