/* functions called in response to button presses in edit modes */


#include "wimp.h"
#include "wimpt.h"
#include "win.h"
#include "event.h"
#include "baricon.h"
#include "res.h"
#include "resspr.h"
#include "menu.h"
#include "template.h"
#include "dbox.h"
#include "werr.h"
#include "bbc.h" 
#include "coords.h" 

#include <math.h>
#include <stdlib.h>

#include "polysaw.h"




#define FF_BIT 128    /* (in grid[][]).  For 'flood-fill' calculation 
                         when joining squares */

static coords_pointstr poly[MAX_SQUARES]; /* for list of such squares */

/*****************  FUNCTIONS **********************************/

static void    join_up_squares(int row, int col);
static int     do_a_neighbour(int r, int c, int ns);




void deal_with_squares_but(coords_pointstr wrk, wimp_bbits mse_b)
{
int x, y, g, row, col;


if (wimp_BLEFT & mse_b)
  {                             
  x = roundtonearest(wrk.x - HS, 2*HS);
  y = roundtonearest(wrk.y - HS, 2*HS);
  /* x,y is bottom left of square */
  row = (-y-2*HS)/(2*HS);
  col = x/(2*HS);
  if (col<0 || row<0 || col>=MAX_BOARD || row>=MAX_BOARD)
       return;
  g = (int) grid[row][col];
  if ( g & (SQUARE_BIT | PIECE_BIT) ) 
       return;   
        
  grid[row][col]  |=  SQUARE_BIT;

  force_grid_redraw(row, col);  
  }

if (wimp_BRIGHT & mse_b)
  {                             
  x = roundtonearest(wrk.x - HS, 2*HS);
  y = roundtonearest(wrk.y - HS, 2*HS);
  /* x,y is bottom left of square */
  row = (-y-2*HS)/(2*HS);
  col = x/(2*HS);
  if (col<0 || row<0 || col>=MAX_BOARD || row>=MAX_BOARD)
       return;
  g = (int) grid[row][col];
  if ( g & SQUARE_BIT) 
    {
    grid[row][col]  &=  ~SQUARE_BIT;
    force_grid_redraw(row, col);  
    }
  } 
 
}



void deal_with_holes_but(coords_pointstr wrk, wimp_bbits mse_b)
{
int x, y, g, row, col;


if (wimp_BLEFT & mse_b)
  {                             
  x = roundtonearest(wrk.x - HS, 2*HS);
  y = roundtonearest(wrk.y - HS, 2*HS);
  /* x,y is bottom left of hole */
  row = (-y-2*HS)/(2*HS);
  col = x/(2*HS);
  if (col<0 || row<0 || col>=MAX_BOARD || row>=MAX_BOARD)
       return;
  g = (int) grid[row][col];
  if ( g & (HOLE_BIT | SQUARE_BIT | PIECE_BIT) ) 
       return;   
        
  grid[row][col]  |=  HOLE_BIT;

  force_grid_redraw(row, col); 
  
  }

if (wimp_BRIGHT & mse_b)
  {                             
  x = roundtonearest(wrk.x - HS, 2*HS);
  y = roundtonearest(wrk.y - HS, 2*HS);
  /* x,y is bottom left of hole */
  row = (-y-2*HS)/(2*HS);
  col = x/(2*HS);
  if (col<0 || row<0 || col>=MAX_BOARD || row>=MAX_BOARD)
       return;
  g = (int) grid[row][col];
  if ( (g & (HOLE_BIT | SQUARE_BIT | PIECE_BIT)) == HOLE_BIT) 
    { 
    grid[row][col]  &=  ~HOLE_BIT;
    force_grid_redraw(row, col); 
    }
  }

}



