/*
 * Copyright (c) 1996 Michael A. Perzl
 * All rights reserved.
 *
 * Permission to use, copy, modify, distribute, and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear in
 * supporting documentation, and that the name of Michael A. Perzl not
 * be used in advertising or publicity pertaining to distribution of
 * the software without specific, written prior permission.
 * Michael A. Perzl makes no representations about the suitability of
 * this software for any purpose.  It is provided "as is" without any
 * express or implied warranties, including, without limitation, the
 * implied warranties of merchantability and fitness for a particular
 * purpose.
 *
 * Michael A. Perzl DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS.  IN NO EVENT SHALL Michael A. Perzl BE LIABLE FOR ANY
 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */



/* include standard header files */

#include <stdlib.h>


/* include Motif header files */

#include <Xm/Xm.h>

#include <Xm/Form.h>
#include <Xm/Frame.h>
#include <Xm/PushB.h>

#include "ProgressMeter.h"



/* fallback resources */

static String fallbackResources[] = {
"*background:			#c2c2c2",
"*fontList:			-*-helvetica-bold-r-normal-*-12-*-*-*-*-*-iso8859-1",
"*vMeter1.width:		40",
"*vMeter1.foreground:		#0000ff",
"*vMeter1.background:		#ffffff",
"*vMeter1.fontList:		-*-helvetica-bold-r-normal-*-10-*-*-*-*-*-iso8859-1",
"*vMeter2.width:		40",
"*vMeter2.foreground:		#ff0000",
"*vMeter2.background:		#ffffff",
"*vMeter2.showPercentage:	FALSE",
"*vMeter2.showTime:		TRUE",
"*vMeter2.showTimeUnit:		FALSE",
"*vMeter2.fontList:		-*-helvetica-bold-r-normal-*-10-*-*-*-*-*-iso8859-1",
"*vMeter3.width:		40",
"*vMeter3.foreground:		#ff0000",
"*vMeter3.background:		#ffffff",
"*vMeter3.showTime:		TRUE",
"*vMeter3.showTimeUnit:		FALSE",
"*vMeter3.fontList:		-*-helvetica-bold-r-normal-*-10-*-*-*-*-*-iso8859-1",
"*vMeter4.width:		15",
"*vMeter4.foreground:		#0000ff",
"*vMeter4.background:		#ffffff",
"*vMeter4.boxMode:		TRUE",
"*vMeter4.numBoxes:		20",
"*vMeter5.width:		15",
"*vMeter5.foreground:		#0000ff",
"*vMeter5.background:		#00ffff",
"*vMeter5.boxMode:		TRUE",
"*vMeter5.numBoxes:		20",
"*vMeter5.showBoxSeparators:	FALSE",
"*hMeter1.height:		30",
"*hMeter1.foreground:		#0000ff",
"*hMeter1.background:		#ffffff",
"*hMeter2.height:		30",
"*hMeter2.foreground:		#ff0000",
"*hMeter2.background:		#ffffff",
"*hMeter2.showPercentage:	FALSE",
"*hMeter2.showTime:		TRUE",
"*hMeter3.height:		30",
"*hMeter3.foreground:		#ff0000",
"*hMeter3.background:		#ffffff",
"*hMeter3.showTime:		TRUE",
"*hMeter4.height:		15",
"*hMeter4.foreground:		#0000ff",
"*hMeter4.background:		#ffffff",
"*hMeter4.boxMode:		TRUE",
"*hMeter4.numBoxes:		20",
"*hMeter5.height:		15",
"*hMeter5.foreground:		#0000ff",
"*hMeter5.background:		#dddddd",
"*hMeter5.boxMode:		TRUE",
"*hMeter5.numBoxes:		20",
"*hMeter5.showBoxSeparators:	FALSE",
"*quitButton.labelString:	Quit",
"*inc1Button.labelString:	Inc+1",
"*inc2Button.labelString:	Inc+10",
"*dec1Button.labelString:	Dec-1",
"*dec2Button.labelString:	Dec-10",
NULL
};



