/*
$Log: PanTiltMicro.cc,v $
Revision 1.5  1998/12/18 21:17:25  oreilly
*** empty log message ***

Revision 1.4  1997/10/03 09:31:23  oreilly
*** empty log message ***

Revision 1.3  97/08/12  14:50:24  14:50:24  oreilly (Thomas C. O'Reilly)
*** empty log message ***

Revision 1.2  97/05/30  16:30:25  16:30:25  oreilly (Thomas C. O'Reilly)
*** empty log message ***

Revision 1.1  97/05/06  16:29:53  16:29:53  oreilly (Thomas C. O'Reilly)
Initial revision

*/
#include <stdlib.h>
#include <Xm/Form.h>
#include <Xm/RowColumn.h>
#include <Xm/Label.h>
#include <Xm/PushB.h>
#include <Xm/Separator.h>
#include <Xm/Frame.h>
#include <Vk/VkQuestionDialog.h>
#include <Vk/VkErrorDialog.h>
#include "PanTiltMicro.h"
#include "TiburonApp.h"
#include "DmErrno.h"
#include "parseUtils.h"
#include "DataRates.h"
#include "panTilt.h"


PanTiltMicro::PanTiltMicro(const char *name, const char *dmPrefix)
  : Micro(name, dmPrefix)
{
  panTiltDm = new PanTiltDm(name, dmPrefix);
  if (panTiltDm->error())
  {
    char errorBuf[errorMsgSize];
    panTiltDm->errorMsg(errorBuf);
    setError(errorBuf);
    return;
  }
}


PanTiltMicro::~PanTiltMicro()
{
}


MicroGui *PanTiltMicro::gui(Widget parent, int period)
{
  PanTiltMicroGui *gui = new PanTiltMicroGui(_name, parent, this, period);
  gui->show();
  return gui;
}


MicroH2OTemp *PanTiltMicro::h2OTemp(Widget parent, int period)
{
  PanTiltH2OTemp *gui = new PanTiltH2OTemp(_name, parent, this, period);
  gui->show();
  return gui;
}


MicroGf *PanTiltMicro::gf(Widget parent, int period)
{
  PanTiltGf *gui = new PanTiltGf(_name, parent, this, period);
  gui->show();
  return gui;
}



PanTiltH2OTemp::PanTiltH2OTemp(const char *name, Widget parent, 
			       PanTiltMicro *panTiltMicro, 
			       int period)
  : MicroH2OTemp(name, parent)
{
  if (error())
    return;
  
  /* Find alarm items */
  SystemAlarms *alarms = ((TiburonApp *)theApplication)->systemAlarms;
  
  char alarmName[MaxDmNameLen];
  char errorBuf[errorMsgSize];
  
  strcpy(alarmName, (const char *)panTiltMicro->panTiltDm->dmPrefix());
  
  char *alarmNamePtr = alarmName + strlen(alarmName);

  strcpy(alarmNamePtr, TEMPERATURE_ALARM_DM);
  Alarm *tempAlarm;
  if ((tempAlarm = alarms->find(alarmName)) == NULL)
  {
    sprintf(errorBuf, 
	    "PanTiltH2OTemp::PanTiltH2OTemp() - couldn't find alarm \"%s\"",
	    alarmName);
    
    theErrorDialog->postAndWait(errorBuf);
  }

  strcpy(alarmNamePtr, HUMIDITY_ALARM_DM);
  Alarm *humidityAlarm;
  if ((humidityAlarm = alarms->find(alarmName)) == NULL)
  {
    sprintf(errorBuf, 
	    "PanTiltH2OTemp::PanTiltH2OTemp() - couldn't find alarm \"%s\"",
	    alarmName);
    
    theErrorDialog->postAndWait(errorBuf);
  }

  strcpy(alarmNamePtr, HOUSING_WATER_ALARM_DM);
  Alarm *housingWaterAlarm;
  if ((housingWaterAlarm = alarms->find(alarmName)) == NULL)
  {
    sprintf(errorBuf, 
	    "PanTiltH2OTemp::PanTiltH2OTemp() - couldn't find alarm \"%s\"",
	    alarmName);
    
    theErrorDialog->postAndWait(errorBuf);
  }


  Widget nameWidget =
    XtVaCreateManagedWidget(name, xmLabelWidgetClass, _row->baseWidget(),
			    NULL);			    

  _row->append(nameWidget);
  
  char format[100];
  
  _temp = 
    new AlarmedInt16Text("temperature", _row->baseWidget(), "%-3.0f C", 
			 panTiltMicro->panTiltDm->temperature, 
			 period, tempAlarm, Dynamic); 

  _row->append(_temp);
  
  _humidity = 
    new AlarmedNat16Text("humidity", _row->baseWidget(), "%-3.0f %%", 
			 panTiltMicro->panTiltDm->humidity, 
			 period, humidityAlarm, Dynamic); 

  _row->append(_humidity);
  
  _housingWater = 
    new AlarmText("housingWater", _row->baseWidget(), housingWaterAlarm, "%s");

  _row->append(_housingWater);
  
  // Put in a place-holder label for jbox water alarm
  _jboxWaterLabel = 
    XtVaCreateManagedWidget("notApplicable", xmLabelWidgetClass, 
			    _row->baseWidget(), 
			    NULL);

  _row->append(_jboxWaterLabel);

  _row->show();

}