void deal_with_jnsplt_but(coords_pointstr wrk, wimp_bbits mse_b)
{
int i, p, dead, x, y;


if (mse_b & wimp_BLEFT)
  {
   join_up_squares((-wrk.y)/(2*HS), wrk.x/(2*HS));
  }
if (mse_b & wimp_BRIGHT)
  {
  dead = which_piece(wrk);
  if (dead > MAX_PIECES)
      return;
  /* update grid */
  for (i=0; i<piece[dead].nofunits; i++)
    {
    x = piece[dead].cog.x + piece[dead].units[i].x;
    y = piece[dead].cog.y + piece[dead].units[i].y;
    grid[(-y-HS)/(2*HS)][(x-HS)/(2*HS)] &= ~PIECE_BIT;
    }
  force_piece_redraw(dead);

  /* shuffle down the existing polys to fill gap */

  for (p=dead; p<nofpieces-1; p++)
    {
    piece[p] = piece[p+1];
    }
  nofpieces -= 1;
  

  }
}





int do_a_neighbour(int r, int c, int ns)
{
int g;

if (r<0 || c<0 || r>=MAX_BOARD || c>=MAX_BOARD) return ns;

g = grid[r][c];
if ( (g & SQUARE_BIT)  &&  !(g & FF_BIT) ) 
  {
  poly[ns].y = r;
  poly[ns].x = c;
  ns += 1;
  grid[r][c]  |= FF_BIT;
  }
return ns;
}



void join_up_squares(int row, int col)

/* passed grid posn to start from.  does a flood fill from row, col
using   (grid[][] & SQUARE_BIT)  values */

{
int cogx=0, cogy=0;
int nofs=1, next=0, i;

if (nofpieces == MAX_PIECES)
  {
  werr(FALSE, "Too many polyonimoes\n");
  return;
  }

if (!(grid[row][col] & SQUARE_BIT))
    return;

poly[0].y = row;
poly[0].x = col;
grid[row][col] |= FF_BIT;

while (next < nofs)
  {
  nofs = do_a_neighbour(poly[next].y, poly[next].x - 1, nofs);
  nofs = do_a_neighbour(poly[next].y, poly[next].x + 1, nofs);
  nofs = do_a_neighbour(poly[next].y - 1, poly[next].x, nofs);
  nofs = do_a_neighbour(poly[next].y + 1, poly[next].x, nofs);
  next ++;
  }

/* clear all FF_BITs for next time */
for (i=0; i<nofs; i++)
  {
  grid[poly[i].y][poly[i].x] &= ~FF_BIT;
  }

if (nofs > MAX_SQUARES)
  {
  werr(FALSE, "Poly too big\n");
  return;
  }


/* now we're committed to actually making the thing. First clear squares. */

for (i=0; i<nofs; i++)
  {
  grid[poly[i].y][poly[i].x] &= ~SQUARE_BIT;
  }


/* turn into work area units */
for (i=0; i<nofs; i++)
  {
  poly[i].y *= 2*HS;
  poly[i].y = -HS - poly[i].y;
  poly[i].x *= 2*HS;
  poly[i].x += HS;
  /* these are now centres of squares in work coords */
  }

/* find cog */
for (i=0; i<nofs; i++)
  {
  cogx += poly[i].x;
  cogy += poly[i].y;
  }
cogx = cogx/nofs;
cogy = cogy/nofs;
cogx = roundtonearest(cogx, HS);
cogy = roundtonearest(cogy, HS);

/* start filling in info, getting square centres rel. to cog */
piece[nofpieces].cog.x = cogx;
piece[nofpieces].cog.y = cogy;

piece[nofpieces].nofunits = nofs;
for (i=0; i<nofs; i++)
  {
  piece[nofpieces].units[i].x = poly[i].x - cogx;
  piece[nofpieces].units[i].y = poly[i].y - cogy;
  }

/* now at stage like just after reading in a file */
fill_out_polydefn(nofpieces);

/* finally draw the new piece and update number of pieces*/
force_piece_redraw(nofpieces);
nofpieces += 1;
}











