/* color_draw.c -- simple drawing program using predefined colours.  */
   #include <Xm/MainW.h>
   #include <Xm/DrawingA.h>
   #include <Xm/PushBG.h>
   #include <Xm/PushB.h>
   #include <Xm/RowColumn.h>
   #include <Xm/ScrolledW.h>
   #include <Xm/List.h>
   #include <Xm/Form.h>
   #include <stdio.h>
   #include <stdlib.h>
   #include <stdint.h>
   
  void  sel_callback ( Widget list_w, XtPointer client_data,  XtPointer call_data);
  void  set_color(  Widget widget, XtPointer client_data, XtPointer call_data);
  int   create_gui(  void )  ;
  void  draw(  Widget widget,  XEvent *event, String *args,  int *num_args) ;
  void  clear_it(  Widget pb,  XtPointer client_data,  XtPointer call_data) ;
  void  redraw(  Widget    drawing_a,  XtPointer client_data,  XtPointer call_data) ;
  void render_objects(Widget widget, XtPointer client_data, XtPointer call_data) ;
  
  
   GC gc;
   Pixmap pixmap;
   /* dimensions of drawing area (pixmap) */
   Dimension width, height;
   Widget  drawing_a;
   XtAppContext app;

   uint8_t ready = FALSE;

  // String colours[] = {
  char * colours[] = {
       "Black", "Red", "Green", "Blue", "White", "Navy", "Orange", "Yellow",
       "Pink", "Magenta", "Cyan", "Brown", "Grey", "LimeGreen", "Turquoise",
       "Violet" , "Wheat", "Purple"
   };
   
   
   

 int main( int argc, char *argv[] )    {
      
   if (argc > 1) { // would you like me to open a file!?!?!?!
      
   } else {
     printf("You will get farther with a filename\n");
   }
   
   create_gui();
   ready = TRUE;
 
   XtAppMainLoop (app);
   
 
   return 0;
 
 }


   int create_gui( void )    {
   
       Widget toplevel, main_w, sw, rc, form,  pb;              
       XGCValues gcv;
       int i;
       XtActionsRec actions;
       String translations =   "<Btn1Down>:   draw(down)  \n      <Btn1Up>:     draw(up)  \n   <Btn1Motion>: draw(motion) \n";
       XmStringTable  str_list;
       
       int argc = 1;         
       char *argvs = "Program";
       char **argv = &argvs;


       XtSetLanguageProc (NULL, NULL, NULL);

       toplevel = XtVaAppInitialize (&app, "AwesomeCAM", NULL, 0,  &argc, argv, NULL,
           XmNx,            200, // Initial position
           XmNy,            400, 
           XmNminWidth,     700, // initial size
           XmNminHeight,    500,
           NULL);

       /* Create a MainWindow to contain the drawing area */
       main_w = XtVaCreateManagedWidget ("main_w",  
           xmFormWidgetClass, toplevel, 
           NULL);

       /* Create a GC for drawing (callback).  Used a lot -- make global */
       gcv.foreground = WhitePixelOfScreen (XtScreen (main_w));
       gc = XCreateGC (XtDisplay (main_w),  RootWindowOfScreen (XtScreen (main_w)), GCForeground, &gcv);






   str_list = (XmStringTable) XtMalloc (XtNumber(colours) * sizeof (XmString));

   for (i = 0; i < XtNumber(colours); i++)
       str_list[i] = XmStringCreateLocalized (colours[i]);                              


     pb = XmCreateScrolledList (main_w, "List", NULL, 0);
     XtVaSetValues(pb,
           XmNitems, str_list,
           XmNitemCount, XtNumber(colours),
           XmNvisibleItemCount, 5,
           XmNselectionPolicy,   XmEXTENDED_SELECT,
           NULL);


     XtVaSetValues( XtParent(pb),
       XmNleftAttachment, XmATTACH_FORM,
       XmNtopAttachment, XmATTACH_FORM,
       XmNbottomAttachment, XmATTACH_FORM,
       NULL);

     XtManageChild(pb);
     XtAddCallback (pb,  XmNextendedSelectionCallback , sel_callback, NULL);




       sw = XtVaCreateManagedWidget ("scrolled_win",
           xmScrolledWindowWidgetClass, main_w,
           XmNwidth,                  300,
           XmNscrollingPolicy,        XmAUTOMATIC,
           XmNscrollBarDisplayPolicy, XmAS_NEEDED,
           XmNtopAttachment,          XmATTACH_FORM,
           XmNbottomAttachment,       XmATTACH_FORM,
           XmNleftAttachment,         XmATTACH_WIDGET,
           XmNleftWidget,             pb,
           XmNrightAttachment,        XmATTACH_FORM,
           NULL);

       /* Add the "draw" action/function used by the translation table
        * parsed by the translations resource below.
        */
       actions.string = "draw";
       actions.proc = (void (*)())draw;
       
       XtAppAddActions (app, &actions, 1);

       /* Create a DrawingArea widget.  Make it 5 inches wide by 6 inches tall.
        * Don't let it resize so the Clear Button doesn't force a resize.
        */
       drawing_a = XtVaCreateManagedWidget ("drawing_a",
           xmDrawingAreaWidgetClass, sw,
           XmNtranslations, XtParseTranslationTable (translations),
           XmNunitType,     Xm1000TH_INCHES,
           XmNwidth,        5000, /* 5 inches */
           XmNheight,       6000, /* 6 inches */
           XmNresizePolicy, XmNONE,  /* remain this a fixed size */
           NULL);
       /* When scrolled, the drawing area will get expose events */
       XtAddCallback (drawing_a, XmNexposeCallback, redraw, NULL);
       
       
       
       /* Pushing the clear button clears the drawing area widget */
//       XtAddCallback (pb, XmNactivateCallback, clear_it, drawing_a);

       /* convert drawing area back to pixels to get its width and height */
       XtVaSetValues (drawing_a, XmNunitType, XmPIXELS, NULL);
       XtVaGetValues (drawing_a, XmNwidth, &width, XmNheight, &height, NULL);
       
       /* create a pixmap the same size as the drawing area. */
       pixmap = XCreatePixmap (XtDisplay (drawing_a),  RootWindowOfScreen (XtScreen (drawing_a)), width, height,  DefaultDepthOfScreen (XtScreen (drawing_a)));
       /* clear pixmap with white */
       set_color (drawing_a, "White", NULL);
       XFillRectangle (XtDisplay (drawing_a), pixmap, gc, 0, 0, width, height);
       set_color (drawing_a, "Black", NULL);
    //   XDrawArc( XtDisplay (drawing_a), pixmap, gc, 100, 100, 30, 30, 0, 360*64);
       

       XtRealizeWidget (toplevel);
       
   }


