/* program to draw lines in a window. */


#include <stdio.h>              /* the standard c library */
#include <X11/Xlib.h>           /* the X library          */
#include <X11/Xutil.h>          /* the X library          */
#include <X11/cursorfont.h>     /* the cursors            */

/* a few arbitary constants */

#define TOLERANCE 8
#define MAX_VERTEX 100
#define START_X         10
#define START_Y         20
#define WINDOW_WIDTH   640   
#define WINDOW_HEIGHT  480
#define BORDER_WIDTH     1
#define NUMBER_OF_IMAGES 30

  
Display *u_Display;           /* the display that will be used     */
Window the_window;              /* the window that will be opened    */
Window dsp_window1;              /* the window that will be opened    */
Window dsp_window2;              /* the window that will be opened    */
int the_screen;                 /* the screen that will be used      */
Window root_window;             /* the root window on the screen     */
XSizeHints size_hints;          /* size hints for the window manager */
XEvent the_event;               /* the structure for the input event */
GC the_GC;
GC invert_GC;
Cursor the_cursor;              /* the variable for the cursor */

struct head {
 int *student_x;
 int *student_y;
 int *inner_x;
 int *inner_y;
 int *outer_x;
 int *outer_y;
};

struct head header[NUMBER_OF_IMAGES];
				 

/************************** MAIN ***************************/

main(argc,argv)
     int argc;
     char *argv[];
{ 
  /* Set the display to be the default display (ie, your
     display as given in the environment variable DISPLAY). */

  if ((u_Display = XOpenDisplay("")) == NULL)
     {
        printf("in %s:  can't open display\n",argv[0]);
	return(-1);
     }       

     /* A few useful values. */

  the_screen = DefaultScreen(u_Display);
  
  root_window = DefaultRootWindow(u_Display);
  
  /* Set the size hints for the window manager. */

  size_hints.x = START_X;
  size_hints.y = START_Y;
  size_hints.width = WINDOW_WIDTH;
  size_hints.height = WINDOW_HEIGHT;
  size_hints.flags = PSize|PPosition;

  /* Create a window of fixed size, origin, and borderwidth.
     The window will have a black border and white background. */

  the_window = XCreateSimpleWindow(u_Display, root_window,
				   size_hints.x,size_hints.y,
				   size_hints.width,size_hints.height,
				   BORDER_WIDTH,
				   BlackPixel(u_Display,the_screen),
				   WhitePixel(u_Display,the_screen));
  dsp_window1 = XCreateSimpleWindow(u_Display, root_window,
				   0, 480,
				   size_hints.width,size_hints.height,
				   BORDER_WIDTH,
				   BlackPixel(u_Display,the_screen),
				   WhitePixel(u_Display,the_screen));
  dsp_window2 = XCreateSimpleWindow(u_Display, root_window,
				   640, 480,
				   size_hints.width,size_hints.height,
				   BORDER_WIDTH,
				   BlackPixel(u_Display,the_screen),
				   WhitePixel(u_Display,the_screen));


  /* what are we doing? */
  the_GC = XCreateGC(u_Display, the_window, 0, NULL);
  invert_GC = XCreateGC(u_Display, the_window, 0,NULL);

/*  XFreeGC(u_Display, the_GC); */

  XSetState (u_Display, invert_GC, 
	     BlackPixel(u_Display, the_screen),
	     WhitePixel(u_Display, the_screen),
	     GXinvert, AllPlanes);

    /* Round up the usual suspects for the window manager. */
  
  XSetStandardProperties(u_Display,the_window,
			 "Funest Polygon Window","Line Icon",
			 None,argv,argc,&size_hints);
  
  
  XSelectInput(u_Display,the_window,
	       ExposureMask|ButtonPressMask|ButtonReleaseMask
	       |PointerMotionMask);
  
  
  XSelectInput(u_Display,dsp_window1,
	       ExposureMask|ButtonPressMask|ButtonReleaseMask
	       |PointerMotionMask);
  
  
  XSelectInput(u_Display,dsp_window2,
	       ExposureMask|ButtonPressMask|ButtonReleaseMask
	       |PointerMotionMask);
  
  /* Tell the server to make the windows visible. */


  /* Create the cursor. */

  the_cursor = XCreateFontCursor(u_Display,XC_top_left_arrow);

  /* Set the cursor for the window. */

  XDefineCursor(u_Display,the_window,the_cursor);

  
  XMapWindow(u_Display,the_window); 
  XMapWindow(u_Display,dsp_window1); 
  XMapWindow(u_Display,dsp_window2); 
  
  /* Enter the main input event loop. */
  {
  int choice;
  int num;
  int win;
  Window winptr;
  void polyinput(), polydraw();
  while(1)
    {
      printf("\nTo input an image enter: 1. To draw an image enter: 2 ");
      scanf("%d", &choice);
      printf("\nEnter image number.");
      scanf("%d", &num);
        printf("\nEnter window number (1 or 2).");
        scanf("%d", &win);
	winptr = (win == 1)? dsp_window1 : dsp_window2;
      if (choice == 1)
	polyinput(num,winptr);
      else
      {
	polydraw(num,winptr );
       }
      XFlush(u_Display);
    }
  }
}




