#include <math.h>

/* $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                                           */
/* The Graph Widget is the property of Kent State University        */

#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include <stdio.h>
#include "Graph.h"
#include "GraphP.h"
#include "globals.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,0);
    XFillRectangle(XtDisplay(wid),wid->core.background_pixmap,
    wid->graph.XGPgc,0,0,wid->core.width,wid->core.height);
}


void XGPDrawPoint(wid,x,y,len1,len2,multfact,col)
int col,x,y,len1,len2,multfact;
GraphWidget   wid;
{
    if ((even(x) & even(y)) | (!even(x)& !even(y))){
        XSetForeground(XtDisplay(wid),wid->graph.XGPgc,col);
        XDrawRectangle(XtDisplay(wid),wid->core.background_pixmap ,wid->graph.XGPgc,x*multfact,y*multfact,multfact, multfact);
        XFillRectangle(XtDisplay(wid),wid->core.background_pixmap, wid->graph.XGPgc,x*multfact,y*multfact,multfact, multfact);
        }
    XSetForeground(XtDisplay(wid),wid->graph.XGPgc,wid->graph.background);

/*    XGPCopyArea(wid,x*multfact,y*multfact,len1,len2,x*multfact,y*multfact); */

    XGPCopyArea(wid,x*multfact,y*multfact,multfact+1,multfact+1,x*multfact,y*multfact);
}

void DrawPoint(wid,x,y,len,multfact,col)
int col,x,y,len,multfact;
GraphWidget   wid;
{
    if ((even(x) & even(y)) | (!even(x)& !even(y))){
        XSetForeground(XtDisplay(wid),wid->graph.XGPgc,col);
        XDrawRectangle(XtDisplay(wid),wid->core.background_pixmap,wid->graph.XGPgc,x*multfact,y*multfact,multfact,multfact);
        XFillRectangle(XtDisplay(wid),wid->core.background_pixmap,wid->graph.XGPgc,x*multfact,y*multfact,multfact,multfact);
        }
    XSetForeground(XtDisplay(wid),wid->graph.XGPgc,wid->graph.background);
}

void displaypicture(pic,wid,len,hei,multfact)
int pic[MAX_WORLD_X][MAX_WORLD_Y];
int len,hei,multfact;
GraphWidget  wid;
{
    int x,y;

    for(x=0;x<len;x++)
        for(y=0;y<hei;y++)
            DrawPoint(wid,x,y,len,multfact,pic[x][y]);

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

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);
}

extern int widget_height,widget_width,box_size;
extern Widget thegraph;
extern int uimage[MAX_WORLD_X][MAX_WORLD_Y];

#define MAX(x,y)      (x > y ? x : y)

static void XGPResize(w,event)
GraphWidget    w;
XEvent         *event;
{ 
    if (XtIsRealized(w) != True)
        return;
    else {
        if (bcmp(w->core.name,"hello",6) == 0){
            if ((w->core.width/X_Size) < (w->core.height/Y_Size))
                box_size = w->core.width/X_Size;
            else
                box_size = w->core.height/Y_Size;
            }

        redisplay_picture(w);
        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)));
        if (bcmp(w->core.name,"hello",6) == 0)
            displaypicture(uimage,thegraph,X_Size,Y_Size,box_size);
        }
}

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		*/	TRUE,
    /* 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;
