/***********************************************************************
 * 
 *  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 str2obj (char *str ,char *filled_str, Object *obj) 
{
  int size,i,j,k ; 
  
  obj->length = obj->width = obj->depth = 0;
  bzero(obj->filled, sizeof(obj->filled));

  if( (size = strlen(str)) % 4) {
    puts("str2obj: Invalid size of input string");
    exit(1);
  }

  size /= 4; 
  obj->npoints = size;

  for ( i = 0 ;  i < size ; i++) { 
    obj->x[i] = *(str++) - '0'; 
    obj->y[i] = *(str++) - '0'; 
    obj->z[i] = *(str++) - '0'; 
    obj->connect[i] = *(str++) - '0'; 

    /* find the maximum dimensions */ 
    obj->length = (obj->length > obj->x[i]) ? obj->length : obj->x[i];
    obj->width = (obj->width > obj->y[i]) ? obj->width : obj->y[i];
    obj->depth = (obj->depth > obj->z[i]) ? obj->depth : obj->z[i];
  }

  /* deal with filled string */
  for( k = 0; k < obj->depth ; k++) { 
    for( j = 0; j < obj->width; j++) {
      for( i = 0; i < obj->length; i++) {
	if (*filled_str) {
	  obj->filled[i][j][k] = *(filled_str) - '0';
	} else {
	  puts("str2obj: filled_str too short ");
	  exit(1);
	}
	filled_str++;
      }
    }
  }
  if(!filled_str) {
    puts("str2obj: filled_str too long");
    exit(1);
  }
}



void RotateCClock(Object *obj) 
{
  Object newobj; 
  int i,j,k;

  newobj = *obj;

  newobj.length = obj->width;
  newobj.width = obj->length;

  /* rotating the points */ 
  for( i = 0 ; i < obj->npoints; i++) {

    newobj.x[i] = obj->y[i]; 
    newobj.y[i] = 0 - obj->x[i] + newobj.width;
  }

  bzero(newobj.filled, sizeof(newobj.filled)) ;
  /* rotate the filled */
  for (i = 0; i < MAX_BLENGTH; i++) {
    for (j = 0; j < MAX_BLENGTH; j++) {
      for (k = 0; k < MAX_BDEPTH; k++) {
	if(obj->filled[i][j][k]) {
	  newobj.filled[ j ][obj->length - 1 - i][k] = 
	    obj->filled[ i ][ j ][k];
	}
      }
    }
  }
 
  *obj  = newobj;
}


void RotateForward(Object *obj) 
{
  Object newobj; 
  int i, j, k;

  newobj = *obj;

  newobj.width = obj->depth;
  newobj.depth = obj->width;

  /* rotating the points */ 
  for( i = 0 ; i < obj->npoints; i++) {
    newobj.y[i] = obj->z[i];
    newobj.z[i] = 0 - obj->y[i] + newobj.depth;
  }


  bzero(newobj.filled, sizeof(newobj.filled)) ;
  /* rotate the filled */
  for (i = 0; i < MAX_BLENGTH; i++) {
    for (j = 0; j < MAX_BLENGTH; j++) {
      for (k = 0; k < MAX_BDEPTH; k++) {
	if(obj->filled[i][j][k]) {
	  newobj.filled[i][k][obj->width - 1 - j] = 
	    obj->filled[ i ][ j ][ k ];
	}
      }
    }
  }

  *obj  = newobj;
}


void RotateRight(Object *obj) 
{
  Object newobj; 
  int i, j, k;


  newobj = *obj;
  newobj.length = obj->depth;
  newobj.depth = obj->length;

  /* rotating the points */ 
  for( i = 0 ; i < obj->npoints ; i++) {
    newobj.x[i] = 0 - obj->z[i] + newobj.length;
    newobj.z[i] = obj->x[i];
  }

  bzero(newobj.filled, sizeof(newobj.filled)) ;
  /* rotate the filled */
  for (i = 0; i < MAX_BLENGTH; i++) {
    for (j = 0; j < MAX_BLENGTH; j++) {
      for (k = 0; k < MAX_BDEPTH; k++) {
	if(obj->filled[i][j][k]) {
	  newobj.filled[obj->depth - 1 - k][j][i] =
	    obj->filled[ i ][ j ][ k ];
	}
      }
    }
  }

  *obj  = newobj;
}



void try_Rotate(Well *w, Block *b, void (*funct)(Object *o)) 
{
  Block blk; 
  Object obj;
  int bc;

  blk = *b;
  obj = *(b->object);
  blk.object = &obj;

  funct(&obj);
  bc = block_collide(w,&blk);
  if(!bc) { 
    erase_block(w,b);
    *(b->object) = obj;
    draw_block(w,b);
  }
}

void make_object(Object *o, int n)
{
  static char *blocks[] = 
    {
/* 0 */
      "0000100111010101000100110111111110110011010001111000101111001111",
      "1",
/* 1 */
      "0000200122010201000100110211221120110011020002112000201122002211",
      "1111",
/* 2 */
      "0000300131010101000100113011311101110011010001113000301131003111",
      "111",
/* 3 */
      "\
0000300131011101120102010001\
0011301131111111121102110011\
30003011\
31003111\
11001111\
12001211\
02000211",
      "111100",
/* 4 */
      "\
000020012101310132011201110101010001\
001120112111311132111211111101110011\
20002011\
21002111\
31003111\
32003211\
12001211\
11001111\
01000111",
      "110011",
/* 5 */
      "\
000030013101210122011201110101010001\
001130113111211122111211111101110011\
30003011\
31003111\
21002111\
22002211\
12001211\
11001111\
01000111",
      "111010",
/* 6 */
      "0000200121010101000100110111211120110011010001112000201121002111",
      "11",
/* 7 */
      "\
0000200122011201110101010001\
0011201122111211111101110011\
20002011\
22002211\
12001211\
11001111\
01000111",
      "1101",
/* 8 */
      "\
00004001410101010001\
00114011411101110011\
40004011\
41004111\
01000111",
      "1111",
/* 9 */
      "\
00005001510101010001\
00115011511101110011\
50005011\
51005111\
01000111",
      "11111",
/* 10 */
      "\
0000300133012301210101010001\
0011301133112311211101110011\
30003011\
33003311\
23002311\
21002111\
01000111",
      "111001001",
/* 11 */
      "\
0010201122111211111101110011\
00212021222102210021\
20102021\
22102221\
02000221\
11001111\
12001211\
01000111\
02000101110112010201",
      "00101111"


};
/*  printf ("Generating object %d\n",n);*/
  str2obj (blocks[2*n], blocks[2*n+1], o);
}

