#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include "TraceP.h"
#include "StripchartP.h"    

#define offset(field) XtOffset(AtTraceWidget, field)
static XtResource resources[] = {
{XtNforeground, XtCForeground, XtRPixel,
     sizeof(Pixel), offset(trace.foreground),
     XtRString, XtDefaultForeground},
{XtNbackground, XtCBackground, XtRPixel,
     sizeof(Pixel), offset(trace.background),
     XtRString, XtDefaultBackground},
{XtNlineWidth, XtCLineWidth, XtRInt,
     sizeof(int), offset(trace.lineWidth),
     XtRImmediate, (caddr_t)0},
{XtNlineStyle, XtCLineStyle, XtRInt,
     sizeof(int), offset(trace.lineStyle),
     XtRImmediate, (caddr_t)LineSolid},
{XtNdashLength, XtCDashLength, XtRInt,
     sizeof(int), offset(trace.dashLength),
     XtRImmediate, (caddr_t)4},
{XtNsampleInterval, XtCSampleInterval, XtRDouble, sizeof(double),
     offset(trace.sampleInterval), XtRString, ".1"},
{XtNpointsSaved, XtCPointsSaved, XtRInt,
     sizeof(int), offset(trace.pointsSaved),
     XtRImmediate, 0},
};
#undef offset

static void Initialize(AtTraceWidget, AtTraceWidget);
static void Destroy(AtTraceWidget);
static Boolean SetValues(AtTraceWidget, AtTraceWidget, AtTraceWidget);
static void Draw(AtTraceWidget);
static void AddPoint(AtTraceWidget, point);

AtTraceClassRec atTraceClassRec = {
{ /* core part */
    /* superclass         */    &objectClassRec,
    /* class_name         */    "AtTrace",
    /* widget_size        */    sizeof(AtTraceRec),
    /* class_initialize   */    NULL,
    /* class_part_initialize*/  NULL,
    /* class_inited       */    FALSE,
    /* initialize         */    (XtInitProc) Initialize,
    /* initialize_hook    */    NULL,
    /* pad                */    NULL,
    /* pad                */    NULL,
    /* pad                */    0,
    /* resources          */    resources,
    /* num_resources      */    XtNumber(resources),
    /* xrm_class          */    NULLQUARK,
    /* pad                */    FALSE,
    /* pad                */    FALSE,
    /* pad                */    FALSE,
    /* pad                */    FALSE,
    /* destroy            */    (XtWidgetProc)Destroy,
    /* pad                */    NULL,
    /* pad                */    NULL,
    /* set_values         */    (XtSetValuesFunc) SetValues,
    /* set_values_hook    */    NULL,
    /* pad                */    NULL,
    /* get_values_hook    */    NULL,
    /* pad                */    NULL,
    /* version            */    XtVersion,
    /* callback_offsets   */    NULL,
    /* pad                */    NULL,
    /* pad                */    NULL,
    /* pad                */    NULL,
    /* extension            */  NULL
},
/* AtTraceClassPart initialization */
{
    /* draw()       */   Draw,
    /* addpoint()   */   AddPoint,			 
}
};

WidgetClass atTraceWidgetClass = (WidgetClass)&atTraceClassRec;

static void GetGC(AtTraceWidget w)
{
    XGCValues gcv;

    gcv.foreground = w->trace.foreground;
    gcv.background = w->trace.background;
    gcv.line_width = w->trace.lineWidth;
    gcv.line_style = w->trace.lineStyle;
    gcv.dashes = (char) w->trace.dashLength;
    w->trace.gc = XtGetGC(XtParent((Widget)w),
                         GCForeground | GCBackground | GCLineWidth
                         | GCLineStyle | GCDashList, &gcv);
}

static void FreeGC(AtTraceWidget w)
{
    XtReleaseGC(XtParent((Widget)w), w->trace.gc);
}

static void Initialize(AtTraceWidget request, AtTraceWidget new)
{
    GetGC(new);
}

static void Destroy(AtTraceWidget w)
{
    FreeGC(w);
}

static Boolean SetValues(AtTraceWidget current,
                         AtTraceWidget request,
                         AtTraceWidget new)
{
    Boolean redisplay = False;
#define Changed(field) (new->trace.field != current->trace.field)

    if (Changed(foreground) || Changed(background) ||
        Changed(lineWidth) || Changed(lineStyle) || Changed(dashLength)) {
        FreeGC(new);
        GetGC(new);
        redisplay = True;
    }

    if (redisplay) {
        /* force a redisplay of our parent! */
    }
    return False;
#undef Changed
}
