/*
-----------------------------------------------------------------------------
This source file is part of OpenSpace3D
For the latest info, see http://www.openspace3d.com

Copyright (c) 2010 I-maginer

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt

You may alternatively use this source under the terms of a specific version of
the OpenSpace3D Unrestricted License provided you have obtained such a license from
I-maginer.
-----------------------------------------------------------------------------
*/

#include "usbuirt.h"

/*!
* \brief Bloc constructor
* 
*/
UsbUIRT::UsbUIRT(void)
{
  bInitialized = false;
  hinstLib = NULL;
  hDrvHandle = NULL;

  uConfig = NULL;

  fnUUIRTOpen = NULL;
  fnUUIRTClose = NULL;
  fn_UUIRTGetDrvInfo = NULL;
  fn_UUIRTGetUUIRTInfo = NULL;
  fn_UUIRTGetUUIRTConfig = NULL;
  fn_UUIRTSetUUIRTConfig = NULL;
  fn_UUIRTSetReceiveCallback = NULL;
  fn_UUIRTTransmitIR = NULL;
  fn_UUIRTLearnIR = NULL;  
  
  if (Load())
    bInitialized = Open();
}

/*!
* \brief Bloc destructor
* 
*/
UsbUIRT::~UsbUIRT(void)
{
  Close();
  UnLoad();
}

bool UsbUIRT::Open()
{
  hDrvHandle = fnUUIRTOpen();
  if(hDrvHandle == INVALID_HANDLE_VALUE)
    return false;
  
  if (!fn_UUIRTGetUUIRTInfo(hDrvHandle, &UsbUirtInfo))
    return false;

  if (!fn_UUIRTGetUUIRTConfig(hDrvHandle, &uConfig))
    return false;

  return true;
}

bool UsbUIRT::Close()
{
  if(fnUUIRTClose(hDrvHandle))
    return true;

  return false;
}

void UsbUIRT::UnLoad(void)
{
	if (hinstLib)
		FreeLibrary(hinstLib);
	hinstLib = NULL;
}

bool UsbUIRT::Load(void)
{
    // Get a handle to the DLL module.
    hinstLib = LoadLibrary("uuirtdrv"); 
 
    // If the handle is valid, try to get the function address.
    if (hinstLib != NULL) 
    { 
      fnUUIRTOpen = (pfn_UUIRTOpen) GetProcAddress(hinstLib, "UUIRTOpen");
      fnUUIRTClose = (pfn_UUIRTClose) GetProcAddress(hinstLib, "UUIRTClose");
	    fn_UUIRTGetDrvInfo  = (pfn_UUIRTGetDrvInfo) GetProcAddress(hinstLib, "UUIRTGetDrvInfo");
	    fn_UUIRTGetUUIRTInfo = (pfn_UUIRTGetUUIRTInfo) GetProcAddress(hinstLib, "UUIRTGetUUIRTInfo");
	    fn_UUIRTGetUUIRTConfig = (pfn_UUIRTGetUUIRTConfig) GetProcAddress(hinstLib, "UUIRTGetUUIRTConfig");
	    fn_UUIRTSetUUIRTConfig = (pfn_UUIRTSetUUIRTConfig) GetProcAddress(hinstLib, "UUIRTSetUUIRTConfig");
	    fn_UUIRTSetReceiveCallback = (pfn_UUIRTSetReceiveCallback) GetProcAddress(hinstLib, "UUIRTSetReceiveCallback");
	    fn_UUIRTTransmitIR = (pfn_UUIRTTransmitIR) GetProcAddress(hinstLib, "UUIRTTransmitIR");
	    fn_UUIRTLearnIR = (pfn_UUIRTLearnIR) GetProcAddress(hinstLib, "UUIRTLearnIR");

		  if (!fnUUIRTOpen || 
			  !fnUUIRTClose || 
			  !fn_UUIRTGetDrvInfo || 
			  !fn_UUIRTGetUUIRTInfo || 
			  !fn_UUIRTGetUUIRTConfig || 
			  !fn_UUIRTSetUUIRTConfig || 
			  !fn_UUIRTSetReceiveCallback || 
			  !fn_UUIRTTransmitIR || 
			  !fn_UUIRTLearnIR)
		  {
			  UnLoad();
			  return false;
		  }
      
		  return true;
	  }
  
  return false;
}

bool UsbUIRT::SetReceiveCallback(PUUCALLBACKPROC receiveProc)
{
  if(fn_UUIRTSetReceiveCallback(hDrvHandle, receiveProc, (void*)this))
    return true;

  return false;
};

bool UsbUIRT::SendIrData(char* data, int format, int repeat, int waitTime)
{
  char irCode[2048];
  strcpy_s(irCode, 2048, data);
  
	if (!fn_UUIRTTransmitIR(hDrvHandle,
							irCode /* IRCode */,
							format /* codeFormat */,
							repeat /* repeatCount */,
							waitTime /* inactivityWaitTime */,
							NULL /* hEvent */,
							NULL /* reserved1 */,
							NULL /* reserved2 */
							))
  return false;

  return true;
};

bool UsbUIRT::isInitialized(void)
{
  return bInitialized;
}