PanTiltH2OTemp::~PanTiltH2OTemp()
{
}


PanTiltGf::PanTiltGf(const char *name, Widget parent, PanTiltMicro *micro, 
		 int period)
  : MicroGf(name, parent)
{
  if (error())
    return;
  
  /* Find alarm items */
  SystemAlarms *alarms = ((TiburonApp *)theApplication)->systemAlarms;
  
  char alarmName[MaxDmNameLen];
  char errorBuf[errorMsgSize];
  
  strcpy(alarmName, (const char *)micro->panTiltDm->dmPrefix());
  
  char *alarmNamePtr = alarmName + strlen(alarmName);

  strcpy(alarmNamePtr, LOCAL_GND_FLT_ALARM_DM);
  Alarm *localGfAlarm;
  if ((localGfAlarm = alarms->find(alarmName)) == NULL)
  {
    sprintf(errorBuf, 
	    "PanTiltGf::PanTiltGf() - couldn't find alarm \"%s\"",
	    alarmName);
    
    theErrorDialog->postAndWait(errorBuf);
  }

  strcpy(alarmNamePtr, EXT_GND_FLT_ALARM_DM);
  Alarm *externGfAlarm;
  if ((externGfAlarm = alarms->find(alarmName)) == NULL)
  {
    sprintf(errorBuf, 
	    "PanTiltGf::PanTiltGf() - couldn't find alarm \"%s\"",
	    alarmName);
    
    theErrorDialog->postAndWait(errorBuf);
  }

  Widget nameWidget =
    XtVaCreateManagedWidget(name, xmLabelWidgetClass, _row->baseWidget(),
			    NULL);			    

  _row->append(nameWidget);

  _localGf = 
    new AlarmedInt16Text("localGf", _row->baseWidget(), "%-3.0f", 
			 micro->panTiltDm->localGfCurrent,
			 period, localGfAlarm, Dynamic); 

  _row->append(_localGf);
  
  _externGf = 
    new AlarmedInt16Text("externGf", _row->baseWidget(), "%-3.0f", 
			 micro->panTiltDm->externGfCurrent,
			 period, externGfAlarm, Dynamic); 

  _row->append(_externGf);

  _row->show();
}


PanTiltGf::~PanTiltGf()
{
}



