#include "tasksynchronizer.h"
#include "debug.h"
#include <time.h>
#ifdef _WIN32_
#include <malloc.h>
#endif
#ifdef _VXWORKS_
#include <taskLib.h>
#include <stdio.h>
#endif

TaskSynchronizer::TaskSynchronizer(const char *name, unsigned nTasks)
	:_mutex (),
	_shutdown (FALSE),
	_reset (FALSE),
	_nTasks (3)
{
 
  if ((_tasks = (TaskData *)malloc(_nTasks * sizeof(TaskData))) == 0)
  {
    setError("TaskSynchronizer::TaskSynchronizer() - "
	     "malloc() of TaskData failed");
    return;
  }
  
  for (unsigned i = 0; i < _nTasks; i++)
  {
    _tasks[i].pid = 0;

	if ((_tasks[i].sem = new BinarySemaphore(SEM_EMPTY, NULL)) == 0)
	{
      setError("TaskSynchronizer::TaskSynchronizer() - task[i].sem create failed");
      return;
    }
	if ((_tasks[i].shutdownSem = new BinarySemaphore(SEM_EMPTY, NULL)) == 0)
	{
       setError("TaskSynchronizer::TaskSynchronizer() - task[i].shutdownSem create failed");
      return;
    }	
	if ((_tasks[i].resetSem = new BinarySemaphore(SEM_EMPTY, NULL)) == 0)
	{
       setError("TaskSynchronizer::TaskSynchronizer() - task[i].resetSem create failed");
      return;
    }	
  }

  _mutex.unlock();
}


TaskSynchronizer::~TaskSynchronizer()
{
  for (unsigned i = 0; i < _nTasks; i++)
  {
	  if(_tasks[i].sem != 0)
		  delete _tasks[i].sem;

	  if(_tasks[i].shutdownSem != 0)
  		  delete _tasks[i].shutdownSem;

	  if(_tasks[i].shutdownSem != 0)
  		  delete _tasks[i].resetSem;
  }
  free((void *)_tasks);

}

int TaskSynchronizer::semGive(TaskNo taskNo)
{
  if (taskNo >= (TaskNo) _nTasks)
    return -1;
  
  _tasks[taskNo].sem->semGive();
  return 0;
}


int TaskSynchronizer::semTake(TaskNo taskNo, int timeout)
{
  if(taskNo >= (TaskNo) _nTasks)
    return -1;

  //wait for timeout in milliseconds
  return _tasks[taskNo].sem->semTake(timeout); 
}

int TaskSynchronizer::setTaskId(TaskNo taskNo, DWord pid)
{
  if ((unsigned)taskNo >= _nTasks)
    return -1;
  
  _tasks[taskNo].pid = pid;
  return 0;
}
//d.cline added
void TaskSynchronizer::setTaskShutdown(TaskNo taskNo)
{
  if ((unsigned)taskNo >= _nTasks)
    return;  

  DPRINTF("Shutdown from task %d received\n", taskNo);
  _tasks[taskNo].shutdownSem->semGive();
}
//d.cline added
void TaskSynchronizer::setTaskReset(TaskNo taskNo)
{
  if ((unsigned)taskNo >= _nTasks)
    return;  

  DPRINTF("Reset from task %d received\n", taskNo);
  _tasks[taskNo].resetSem->semGive();
}
//d.cline added
void TaskSynchronizer::waitForShutdown(TaskNo taskNo, int timeoutSecs )
{
  if ((unsigned)taskNo >= _nTasks)
    return;  

  _tasks[taskNo].shutdownSem->semTake(timeoutSecs*1000);
}
//d.cline added
void TaskSynchronizer::waitForReset(TaskNo taskNo, int timeoutSecs )
{
  if ((unsigned)taskNo >= _nTasks)
    return;  

  _tasks[taskNo].resetSem->semTake(timeoutSecs*1000);
}

void TaskSynchronizer::shutdown()
{
	_shutdown = TRUE;
}
void TaskSynchronizer::reset(Boolean state)
{
	_reset = state;
}
