#include <stdlib.h>
#include <unistd.h>
#include <mbariTypes.h>
#include "lapBox.h"
#include "LapBoxMicro.h"
#include "LapBoxApp.h"
#include "LapBoxOutTask.h"

LapBoxOutTask::LapBoxOutTask(LapBoxTaskControl *taskParams, 
                             LapBoxMicro *uiObject,
                             IviewControl *iviewControlPT, 
                             IviewControl *iviewControlZFI)
{
  DM_Item  msgItemPT, msgItemZFI;

  char name[256], dmPrefix[MaxDmNameLen];
  char dmAutoIrisName[256], dmMemoryName[256], 
       dmSensitivityName[256], dmEnabledName[256];

  strcpy(name, taskParams->name());
  strcpy(dmPrefix, taskParams->prefix());

  _uiObject = uiObject;
  _taskParams = taskParams;

  _iviewControlPT = iviewControlPT;
  _iviewControlZFI = iviewControlZFI;
 
  msgItemPT = _iviewControlPT->msgItem();
  msgItemZFI = _iviewControlZFI->msgItem(); 

  _msgObjPT = new DmObject(&msgItemPT);
  _msgObjZFI = new DmObject(&msgItemZFI);

  //Button Grabber Stuff
  _iviewMonitor = new IviewMonitor();

  _portLightPT = new DeviceLight(IviewPortLight , PORT_LIGHT_BUTTON,
				 _iviewControlPT, 
                                 _iviewMonitor, _uiObject, 
                                 _taskParams->SRQTaskPid);

  _stbdLightPT = new DeviceLight(IviewStbdLight , STBD_LIGHT_BUTTON,
				 _iviewControlPT, 
                                 _iviewMonitor, _uiObject, 
                                 _taskParams->SRQTaskPid);

  _portCameraPT = new DeviceLight(IviewPortCamera , PORT_CAMERA_BUTTON,
				  _iviewControlPT, 
                                  _iviewMonitor, _uiObject, 
                                  _taskParams->SRQTaskPid);

  _stbdCameraPT = new DeviceLight(IviewStbdCamera , STBD_CAMERA_BUTTON,
				  _iviewControlPT, 
                                  _iviewMonitor, _uiObject, 
                                  _taskParams->SRQTaskPid);

  _portCameraZFI = new DeviceLight(IviewPortCamera , 
				   PORT_CAMERA_SELECT_BUTTON,
				   _iviewControlZFI, 
                                   _iviewMonitor, _uiObject, 
                                   _taskParams->SRQTaskPid);

  _stbdCameraZFI = new DeviceLight(IviewStbdCamera , 
				   STBD_CAMERA_SELECT_BUTTON,
				   _iviewControlZFI, 
                                   _iviewMonitor, _uiObject, 
                                   _taskParams->SRQTaskPid);


  strcpy(dmAutoIrisName, dmPrefix);
  strcat(dmAutoIrisName, LAP_BOX_AUTO_IRIS_DM);

  strcpy(dmMemoryName, dmPrefix);
  strcat(dmMemoryName, LAP_BOX_AUX2_DM);

  strcpy(dmSensitivityName, dmPrefix);
  strcat(dmSensitivityName, LAP_BOX_AUX1_DM);

  strcpy(dmEnabledName, dmPrefix);
  strcat(dmEnabledName, LAP_BOX_ENABLED_DM);
 
  autoIris = new DmBooleanObject(dmAutoIrisName);

  enabled = new DmBooleanObject(dmEnabledName);

  portAutoIris = new DmBooleanObject(LAP_BOX_PORT_AUTO_IRIS_DM);
  stbdAutoIris = new DmBooleanObject(LAP_BOX_STBD_AUTO_IRIS_DM);

  memory = new DmBooleanObject(dmMemoryName);
  sensitivity = new DmEnumObject(dmSensitivityName);

  if ((_dmUpdateSem = semBCreate(SEM_Q_FIFO, SEM_EMPTY)) == NULL)
  {
    fprintf(stderr, "LapBoxOutTask::LapBoxOutTask() - semBCreate() failed\n");
    exit(1);
  } 
}