/************************* POLYGON INPUT FUNCTION **********************/

void polyinput(image, window)
     int image;
	Window window;
{
  char *calloc();
  XButtonEvent *button_event;
  XPointerMovedEvent *pointer_moved_event;
  int count = 0;
  int i;
  int done = 0;
  int buffer_x[MAX_VERTEX];
  int buffer_y[MAX_VERTEX];
  int *target_x;
  int *target_y;
 
  while(!done)
    {
      XNextEvent(u_Display, &the_event);
/* printf("event...\n");   */
      if (done)
	break;
      if (the_event.type == ButtonRelease)
	{
	  button_event = (XButtonEvent *)&the_event;
	  buffer_x[count + 1] = buffer_x[count] = button_event->x;
	  buffer_y[count + 1] = buffer_y[count] = button_event->y;
	/*  printf ("x is %d, y is %d\n", buffer_x[count], buffer_y[count]);*/
	  if (!count)
	    {
	      XDrawPoint(u_Display, window, the_GC,
			 buffer_x[0],buffer_y[0]);
	      count++;
	    }
	  else if ((buffer_x[count] > buffer_x[0] - TOLERANCE) && 
		   (buffer_x[count] < buffer_x[0] + TOLERANCE) &&
		   		   (buffer_y[count] > buffer_y[0] - TOLERANCE) && 
		   (buffer_y[count] < buffer_y[0] + TOLERANCE))
	    {
	      XDrawLine(u_Display, window, invert_GC,
			buffer_x[count-1], buffer_y[count-1],
			buffer_x[0], buffer_y[0]);
	      XDrawLine(u_Display, window, the_GC,
			buffer_x[count-1], buffer_y[count-1],
			buffer_x[0], buffer_y[0]);
	      buffer_x[count] = -1;
	      buffer_y[count] = -1;
	      done = 1;
	    }
	  else 
	    {
	      XDrawLine(u_Display, window, the_GC,
			buffer_x[count-1], buffer_y[count-1],
			buffer_x[count], buffer_y[count]);
	      count++;
	    }
	}
      else if (the_event.type == Expose)
	; 

      else if (the_event.type == MotionNotify && count)
	{
	  pointer_moved_event = (XPointerMovedEvent *)&the_event;

	  XDrawLine(u_Display, window, invert_GC,
		    buffer_x[count-1], buffer_y[count-1], 
		    buffer_x[count], buffer_y[count]);

	  buffer_x[count] = pointer_moved_event->x;
	  buffer_y[count] = pointer_moved_event->y;

	  if ((buffer_x[count] > buffer_x[0] - TOLERANCE) && 
		   (buffer_x[count] < buffer_x[0] + TOLERANCE) &&
		   (buffer_y[count] > buffer_y[0] - TOLERANCE) && 
		   (buffer_y[count] < buffer_y[0] + TOLERANCE)) {
	    buffer_x[count] = buffer_x[0];
	    buffer_y[count] = buffer_y[0];
	  }

	  XDrawLine(u_Display, window, invert_GC,
		    buffer_x[count-1], buffer_y[count-1],
		    buffer_x[count], buffer_y[count]);
	}
	
      else /* anything else */
	;
    }
	 
		  
  target_x = (int *)calloc(count + 1, sizeof(int));
  target_y = (int *)calloc(count + 1, sizeof(int)); 

  header[image].student_x = target_x;
  header[image].student_y = target_y;
  for (i = 0; i <= count; ++i)
    {
      target_x[i] = buffer_x[i];
      target_y[i] = buffer_y[i];
    }
  XFlush(u_Display);
  return;
    
}



/************************** POLYGON DRAW FUNCTION **********************/

/*void polydraw(image, type) */
void polydraw(image, dsp_window)
     int image;	
     Window dsp_window;
/*     char *type; */
{
 int *target_x, *target_y;
 int i;

/*
 target_x = header[image].type;
 target_y = header[image].type;

 if (!target_x)
  {
     printf("\nThis polygon is not present or has not been entered\n");
     return;
   }
*/

 target_x = header[image].student_x;
 target_y = header[image].student_y;

 if (!target_x)
  {
     printf("\nThis polygon is not present or has not been entered\n");
     return;
   }

 for(i = 1; target_x[i] != -1 ; ++i) 
   XDrawLine(u_Display, dsp_window, the_GC, 
		       target_x[i-1], target_y[i-1],
		       target_x[i], target_y[i]);
 XDrawLine(u_Display, dsp_window, the_GC,
		      target_x[i-1], target_y[i-1],
		      target_x[0], target_y[0]);

 return;
}