void sel_callback ( Widget list_w, XtPointer client_data,  XtPointer call_data) {

    XmListCallbackStruct  *cbs = (XmListCallbackStruct *) call_data;
    char                  *choice;
    int                   i;

    if (cbs->reason == XmCR_EXTENDED_SELECT) {
    
        printf ("%d items selected\n", cbs->selected_item_count);

        for (i = 0; i < cbs->selected_item_count; i++) {
            choice = (char *) XmStringUnparse (cbs->selected_items[i],  XmFONTLIST_DEFAULT_TAG,  XmCHARSET_TEXT,  XmCHARSET_TEXT,  NULL, 0,  XmOUTPUT_ALL);
            
      //      printf ("%s (%d)\n", choice, cbs->selected_item_positions[i]);
            
            set_color (list_w, choice, NULL);
            
            XtFree (choice);
        }
    }
}




   /* Action procedure to respond to any of the events from the
    * translation table declared in main().  This function is called
    * in response to Button1 Down, Up and Motion events.  Basically,
    * we're just doing a freehand draw -- not lines or anything.
    */
   void    draw(  Widget widget,  XEvent *event, String *args,  int *num_args)    {
       static Position x, y;
       XButtonEvent *bevent = (XButtonEvent *) event;

       if (*num_args != 1)
           XtError ("Wrong number of args!");

       if (0) {
         XSetLineAttributes(bevent->display, gc, 2, LineSolid,  CapRound, JoinBevel); 
 //      XDrawLine (bevent->display, bevent->window, gc, x, y, bevent->x, bevent->y); 
         XDrawArc( bevent->display, bevent->window, gc, bevent->x-15, bevent->y-15, 30, 30, 0, 360*64);
       }

       if (strcmp (args[0], "down")) {
           /* if it's not "down", it must either be "up" or "motion"
            * draw full line from anchor point to new point.
            */
           XSetLineAttributes(bevent->display, gc, 3, LineSolid,  CapRound, JoinBevel);             
           XDrawLine (bevent->display, bevent->window, gc, x, y, bevent->x, bevent->y);                    
           XDrawLine (bevent->display, pixmap, gc, x, y, bevent->x, bevent->y);
       }

       /* freehand is really a bunch of line segements; save this point */
       x = bevent->x;
       y = bevent->y;
   }

   /* Clear the window by clearing the pixmap and calling XCopyArea() */
   void clear_it(  Widget pb,  XtPointer client_data,  XtPointer call_data)    {
       Widget drawing_a = (Widget) client_data;
       XmPushButtonCallbackStruct *cbs =  (XmPushButtonCallbackStruct *) call_data;

       /* clear pixmap with white */
       XSetForeground (XtDisplay (drawing_a), gc,  WhitePixelOfScreen (XtScreen (drawing_a)));
       /* this clears the pixmap */
       XFillRectangle (XtDisplay (drawing_a), pixmap, gc, 0, 0, width, height);
       /* drawing is now done using black; change the gc */
       XSetForeground (XtDisplay (drawing_a), gc, BlackPixelOfScreen (XtScreen (drawing_a)));
       /* render the newly cleared pixmap onto the window */
       XCopyArea (cbs->event->xbutton.display, pixmap, XtWindow (drawing_a), gc,  0, 0, width, height, 0, 0);
   }

   /* redraw is called whenever all or portions of the drawing area is
    * exposed.  This includes newly exposed portions of the widget resulting
    * from the user's interaction with the scrollbars.
    */
   void  redraw(  Widget    drawing_a,  XtPointer client_data,  XtPointer call_data)    {
       XmDrawingAreaCallbackStruct *cbs =  (XmDrawingAreaCallbackStruct *) call_data;

       XCopyArea (cbs->event->xexpose.display, pixmap, cbs->window, gc,  0, 0, width, height, 0, 0);
   }

   /* callback routine for when any of the color tiles are pressed.
    * This general function may also be used to set the global gc's
    * color directly.  Just provide a widget and a color name.
    */
   void  set_color(  Widget widget, XtPointer client_data, XtPointer call_data)    {
   
       String color = (String) client_data;
       Display *dpy = XtDisplay (widget);
       Colormap cmap = DefaultColormapOfScreen (XtScreen (widget));
       XColor col, unused;
       
    //   Widget drawing_a = (Widget) client_data;
       XmPushButtonCallbackStruct *cbs =  (XmPushButtonCallbackStruct *) call_data;

       if (!XAllocNamedColor (dpy, cmap, color, &col, &unused)) {
           char buf[32];
           sprintf (buf, "Can't alloc %s", color);
           XtWarning (buf);
           return;
       }
       XSetForeground (dpy, gc, col.pixel);
       
       XSetLineAttributes(dpy, gc, 2, LineSolid,  CapRound, JoinBevel); 
       XDrawArc( dpy, pixmap, gc, 100, 100, 30, 30, 0, 360*64);
       XDrawArc( dpy, XtWindow(drawing_a), gc, 100, 100, 30, 30, 0, 360*64);
       
   }
   
   
   
   void render_objects(Widget widget, XtPointer client_data, XtPointer call_data)    {
   
     Widget drawing_a = (Widget) client_data;
     XmPushButtonCallbackStruct *cbs =  (XmPushButtonCallbackStruct *) call_data;
     
     
   //  XFillRectangle (XtDisplay(drawing_a), pixmap, gc, 0, 0, width, height);
     XDrawArc( XtDisplay(drawing_a), pixmap, gc, 100, 100, 30, 30, 0, 360*64);
     
     XCopyArea (cbs->event->xexpose.display, pixmap, XtWindow(drawing_a), gc,  0, 0, width, height, 0, 0);
   }








