#include <X11/copyright.h>
#include <math.h>
extern parse();
extern error();
/* $XConsortium: Graph.c,v 1.2 88/10/25 17:40:25 swick Exp $ */
/* Copyright	Massachusetts Institute of Technology	1987, 1988 */


/* this is a modification of the template widget provided by the    */
/* XConsortium.                                                     */
/* Programmer Dan Bennett                                           */

#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include <stdio.h>
#include "Graph.h"
#include "GraphP.h"



static char defaultTranslations[]=
     "<EnterWindow>:       cmap()       \n\
      <LeaveWindow>:       uncmap()       ";

static XtResource resources[] = {
#define offset(field) XtOffset(GraphWidget, graph.field)
    /* {name, class, type, size, offset, default_type, default_addr}, */
       {XtNforeground,XtCForeground,XtRPixel, sizeof(Pixel),
               offset(foreground), XtRString, "XtDefaultForeground"},
       {XtNbackground,XtCBackground,XtRPixel, sizeof(Pixel),
	       offset(background), XtRString, "XtDefaultBackground"},
#undef offset
};

/*******************************************************/
/* this solution (Adding a translation to map and unamp*/
/* is incorrect according to the X11R4 standards but   */
/* I can't get the reccomended method to work.         */
/*******************************************************/

static void CMAP(),UNCMAP();

static XtActionsRec actionsList[]=
{
    {"cmap",          CMAP},
    {"uncmap",        UNCMAP},
};

static void CMAP(wid,event,params,num_params)
GraphWidget wid;
XEvent *event;
String *params;
Cardinal *num_params;
{
       XInstallColormap(XtDisplay(wid),wid->core.colormap);
}

static void UNCMAP(wid,event,params,num_params)
GraphWidget wid;
XEvent *event;
String *params;
Cardinal *num_params;
{
         XUninstallColormap(XtDisplay(wid),wid->core.colormap);
}

void XGPCopyArea(wid,slx,sly,swd,shg,dlx,dly)
    GraphWidget    wid;
    Position   slx,sly,swd,shg,dlx,dly;

    {
          XCopyArea(XtDisplay(wid),wid->core.background_pixmap,XtWindow(wid),
                               wid->graph.XGPgc,slx,sly,swd,shg,
                                dlx,dly);
    }

void redisplay_picture(wid)
	GraphWidget    wid;

	{
	   XSetForeground(XtDisplay(wid),wid->graph.XGPgc,1);
	   XFillRectangle(XtDisplay(wid),wid->core.background_pixmap,
		   wid->graph.XGPgc,0,0,wid->core.width,wid->core.height);
	}


void XGPDrawPoint(wid,x,y,len,multfact,col)
      int col,x,y,len,multfact;
      GraphWidget   wid;
      {
	 int i,j;

	 if ((even(x) & even(y)) | (!even(x)& !even(y))){
	     XSetForeground(XtDisplay(wid),wid->graph.XGPgc,col);
	     for(j=0;j<multfact;j++){
	        for(i=0;i<multfact;i++){
	           XDrawPoint(XtDisplay(wid),wid->core.background_pixmap
	               ,wid->graph.XGPgc,x*multfact+j,y*multfact+i);
		}
	    }
	 }
	 XSetForeground(XtDisplay(wid),wid->graph.XGPgc,wid->graph.background);
	 XGPCopyArea(wid,x*multfact,y*multfact,len,len
		    ,x*multfact,y*multfact);
      }

void DrawPoint(wid,x,y,len,multfact,col)
      int col,x,y,len,multfact;
      GraphWidget   wid;
      {
	 int i,j;

	 if ((even(x) & even(y)) | (!even(x)& !even(y))){
	     XSetForeground(XtDisplay(wid),wid->graph.XGPgc,col);
	     for(j=0;j<multfact;j++){
	        for(i=0;i<multfact;i++){
	           XDrawPoint(XtDisplay(wid),wid->core.background_pixmap
	               ,wid->graph.XGPgc,x*multfact+j,y*multfact+i);
		}
	    }
	 }
	 XSetForeground(XtDisplay(wid),wid->graph.XGPgc,wid->graph.background);
      }