#define MIN_VALUE 0
#define MAX_VALUE 1000



static Widget vMeter1, vMeter2, vMeter3, vMeter4, vMeter5,
              hMeter1, hMeter2, hMeter3, hMeter4, hMeter5;



static void QuitCB (widget, clientData, callData)
  Widget    widget;
  XtPointer clientData,
            callData;
{
  exit (0);
}



static void IncrementCB (widget, clientData, callData)
  Widget    widget;
  XtPointer clientData,
            callData;
{
  int value;


  value = XmProgressMeterGetValue (vMeter1);

  if (value == MAX_VALUE) return;

  value += (int) clientData;

  if (value > MAX_VALUE) value = MAX_VALUE;

  XmProgressMeterSetValue (vMeter1, value);
  XmProgressMeterSetValue (vMeter2, value);
  XmProgressMeterSetValue (vMeter3, value);
  XmProgressMeterSetValue (vMeter4, value);
  XmProgressMeterSetValue (vMeter5, value);

  XmProgressMeterSetValue (hMeter1, value);
  XmProgressMeterSetValue (hMeter2, value);
  XmProgressMeterSetValue (hMeter3, value);
  XmProgressMeterSetValue (hMeter4, value);
  XmProgressMeterSetValue (hMeter5, value);
}



static void DecrementCB (widget, clientData, callData)
  Widget    widget;
  XtPointer clientData,
            callData;
{
  int value;


  value = XmProgressMeterGetValue (vMeter1);

  if (value == MIN_VALUE) return;

  value -= (int) clientData;

  if (value < MIN_VALUE) value = MIN_VALUE;

  XmProgressMeterSetValue (vMeter1, value);
  XmProgressMeterSetValue (vMeter2, value);
  XmProgressMeterSetValue (vMeter3, value);
  XmProgressMeterSetValue (vMeter4, value);
  XmProgressMeterSetValue (vMeter5, value);

  XmProgressMeterSetValue (hMeter1, value);
  XmProgressMeterSetValue (hMeter2, value);
  XmProgressMeterSetValue (hMeter3, value);
  XmProgressMeterSetValue (hMeter4, value);
  XmProgressMeterSetValue (hMeter5, value);
}



static void CreateWidgets (parent)
  Widget parent;
{
  Widget   dlg, form,
           vFrame, vForm, hFrame, hForm,
           frame, buttonForm,
           quitButton, inc1Button, inc2Button, dec1Button, dec2Button;
  Arg      args[20];
  Cardinal n, nSave;


/* create a Form widget */

  dlg = XmCreateForm (parent, "form", (Arg *) NULL, 0);

  XtManageChild (dlg);


/* create container for the horizontal and vertical progress meters */

  n = 0;
  XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);   n++;
  XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);  n++;
  XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);    n++;
  XtSetArg (args[n], XmNleftOffset, 10);                  n++;
  XtSetArg (args[n], XmNrightOffset, 10);                 n++;
  XtSetArg (args[n], XmNtopOffset, 10);                   n++;

  form = XmCreateForm (dlg, "form", args, n);

  XtManageChild (form);


/* create the frame around the vertical progress meters */

  n = 0;
  XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);    n++;
  XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);     n++;
  XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM);  n++;
  XtSetArg (args[n], XmNshadowThickness, 4);               n++;

  vFrame = XmCreateFrame (form, "vFrame", args, n);

  XtManageChild (vFrame);


/* create the frame around the vertical progress meters */

  n = 0;
  XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET);  n++;
  XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);   n++;
  XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);     n++;
  XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM);  n++;
  XtSetArg (args[n], XmNleftWidget, vFrame);               n++;
  XtSetArg (args[n], XmNleftOffset, 10);                   n++;
  XtSetArg (args[n], XmNshadowThickness, 4);               n++;

  hFrame = XmCreateFrame (form, "hFrame", args, n);

  XtManageChild (hFrame);


