/***********************************************************************
 * 
 *  G F O ! 
 *  by Chee Chew
 *      and 
 *     Ken Duda 
 *
 *  (c) 1990
 *
 *  This software is free for distribution.  This notice, however, may 
 *  not be altered.
 *  
 *  Enjoy! (and punt... )
 *
 ***********************************************************************/

#include "gfo.h"

void resize_well (Well *w)
{
  w->max_x = w->length/2;
  w->max_y = w->width/2;
  w->center_x = w->xc->width/2;
  w->center_y = w->xc->height/2;
  w->z_offset = 3;
  if (w->length & 1) 
    w->x_adjust = - w->center_x * w->z_offset / 2;
  else
    w->x_adjust = 0;
  if (w->width& 1) 
    w->y_adjust = - w->center_y * w->z_offset / 2;
  else 
    w->y_adjust = 0;
  if ((w->length | w->width) & 1)
    w->z_adjust = (w->z_offset+1) / 2;
  else
    w->z_adjust = 0;
}

/* routines for drawing a block */

void draw_block_gc (Well *w, Block *b, GC gc)
{
  int n, center_x, center_y, x, y, z, z_offset;
  XPoint pts[2];
  Pixmap pix;
  

  for (n = 0; n < b->object->npoints; n++) {
    x = b->object->x[n]+b->x;
    y = b->object->y[n]+b->y;
    z = b->object->z[n]+b->z;
    pts[1].x = project_x(w,x,y,z);
    pts[1].y = project_y(w,x,y,z);
    
    if (b->object->connect[n]) {
      XDrawLine(w->xc->dsp, w->xc->mwin, gc, 
		 pts[0].x, pts[0].y, pts[1].x, pts[1].y);

      if( abs(pts[0].x - pts[1].x) > abs(pts[0].y - pts[1].y)) {
	XDrawLine(w->xc->dsp, w->xc->mwin, gc, 
		 pts[0].x, pts[0].y+1, pts[1].x, pts[1].y+1);
	XDrawLine(w->xc->dsp, w->xc->mwin, gc, 
		 pts[0].x, pts[0].y-1, pts[1].x, pts[1].y-1);
      } else {
	XDrawLine(w->xc->dsp, w->xc->mwin, gc, 
		  pts[0].x+1, pts[0].y, pts[1].x+1, pts[1].y);
	XDrawLine(w->xc->dsp, w->xc->mwin, gc, 
		  pts[0].x-1, pts[0].y, pts[1].x-1, pts[1].y);

      }
    }
    pts[0] = pts[1];
  }


  
}

void draw_block (Well *w, Block *b)
{
  int n, x,y,z, xx,yy;
  b->max_y = b->max_x = 0 ;
  b->min_y = b->min_x = w->xc->width + w->xc->height; 
  for (n = 0; n < b->object->npoints; n++) {
    x = b->object->x[n]+b->x;
    y = b->object->y[n]+b->y;
    z = b->object->z[n]+b->z;
    xx = project_x(w,x,y,z);
    yy = project_y(w,x,y,z);
    
    
    if(b->max_x < xx) b->max_x = xx;
    if(b->min_x > xx) b->min_x = xx;
    if(b->max_y < yy) b->max_y = yy;
    if(b->min_y > yy) b->min_y = yy;
    

  }
  
  draw_block_gc (w, b, w->xc->bdraw_gc);
}

void erase_block (Well *w, Block *b)
{
  redraw_well(w, b->min_x - 3, b->min_y - 3, 
	      b->max_x - b->min_x + 6, b->max_y - b->min_y + 6);
}

int block_collide (Well *w, Block *b)
{
  int x, y, z;

  if (b->x < 0 || b->y < 0 || b->z < 1 ||
      b->x+b->object->length > w->length ||
      b->y+b->object->width > w->width ||
      b->z+b->object->depth > w->depth)
    return 1;
  for (x = 0; x < b->object->length; x++)
    for (y = 0; y < b->object->width; y++)
      for (z = 0; z < b->object->depth; z++)
	if (b->object->filled[x][y][z] && w->filled[x+b->x][y+b->y][z+b->z])
	  return 1;
  return 0;
}

int advance_block (Well *w, Block *b)
{
  int bc;
  
  b->z++;
  bc = block_collide (w,b);
  b->z--;
  if (bc)
    return 0;
  erase_block(w, b);
  b->z++;
  draw_block(w, b);
  return 1;
}
  

/*** for xstuff.c ***/

