#include <parallel.h>
#include <stdio.h>
#include <math.h>
#include "rtd.h"
#include "macros.h"
#include "globals.h"

/* these definitions describe a window in the x-y plane
   that the whole thing is viewed through. */
#define INC  1.0
#define NUM_PROCS 6
#define PAGESIZE 1024
#define X_MIN 0.0
#define X_MAX 511.0
#define Y_MIN 0.0
#define Y_MAX 511.0

struct object_data *data; 
double sam = 1.0;
int xground, yground;
int     level;

struct sphere_data light_source;

struct barrier_area
         {
         char lock;
         char wait_lock;
         int procs_in;
         int height;
         };

struct shared_pointer 
         {
         char start_pad[PAGESIZE], start;
         char lock;
         char img[512][512];
         double ground[300][300];
         struct barrier_area barrier;
         char fin, end_pad[PAGESIZE];
         };

struct shared_pointer shared_info;
int id;

main (argc, argv)
int     argc;
char  **argv;
{
    FILE * df, *texfile, *fs, *viewpoint_file, *fp;
    char output_file_name[40];  
    static double   xco,
                    yco;
    struct ray  rr;
    struct vector   vp;
    float tx, ty, tz, dx, dy, dz;
    double  x,
            y,
            z,
            view_x,
            view_y,
            view_z;
    int     i,
            in = 0,
            out = 0,
            tex = 0,
            view = 0;
    int x1, y1, z1;
    int     c, num_bytes = 512 * 512;
    double offset_x = 0.0,
           offset_y = 0.0;

/* command interp */

    for (i = 1; i < argc; i++) {
	if (argv[i][0] != '-')
	    booboo ("Options strt with a '-' bozo");
	c = argv[i][1];

	switch (c) {
	    case ('i'): 
		if (in)
		    booboo ("Sorry, but you may only have one input file");
		in = 1;
		if ((i + 1) >= argc || argv[i + 1][0] == '-')/* no arg */
		    df = stdin;
		else
		    if ((df = fopen (argv[++i], "r")) == NULL)
			booboo ("input file not found");
		break;
	    case ('o'): 
		if (out)
		    booboo ("Sorry, but you may have only one output file");
		out = 1;
		if ((i + 1) >= argc || argv[i + 1][0] == '-')/* no arg */
		    fp = stdout;
		else
                    strcpy(output_file_name, argv[++i]);
/*
		    fp = fopen (argv[++i], "w");
*/
		break;
	    case ('s'): 
		if (tex)
		    booboo ("Sorry, but you may have only one image file");
		if ((i + 1) >= argc || argv[i + 1][0] == '-')/* no arg */
		    booboo ("-s requires an argument");
		tex = 1;
		if ((texfile = fopen (argv[++i], "r")) == NULL)
		    booboo ("image file not found");
		break;
		booboo ("this line shouldn't do anything");
	    case ('S'): 
		if (argv[i][2] < '0' || argv[i][2] > '9'){
printf("%c\n",argv[i][2]);
		    booboo ("-S needs a numerical argument");}
		sam = atof (&(argv[i][2]));
		break;
            case ('v'):
                view = TRUE;
                if ((i + 1) >= argc || argv[i + 1][0] == '-')
                  booboo("-v requires an argument");
                if ((viewpoint_file = fopen(argv[++i], "r")) == NULL)
                  booboo ("viewpoint file not found");
                break;
	    default: 
		booboo ("Unrecognized option. Better try again");
	}
    }


    if (!in)
	if ((df = fopen ("bdata.i", "r")) == NULL)
	    booboo ("bdata.i not found");
    if (!out)
      strcpy(output_file_name, "data.dis");
/*
	fp = fopen ("data.dis", "w");
*/
    if (!tex)
	if ((texfile = fopen ("pat.def", "r")) == NULL)
	    booboo ("pat.def not found");
    if (view)
      {
      printf("reading viewpoint file\n");
      fscanf(viewpoint_file,"%F %F %F\n", &view_x, &view_y, &view_z);
      printf("view point x = %f y = %f z = %f\n", view_x, view_y, view_z);
      }
    else
        /* define viewpoint */
      {
      view_x = 256.0;
      view_y = 256.0;
      view_z = -600.0;
      };

    MV(view_x, view_y, view_z, vp);
    offset_x = view_x - ((X_MAX - X_MIN) / 2);
    
    init_global();
    init_seads(x_world_start, x_world_end, y_world_start, y_world_end,
               z_world_start, z_world_end);
    
    printf("finished initializing seads\n");

    g_bal (df);
    g_bod (texfile);


    printf ("%d %d\n", ((int) (X_MAX + 1.0)), ((int) (Y_MAX + 1.0)));
    share(&shared_info.start,
          &shared_info.fin - &shared_info.start);
    printf("shared area\n");
/* define light source (rad defines how fuzzy the shadows will be) */
    MV(0.0, 900.0, 0.0, light_source.cent);
    light_source.rad = 40;
    id = NUM_PROCS - 1;

    print_seads();
    do 
      {
      printf("Enter x value (< 0 to quit) --> ");
      scanf("%f", &tx);
      if (tx < 0) break;
      printf("Enter y value --> ");
      scanf("%f", &ty);
      printf("Enter z value --> ");
      scanf("%f", &tz);
      dx = (float) ((double) tx - vp.x);
      dy = (float) ((double) ty - vp.y);
      dz = (float) ((double) tz - vp.z);
      x1 = (int) (vp.x + (dx / dz * -vp.z));
      y1 = (int) (vp.y + (dy / dz * -vp.z));
      printf("x1 = %d  y1 = %d  dx = %f dy = %f dz = %f\n", x1, y1, dx, dy, dz);
      xco = x1 * INC + offset_x;
      yco = y1 * INC + offset_y;
      MV(xco, yco, 0.0, rr.org);
/* define the ray through a pixel and find out the value for that pixel */
      SV(rr.dir, rr.org, vp);
      rr.src = 0;
      printf("intensity = %d\n", shade(&rr, yco));
      }
    while (x1 >= 0);


}  /* end of main */

bar()
  {
  spinlock(&shared_info.barrier.lock);
  shared_info.barrier.procs_in++;
  if (shared_info.barrier.procs_in < shared_info.barrier.height)
    {
    spinunlock(&shared_info.barrier.lock);
    spinlock(&shared_info.barrier.wait_lock);
    };
  if (shared_info.barrier.procs_in == 0)
    spinunlock(&shared_info.barrier.lock);
  else
    {
    shared_info.barrier.procs_in--;
    spinunlock(&shared_info.barrier.wait_lock);
    };
  } /* end of bar */

booboo (str)
char   *str; {
    printf ("%s\n", str);
    exit (-1);
}