/* create the container for the vertical progress meters */

  vForm = XmCreateForm (vFrame, "vForm", (Arg *) NULL, 0);

  XtManageChild (vForm);

  
/* create the container for the horizontal progress meters */

  hForm = XmCreateForm (hFrame, "hForm", (Arg *) NULL, 0);

  XtManageChild (hForm);


/* create the vertical progress meters */

  n = 0;
  XtSetArg (args[n], XmNorientation, XmVERTICAL);            n++;
  XtSetArg (args[n], XmNprocessingDirection, XmMAX_ON_TOP);  n++;
  XtSetArg (args[n], XmNminimum, MIN_VALUE);                 n++;
  XtSetArg (args[n], XmNmaximum, MAX_VALUE);                 n++;
  XtSetArg (args[n], XmNvalue, 500);                         n++;
  XtSetArg (args[n], XmNheight, 250);                        n++;

  nSave = n;


  n = nSave;
  XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);    n++;
  XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);     n++;
  XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM);  n++;
  XtSetArg (args[n], XmNleftOffset, 10);                   n++;
  XtSetArg (args[n], XmNtopOffset, 10);                    n++;
  XtSetArg (args[n], XmNbottomOffset, 10);                 n++;

  vMeter1 = XmCreateProgressMeter (vForm, "vMeter1", args, n);

  XtManageChild (vMeter1);


  n = nSave;
  XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET);  n++;
  XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);     n++;
  XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM);  n++;
  XtSetArg (args[n], XmNleftWidget, vMeter1);              n++;
  XtSetArg (args[n], XmNleftOffset, 10);                   n++;
  XtSetArg (args[n], XmNtopOffset, 10);                    n++;
  XtSetArg (args[n], XmNbottomOffset, 10);                 n++;

  vMeter2 = XmCreateProgressMeter (vForm, "vMeter2", args, n);

  XtManageChild (vMeter2);


  n = nSave;
  XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET);  n++;
  XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);     n++;
  XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM);  n++;
  XtSetArg (args[n], XmNleftWidget, vMeter2);              n++;
  XtSetArg (args[n], XmNleftOffset, 10);                   n++;
  XtSetArg (args[n], XmNtopOffset, 10);                    n++;
  XtSetArg (args[n], XmNbottomOffset, 10);                 n++;

  vMeter3 = XmCreateProgressMeter (vForm, "vMeter3", args, n);

  XtManageChild (vMeter3);


  n = nSave;
  XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET);  n++;
  XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);     n++;
  XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM);  n++;
  XtSetArg (args[n], XmNleftWidget, vMeter3);              n++;
  XtSetArg (args[n], XmNleftOffset, 10);                   n++;
  XtSetArg (args[n], XmNtopOffset, 10);                    n++;
  XtSetArg (args[n], XmNbottomOffset, 10);                 n++;

  vMeter4 = XmCreateProgressMeter (vForm, "vMeter4", args, n);

  XtManageChild (vMeter4);


  n = nSave;
  XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET);  n++;
  XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);   n++;
  XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);     n++;
  XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM);  n++;
  XtSetArg (args[n], XmNleftWidget, vMeter4);              n++;
  XtSetArg (args[n], XmNleftOffset, 10);                   n++;
  XtSetArg (args[n], XmNrightOffset, 10);                  n++;
  XtSetArg (args[n], XmNtopOffset, 10);                    n++;
  XtSetArg (args[n], XmNbottomOffset, 10);                 n++;

  vMeter5 = XmCreateProgressMeter (vForm, "vMeter5", args, n);

  XtManageChild (vMeter5);


