/******************************************************************************************/
// includes
#include <stdio.h>
#include <stdlib.h>
#include "../Src/ATDemo.h"
#include "../Src/Support/strfunc.h"

CAtBoardManager *BoardManager;
CATBoardModDVBC	ATBoardModDVBC;

static void PrintDeviceInfo(CATBoardPlayRec *pATBoardPlayRec);

void SysConsoleHandlersCallBack()
{
	Message(E_VERBOSE_1, "Closing down.......");
	PlayFileBreak((CATBoardPlayRec*)&ATBoardModDVBC);
}

int main (int argc, char **argv)
{

	if(argc <= 1)
	{
		printf("Incorrect arguments. \nUse the filename as a argument\n");
	}

	SetProgramName("ATBoard2780CPlay");
	SetVerboseLevel(E_VERBOSE_ALL);

	SysSetupConsoleHandlers();

	// Instantiate the board manager
	BoardManager = CAtBoardManager::Instance ();

	// Get a device list
	CAtDeviceList DeviceList;
	BoardManager->GetDeviceList(DeviceList);


	SBoardOpenParams BoardOpenParams;

	// Set the default board index
	BoardOpenParams.m_BoardPos = 0;

	// Use the first board found. If none are found, use the demo board.
	if(DeviceList.GetFreeSize() == 0)
	{
		printf("No (free) device(s) found. Using demo board.\n");

		// set demo board open parameters
		BoardOpenParams.m_BoardPos = -1;
		BoardOpenParams.m_pBoardName = NULL;
	}
	else
	{

		//find the first board that can be used for this application

		BOOL bRet = DeviceList.GetFirstBoard(&BoardOpenParams);
		const ATDEVICEINFO *pDevInfo = DeviceList.GetDeviceInfo(&BoardOpenParams);

		while(bRet && (pDevInfo->DeviceType != AT2780 || pDevInfo->DeviceHasDVB_C_Mod == 0))
		{
			bRet = DeviceList.GetNextBoard(&BoardOpenParams);
			pDevInfo = DeviceList.GetDeviceInfo(&BoardOpenParams);
		}

		if (!bRet || !DeviceList.IsBoardFree(&BoardOpenParams))
		{
			//required board type is not present or already in use.
			printf("Requested device could not be found or is in use. Using demo board.\n");
			// set demo board open parameters
			BoardOpenParams.m_BoardPos = -1;
			BoardOpenParams.m_pBoardName = NULL;
		}

	}


	//////////////////////////////////////////////////////////////////////////
	//Open the selected device
	//////////////////////////////////////////////////////////////////////////
	const ATDEVICEINFO *pDevInfo = DeviceList.GetDeviceInfo(&BoardOpenParams);

	printf("Open and initializing board....\n");

	ATBoardModDVBC.BoardOpen(BoardOpenParams);
	Message(E_VERBOSE_2, "Open and initializing board done");
	PrintDeviceInfo(&ATBoardModDVBC);


	/************************************************************************/
	/* The Modulator settings                                               */
	/************************************************************************/


	SModDVBCOpt ModDVBCOptions =
	{
		TRUE,						///< select RF output
		0UL,						///< if RF is selected, IF output frequency can be 0
		700000000UL,				///< RF output frequency
		-350,						///< -35dBm 
		QAM_64,						///< set qam mode to QAM_16
		FLT_ALPHA_15,				///< set filter roll off to 15%
		INTLEAV_I12_J17,			///< set interleaver to I12/J17
		INVERSION_OFF,				///< set inversion off
		5000000UL,					///< set symbol rate to 5MSymbols/s
		FALSE						///< disable annex B mode
	};


	/************************************************************************/
	/* The Play file  settings                                              */
	/************************************************************************/
	SPlayOpt POptions = 
	{
		FALSE,					///< enable bit rate re multiplexing
		0,						///< set file bit rate to 0. This means tsrate determents the bit rate 
		0UL,					///< set output bit rate to 0 bit/s, so the file bitrate will overwrite it.
		1,						///< The play loop count
		-1,						///< Undefined device
	};

	if (SetModDVBC((CATBoardModDVBC *)&ATBoardModDVBC, ModDVBCOptions))
	{
		// Perform the actual play action
		if (!PlayFile(&ATBoardModDVBC, argv[1], POptions))
			Message(E_VERBOSE_SILENT, "Play terminated with an error");
	}
	else
	{
		printf("Error while initializing modulator\n");
	}

	ATBoardModDVBC.BoardClose();
}




// Print some device information 
static void PrintDeviceInfo(CATBoardPlayRec *pATBoardPlayRec)
{
	CATBoard *pTheBoard = pATBoardPlayRec->GetCurBoard();

	char TmpStr[MAX_TMP_STR_LEN];

	// print friendly name
	u32 nLength = ATDEV_INFO_MAX_STR_LEN;
	char * pFriendlyName = new char[nLength];
	pTheBoard->GetFriendlyName(pFriendlyName, nLength);

	sprintf(TmpStr, "Board found: %s", pFriendlyName);
	Message(E_VERBOSE_SILENT, TmpStr);

	if (pFriendlyName)
		delete pFriendlyName;

	// print API version information
	ATVERSIONINFO * pAPIInfo = NULL;
	pAPIInfo = pTheBoard->GetAPIVersion();
	sprintf(TmpStr, "API version %d.%d", pAPIInfo->Mayor, pAPIInfo->Minor);
	Message(E_VERBOSE_2, TmpStr);

	// print driver version information
	ATVERSIONINFO * pDriverInfo = NULL;
	pDriverInfo = pTheBoard->GetDriverVersion();

	if(pDriverInfo  != NULL)
	{
		sprintf(TmpStr, "Driver version %d.%d", pDriverInfo->Mayor, pDriverInfo->Minor);
		Message(E_VERBOSE_2, TmpStr);
	}
}
