/* This file is part of `checkBox'
 * Copyright (c) 1995 David Deaven
 *
 * In the following, "you" and "You" refer to any entity other than 
 * the Microsoft corporation and its subsidiaries.  All rights are
 * reserved by the author in connection with Microsoft and its
 * subsidiaries.  The Microsoft Network is explicity denied the right
 * to copy, reproduce, or transmit this software.
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Author: deaven $
 * $Id: CheckBox.c,v 1.1 1996/07/12 08:38:59 deaven Exp deaven $
 */

#include <X11/Xos.h>
#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>

#include "CheckBoxP.h"

/* One simple checkbox.
 *
 * Resources:               Type:          Defaults:
 * ----------------------   ------------   ------------------------
 * XtNvalue   	          : Boolean      : False
 * XtNforeground          : Pixel        : XtDefaultForeground
 * XtNlineWidth           : Dimension    : 2
 */

#define DEFAULT_WIDTH 16
#define DEFAULT_HEIGHT 16

#ifdef DEBUG
#include <stdio.h>
#define track(STRING) printf("CheckBox: %s\n", STRING);
#else
#define track(STRING)
#endif

#define offset(field) XtOffset(CheckBoxWidget, checkBox.field)
static XtResource CheckBoxResources[] = 
{
  {XtNvalue, XtCValue, XtRBoolean, sizeof(Boolean),
    offset(value), XtRBoolean, False},
  {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
    offset(foreground), XtRPixel, XtDefaultForeground},
  {XtNlineWidth, XtCLineWidth, XtRInt, sizeof(int),
    offset(lineWidth), XtRImmediate, (XtPointer) 2},
};
#undef offset

#define CORE  ((CheckBoxWidget) cbw)->core
#define CHECKBOX ((CheckBoxWidget) cbw)->checkBox
#define CURRENT ((CheckBoxWidget) cbw_current)->checkBox

static void paint(Widget cbw, Boolean clear)
{
	if(CORE.visible) {
	  if(clear) XClearWindow(XtDisplay(cbw), XtWindow(cbw));
	  XDrawRectangle(XtDisplay(cbw), XtWindow(cbw), CHECKBOX.gc,
	    0, 0, CHECKBOX.width, CHECKBOX.height);
	  if(CHECKBOX.value) {
	    XDrawLine(XtDisplay(cbw), XtWindow(cbw), CHECKBOX.gc,
	      0, 0, CHECKBOX.width - 1, CHECKBOX.height - 1);
	    XDrawLine(XtDisplay(cbw), XtWindow(cbw), CHECKBOX.gc,
	      0, CHECKBOX.height - 1, CHECKBOX.width - 1, 0);
	  }
	}
}

static void Redisplay(Widget cbw, XEvent *event, Region region)
{
	track("Redisplay");
	paint(cbw, False);
}

static void Resize(Widget cbw)
{
	track("Resize");
	CHECKBOX.width = CORE.width;
	CHECKBOX.height = CORE.height;
}

static void set_gc(Widget cbw)
{
	XGCValues gcValues;

	if(CHECKBOX.gc) XtReleaseGC(cbw, CHECKBOX.gc);

	gcValues.foreground = CHECKBOX.foreground;
	gcValues.background = CORE.background_pixel;
	gcValues.line_width = CHECKBOX.lineWidth;
	CHECKBOX.gc = XtGetGC(cbw, GCForeground | GCBackground | GCLineWidth, &gcValues);
}

static void Initialize(Widget request, Widget cbw, ArgList p_args, Cardinal *p_n)
{
	track("Initialize");
	if(CORE.width == 0) CORE.width = DEFAULT_WIDTH;
	if(CORE.height == 0) CORE.height = DEFAULT_HEIGHT;

	CHECKBOX.gc = NULL;

	set_gc(cbw);

	Resize(cbw);
}

static void Destroy(Widget cbw)
{
	track("Destroy");
	XtReleaseGC(cbw, CHECKBOX.gc);
}

static Boolean SetValues(Widget cbw_current,
	Widget request, Widget cbw, ArgList args, Cardinal *n)
{
	Boolean redisplay = False;

	track("SetValues");

	if(CHECKBOX.value != CURRENT.value) {
	  redisplay = True;
	}

	if(CHECKBOX.foreground != CURRENT.foreground) {
	  redisplay = True;
	}

	if(CHECKBOX.lineWidth != CURRENT.lineWidth) {
	  redisplay = True;
	}

	if(redisplay) set_gc(cbw);

	return redisplay;
}

static void toggle(Widget cbw, XEvent *event, String *argv, Cardinal *argc)
{
	track("toggle");
	CHECKBOX.value = !(CHECKBOX.value);
	paint(cbw, True);
}

static char translations[] =
 "<Btn1Down>:    toggle()\n"
 ;

static XtActionsRec actions[] = 
{
	{"toggle", toggle}
};

/* Complete class definition ---------------------------------- */

CheckBoxClassRec checkBoxClassRec = 
{
  {        /* CoreClassPart */
    (WidgetClass)&widgetClassRec,	/* superclass */
    "CheckBox",				/* class_name */
    sizeof(CheckBoxRec),		/* widget_size */
    NULL,				/* class_initialize */
    NULL,				/* class_part_initialize */
    False,				/* class_init */
    Initialize,				/* initialize */
    NULL,				/* initialize_hook */
    XtInheritRealize,			/* realize */
    actions,				/* actions */
    XtNumber(actions),			/* num_actions */
    CheckBoxResources,			/* resources */
    XtNumber(CheckBoxResources),	/* num_resources */
    NULLQUARK,				/* xrm_class */
    True,				/* compress_motion */
    True,				/* compress_exposure */
    True,				/* compress_enterleave */
    True,				/* visible_intrest */
    Destroy,				/* destroy */
    Resize,				/* resize */
    Redisplay,			/* expose */
    SetValues,				/* set_values */
    NULL,				/* set_values_hook */
    XtInheritSetValuesAlmost,		/* set_values_almost */
    NULL,				/* get_values_hook */
    NULL,				/* accept_focus */
    XtVersion,				/* version */
    NULL,				/* callback_private */
    translations,			/* tm_translations */
    NULL,				/* query_geometry */
    NULL,				/* display_accelerator */
    NULL,				/* extension */
  },
  { 	/* CheckBoxClassPart */
    0 /* empty */
  }
};

WidgetClass checkBoxWidgetClass = (WidgetClass) &checkBoxClassRec;