/* create the horizontal progress meters */

  n = 0;
  XtSetArg (args[n], XmNorientation, XmHORIZONTAL);            n++;
  XtSetArg (args[n], XmNprocessingDirection, XmMAX_ON_RIGHT);  n++;
  XtSetArg (args[n], XmNminimum, 0);                           n++;
  XtSetArg (args[n], XmNmaximum, 1000);                        n++;
  XtSetArg (args[n], XmNvalue, 500);                           n++;
  XtSetArg (args[n], XmNwidth, 250);                           n++;

  nSave = n;


  n = nSave;
  XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);   n++;
  XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);  n++;
  XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);    n++;
  XtSetArg (args[n], XmNleftOffset, 10);                  n++;
  XtSetArg (args[n], XmNrightOffset, 10);                 n++;
  XtSetArg (args[n], XmNtopOffset, 10);                   n++;

  hMeter1 = XmCreateProgressMeter (hForm, "hMeter1", args, n);

  XtManageChild (hMeter1);


  n = nSave;
  XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);   n++;
  XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);  n++;
  XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);  n++;
  XtSetArg (args[n], XmNtopWidget, hMeter1);              n++;
  XtSetArg (args[n], XmNleftOffset, 10);                  n++;
  XtSetArg (args[n], XmNrightOffset, 10);                 n++;
  XtSetArg (args[n], XmNtopOffset, 10);                   n++;

  hMeter2 = XmCreateProgressMeter (hForm, "hMeter2", args, n);

  XtManageChild (hMeter2);


  n = nSave;
  XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);   n++;
  XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);  n++;
  XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);  n++;
  XtSetArg (args[n], XmNtopWidget, hMeter2);              n++;
  XtSetArg (args[n], XmNleftOffset, 10);                  n++;
  XtSetArg (args[n], XmNrightOffset, 10);                 n++;
  XtSetArg (args[n], XmNtopOffset, 10);                   n++;

  hMeter3 = XmCreateProgressMeter (hForm, "hMeter3", args, n);

  XtManageChild (hMeter3);


  n = nSave;
  XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);   n++;
  XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);  n++;
  XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);  n++;
  XtSetArg (args[n], XmNtopWidget, hMeter3);              n++;
  XtSetArg (args[n], XmNleftOffset, 10);                  n++;
  XtSetArg (args[n], XmNrightOffset, 10);                 n++;
  XtSetArg (args[n], XmNtopOffset, 10);                   n++;

  hMeter4 = XmCreateProgressMeter (hForm, "hMeter4", args, n);

  XtManageChild (hMeter4);


  n = nSave;
  XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);   n++;
  XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);  n++;
  XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);  n++;
  XtSetArg (args[n], XmNtopWidget, hMeter4);              n++;
  XtSetArg (args[n], XmNleftOffset, 10);                  n++;
  XtSetArg (args[n], XmNrightOffset, 10);                 n++;
  XtSetArg (args[n], XmNtopOffset, 10);                   n++;

  hMeter5 = XmCreateProgressMeter (hForm, "hMeter5", args, n);

  XtManageChild (hMeter5);


/* create frame to separate the progress meters from the buttons */

  n = 0;
  XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);   n++;
  XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);  n++;
  XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);  n++;
  XtSetArg (args[n], XmNtopWidget, form);                 n++;
  XtSetArg (args[n], XmNshadowType, XmSHADOW_IN);         n++;
  XtSetArg (args[n], XmNheight, 4);                       n++;
  XtSetArg (args[n], XmNtopOffset, 10);                   n++;

  frame = XmCreateFrame (dlg, "frame", args, n);

  XtManageChild (frame);


/* create form with the 5 buttons */

  n = 0;
  XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);    n++;
  XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);   n++;
  XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);   n++;
  XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM);  n++;
  XtSetArg (args[n], XmNtopWidget, frame);                 n++;
  XtSetArg (args[n], XmNleftOffset, 10);                   n++;
  XtSetArg (args[n], XmNrightOffset, 10);                  n++;
  XtSetArg (args[n], XmNtopOffset, 10);                    n++;
  XtSetArg (args[n], XmNbottomOffset, 10);                 n++;
  
  buttonForm = XmCreateForm (dlg, "buttonForm", args, n);

  XtManageChild (buttonForm);


