#include <stdio.h>
#include <stdlib.h>
#include <Xm/Label.h>
#include <Xm/Form.h>
#include <Xm/RowColumn.h>
#include <Xm/ScrollBar.h>
#include <Xm/PushB.h>
#include <Vk/VkApp.h>
#include <Vk/VkSimpleWindow.h>
#include <Vk/VkOptionMenu.h>
#include <Vk/VkErrorDialog.h>
#include <Vk/VkWarningDialog.h>
#include "TiburonApp.h"
#include "MainWindow.h"
#include "camera.h"

MainPage::MainPage(const char *name, Widget parent, 
		   const char *dmPrefix)
  : DmGuiObject(name, parent)
{
  Boolean debug = True;

  char errorBuf[512];

  _baseWidget = XtVaCreateWidget(_name, xmRowColumnWidgetClass, parent,
				 XmNorientation, XmVERTICAL,
				 NULL);
  
  installDestroyHandler();

  _camera = new Camera("mainCamera", baseWidget(), dmPrefix, 50);

  _camera->show();

  _temperature = 0;
  _humidity = 0;
  _water = 0;

  // Find alarms
  SystemAlarms *alarms = ((TiburonApp *)theApplication)->systemAlarms;

  char dmItemName[MaxDmNameLen];
  strcpy(dmItemName, dmPrefix);

  char *namePtr = dmItemName + strlen(dmItemName);

  strcpy(namePtr, HUMIDITY_DM);
  _dmHumidity = new DmNat16Object(dmItemName);

  strcpy(namePtr, TEMPERATURE_DM);
  _dmTemperature = new DmInt16Object(dmItemName);

  strcpy(namePtr, HUMIDITY_ALARM_DM);
  Alarm *humidityAlarm;
  if ((humidityAlarm = alarms->find(dmItemName)) == NULL)
  {
    sprintf(errorBuf,
	    "MainPage::MainPage() - couldn't find alarm \"%s\"",
	    dmItemName);

    theErrorDialog->postAndWait(errorBuf);
  }
  else {
    int ret;
    ret = humidityAlarm->update();
    _prevHumidityAlarmValue = humidityAlarm->value();
    dprintf(stderr, 
	    "MainPage::MainPage() - humidity alarm update=%d, value=%d\n",
	    ret, _prevHumidityAlarmValue);
  }
  strcpy(namePtr, TEMPERATURE_ALARM_DM);
  Alarm *tempAlarm;
  if ((tempAlarm = alarms->find(dmItemName)) == NULL)
  {
    sprintf(errorBuf,
	    "MainPage::MainPage() - couldn't find alarm \"%s\"",
	    dmItemName);

    theErrorDialog->postAndWait(errorBuf);
  }
  else
    _prevTemperatureAlarmValue = tempAlarm->value();

  strcpy(namePtr, HOUSING_WATER_ALARM_DM);  
  Alarm *waterAlarm;
  if ((waterAlarm = alarms->find(dmItemName)) == NULL)
  {
    sprintf(errorBuf,
	    "MainPage::MainPage() - couldn't find alarm \"%s\"",
	    dmItemName);

    theErrorDialog->postAndWait(errorBuf);
  }

  int period = 500;

  Widget mgr;
  Widget label;

  mgr = XtVaCreateWidget("mgr", xmRowColumnWidgetClass, baseWidget(),
			 XmNorientation, XmHORIZONTAL,
			 NULL);

  label = XtVaCreateManagedWidget("temperature", xmLabelWidgetClass, 
				  mgr,
				  NULL);

  _temperature = 
    new AlarmedInt16Text("temperature", mgr, "%-3.0f C", 
			 _dmTemperature, 
			 period, tempAlarm, Dynamic); 

  _temperature->show();

  XtManageChild(mgr);

  mgr = XtVaCreateWidget("mgr", xmRowColumnWidgetClass, baseWidget(),
			 XmNorientation, XmHORIZONTAL,
		 NULL);

  label = XtVaCreateManagedWidget("humidity", xmLabelWidgetClass, 
				  mgr,
				  NULL);
  _humidity = 
    new AlarmedNat16Text("humidity", mgr, "%-3.0f %%", 
			 _dmHumidity, period, humidityAlarm, Dynamic); 

  _humidity->show();

  XtManageChild(mgr);

  mgr = XtVaCreateWidget("mgr", xmRowColumnWidgetClass, baseWidget(),
			 XmNorientation, XmHORIZONTAL,
			 NULL);

  label = XtVaCreateManagedWidget("waterAlarm", xmLabelWidgetClass, 
				  mgr,
				  NULL);
  _water = 
    new AlarmText("housingWater", mgr, waterAlarm, "%s");

  _water->show();

  XtManageChild(mgr);

  _temperatureAlarmDetector = 
    new AlarmDetector("temperatureAlarmDetector", _baseWidget, tempAlarm,
		      this);

  _humidityAlarmDetector = 
    new AlarmDetector("humidityAlarmDetector", _baseWidget, humidityAlarm,
		      this);

  _waterAlarmDetector = 
    new AlarmDetector("waterAlarmDetector", _baseWidget, waterAlarm,
		      this);

}


