/*  w2.c    w1.c with more windows, connect the points*/

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/***************** global variables **************************/

static Display *dpy;
static Window window1, window2, quit_w;
static GC gc, gcinv, gcred, gcblue;
static Screen *screen;
static int screen_num;
static XColor red, blue;
static Colormap colormap;
static XPoint points[100];
static int n_points = 0;
static int n = 0;

static void doInitialize(void);          /* function prototypes used below */
static void doCreateWindows(void);
static void doCreateGraphicsContext(void);
static void doHandleEvents(void);
static void redraw(void);

/********************** The main program *******************************/
int main(int argc, char *argv[])
{          
  doInitialize();
  doHandleEvents(); /* this never returns */
  return 0;
}                                        

/***************** doInitialize **************************/
static void doInitialize(void)
{
  dpy = XOpenDisplay(0); 
  if(!dpy)
  {
    printf("Display not opened!\n");
    exit(1);
  }
  screen = XDefaultScreenOfDisplay(dpy);
  screen_num = DefaultScreen(dpy);
  colormap = DefaultColormap(dpy, screen_num);

  doCreateWindows();

  doCreateGraphicsContext();

  XStoreName(dpy, window1, "W2 Connect Points");

  XMapWindow(dpy, window1);
  XMapWindow(dpy, window2);
  XMapWindow(dpy, quit_w );
} 

/******* doCreateWindows *********/
static void doCreateWindows(void)
{   
  int window1X = 300;
  int window1Y = 200;
  int window1W = 400;
  int window1H = 300;
  XSetWindowAttributes xswa;
                   
  /* Create the window1 window */

  xswa.event_mask = ExposureMask | ButtonPressMask | 
                    Button1MotionMask | ButtonReleaseMask;

  xswa.background_pixel = XWhitePixelOfScreen(screen);

  window1 = XCreateWindow(dpy,
                          XRootWindowOfScreen(screen),
                          window1X, 
                          window1Y,
                          window1W,
                          window1H,
                          0,
                          XDefaultDepthOfScreen(screen),
                          InputOutput,
                          XDefaultVisualOfScreen(screen),
                          CWEventMask | CWBackPixel,
                          &xswa);

  window2 = XCreateWindow(dpy,
                          window1, /* parent */
                          0, /* X of this window relative to window1 */
                          20, /* Y of this window relative to window1 */
                          window1W,
                          window1H-20-20, /* leave room at bottom for quit */
                          0,
                          XDefaultDepthOfScreen(screen),
                          InputOutput,
                          XDefaultVisualOfScreen(screen),
                          CWEventMask | CWBackPixel,
                          &xswa);

  quit_w  = XCreateWindow(dpy,
                          window1, /* parent */
                          0, /* X of this window relative to window1 */
                          window1H-20, /* Y relative to window1 */
                          window1W,
                          20, /* leave room at bottom for quit */
                          0,
                          XDefaultDepthOfScreen(screen),
                          InputOutput,
                          XDefaultVisualOfScreen(screen),
                          CWEventMask | CWBackPixel,
                          &xswa);
}

/******** Create the graphics context *********/    
static void doCreateGraphicsContext(void)
{                                                
  XGCValues xgcv;
    
  /* Create graphics context. */
  xgcv.foreground = XBlackPixelOfScreen(screen);
  xgcv.background = XWhitePixelOfScreen(screen);
  gc = XCreateGC(dpy, window1, GCForeground | GCBackground, &xgcv);   

  xgcv.foreground = XWhitePixelOfScreen(screen); /* inverse to erase */
  xgcv.background = XBlackPixelOfScreen(screen);
  gcinv = XCreateGC(dpy, window1, GCForeground | GCBackground, &xgcv);
  xgcv.background = XWhitePixelOfScreen(screen);

  XParseColor(dpy, colormap, "red", &red);
  XAllocColor(dpy, colormap, &red);
  xgcv.foreground = red.pixel;
  gcred = XCreateGC(dpy, window1, GCForeground | GCBackground, &xgcv);

  XParseColor(dpy, colormap, "blue", &blue);
  XAllocColor(dpy, colormap, &blue);
  xgcv.foreground = blue.pixel;   
  gcblue = XCreateGC(dpy, window1, GCForeground | GCBackground, &xgcv);
}

/****************** doHandleEvents ***********************/
static void doHandleEvents(void)
{
  XEvent event;

  for ( ; ; )
  {
    XNextEvent(dpy, &event);
    switch (event.type)
    { 
      case Expose:
         if (event.xexpose.count == 0) 
         {
           redraw();
         }
         break;
      case ButtonPress: 
         if (event.xexpose.window == quit_w)
         {
           exit(0); /* shut down */
         }
         else if (event.xbutton.button == 3)
         {
           n_points=n; 
           redraw();
         }
         else if (event.xbutton.button == 1)
         {
           if (n_points != 0)
           {
             XClearWindow(dpy, window2);
             n_points=0;
             n=0;
           }
           points[n].x = event.xbutton.x;
           points[n].y = event.xbutton.y;
           n++;
           redraw();
           printf(" %d, %d press \n", event.xbutton.x,
                                      event.xbutton.y);
         }
         break;
      case ButtonRelease:
        printf(" %d, %d release \n", event.xbutton.x, event.xbutton.y);
        break;
    } /* end switch */
  }                                           
}

/***** Write the message in quit_window, draw in window2 *****/
static void redraw(void)
{
  static char instruct[] = {"press button 1 for point, press button 3 to connect"};
  static char message[] = {"Click here to exit"}; 
  int i, j;

  XDrawImageString(dpy, window1, gc, 20, 15, instruct, strlen(instruct));
  XDrawImageString(dpy, quit_w, gc, 150, 15, message, strlen(message));

  XClearWindow(dpy, window2);
  XDrawRectangle(dpy, window2, gc, 10, 0, 380, 259); 

  for(i=0; i<n; i++)
  {
    XFillRectangle(dpy, window2, gcred, points[i].x-2, points[i].y-2,
                   5, 5);
  }
  for(i=0; i<n_points-1; i++)  /* connect every point to every other */
  {
    for(j=i+1; j<n_points; j++)
    {
      XDrawLine(dpy, window2, gcblue, points[i].x, points[i].y,
                                      points[j].x, points[j].y );
    }
  }
}