PanTiltMicroGui::PanTiltMicroGui(const char *name, Widget parent, 
			       PanTiltMicro *micro, int period)
  : MbariMicroGui(name, parent, micro)
{
  _externGf = 0;
  _localGf = 0;
  _temperature = 0;
  _stepperTemperature = 0;
  _humidity = 0;
  _housingWater = 0;
  _gfSelfTest = 0;

  for (int i = 0; i < NControllers; i++)
  {
    _stepper[i] = 0;
    _analog[i] = 0;
    _cwSwitch[i] = 0;
    _ccwSwitch[i] = 0;
    _deltaAlarm[i] = 0;
    _fault[i] = 0;
  }

  // Not done building yet, so stop any consumers
  stopConsume();
  
  if (error())
    return;
  
  _micro = micro;

  TiburonApp *app = (TiburonApp *)theApplication;
  app->powerOnColors(&_onForeground, &_onBackground);
  app->okColors(&_offForeground, &_offBackground);
  
  /* Find alarm items */
  SystemAlarms *alarms = app->systemAlarms;
  
  char alarmName[MaxDmNameLen];
  char errorBuf[errorMsgSize];
  
  strcpy(alarmName, (const char *)_micro->panTiltDm->dmPrefix());
  
  char *alarmNamePtr = alarmName + strlen(alarmName);

  strcpy(alarmNamePtr, TEMPERATURE_ALARM_DM);
  Alarm *tempAlarm;
  if ((tempAlarm = alarms->find(alarmName)) == NULL)
  {
    sprintf(errorBuf, 
	    "PanTiltMicroGui::PanTiltMicroGui() - couldn't find alarm \"%s\"",
	    alarmName);
    
    theErrorDialog->postAndWait(errorBuf);
  }

  strcpy(alarmNamePtr, HUMIDITY_ALARM_DM);
  Alarm *humidityAlarm;
  if ((humidityAlarm = alarms->find(alarmName)) == NULL)
  {
    sprintf(errorBuf, 
	    "PanTiltMicroGui::PanTiltMicroGui() - couldn't find alarm \"%s\"",
	    alarmName);
    
    theErrorDialog->postAndWait(errorBuf);
  }

  strcpy(alarmNamePtr, LOCAL_GND_FLT_ALARM_DM);
  Alarm *localGfAlarm;
  if ((localGfAlarm = alarms->find(alarmName)) == NULL)
  {
    sprintf(errorBuf, 
	    "PanTiltMicroGui::PanTiltMicroGui() - couldn't find alarm \"%s\"",
	    alarmName);
    
    theErrorDialog->postAndWait(errorBuf);
  }

  strcpy(alarmNamePtr, EXT_GND_FLT_ALARM_DM);
  Alarm *externGfAlarm;
  if ((externGfAlarm = alarms->find(alarmName)) == NULL)
  {
    sprintf(errorBuf, 
	    "PanTiltMicroGui::PanTiltMicroGui() - couldn't find alarm \"%s\"",
	    alarmName);
    
    theErrorDialog->postAndWait(errorBuf);
  }

  strcpy(alarmNamePtr, HOUSING_WATER_ALARM_DM);
  Alarm *housingWaterAlarm;
  if ((housingWaterAlarm = alarms->find(alarmName)) == NULL)
  {
    sprintf(errorBuf, 
	    "PanTiltMicroGui::PanTiltMicroGui() - couldn't find alarm \"%s\"",
	    alarmName);
    
    theErrorDialog->postAndWait(errorBuf);
  }
  
  strcpy(alarmNamePtr, STEPPER_TEMP_ALARM_DM);
  Alarm *stepperTempAlarm;
  if ((stepperTempAlarm = alarms->find(alarmName)) == NULL)
  {
    sprintf(errorBuf, 
	    "PanTiltMicroGui::PanTiltMicroGui() - couldn't find alarm \"%s\"",
	    alarmName);
    
    theErrorDialog->postAndWait(errorBuf);
  }
  
  
  Widget label;
  TableRowForm *mgr;
  
  mgr = new TableRowForm("mgr", _baseWidget, 2);

  label = 
    XtVaCreateManagedWidget("humidityLabel", xmLabelWidgetClass, 
			    mgr->baseWidget(), NULL);

  _humidity = 
    new AlarmedNat16Text("humidity", mgr->baseWidget(), "%-3.0f %%",
			 _micro->panTiltDm->humidity, period, humidityAlarm,
			 Dynamic, 1., XmALIGNMENT_BEGINNING);

  mgr->append(label);
  mgr->append(_humidity);
  mgr->show();

  mgr = new TableRowForm("mgr", _baseWidget, 2);

  label = 
    XtVaCreateManagedWidget("tempLabel", xmLabelWidgetClass, 
			    mgr->baseWidget(), NULL);

  _temperature =
    new AlarmedInt16Text("temperature", mgr->baseWidget(), "%-3.0f C",
			 _micro->panTiltDm->temperature, period, tempAlarm,
			 Dynamic, 1., XmALIGNMENT_BEGINNING);

  mgr->append(label);
  mgr->append(_temperature);
  mgr->show();

  mgr = new TableRowForm("mgr", _baseWidget, 2);

  label = 
    XtVaCreateManagedWidget("stepperTempLabel", xmLabelWidgetClass, 
			    mgr->baseWidget(), NULL);

  _stepperTemperature =
    new AlarmedInt16Text("stepperTemperature", mgr->baseWidget(), "%-3.0f C",
			 _micro->panTiltDm->stepperTemperature, period, 
			 stepperTempAlarm,
			 Dynamic, 1., XmALIGNMENT_BEGINNING);

  mgr->append(label);
  mgr->append(_stepperTemperature);
  mgr->show();

  mgr = new TableRowForm("mgr", _baseWidget, 2);

  label = 
    XtVaCreateManagedWidget("housingWaterLabel", xmLabelWidgetClass, 
			    mgr->baseWidget(), 
			    NULL);

  _housingWater = 
    new AlarmText("housingWater", mgr->baseWidget(), housingWaterAlarm, "%s");

  mgr->append(label);
  mgr->append(_housingWater);
  mgr->show();

  char testCmdItemName[MaxDmNameLen];
  char testStatusItemName[MaxDmNameLen];
  strcpy(testCmdItemName, _micro->panTiltDm->dmPrefix());
  strcat(testCmdItemName, GND_FLT_TEST_DM);
  strcpy(testStatusItemName, _micro->panTiltDm->dmPrefix());
  strcat(testStatusItemName, GND_FLT_TEST_STATUS_DM);

  _gfSelfTest = new GfSelfTest("gfSelfTest", _baseWidget,
			       testCmdItemName, testStatusItemName);
  
  _gfSelfTest->show();
  
  mgr = new TableRowForm("mgr", _baseWidget, 2); 
  
  label = 
    XtVaCreateManagedWidget("localGfLabel", xmLabelWidgetClass, 
			    mgr->baseWidget(), NULL);

  _localGf = new AlarmedInt16Text("localGf", mgr->baseWidget(), "%-3.0f",
				  _micro->panTiltDm->localGfCurrent,
				  period, localGfAlarm, Dynamic, 1., 
				  XmALIGNMENT_BEGINNING);

  mgr->append(label);
  mgr->append(_localGf);
  mgr->show();

  mgr = new TableRowForm("mgr", _baseWidget, 2); 
  
  label = 
    XtVaCreateManagedWidget("externGfLabel", xmLabelWidgetClass, 
			    mgr->baseWidget(), NULL);

  _externGf = new AlarmedInt16Text("externGf", mgr->baseWidget(), "%-3.0f",
				  _micro->panTiltDm->externGfCurrent,
				  period, localGfAlarm, Dynamic, 1., 
				  XmALIGNMENT_BEGINNING);

  mgr->append(label);
  mgr->append(_externGf);
  mgr->show();

  XtVaCreateManagedWidget("separator", xmSeparatorWidgetClass, 
			  _baseWidget, NULL);
  
  mgr = new TableRowForm("mgr", _baseWidget, 5); 

  label = 
    XtVaCreateManagedWidget("lightPanLabel", xmLabelWidgetClass, 
			    mgr->baseWidget(), NULL);

  mgr->attach(1, label);

  label = 
    XtVaCreateManagedWidget("lightTiltLabel", xmLabelWidgetClass, 
			    mgr->baseWidget(), NULL);

  mgr->attach(2, label);
  
  label = 
    XtVaCreateManagedWidget("cameraPanLabel", xmLabelWidgetClass, 
			    mgr->baseWidget(), NULL);

  mgr->attach(3, label);

  label = 
    XtVaCreateManagedWidget("cameraTiltLabel", xmLabelWidgetClass, 
			    mgr->baseWidget(), NULL);

  mgr->attach(4, label);

  mgr->show();
  
  mgr = new TableRowForm("mgr", _baseWidget, 5); 
  int index;
  
  for (index = 0; index < NControllers; index++)
  { 
    _initialize[index] = 
      XtVaCreateManagedWidget("initializePT", xmPushButtonWidgetClass,
			      mgr->baseWidget(), NULL);

    XtAddCallback(_initialize[index], XmNactivateCallback, 
		  &PanTiltMicroGui::cmdButtonCallback, this);
    
    mgr->attach(index + 1, _initialize[index]);
  }

  mgr->show();

  mgr = new TableRowForm("mgr", _baseWidget, 5); 
  
  for (index = 0; index < NControllers; index++)
  { 
    _reset[index] = 
      XtVaCreateManagedWidget("reset", xmPushButtonWidgetClass,
			      mgr->baseWidget(), NULL);

    XtAddCallback(_reset[index], XmNactivateCallback, 
		  &PanTiltMicroGui::cmdButtonCallback, this);

    mgr->attach(index + 1, _reset[index]);
  }

  mgr->show();

  mgr = new TableRowForm("mgr", _baseWidget, 5); 

  label = 
    XtVaCreateManagedWidget("stepperLabel", xmLabelWidgetClass, 
			    mgr->baseWidget(), NULL);

  mgr->append(label);
  
  for (index = 0; index < NControllers; index++)
  {
    _stepper[index] = new DynamicLabel("stepper", mgr->baseWidget());
    mgr->append(_stepper[index]);
  }

  mgr->show();


  mgr = new TableRowForm("mgr", _baseWidget, 5); 

  label = 
    XtVaCreateManagedWidget("analogLabel", xmLabelWidgetClass, 
			    mgr->baseWidget(), NULL);

  mgr->append(label);
  
  for (index = 0; index < NControllers; index++)
  {
    _analog[index] = new DynamicLabel("analog", mgr->baseWidget());
    mgr->append(_analog[index]);
  }

  mgr->show();

  mgr = new TableRowForm("mgr", _baseWidget, 5); 

  label = 
    XtVaCreateManagedWidget("cwSwitchLabel", xmLabelWidgetClass, 
			    mgr->baseWidget(), NULL);

  mgr->append(label);
  
  for (index = 0; index < NControllers; index++)
  {
    _cwSwitch[index] = new DynamicLabel("cwSwitch", mgr->baseWidget());
    mgr->append(_cwSwitch[index]);
    _prevCwSwitch[index] = 999;
  }

  mgr->show();

  mgr = new TableRowForm("mgr", _baseWidget, 5); 

  label = 
    XtVaCreateManagedWidget("ccwSwitchLabel", xmLabelWidgetClass, 
			    mgr->baseWidget(), NULL);

  mgr->append(label);
  
  for (index = 0; index < NControllers; index++)
  {
    _ccwSwitch[index] = new DynamicLabel("ccwSwitch", mgr->baseWidget());
    mgr->append(_ccwSwitch[index]);
    _prevCcwSwitch[index] = 999;
  }

  mgr->show();

  Alarm *alarm;
    
  mgr = new TableRowForm("mgr", _baseWidget, 5); 

  label = 
    XtVaCreateManagedWidget("deltaAlarmLabel", xmLabelWidgetClass, 
			    mgr->baseWidget(), NULL);

  mgr->append(label);
  
  for (index = 0; index < NControllers; index++)
  {
    if ((alarm = alarms->find(_micro->panTiltDm->deltaAlarm[index]->getName()))
	== NULL)
    {
    }
    _deltaAlarm[index] = new AlarmText("deltaAlarm", mgr->baseWidget(), alarm);
    mgr->append(_deltaAlarm[index]);
  }

  mgr->show();

  mgr = new TableRowForm("mgr", _baseWidget, 5); 

  label = 
    XtVaCreateManagedWidget("faultLabel", xmLabelWidgetClass, 
			    mgr->baseWidget(), NULL);

  mgr->append(label);
  
  for (index = 0; index < NControllers; index++)
  {
    if ((alarm = alarms->find(_micro->panTiltDm->fault[index]->getName()))
	== NULL)
    {
    }
    _fault[index] = new AlarmText("fault", mgr->baseWidget(), alarm);
    mgr->append(_fault[index]);
  }

  mgr->show();

  for (index = 0; index < NControllers; index++)
  {
    addDmObject(_micro->panTiltDm->initialize[index], DmProvideFlag);
    addDmObject(_micro->panTiltDm->reset[index], DmProvideFlag);
    addDmObject(_micro->panTiltDm->stepper[index], DmConsumeFlag);
    addDmObject(_micro->panTiltDm->analog[index], DmConsumeFlag);
    addDmObject(_micro->panTiltDm->cwSwitch[index], DmConsumeFlag);
    addDmObject(_micro->panTiltDm->ccwSwitch[index], DmConsumeFlag);
  }
  
  if (setConsumePeriod(period) == -1)
    return;
  
  updateGui();
}


