
static char PowerSwitchStatus_id[] = "$Header: /usr/tiburon/unix/gui/tmacs/RCS/PowerSwitchStatus.cc,v 1.1 1998/05/18 20:18:09 oreilly Exp $";


/*
$Log: PowerSwitchStatus.cc,v $
Revision 1.1  1998/05/18 20:18:09  oreilly
Initial revision

*/
#include <Xm/Form.h>
#include <Xm/PushB.h>
#include <Vk/VkApp.h>
#include "PowerSwitchStatus.h"
#include "powerDM.h"
#include "DmErrno.h"
#include "TiburonApp.h"

#define dprintf if (debug) fprintf

XtResource PowerSwitchStatus::_resources[] = 
{
  {  
    "noPwrForeground",
    "NoPwrForeground",
    XtRPixel,
    sizeof(Pixel),
    XtOffset(PowerSwitchStatus *, _noPwrForeground),
    XmRString,
    "white"
  },

  {  
    "noPwrBackground",
    "NoPwrBackground",
    XtRPixel,
    sizeof(Pixel),
    XtOffset(PowerSwitchStatus *, _noPwrBackground),
    XmRString,
    "black"
  }
};

const char *const PowerSwitchStatus::statusChangeCallback = "statusCallback";

PowerSwitchStatus::PowerSwitchStatus(const char *name, Widget parent, 
				     const char *switchDmPrefix, 
				     const char *switchName, 
				     int labelWidth, int labelHeight,
				     int period, Boolean showCurrent) :
  DmGuiObject(name, parent)
{
  _baseWidget = XtVaCreateWidget(name, xmFormWidgetClass, parent, NULL);
  installDestroyHandler();

  getResources(_resources, XtNumber(_resources));

  _statusDetector = NULL;
  
  _showCurrent = showCurrent;
  
  char prefix[MaxDmNameLen];
  

  strcpy(prefix, switchDmPrefix);
    
  if (prefix[strlen(prefix)-1] != '.')
    strcat(prefix, ".");
    
  _label = new DynamicLabel("label", _baseWidget);

  _switchName = strdup(switchName);

  XtVaSetValues(_label->baseWidget(),
		XmNtopAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNleftAttachment, XmATTACH_FORM,
		NULL);

  _label->show();
  
  char itemName[MaxDmNameLen];
  char errorBuf[errorMsgSize];
  
  strcpy(itemName, prefix);
  strcat(itemName, SWITCH_REQUEST);
  _dmRequest = new DmEnumObject(itemName);
  if (_dmRequest->error())
  {
    _dmRequest->errorMsg(errorBuf);
    setError(errorBuf);
    return;
  }

  if (addDmObject(_dmRequest, DmProvideFlag) == -1)
    return;

  strcpy(itemName, prefix);
  strcat(itemName, SWITCH_STATUS);
  _dmStatus = new DmEnumObject(itemName);
  if (_dmStatus->error())
  {
    _dmStatus->errorMsg(errorBuf);
    setError(errorBuf);
    return;
  }

  _statusDetector = 
    new DmInputDetector("status", parent, _dmStatus, this);
  
  if (showCurrent)
  {
    strcpy(itemName, prefix);
    strcat(itemName, SWITCH_CURRENT);
  
    _dmCurrent = new DmInt16Object(itemName);
    if (_dmCurrent->error())
    {
      _dmCurrent->errorMsg(errorBuf);
      setError(errorBuf);
      return;
    }
    if (addDmObject(_dmCurrent, DmConsumeFlag) == -1)
      return;
  }
  else
    _dmCurrent = NULL;


  if (setConsumePeriod(period) == -1)
    return;

  _status = SWITCH_NO_POWER;
  _current = NoCurrent;
  
  // Get colors from application
  TiburonApp *app = (TiburonApp *)theApplication;

  app->powerOnColors(&_onForeground, &_onBackground);

  // Use default foreground/background for "off" state 
  XtVaGetValues(_baseWidget, 
		XmNforeground, &_offForeground,
		XmNbackground, &_offBackground,
		NULL);
  
  app->faultColors(&_faultForeground, &_faultBackground);
  
  updateGui();
  updateFromPeer(this, NULL);
}


PowerSwitchStatus::~PowerSwitchStatus()
{
  free(_switchName);
  if (_statusDetector)
    delete _statusDetector;
}


void PowerSwitchStatus::updateFromPeer(DmGuiObject *peer, void *clientData)
{
  char errorBuf[errorMsgSize];
  
  Boolean debug = False;
  dprintf(stderr, "PowerSwitchStatus::updateFromPeer()\n");

  DM_Time t;
  Errno err;
  
  // Read status
  if ((err = _dmStatus->read(&_status, &t)) != SUCCESS)
  {
    sprintDmError(err, "PowerSwitchStatus::updateFromPeer()", errorBuf);
    setError(errorBuf);
    return;
  }

  callCallbacks(statusChangeCallback, (void *)_status);
  
  // Set label colors appropriate to switch status
  Pixel foreground, background;
  Pixel topColor, bottomColor, selectColor, borderColor;
  Pixel feedColor;
  
  char buf[100];

  switch (_status)
  {  
    case SWITCH_NO_POWER:
    foreground = _noPwrForeground;
    background = _noPwrBackground;
    _current = NoCurrent;
    
    sprintf(buf, "%s\nNO PWR", _switchName);
    _label->setText(buf);
    feedColor = _offBackground;
    break;
    
    case SWITCH_OFF:
    foreground = _offForeground;
    background = _offBackground;
    _current = NoCurrent;
    
    sprintf(buf, "%s\nOFF", _switchName);
    _label->setText(buf);
    feedColor = _offBackground;
    break;
    
    case SWITCH_ON:
    foreground = _onForeground;
    background = _onBackground;
    feedColor = _onBackground;

    if (_showCurrent)
      // Update current display
      updateGui();
    else
    {
      sprintf(buf, "%s\nON", _switchName);
      _label->setText(buf);
    }
    break;
    
    case SWITCH_POWER_ERROR:
    foreground = _faultForeground;
    background = _faultBackground;
    feedColor = _offBackground;
    _current = NoCurrent;

    sprintf(buf, "%s\nFAULT", _switchName);
    _label->setText(buf);
    break;

    default:
    return;
  }

  Colormap colormap;
  XtVaGetValues(_baseWidget, XmNcolormap, &colormap, NULL);
  
  XmGetColors(XtScreen(_baseWidget), colormap, background, &borderColor, 
	      &topColor, &bottomColor, &selectColor);
  
  _label->setColors(foreground, background);

}



void PowerSwitchStatus::updateGui(DM_Item handle)
{
  DM_Time t;
  char errorBuf[errorMsgSize];
  Int16 current;
  char buf[100];
  Errno err;
  
  if (_dmCurrent && _status == SWITCH_ON)
  {
    // Read current
    if ((err = _dmCurrent->read(&current, &t)) != SUCCESS)
    {
      sprintDmError(err, "PowerSwitchStatus::updateGui()", errorBuf);
      setError(errorBuf);
      sprintf(buf, "curr read err");
      _label->setText(buf);
      return;
    }

    if (current != _current)
    {
      sprintf(buf, "%s\n%4.1fA", _switchName, current / 1000.);
      _label->setText(buf);
      _current = current;
    }
  }
  else
    _current = NoCurrent;
}


switchStatus PowerSwitchStatus::status()
{
  return (switchStatus )_status;
}




