#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>

#include "mbariTypes.h"
#include "PilotTrayMicro.h"
#include "pilotTray.h"

extern "C"
{
# include "usrTime.h"
};
#define dprintf if (debug) fprintf


PilotTrayMicro::PilotTrayMicro(const char *name)
{
  MBool debug = TRUE;

  /* Create Update semaphores              */
  dprintf(stderr, "PilotTrayMicro constructor; semBCreate()...");
  if ((_dmUpdateSem = semBCreate(SEM_Q_FIFO, SEM_EMPTY)) == SEM_NULL)
  {
    fprintf(stderr, "PilotTrayMicro::PilotTrayMicro() - semBCreate failed\n");
    exit(1);
  }

  dprintf(stderr, "done.\n");

  _data = new PilotTrayUiData("TIBURON.CONSOLE", DmConsumeFlag, SEM_NULL);

  _events = new PilotTrayUiEvents("TIBURON.CONSOLE", DmConsumeFlag, _dmUpdateSem);
  _settings = new PilotTrayUiSettings("TIBURON.CONSOLE", DmProvideFlag);

  _dmGroup = dm_create_group();  /* Create Data Manager Group for items */

  dm_group_add_item(_dmGroup, _events->portLight->getHandle(),
                    &_portLightBit);

  dm_group_add_item(_dmGroup, _events->portCamera->getHandle(),
                    &_portCameraBit);

  dm_group_add_item(_dmGroup, _events->stbdLight->getHandle(),
                    &_stbdLightBit);

  dm_group_add_item(_dmGroup, _events->stbdCamera->getHandle(),
                    &_stbdCameraBit);


  dm_group_add_item(_dmGroup, _events->portCameraSelect->getHandle(),
                    &_portCameraSelectBit);

  dm_group_add_item(_dmGroup, _events->stbdCameraSelect->getHandle(),
                    &_stbdCameraSelectBit);

}



/* UNIX version */
PilotTrayMicro::~PilotTrayMicro()
{
  fprintf(stderr, "In PilotTrayMicro Destructor..\n");
  semDelete(_dmUpdateSem);
}

/* UNIX version */
int PilotTrayMicro::readData(Int16 *joystickX,
                          Int16 *joystickY,
                          Int16 *zoom,
                          Int16 *focus)

{
    DM_Time dmTime;
    _data->pan->read(joystickX,  &dmTime);
    _data->tilt->read(joystickY, &dmTime);
    _data->zoom->read(zoom,      &dmTime);
    _data->focus->read(focus,    &dmTime);
    //Return Status
    return (OK);
};//readData

int PilotTrayMicro::startConsumeData()
{
    _data->pan->startConsume(DM_STATIC);
    _data->tilt->startConsume(DM_STATIC);
    _data->zoom->startConsume(DM_STATIC);
    _data->focus->startConsume(DM_STATIC);
    return(OK);
};//startConsumeData

/* UNIX version */
int PilotTrayMicro::writeSettings(PilotTrayButton button,
                                  MBool state,
                                  MBool flash)
{
   DmBooleanObject *obj;
   DM_Time dmTime;

   switch (button)
   {
     case PORT_LIGHT_BUTTON:
        obj = _settings->portLight;
        break;

     case PORT_CAMERA_BUTTON:
        obj = _settings->portCamera;
        break;

     case STBD_LIGHT_BUTTON:
        obj = _settings->stbdLight;
        break;

     case STBD_CAMERA_BUTTON:
        obj = _settings->stbdCamera;
        break;

     case PORT_CAMERA_SELECT_BUTTON:
        obj = _settings->portCameraSelect;
        break;

     case STBD_CAMERA_SELECT_BUTTON:
        obj = _settings->stbdCameraSelect;
        break;

     default:
        return 0;

   }//end case

   Nat16 value = PilotTrayUiSettings::encode(state, flash);

   gettimeofday(&dmTime, (struct timezone *) NULL);

   obj->write(value, &dmTime);

   return(0);
}

int PilotTrayMicro::startProvideSettings()
{
    _settings->portLight->startProvide(DM_ASYNC);
    _settings->stbdLight->startProvide(DM_ASYNC);
    _settings->portCamera->startProvide(DM_ASYNC);
    _settings->stbdCamera->startProvide(DM_ASYNC);
    _settings->portCameraSelect->startProvide(DM_ASYNC);
    _settings->stbdCameraSelect->startProvide(DM_ASYNC);

    return(OK);
};//startProvideSettings

/* UNIX version */
MBool PilotTrayMicro::readEvent(PilotTrayButton *button)
{
  *button = NO_BUTTON;

  /* Wait for any data items to change     */
  semTake(_dmUpdateSem, WAIT_FOREVER);

  DWord groupItem = dm_get_group_changes(_dmGroup);
  if (groupItem == 0)
    return FALSE;

    if(groupItem & _portLightBit)
    {
          *button = PORT_LIGHT_BUTTON;
    }
    if(groupItem & _portCameraBit)
    {
          *button = PORT_CAMERA_BUTTON;
    }
    if(groupItem & _stbdLightBit)
    {
          *button = STBD_LIGHT_BUTTON;
    }
    if(groupItem & _stbdCameraBit)
    {
          *button = STBD_CAMERA_BUTTON;
    }
    if(groupItem & _portCameraSelectBit)
    {
          *button = PORT_CAMERA_SELECT_BUTTON;
    }
    if(groupItem & _stbdCameraSelectBit)
    {
          *button = STBD_CAMERA_SELECT_BUTTON;
    }

    return FALSE;

}//readEvent




















