static char AlarmLight_id[] = "$Header: /usr/tiburon/unix/gui/tmacs/RCS/AlarmLight.cc,v 1.4 1997/10/03 09:23:36 oreilly Exp $";


/*
$Log: AlarmLight.cc,v $
Revision 1.4  1997/10/03 09:23:36  oreilly
Changed flash period to 1 sec

Revision 1.3  97/05/30  15:43:34  15:43:34  oreilly (Thomas C. O'Reilly)
*** empty log message ***

Revision 1.2  97/03/20  12:28:31  12:28:31  oreilly (Thomas C. O'Reilly)
*** empty log message ***

Revision 1.1  96/07/22  10:41:25  10:41:25  oreilly (Thomas C. O'Reilly)
First external release

*/
#include <stdio.h>
#include <stdlib.h>
#include <Xm/Form.h>
#include <Xm/PushB.h>
#include "AlarmLight.h"
#include "TiburonApp.h"

#define dprintf if (debug) fprintf


AlarmLight::AlarmLight(const char *name, Widget parent)
  : VkComponent(name)
{
  _baseWidget = XtCreateWidget(_name, xmFormWidgetClass, parent, NULL, 0);
  installDestroyHandler();

  XtVaGetValues(_baseWidget,
		XmNforeground, &_inactiveForeground,
		XmNbackground, &_inactiveBackground,
		NULL);
  
  _state = InitState;
  XtVaSetValues(_baseWidget, XmNresizable, False, NULL);
  
  _alarmButton = XtVaCreateManagedWidget("alarmButton", 
					 xmPushButtonWidgetClass, _baseWidget, 
					 XmNleftAttachment, XmATTACH_FORM,
					 XmNrightAttachment, XmATTACH_FORM,
					 XmNtopAttachment, XmATTACH_FORM,
					 XmNbottomAttachment, XmATTACH_FORM,
					 XmNrecomputeSize, False,
					 NULL);

  XtAddCallback(_alarmButton, XmNactivateCallback,
		&AlarmLight::alarmButtonCallback, (XtPointer )this);
  
  XtManageChild(_baseWidget);
  _flashTimer = 0;
  _flashPeriod = 1000;

  // Get colors from application
  TiburonApp *app = (TiburonApp *)theApplication;
  app->priority1Colors(&_priority1Foreground, &_priority1Background);
  app->priority2Colors(&_priority2Foreground, &_priority2Background);
  app->priority3Colors(&_priority3Foreground, &_priority3Background);
  app->priorityColors(NoPriority, &_noPriorityForeground, 
		      &_noPriorityBackground);
}


AlarmLight::~AlarmLight()
{
}


void AlarmLight::shine()
{
  static Priority prevPriority = Priority1;

  // Avoid thrashing
  if (_state == Shining && _priority == prevPriority)
    return;
  
  prevPriority = _priority;
  
  _state = Shining;

  if (_flashTimer)
  {
    XtRemoveTimeOut(_flashTimer);
    _flashTimer = 0;
  }
  XtVaSetValues(_alarmButton, XmNbackground, buttonBackground(),
		XmNforeground, buttonForeground(), NULL);
}


void AlarmLight::darken()
{
  if (_state == Dark)
    return;
  
  _state = Dark;

  if (_flashTimer)
  {
    XtRemoveTimeOut(_flashTimer);
    _flashTimer = 0;
  }

  XtVaSetValues(_alarmButton, XmNbackground, _inactiveBackground, 
		XmNforeground, _inactiveForeground, NULL);
}


void AlarmLight::flash()
{
  static Priority prevPriority;
  
  // Avoid thrashing
  if (_state == Flashing && _priority == prevPriority)
    return;
  
  prevPriority = _priority;
  _state = Flashing;

  XtVaSetValues(_alarmButton, XmNbackground, buttonBackground(),
		XmNforeground, buttonForeground(), NULL);

  _phase = 0;

  if (_flashTimer)
  {
    XtRemoveTimeOut(_flashTimer);
    _flashTimer = 0;
  }
  _flashTimer = XtAppAddTimeOut(theApplication->appContext(), _flashPeriod,
				&AlarmLight::timerCallback, 
				(XtPointer )this);
}


void AlarmLight::timerCallback(XtPointer clientData, XtIntervalId *id)
{
  MBool debug = FALSE;
  
  AlarmLight *obj = (AlarmLight *)clientData; 
  obj->_flashTimer = XtAppAddTimeOut(theApplication->appContext(), 
				     obj->_flashPeriod, 
				     &AlarmLight::timerCallback, 
				     (XtPointer )obj);

  if (obj->_phase)
  {
    XtVaSetValues(obj->_alarmButton, 
		  XmNbackground, obj->buttonBackground(),
		  XmNforeground, obj->buttonForeground(), NULL);

    obj->_phase = 0;
  }
  else
  {
    XtVaSetValues(obj->_alarmButton, 
		  XmNbackground, obj->_inactiveBackground, 
		  XmNforeground, obj->_inactiveForeground, NULL);

    obj->_phase = 1;
  }
}



void AlarmLight::setButtonCallback(XtCallbackProc callback, 
				   XtPointer clientData)
{
  XtAddCallback(_alarmButton, XmNactivateCallback,
		callback, clientData);
}


void AlarmLight::setLabel(char *label)
{
  XmString currentXmstr;
  XtVaGetValues(_alarmButton, XmNlabelString, &currentXmstr, NULL);
  XmString xmstr = XmStringCreateLtoR(label, XmSTRING_DEFAULT_CHARSET);

  // Avoid thrashing: only update label if new one differs from current
  if (!XmStringCompare(currentXmstr, xmstr))
  {
    Dimension width, height;
    XtVaGetValues(_alarmButton, XmNwidth, &width, XmNheight, &height, NULL);
    XtVaSetValues(_alarmButton, XmNwidth, width, XmNheight, height, 
		  XmNlabelString, xmstr, NULL);
  }
  
  XmStringFree(xmstr);
}


void AlarmLight::alarmButtonCallback(Widget w, XtPointer clientData, 
				     XtPointer callData)
{
  // Default does nothing
  ;
  
}


Pixel AlarmLight::buttonBackground()
{
  Pixel val;
  
  switch (_priority)
  {
    case Priority1:
    val = _priority1Background;
    break;
    
    case Priority2:
    val = _priority2Background;
    break;
    
    case Priority3:
    val = _priority3Background;
    break;

    case NoPriority:
    val = _noPriorityBackground;
    break;
    
  }

  return val;
}


Pixel AlarmLight::buttonForeground()
{
  Pixel val;
  
  switch (_priority)
  {
    case Priority1:
    val = _priority1Foreground;
    break;
    
    case Priority2:
    val = _priority2Foreground;
    break;
    
    case Priority3:
    val = _priority3Foreground;
    break;

    case NoPriority:
    val = _noPriorityForeground;
    break;
  }

  return val;
}