PanTiltMicroGui::~PanTiltMicroGui()
{
  delete _externGf;
  delete _localGf;
  delete _temperature;
  delete _stepperTemperature;
  delete _humidity;
  delete _housingWater;
  delete _gfSelfTest;

  for (int i = 0; i < NControllers; i++)
  {
    delete _stepper[i];
    delete _analog[i];
    delete _cwSwitch[i];
    delete _ccwSwitch[i];
    delete _deltaAlarm[i];
    delete _fault[i];
  }
}


void PanTiltMicroGui::updateGui(DM_Item handle)
{
  MicroGui::updateGui();

  Flt32 fltValue;
  MBool boolValue;

  char buf[100];
  DM_Time t;
  Errno errno;
  char errorBuf[errorMsgSize];
  
  for (int i = 0; i < NControllers; i++)
  {
    if ((errno = _micro->panTiltDm->stepper[i]->read(&fltValue, &t)) != SUCCESS)
    {
      sprintDmError(errno, "PanTiltMicroGui::updateGui(), reading stepper", 
		    errorBuf);
      
      setError(errorBuf);
    }
    else
    {
      sprintf(buf, "%.2f", fltValue);
      _stepper[i]->setText(buf);
    }

    if ((errno = _micro->panTiltDm->analog[i]->read(&fltValue, &t)) != SUCCESS)
    {
      sprintDmError(errno, "PanTiltMicroGui::updateGui(), reading analog", 
		    errorBuf);
      
      setError(errorBuf);
    }
    else
    {
      sprintf(buf, "%.2f", fltValue);
      _analog[i]->setText(buf);
    }

    if ((errno = _micro->panTiltDm->cwSwitch[i]->read(&boolValue, &t)) != SUCCESS)
    {
      sprintDmError(errno, "PanTiltMicroGui::updateGui(), reading cwSwitch", 
		    errorBuf);
      
      setError(errorBuf);
    }
    else if (boolValue != _prevCwSwitch[i])
    {
      if (boolValue)
	_cwSwitch[i]->set("On", _onForeground, _onBackground);
      else
	_cwSwitch[i]->set("Off", _offForeground, _offBackground);
      
      _prevCwSwitch[i] = boolValue;
    }

    if ((errno = _micro->panTiltDm->ccwSwitch[i]->read(&boolValue, &t)) 
	!= SUCCESS)
    {
      sprintDmError(errno, "PanTiltMicroGui::updateGui(), reading ccwSwitch", 
		    errorBuf);
      
      setError(errorBuf);
    }
    else if (boolValue != _prevCcwSwitch[i])
    {
      if (boolValue)
	_ccwSwitch[i]->set("On", _onForeground, _onBackground);
      else
	_ccwSwitch[i]->set("Off", _offForeground, _offBackground);

      _prevCcwSwitch[i] = boolValue;
    }
  }
}


int PanTiltMicroGui::sendCmd(Widget w)
{
  DmEmptyObject *dmObj = NULL;
  
  for (int index = 0; index < NControllers; index++)
  {
    if (w == _initialize[index])
    {
      dmObj = _micro->panTiltDm->initialize[index];
      break;
    }
    else if (w == _reset[index])
    {
      dmObj = _micro->panTiltDm->reset[index];
      break;
    }
  }

  if (dmObj == NULL)
    return -1;
  
  DM_Time t;
  t.tv_sec = time(NULL);
  t.tv_usec = 0;
  
  Errno errno;
  
  if ((errno = dmObj->write(&t)) != SUCCESS)
  {
    char errorBuf[errorMsgSize];
    sprintDmError(errno, "PanTiltMicroGui::sendCmd()", errorBuf);
    theErrorDialog->postAndWait(errorBuf);
    return -1;
  }

  return 0;
}


void PanTiltMicroGui::cmdButtonCallback(Widget w,
					XtPointer clientData,
					XtPointer callData)
{
  PanTiltMicroGui *obj = (PanTiltMicroGui *)clientData;
  
  obj->sendCmd(w);
}