LapBoxOutTask::~LapBoxOutTask()
{
  semDelete(_dmUpdateSem);
  delete _uiObject;
  delete _msgObjPT;
  delete _msgObjZFI;
}

int LapBoxOutTask::run()
{
   DM_Group dmGroup;               /* Lap Box Data Manager Group            */
   DWord    changedBits;           /* Holds dm_group_changes bit vector     */

   DWord    enabledBit;            /* Lap Box Enabled bit                   */
   DWord    autoIrisBit;           /* Lap Box auto Iris bit                 */
   DWord    portAutoIrisBit;
   DWord    stbdAutoIrisBit;
   DWord    sensitivityBit;        /* Lap Box sensitivity bit               */
   DWord    memoryBit;             /* Lap Box memory bit                    */

   DWord    resetEventBit;
   DWord    resetCmdBit;
   DWord    msgObjPTBit;
   DWord    msgObjZFIBit;

   MBool    Flash = FALSE;
   MBool    state;
   
   //IviewSensitivity sensitivityState;

   Int32 sensitivityState;
   LapBoxButtonState buttonState;
   
   IviewMessage msg;

   const int SetDeviceTimeout = 2;


   DM_Time  dmTime;                /* Create switch & power sync semaphores */
   

                                   /* Declare this task a consumer of items */

                                   /* which are written to the Lap Box      */
   
   DmEmptyObject *dmResetEvent = _taskParams->dmResetEvent();
   DmEmptyObject *dmResetCmd = _taskParams->dmResetCmd();

   _msgObjPT->startConsume(DM_STATIC, _dmUpdateSem);
   _msgObjZFI->startConsume(DM_STATIC, _dmUpdateSem);

   enabled->startConsume(DM_STATIC, _dmUpdateSem);
   autoIris->startConsume(DM_STATIC, _dmUpdateSem);
   portAutoIris->startConsume(DM_STATIC, _dmUpdateSem);
   stbdAutoIris->startConsume(DM_STATIC, _dmUpdateSem);
   sensitivity->startConsume(DM_STATIC, _dmUpdateSem);
   memory->startConsume(DM_STATIC, _dmUpdateSem);
  
   autoIris->startProvide(DM_STATIC);
   stbdAutoIris->startProvide(DM_STATIC);
   portAutoIris->startProvide(DM_STATIC);
   

//Task Control objects   
   dmResetEvent->startConsume(DM_STATIC, _dmUpdateSem);
   dmResetCmd->startConsume(DM_STATIC, _dmUpdateSem);

   dmGroup = dm_create_group();    /* Create Data Manager Group for items   */

   dm_group_add_item(dmGroup, _msgObjPT->getHandle(), &msgObjPTBit);
   dm_group_add_item(dmGroup, _msgObjZFI->getHandle(), &msgObjZFIBit);
    
   dm_group_add_item(dmGroup, enabled->getHandle(), &enabledBit);

   dm_group_add_item(dmGroup, autoIris->getHandle(), &autoIrisBit);
   dm_group_add_item(dmGroup, portAutoIris->getHandle(), &portAutoIrisBit);
   dm_group_add_item(dmGroup, stbdAutoIris->getHandle(), &stbdAutoIrisBit);

   dm_group_add_item(dmGroup, sensitivity->getHandle(), &sensitivityBit);
   dm_group_add_item(dmGroup, memory->getHandle(), &memoryBit);
   dm_group_add_item(dmGroup, dmResetCmd->getHandle(), &resetCmdBit);
   dm_group_add_item(dmGroup, dmResetEvent->getHandle(), &resetEventBit);

   // Initialize device States
   _portLightPT->getIviewDeviceState();
   _stbdLightPT->getIviewDeviceState();
   _portCameraPT->getIviewDeviceState();
   _stbdCameraPT->getIviewDeviceState();

   _portCameraZFI->getIviewDeviceState();
   _stbdCameraZFI->getIviewDeviceState();


   FOREVER
   {    
        _taskParams->setMicroConfigured(FALSE);    
	//printf("Out task, before wait(): _params=X%x\n", _taskParams);
        _taskParams->wait(OUT_TASK, WAIT_FOREVER);
	//printf("Out task, after wait(): _params=X%x\n", _taskParams);

        /* We need to initialize default state of Data manager Items here    */
                                    /* Clear item changed bits after reset   */
        changedBits = dm_get_group_changes(dmGroup);

        _taskParams->setMicroConfigured(TRUE);
        
        _taskParams->wakeupTask(IN_TASK);
        
      while(_taskParams->microLinkState()==LINK_UP)
      {
        //Get Device light States Periodicaly
        _portLightPT->getIviewDeviceState();
        _stbdLightPT->getIviewDeviceState();
        _portCameraPT->getIviewDeviceState();
        _stbdCameraPT->getIviewDeviceState();

        _portCameraZFI->getIviewDeviceState();
#if 0
        portAutoIris->read(&state, (DM_Time *) NULL);

	state == TRUE ? buttonState = LapBoxButtonOn: 
	   buttonState = LapBoxButtonOff ; 

	_uiObject->writeSettings(AUTO_IRIS_BUTTON,
				 buttonState, FALSE);
#endif
        _stbdCameraZFI->getIviewDeviceState();

#if 0
        stbdAutoIris->read(&state, (DM_Time *) NULL);
	state == TRUE ? buttonState = LapBoxButtonOn: 
	   buttonState = LapBoxButtonOff ; 
	     
	_uiObject->writeSettings(AUTO_IRIS_BUTTON,
				 buttonState, FALSE);
#endif

        semTake(_dmUpdateSem, SetDeviceTimeout);

                                    /* Ask Data Manager which items changed  */
        changedBits = dm_get_group_changes(dmGroup);


        if (changedBits & resetEventBit)
	{
	break;
        }
	
        taskSafe();                 /* Prevent task from being delete during */
                                    /* serial IO and Data Manager updates    */ 
        if (changedBits & resetCmdBit)
	{
	_taskParams->announceResets(TRUE);
	_uiObject->reset();
        }

        if (changedBits & enabledBit)
	{
                enabled->read(&state, &dmTime);
                _taskParams->setEnabled(state);
                
                state == TRUE ? buttonState = LapBoxButtonOn : 
                                buttonState = LapBoxButtonError;

                _uiObject->writeSettings(ENABLE_BUTTON,
                                          buttonState, Flash);
        } 

        // Mgs Changed Bit
        if (changedBits & msgObjPTBit)
        {
            _iviewControlPT->getMsg(&msg);

	    if (msg.serverStarting)
               _iviewControlPT->initialize();

	    if (msg.panoramic)
	    {
	       _uiObject->writeSettings(PANORAMIC_BUTTON, LapBoxButtonOn, FALSE);
	       _taskParams->panoramic = TRUE;
            }
	    else if (!msg.panoramic)
	    {
	       _uiObject->writeSettings(PANORAMIC_BUTTON, LapBoxButtonOff, FALSE);
	       _taskParams->panoramic = FALSE;
            }

            if(msg.deviceMask & IviewPortLight)
            {
               _portLightPT->getIviewDeviceState();
	    }
            if(msg.deviceMask & IviewStbdLight)
	    {
               _stbdLightPT->getIviewDeviceState();
            }
            if(msg.deviceMask & IviewPortCamera)             
            {
               _portCameraPT->getIviewDeviceState();
            }
            if(msg.deviceMask & IviewStbdCamera)
            {
               _stbdCameraPT->getIviewDeviceState();
	    }
        }

        if (changedBits & msgObjZFIBit)
        {
            _iviewControlZFI->getMsg(&msg);
            if(msg.serverStarting)
               _iviewControlZFI->initialize();
            
	    if(msg.focusCaptured)
	       _uiObject->writeSettings(FOCUS_CAPTURE, LapBoxButtonOn, FALSE);
	    else if(!msg.focusCaptured)
	       _uiObject->writeSettings(FOCUS_CAPTURE, LapBoxButtonOff, FALSE);

            if(msg.deviceMask & IviewPortCamera)             
            {
               _portCameraZFI->getIviewDeviceState();
               _taskParams->setCamera(IviewPortCamera);
               portAutoIris->read(&state, (DM_Time *) NULL);
               !state ? buttonState = LapBoxButtonOn:
                                   buttonState = LapBoxButtonOff ; 

               _uiObject->writeSettings(AUTO_IRIS_BUTTON,
                                          buttonState, FALSE);
            }
            else if(msg.deviceMask & IviewStbdCamera)
            {               
               _stbdCameraZFI->getIviewDeviceState();
               _taskParams->setCamera(IviewStbdCamera);
               stbdAutoIris->read(&state, (DM_Time *) NULL);
          
               !state ? buttonState = LapBoxButtonOn: 
                                 buttonState = LapBoxButtonOff ; 

               _uiObject->writeSettings(AUTO_IRIS_BUTTON,
                                          buttonState, FALSE);
            }    
        }


        if (changedBits & autoIrisBit)
	{            
                _iviewControlZFI->getMsg(&msg);
                if(msg.deviceMask == IviewPortCamera)
                {
                   portAutoIris->read(&state, &dmTime);
                   portAutoIris->write((!state ? -1 : FALSE), &dmTime);                       
                }
                else if(msg.deviceMask == IviewStbdCamera)
                {
                   stbdAutoIris->read(&state, &dmTime);
                   stbdAutoIris->write((!state ? -1 : FALSE), &dmTime);
                }
        } 

        if (changedBits & portAutoIrisBit)
	{
           _iviewControlZFI->getMsg(&msg);
           if(msg.deviceMask == IviewPortCamera)
           { 
              portAutoIris->read(&state, &dmTime);
              
              !state ? buttonState = LapBoxButtonOn:                
                               buttonState = LapBoxButtonOff ; 

              _uiObject->writeSettings(AUTO_IRIS_BUTTON,
                                          buttonState, FALSE);
           }
        }
        
        if (changedBits & stbdAutoIrisBit)
	{  
           _iviewControlZFI->getMsg(&msg);
           if(msg.deviceMask == IviewStbdCamera)
           { 
             stbdAutoIris->read(&state, &dmTime);
             !state ? buttonState = LapBoxButtonOn : 
                              buttonState = LapBoxButtonOff;                

             _uiObject->writeSettings(AUTO_IRIS_BUTTON,
                                         buttonState, FALSE);
           }
        }
        
        if (changedBits & memoryBit)
	{
                memory->read(&state, &dmTime);
                       
                state == TRUE ? buttonState = LapBoxButtonOn : 
                                buttonState = LapBoxButtonOff;

                _uiObject->writeSettings(MEMORY_BUTTON,
                                          buttonState, FALSE);
        } 

        if (changedBits & sensitivityBit)
	{
	        sensitivity->read(&sensitivityState, &dmTime);
                //sensitivityState = _taskParams->getSensitivity();
                       
                if(sensitivityState == IviewHighSensitivity)
                   buttonState = LapBoxButtonOn; 
                else if (sensitivityState == IviewAutoSensitivity)
                   buttonState = LapBoxButtonError;
                else if (sensitivityState == IviewDefaultSensitivity)
                                buttonState = LapBoxButtonOff;
                
                _uiObject->writeSettings(SENSITIVITY_BUTTON,
                                          buttonState, FALSE);
        } 
                
        taskUnsafe();
      }//while (LINK_UP)
   }//FOREVER

  return 0;
}//LapBoxOutTask::run