/* create 'Quit' button */

  n = 0;
  XtSetArg (args[n], XmNtraversalOn, TRUE);                   n++;
  XtSetArg (args[n], XmNhighlightThickness, 2);               n++;
  XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION);   n++;
  XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION);  n++;
  XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);        n++;
  XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM);     n++;
  XtSetArg (args[n], XmNleftPosition, 5);                     n++;
  XtSetArg (args[n], XmNrightPosition, 19);                   n++;

  quitButton = XmCreatePushButton (buttonForm, "quitButton", args, n);

  XtManageChild (quitButton);

  XtAddCallback (quitButton, XmNactivateCallback,
                 QuitCB, (XtPointer) NULL);


/* create 'Inc+1' button */

  n = 0;
  XtSetArg (args[n], XmNtraversalOn, TRUE);                   n++;
  XtSetArg (args[n], XmNhighlightThickness, 2);               n++;
  XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION);   n++;
  XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION);  n++;
  XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);        n++;
  XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM);     n++;
  XtSetArg (args[n], XmNleftPosition, 24);                    n++;
  XtSetArg (args[n], XmNrightPosition, 38);                   n++;

  inc1Button = XmCreatePushButton (buttonForm, "inc1Button", args, n);

  XtManageChild (inc1Button);

  XtAddCallback (inc1Button, XmNactivateCallback,
                 IncrementCB, (XtPointer) 1);


/* create 'Inc+10' button */

  n = 0;
  XtSetArg (args[n], XmNtraversalOn, TRUE);                   n++;
  XtSetArg (args[n], XmNhighlightThickness, 2);               n++;
  XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION);   n++;
  XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION);  n++;
  XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);        n++;
  XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM);     n++;
  XtSetArg (args[n], XmNleftPosition, 43);                    n++;
  XtSetArg (args[n], XmNrightPosition, 57);                   n++;

  inc2Button = XmCreatePushButton (buttonForm, "inc2Button", args, n);

  XtManageChild (inc2Button);

  XtAddCallback (inc2Button, XmNactivateCallback,
                 IncrementCB, (XtPointer) 10);


/* create 'Dec-1' button */

  n = 0;
  XtSetArg (args[n], XmNtraversalOn, TRUE);                   n++;
  XtSetArg (args[n], XmNhighlightThickness, 2);               n++;
  XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION);   n++;
  XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION);  n++;
  XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);        n++;
  XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM);     n++;
  XtSetArg (args[n], XmNleftPosition, 62);                    n++;
  XtSetArg (args[n], XmNrightPosition, 76);                   n++;

  dec1Button = XmCreatePushButton (buttonForm, "dec1Button", args, n);

  XtManageChild (dec1Button);

  XtAddCallback (dec1Button, XmNactivateCallback, 
                 DecrementCB, (XtPointer) 1);


/* create 'Dec-10' button */

  n = 0;
  XtSetArg (args[n], XmNtraversalOn, TRUE);                   n++;
  XtSetArg (args[n], XmNhighlightThickness, 2);               n++;
  XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION);   n++;
  XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION);  n++;
  XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);        n++;
  XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM);     n++;
  XtSetArg (args[n], XmNleftPosition, 81);                    n++;
  XtSetArg (args[n], XmNrightPosition, 95);                   n++;

  dec2Button = XmCreatePushButton (buttonForm, "dec2Button", args, n);

  XtManageChild (dec2Button);

  XtAddCallback (dec2Button, XmNactivateCallback, 
                 DecrementCB, (XtPointer) 10);
}



void main (argc, argv)
  int   argc;
  char *argv[];
{
  Widget       shell;
  XtAppContext app;


  shell = XtAppInitialize (&app, "PTest", NULL, 0,
                           &argc, argv, fallbackResources, NULL, 0);

  CreateWidgets (shell);

  XtRealizeWidget (shell);

  XtAppMainLoop (app);
}