void displaypicture(pic,wid,len,hei,multfact)
      int *pic,len,hei,multfact;
      GraphWidget  wid;
      {
	 int x,y,i,j;
	 for(x=0;x<len;x++){
	    for(y=0;y<hei;y++){
		DrawPoint(wid,x,y,len,multfact,pic[x*len+y]);
	    }
	 }
	 XGPCopyArea(wid,0,0,wid->core.width,wid->core.height,0,0);
      }

void rawdrawpoint(wid,x,y)
      GraphWidget            wid;
      Position                  x,y; 

      {
	XDrawPoint(XtDisplay(wid),wid->core.background_pixmap
	     ,wid->graph.XGPgc,x,y);
      }

static void XGPInitialize(junk,new)
    GraphWidget  junk,new;

    {
    }

void XGPInit(wid)
     GraphWidget  wid;
     {
	 XGPInitialize(NULL,wid);
     }

static void XGPRealize(w,valueMask, attributes)
     GraphWidget w;
     Mask *valueMask;
     XSetWindowAttributes *attributes;
     
     { 
       XGCValues values;
       Display   *disp;
       int       scrnnum;

       (widgetClassRec.core_class.realize)(w,valueMask,attributes);

/*******************************************************************/
/*   find the display and the screen number, then finally point to */
/*   the default colormap of the wm                                */
/*******************************************************************/

       disp = XtDisplay(w);
       scrnnum = XDefaultScreen(disp);

       w->core.colormap = 
	  XCreateColormap(disp,XtWindow(w)
	  ,DefaultVisual(disp,scrnnum),AllocNone);
/*******************************************************************/
/* get a pixmap to draw in so that all is nice and purdy           */
/*******************************************************************/

       w->core.background_pixmap = XCreatePixmap(disp,XtWindow(w), 
		       w->core.width,w->core.height,
                       XDefaultDepthOfScreen(XtScreen(w)));
       w->graph.XGPgc = XtGetGC(w,GCForeground|GCBackground,&values);
       redisplay_picture(w);
     }

static void XGPResize(w,event)
    GraphWidget    w;
    XEvent         *event;

    { 
       if (XtIsRealized(w) != True) {
	  return;
       } else {
           XFreePixmap(XtDisplay(w),w->core.background_pixmap);
           w->core.background_pixmap = XCreatePixmap(XtDisplay(w),XtWindow(w), 
		       w->core.width,w->core.height,
                       XDefaultDepthOfScreen(XtScreen(w)));
           redisplay_picture(w);
      }
    }

static void XGPExpose(wid,event)
    GraphWidget    wid;
    XEvent         *event;

    { 
       XGPCopyArea(wid,0,0,wid->core.width,wid->core.height,0,0); 
    }

GraphClassRec graphClassRec = {
  { /* core fields */
    /* superclass		*/	(WidgetClass) &widgetClassRec,
    /* class_name		*/	"Graph",
    /* widget_size		*/	sizeof(GraphRec),
    /* class_initialize		*/	NULL,
    /* class_part_initialize	*/	NULL,
    /* class_inited		*/	FALSE,
    /* initialize		*/	XGPInitialize,
    /* initialize_hook		*/	NULL,
    /* realize			*/	XGPRealize,
    /* actions			*/	actionsList,
    /* num_actions		*/	XtNumber(actionsList),
    /* resources		*/	resources,
    /* num_resources		*/	XtNumber(resources),
    /* xrm_class		*/	NULLQUARK,
    /* compress_motion		*/	FALSE,
    /* compress_exposure	*/	TRUE,
    /* compress_enterleave	*/	TRUE,
    /* visible_interest		*/	FALSE,
    /* destroy			*/	NULL,
    /* resize			*/	XGPResize,
    /* expose			*/	XGPExpose,
    /* set_values		*/	NULL,
    /* set_values_hook		*/	NULL,
    /* set_values_almost	*/	XtInheritSetValuesAlmost,
    /* get_values_hook		*/	NULL,
    /* accept_focus		*/	NULL,
    /* version			*/	XtVersion,
    /* callback_private		*/	NULL,
    /* tm_table			*/	defaultTranslations,
    /* query_geometry		*/	XtInheritQueryGeometry,
    /* display_accelerator	*/	XtInheritDisplayAccelerator,
    /* extension		*/	NULL
  },
  { /* graph fields */
    /* empty			*/	0
  }
};

WidgetClass graphWidgetClass = (WidgetClass)&graphClassRec;