MainPage::~MainPage(const char *name, Widget parent)
{
  Boolean debug = True;

  dprintf(stderr, "delete _camera\n");
  delete _camera;

  dprintf(stderr, "delete _temperature\n");
  delete _temperature;
  dprintf(stderr, "delete _humidity\n");
  delete _humidity;
  dprintf(stderr, "delete _water\n");
  delete _water;

  dprintf(stderr, "delete _temperatureAlarmDetector\n");
  delete _temperatureAlarmDetector;
  dprintf(stderr, "delete _humidityAlarmDetector\n");
  delete _humidityAlarmDetector;
  dprintf(stderr, "delete _waterAlarmDetector\n");
  delete _waterAlarmDetector;

  dprintf(stderr, "delete _dmTemperature\n");
  delete _dmTemperature;
  dprintf(stderr, "delete _dmHumidity\n");
  delete _dmHumidity;
  dprintf(stderr, "Done with MainWindow destructor\n");
}


void MainPage::updateFromPeer(DmGuiObject *peer, XtPointer clientData)
{
  Boolean debug = True;
  Boolean postDialog = False;

  const char *msg;
  Alarm *alarm;
  int alarmValue;

  if (peer == _temperatureAlarmDetector) {
    msg = "HDTV Temperature alarm!";
    alarm = _temperatureAlarmDetector->update();
    alarmValue = alarm->value();
    if (alarmValue > _prevTemperatureAlarmValue)
      postDialog = True;

    _prevTemperatureAlarmValue = alarmValue;
  }
  else if (peer == _humidityAlarmDetector) {
    msg = "HDTV Humidity alarm!";
    alarm = _humidityAlarmDetector->update();
    alarmValue = alarm->value();
    dprintf(stderr, "humidity alarm value: %d\n", alarmValue);
    if (alarmValue > _prevHumidityAlarmValue)
      postDialog = True;

    _prevHumidityAlarmValue = alarmValue;
  }
  else if (peer == _waterAlarmDetector) {
    msg = "HDTV Water alarm!";
    alarm = _waterAlarmDetector->update();
    if (alarm->value())
      postDialog = True;
  }

  if (postDialog)
    theWarningDialog->post(msg);
}



MainWindow::MainWindow(const char *name, const char *systemName) :
  VkSimpleWindow(name)
{
  char dmPrefix[MaxDmNameLen];

  sprintf(dmPrefix, "%s.HDTV.", systemName);

  _mainPage = new MainPage("mainPage", mainWindowWidget(), dmPrefix);
  _mainPage->show();

  addView(_mainPage->baseWidget());

}


MainWindow::~MainWindow ()
{
  delete _mainPage;
}




