
#include <iostream.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "glaux.h"
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <stdio.h>
#include "/usr/pvm3/include/pvm3.h"
#define SLAVENAME "sub1"
#define MAXTASKS 
#define MAXCOL 8


//universal constants
 float xmax=1.5, xmin=-2.5, ymax=2.0, ymin=-2.0; //screen size
 int wid=400, hig=400; //screen size
 float intvx; 
 float intvy; 
 float rali, imagi; //Julia set initial points
 int pressed=0; //Mantel of Julia
 int output=0; //Output to Target File
//

typedef struct {
   char id_len;                 // ID Field (Number of bytes - max 255)
   char map_type;               // Colormap Field (0 or 1)
   char img_type;               // Image Type (7 options - color vs. compression)
   int  map_first;              // Color Map stuff - first entry index
   int  map_len;                // Color Map stuff - total entries in file
   char map_entry_size;         // Color Map stuff - number of bits per entry
   int  x;                      // X-coordinate of origin 
   int  y;                      // Y-coordinate of origin
   int  width;                  // Width in Pixels
   int  height;                 // Height in Pixels
   char bpp;                    // Number of bits per pixel
   char misc;                   // Other stuff - scan origin and alpha bits
} targa_header;

static void Init (void)
//sets up the screen
{
  glClearColor(1.0, 1.0, 1.0, 1.0);
  glShadeModel( GL_FLAT  );
  intvx= ( (fabs) (xmax-xmin) ) /(wid);
  intvy= ( (fabs) (ymax-ymin) ) /(hig);
  cout<<intvx<<intvy<<endl;

}

static void Reshape (int width, int height )
//sets up the screen. How large and wide it is. 
{ 
  wid=width; hig=height;
  glViewport( 0, 0, (GLint)width, (GLint)height);
  glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
  glOrtho( xmin,xmax,ymin,ymax, -1.0, 1.0);
  glMatrixMode(GL_MODELVIEW);
}


static void color(int num)
//color defaults for number of iterations to escape
//depending on Mandel of Julia the color goes from green to red
{
 pressed=1;
 int temp;
 temp = num %10;
 switch (temp)
 {
  case 1: glColor3f(1*pressed, .1, .1 ); break;
  case 2: glColor3f(1*pressed, .2, .1 ); break;

  case 3: glColor3f(1*pressed, .3, .1); break;
  case 4: glColor3f(1*pressed, .4, .1); break;

  case 5: glColor3f(1*pressed, .5, .1); break;
  case 6: glColor3f(1*pressed, .6, .1); break;

  case 7: glColor3f(1*pressed ,.7,.1); break;
  case 8: glColor3f(1*pressed ,.8, .1); break;

  case 9: glColor3f(1*pressed,.9,.1); break;
  case 0: glColor3f(1*pressed,1,1); break;
 }
}

void DrawMyStuff()
//plotting the points
{

 float imag,ral,temp; 
 float i,t;
 double max, min;
 glBegin( GL_POINTS );
 float check;
 float blue, red, green;
 
 cout<<"in drawmystuff"<<endl;
//for PVM
    int n, nproc, numt,  who, msgtype, nhost, narch;
    int mytid;                  /* my task id */
    int tids[hig];                   /* slave task ids */
    int avail[hig];           /* availailable slaves  */
    float  mdata[hig];			/*arrat of Y variables */
    float  data [wid];                    /* array of X variables  */

    int iter;		//Returned result = number of iterations
    struct pvmhostinfo *hostp[hig]; /* pointers to host information */

    /* enroll in pvm */
    mytid = pvm_mytid();

    /* Set number of slaves to start */
    /* Can not do stdin from spawned task */
    
    nproc=hig;

    /* start up slave tasks */
    numt=pvm_spawn(SLAVENAME, (char**)0, 0, "", nproc, tids);

    if( numt < nproc )
      {
       	printf("Trouble spawning slaves. Aborting. Error codes are:\n");
        for( int p=numt ; p<nproc ; p++ ) 
           {
           	printf("TID %d %d\n",i,tids[p]); 
           }
        for( int p=0 ; p<numt ; p++ )
           {
           	pvm_kill( tids[p] );
       }
        
        pvm_exit();
        exit(0);
      }
 int count=0;
 //fill in the Y values
 for (i=ymin; i<ymax; i+=intvy)
    {
    mdata[count]=i;
    count++;
    }
char ch;

/* 
 count=0;
 for (i=ymin; i<ymax; i+=intvy)
    {
    cout<<mdata[count];
    count++;
    }
 cin>>ch; 
*/

 count=0;
 //fill in the X values
 for (t=xmin; t<xmax; t+=intvx)
    {
    data[count]=t;
    count++;
    }
 
/*count=0;
 for (t=xmin; t<xmax; t+=intvx)
    {
    cout<<data[count];
    count++;
    }
 cin>>ch;
*/
    /* Broadcast initial data to slave tasks */
       pvm_initsend(PvmDataDefault);                   // Get ready to send message buffer 
       pvm_pkint(&nproc, 1, 1);                  // Pack number of slave processors
       pvm_pkint(tids, nproc, 1);                // Pack array of task IDs

       int numy=hig;
       int numx=wid;

   
       pvm_pkfloat(data, numx, 1);  // Pack array of X data to send
       pvm_pkfloat(mdata, numy, 1); // Pack array of Y data to send
       pvm_mcast(tids, nproc, 0);                // Multicast message to all processors
     
       cout<<"Multicased Out"<<endl;
    /* Wait for results from slaves */
    msgtype = 5;
    
    int result[numy];
    int temp2;

    for (i=0 ; i<nproc ; i++)
     {
       cout<<"Received One!"<<endl;
       pvm_recv( -1, msgtype );                  // Wait for message of right type
       pvm_upkint( &who, 1, 1 );                       // Find out who sent message

//       temp2=0;
//       pvm_upkint(&temp2,1,1);
//       cout<<"who="<<who<<" temp2="<<temp2<<endl;

       pvm_upkint(result, numy, 1 );			//Checking on the final value
//	for (int u=0;u<numy;u++)
//	   cout<<"From "<<who<<" result["<<u<<"] ="<<result[u]<<endl;

       for (int step=0; step<numy; step++)
       {
        if (result[step]==0)  glColor3f( 0.0, 0.0, 0.0);
        if (result[step]>0)  color(result[step]);
        glVertex3f(data[who],mdata[step],0.0);
	cout<<"who="<<who<<" x="<<data[who]<<" y="<<mdata[step]<<" Result="<<result[step]<<endl;
       }
     }  

    /* Program Finished - exit PVM before stopping */
 pvm_exit();          
 glEnd();
}

static void display()
//displays
{
 cout<<"IN display function-"<<endl;
 glClear ( GL_COLOR_BUFFER_BIT);
 DrawMyStuff();
 glFlush(); //pushes the drawn stuf
 auxSwapBuffers(); //replots second buffer 
}

main (int argc, char **argv)
{ 

 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
 glEnable(GL_DEPTH_TEST);

 glutInitWindowSize(400, 400);
 glutInitWindowPosition(100,100);
 if (glutCreateWindow("Mantle Box")==GL_FALSE) auxQuit();
 Init();
 glutDisplayFunc(display);
 glutReshapeFunc(Reshape);
 glutMainLoop();



}

