/*************************************************************************\
* "$RCSfile: CDlgTools.cpp,v $"                                           *
***************************************************************************
* Information by CVS or VSS:                                              *
*     Last check in on: $Date: 2011-10-20 07:53:26 $                      *
*     by                $Author: schluckebier $
*     Revision        : $Revision: 1.28 $                                 *
\*************************************************************************/
/*! \file CDlgTools.cpp
*	\brief Implementation CDlgTools Class
**************************************************************************/

#include "VIC_PS.h"
#include "GBit.h"
#include "CRegion.h"
#include "CLog.hpp"
#include "CPSApp.hpp"
#include "CDlg.hpp"
#include "CDlgTools.hpp"
#include "CDlgConfig.hpp"
#include "CDlgFileMgr.hpp"
#include "CFeature.hpp"
#include "CCamFeatures.hpp"
#include "tinyxml.h"

CDlgTools *CDlgTools::m_pThis = NULL;	//!< The one and only CDlgTools instance

/*************************************************************************/
CDlgTools::CDlgTools(int x, int y, int Width, int Height) :
	CDlg(x, y, Width, Height, DialogId::TOOLS)
/*************************************************************************/
/*! @brief Constructor
**************************************************************************/
{
	int iWidth, iHeight;
	int PosX, PosY;
	int yOffset, xOffset;

	GUI_DlgSetTitle(&m_Dlg, m_pStrings->getValue("DlgToolsTitle", "Tools"));
	m_Choice = 1;
	m_bUpdate = true;

	VIB_ChDir(VIB_Drive[1], m_pApp->GetSkinPath());
	m_Icon[ICON(ID_PARAMETER)] = ReadIcon("B_CONFIG.PNG", 98, 98);
	m_Icon[ICON(ID_REBOOT)] = ReadIcon("B_REBOOT.PNG", 98, 98);
	m_Icon[ICON(ID_LOG)] = ReadIcon("B_LOG.PNG", 98, 98);
	m_Icon[ICON(ID_CLOCK)] = ReadIcon("B_CLOCK.PNG", 98, 98);
	m_Icon[ICON(ID_DIGIO)] = ReadIcon("B_DIGIO.PNG", 98, 98);
	m_Icon[ICON(ID_FULLSCREEN)] = ReadIcon("B_FULLS.PNG", 98, 98);
	m_Icon[ICON(ID_INFO)] = ReadIcon("B_STATS.PNG", 98, 98);
	m_Icon[ICON(ID_FILEMANAGER)] = ReadIcon("B_FILEM.PNG", 98, 98);
	VIB_ChDir(VIB_Drive[1], "..");

	iWidth  = m_Icon[ICON(ID_PARAMETER)].Width;
	iHeight = m_Icon[ICON(ID_PARAMETER)].Height;
	xOffset = iWidth + 4;
	yOffset = iHeight + 4;

	GUI_DlgGetZeroZero(&m_Dlg, &PosX, &PosY);
	PosX += 4;
	PosY += 4;
	GUI_DlgAddIconButton(&m_Dlg, PosX, PosY, iWidth, iHeight,
						 m_pStrings->getValue("DlgToolsClock", "_Clock"),
						 &m_Icon[ICON(ID_CLOCK)], ID_CLOCK);
	GUI_DlgAddIconButton(&m_Dlg, PosX + xOffset, PosY, iWidth, iHeight,
						 m_pStrings->getValue("DlgToolsLog", "_Log"),
						 &m_Icon[ICON(ID_LOG)], ID_LOG);
	PosY += yOffset;
	GUI_DlgAddIconButton(&m_Dlg, PosX, PosY, iWidth, iHeight,
						 m_pStrings->getValue("DlgToolsReboot", "_Reboot"),
						 &m_Icon[ICON(ID_REBOOT)], ID_REBOOT);
	GUI_DlgAddIconButton(&m_Dlg, PosX + xOffset, PosY, iWidth, iHeight,
						 m_pStrings->getValue("DlgToolsDigIO", "_DigIO"),
						 &m_Icon[ICON(ID_DIGIO)], ID_DIGIO);
	PosY += yOffset;
	GUI_DlgAddIconButton(&m_Dlg, PosX, PosY, iWidth, iHeight,
						 m_pStrings->getValue("DlgToolsFullScreen", "_FullScreen"),
						 &m_Icon[ICON(ID_FULLSCREEN)], ID_FULLSCREEN);
	GUI_DlgAddIconButton(&m_Dlg, PosX + xOffset, PosY, iWidth, iHeight, "_Info",
						 &m_Icon[ICON(ID_INFO)], ID_INFO);
	PosY += yOffset;
	GUI_DlgAddIconButton(&m_Dlg, PosX, PosY, iWidth, iHeight,
						 m_pStrings->getValue("DlgToolsParameter", "_Parameter"),
						 &m_Icon[ICON(ID_PARAMETER)], ID_PARAMETER);

	GUI_DlgAddLabel(&m_Dlg, PosX + xOffset, PosY,
		m_pStrings->getValue("DlgToolsSelect", "_Select Para"), ID_CHOICE);
	GUI_DlgAddChoiceBox(&m_Dlg, PosX + xOffset, PosY + 32,
		98, 24, "Application\nStrings\nSave Pic\nEthernet\n", 2, &m_Choice, ID_CHOICE);

	PosY += yOffset;
	GUI_DlgAddIconButton(&m_Dlg, PosX, PosY, iWidth, iHeight,
		m_pStrings->getValue("DlgToolsFilemanager", "File _Manager"),
		&m_Icon[ICON(ID_FILEMANAGER)], ID_FILEMANAGER);
	GUI_DlgAddIconButton(&m_Dlg, PosX + xOffset, PosY, iWidth, iHeight,
		m_pApp->GetStr(StringTable::BACK), m_pApp->GetIcon(IconId::BACK), DLG_ABORT);
}

/*************************************************************************/
CDlgTools::~CDlgTools()
/*************************************************************************/
/*! @brief Destructor
**************************************************************************/
{
	for (int i = 0; i < INDEX(ID_XXX); i++)
		GUI_FreeCImage(&m_Icon[i]);
}

/*************************************************************************/
CDlgTools *CDlgTools::CreateInstance(int x, int y, int Width, int Height)
/*************************************************************************/
/*! @brief Creates CDlgMain instance.
	@param x Horizontal position of dialog
	@param y Vertical position of dialog
	@param Width Width of dialog
	@param Height Height of dialog
	@return Pointer to CDlgTools instance
**************************************************************************/
{
	if (m_pThis == NULL)
		m_pThis = new CDlgTools(x, y, Width, Height);
	return m_pThis;
}

/*************************************************************************/
void CDlgTools::DisposeInstance()
/*************************************************************************/
/*! @brief Disposes CDlgTools instance.
**************************************************************************/
{
	if (m_pThis)
		delete m_pThis;
	m_pThis = NULL;
}

/*************************************************************************/
int CDlgTools::OnUserIO(int nKey)
/*************************************************************************/
/*! @brief Function processes the user inputs.
	@param nKey Last key code the user entered 
	@return CDlg::m_Activity (!= \p DLG_EOF if the user has made an input)
**************************************************************************/
{
	CDlgConfig *pDlgConfig = CDlgConfig::GetInstance();

	m_Activity = 0;

	if (m_pApp->IsDlgInFocus(m_ID))
	{
		m_Activity = GUI_DlgWork(&m_Dlg, nKey);
		switch (m_Activity)
		{
		case DLG_ABORT:
			m_pApp->SetDlgNewFocus(DialogId::MAIN);
			m_bIsVisible = false;
			break;
		case ID_PARAMETER:
			switch (m_Choice)
			{
			case ID_APP_INI:
				pDlgConfig->Create(m_pApp->m_AppIni);
				// TODO: Set parameters
				break;
			case ID_STR_INI:
				pDlgConfig->Create(m_pApp->GetPSStringsIni());
				m_pApp->InitStringTable();
				break;
			case ID_SIG_INI:
				pDlgConfig->Create(m_pApp->GetVicIni());// m_VicPs);
				break;
			case ID_ETH_INI:
				pDlgConfig->Create(m_pApp->m_EthernetIni);
				break;
			}
			m_pApp->SetDlgNewFocus(DialogId::CONFIG);
			m_bIsVisible = false;
			break;
		case ID_REBOOT:
			Enable(0);
			Show();
			if (m_pApp->MessageBox("\nReally reboot?\n\n", 1) == 1)
			{
				m_pApp->StopGrabTask();
				m_pApp->m_bAppActive = false;
			}
			Enable(1);
			break;
		case ID_LOG:
			m_pApp->SetDlgNewFocus(DialogId::LOG);
			m_bIsVisible = false;
			break;
		case ID_CLOCK:
			Enable(0);
			Show();
			SetTime();
			Enable(1);
			break;
		case ID_DIGIO:
			Enable(0);
			Show();
			m_pApp->SetDlgNewFocus(DialogId::DIGIO);
			Enable(1);
			m_bIsVisible = false;
			break;
		case ID_FULLSCREEN:
			m_pApp->PrepareFullScreen();
			break;
		case ID_INFO:
			m_pApp->StopGrabTask();
			Enable(0);
			Show();
			ShowInfo();
			Enable(1);
			m_pApp->StartGrabTask();
			break;
		case ID_FILEMANAGER:
			m_pApp->StopGrabTask();
			Enable(0);
			Show();
			CDlgFileMgr::GetInstance()->Run();
			Enable(1);
			m_pApp->StartGrabTask();
			m_pApp->RecBackground(1);
			break;
		case DLG_MOUSE_PRESSED:	// Handle mouse clicks in info and graph windows
			m_pApp->ChangeInfoArea(&m_Dlg);
			break;
		}
	}
	return m_Activity;
}

/*************************************************************************/
void CDlgTools::SetTime()
/*************************************************************************/
/*! @brief Function opens a dialog to set time in real time clock chip.

	The dialog is modal. The time from the real time clock chip is used
	for file time and date when writing to flash or SD card. The
	application does not use the time function.
**************************************************************************/
{
	const int iHeight = m_pApp->GetIcon(IconId::OK)->Height + 8;
	tm *sTime;
	time_t tTime;
	int Id;
	int Month, Year;
	int PosX, PosY;
	GUI_DLG *pDlgSetTime;

	// *** Get current time ***
	VIB_time(&tTime);
	sTime = localtime(&tTime);
	Month = sTime->tm_mon + 1;
	Year  = sTime->tm_year + 1900;

	// *** Create dialog ***
	GUI_DlgGetZeroZero(&m_Dlg, &PosX, &PosY);
	pDlgSetTime = new GUI_DLG;
	if (pDlgSetTime == NULL)
		return;
	GUI_DlgCreate2(pDlgSetTime, m_Dlg.rgbDlg.Width, m_Dlg.rgbDlg.Height - PosY, "Change date/time");
	GUI_DlgSetGradCol(pDlgSetTime, m_pApp->GetGradCol());
	GUI_DlgSetFlags(pDlgSetTime, DLG_NOSHADOW | DLG_GRADIENT);
	GUI_DlgAddLabel(pDlgSetTime,  8, PosY +   8, "_Day", 10);
	GUI_DlgAddText(pDlgSetTime, 120, PosY +   8, "(1-31)");
	GUI_DlgAddLabel(pDlgSetTime,  8, PosY +  38, "_Month", 11);
	GUI_DlgAddText(pDlgSetTime, 120, PosY +  38, "(1-12)");
	GUI_DlgAddLabel(pDlgSetTime,  8, PosY +  68, "_Year", 12);
	GUI_DlgAddText(pDlgSetTime, 120, PosY +  68, "(1980-2100)");
	GUI_DlgAddLabel(pDlgSetTime,  8, PosY +  98, "_Hour", 13);
	GUI_DlgAddText(pDlgSetTime, 120, PosY +  98, "(0-23)");
	GUI_DlgAddLabel(pDlgSetTime,  8, PosY + 128, "M_inute", 14);
	GUI_DlgAddText(pDlgSetTime, 120, PosY + 128, "(0-59)");
	GUI_DlgAddLabel(pDlgSetTime,  8, PosY + 158, "S_econd", 15);
	GUI_DlgAddText(pDlgSetTime, 120, PosY + 158, "(0-59)");

	GUI_DlgAddVEditBox(pDlgSetTime, 68, PosY +   6, 32, &sTime->tm_mday, 1, 31, 10);
	GUI_DlgAddVEditBox(pDlgSetTime, 68, PosY +  36, 32, &Month, 1, 12, 11);
	GUI_DlgAddVEditBox(pDlgSetTime, 68, PosY +  66, 40, &Year, 1980, 2100, 12);
	GUI_DlgAddVEditBox(pDlgSetTime, 68, PosY +  96, 32, &sTime->tm_hour, 0, 23, 13);
	GUI_DlgAddVEditBox(pDlgSetTime, 68, PosY + 126, 32, &sTime->tm_min, 0, 59, 14);
	GUI_DlgAddVEditBox(pDlgSetTime, 68, PosY + 156, 32, &sTime->tm_sec, 0, 59, 15);
	GUI_DlgAddIconButton(pDlgSetTime,   8, pDlgSetTime->rgbDlg.Height - iHeight,
		98, 98, "_OK", m_pApp->GetIcon(IconId::OK), 16);
	GUI_DlgAddIconButton(pDlgSetTime, 110, pDlgSetTime->rgbDlg.Height - iHeight,
		98, 98, "_Cancel", m_pApp->GetIcon(IconId::CANCEL), DLG_ABORT);

	Id = GUI_DlgModal(pDlgSetTime, m_pApp->GetDispImage(), 0, PosY + m_Dlg.y, m_fKB);
	GUI_DlgFree(pDlgSetTime);
	delete pDlgSetTime;

	// *** Set time ***
	if (Id != DLG_ABORT)
	{
		sTime->tm_mon  = Month - 1;
		sTime->tm_year = Year - 1900;
		/* tTime = */ mktime(sTime);
		VIB_SetTime((unsigned int)sTime->tm_hour, (unsigned int)sTime->tm_min,  (unsigned int)sTime->tm_sec);
		VIB_SetDate((unsigned int)sTime->tm_wday, (unsigned int)sTime->tm_mday, (unsigned int)sTime->tm_mon, (unsigned int)(sTime->tm_year - 100));
		VIB_WaitBios(1000);	// Real-Time-Clock needs rest
	}
}

/**************************************************************************/
void CDlgTools::ShowInfo()
/**************************************************************************/
/*! @brief Shows software and hardware information.
***************************************************************************/
{
	CCamFeatures *pCF = CCamFeatures::GetInstance();
	int LinkStatus = 0;
	int Id;
	float fTemp;
	GUI_DLG *pDlg;
	String Text;
	unsigned short Temperature;
	char ModuleSerialNumber[64];
	unsigned char MacAdr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
	MEM_Stat Stats;
	DRIVEINFO DInfo;

	Text = new char[4096];
	if (Text == NULL)
		return;

	VIB_GetModuleSerialNumber(ModuleSerialNumber);

	if (VIB_IICReadTemp(&Temperature))
		fTemp = 0.0;
	else
		fTemp = Temperature / 256.0;

	VIB_GetDriveInfo(VIB_Drive[1], &DInfo);
	MEM_stat(SDRAM1, &Stats);

	pDlg = new GUI_DLG;
	if (pDlg == NULL)
		goto FnExit;
	GUI_DlgCreate2(pDlg, 552, 298, "Information");
	GUI_DlgSetGradCol(pDlg, m_pApp->GetGradCol());
	m_pApp->SetTP(TextStyle::BOLD);
	GUI_DlgAddFrame(pDlg, 8,  32, 264, 220, "DSP-Module");
	GUI_DlgAddFrame(pDlg, 280, 32, 264, 144, "Camera-Module");
	GUI_DlgAddFrame(pDlg, 280, 188, 264,  64, "Memory");
	m_pApp->SetTP(TextStyle::NORMAL);

	if (m_pApp->GetEthError() == 0)
		GBIT_GetPhyInfo(MacAdr, &LinkStatus);
		
	GUI_SetTxtStyle(GUI_FSEXTEND);
	sprintf(Text, "%s\n"
				  "\\3S/N:\\0 %s\n"
				  "\\3DSP-Module-S/N:\\0 %s\n"
				  "\\3DSP:\\0 C%d   \\3Freq:\\0 %d MHz\n"
				  "\\3Bootloader:\\0 %d\n"
				  "\\3FPGA:\\0 %s\n"
				  "\\3IP address:\\0 %s\n"
				  "\\3MAC address:\\0 %02X-%02X-%02X-%02X-%02X-%02X\n"
				  "\\3Link:\\0 %s\n"
				  "\\3Temp:\\0 %d °C\n",
				  m_pApp->GetLibVersion(), m_pApp->GetSerialNumber(), ModuleSerialNumber,
				  VIB_HWInfo.CPU, VIB_HWInfo.Freq,
				  VIB_HWInfo.Bootloader, pCF->m_pAlteraFPGA->GetValueStr(), m_pApp->GetIPAdr(),
				  MacAdr[0], MacAdr[1], MacAdr[2], MacAdr[3], MacAdr[4], MacAdr[5],
				  (LinkStatus & PHY_1000MBPS) ? "1 GBit/s" : "100 MBit/s",
				  (unsigned int)fTemp);
	GUI_DlgAddTextBox(pDlg, 12, 48, 256, 156, Text, 0);

	sprintf(Text, "\\3Name:\\0 %s\n"
				  "\\3Typecode:\\0 %d\n"
				  "\\3Serial:\\0 %d\n"
				  "\\3FPGA Sensor:\\0 %s\n"
				  "\\3FPGA ADC:\\0 %s\n"
				  "\\3µC:\\0 %s\n",
				  pCF->m_pCameraName->GetValueStr(),
				  pCF->m_pInfoTypecode->GetValue(),
				  pCF->m_pInfoSerial->GetValue(),
				  pCF->m_pInfoFPGASensor->GetValueStr(),
				  pCF->m_pInfoFPGAAdc->GetValueStr(),
				  pCF->m_pInfouC->GetValueStr());
	GUI_DlgAddTextBox(pDlg, 284, 48, 256, 100, Text, 0);

	sprintf(Text, "\\3Free SD:\\0 %d [%d] MByte\n"
				  "\\3Free Mem:\\0 %d [%d] MByte\n",
				  DInfo.Free >> 10, DInfo.Size >> 10, Stats.length >> 20, Stats.size >> 20);
	GUI_DlgAddTextBox(pDlg, 284, 204, 256, 80, Text, 0);

	GUI_SetTxtStyle(GUI_FSNORMAL);
	GUI_DlgAddButton(pDlg, 226, 262, 80, 24, "_OK", 100);
	GUI_DlgAddButton(pDlg, 484, 262, 56, 24, "_More...", 10);
	Id = GUI_DlgModal(pDlg, m_pApp->GetDispImage(), -1, -1, m_fKB);
	if (Id == 10)
	{
		GUI_DlgEnable(pDlg, 0);
		GUI_DlgUpdate(pDlg, m_pApp->GetDispImage(), -1, -1);
	}
	GUI_DlgFree(pDlg);
	delete pDlg;

	if (Id == 10)
	{
		int i, Major, Minor;
		char Str[80];

		pDlg = new GUI_DLG;
		if (pDlg == NULL)
			goto FnExit;
		GUI_DlgCreate2(pDlg, 320, 240, "Libraries");
		GUI_DlgSetGradCol(pDlg, m_pApp->GetGradCol());

		Text[0] = '\0';
		GUI_SetTxtStyle(GUI_FSEXTEND);
		i = VIB_GetLibVersion(&Major, &Minor);
		if (i < 0)
			VIB_GetModuleVersions(Text);
		else if (i == 0)
			sprintf(Text, "\\3VIB_Lib:\\0  V%d.%d, %s\n", Major, Minor, VIB_LibDate);
		else if (i == 1)
			sprintf(Text, "\\3VIB_Lib:\\0  %d, %s\n", Minor, VIB_LibDate);

		i = GUI_GetLibVersion(&Major, &Minor);
		if (i == 0)
			sprintf(Str, "\\3GUI_Lib:\\0  V%d.%d, %s\n", Major, Minor, GUI_LibDate);
		else if (i == 1)
			sprintf(Str, "\\3GUI_Lib:\\0  %d, %s\n", Minor, GUI_LibDate);
		strcat(Text, Str);

		i = GBIT_GetLibVersion(&Major, &Minor);
		if (i == 0)
			sprintf(Str, "\\3GBIT_Lib:\\0  V%d.%d, %s\n", Major, Minor, GBIT_LibDate);
		else if (i == 1)
			sprintf(Str, "\\3GBIT_Lib:\\0  %d, %s\n", Minor, GBIT_LibDate);
		strcat(Text, Str);

		PNG_SprintLibInfo(Str);
		strcat(Text, Str);
		JPEG_SprintLibInfo(Str);
		strcat(Text, Str);
#if (USE_FREETYPE == 1)
		GUI_FTSprintLibInfo(Str);
		strcat(Text, Str);
#endif
		sprintf(Str, "\\3TinyXML:\\0 V%d.%d.%d\n", TIXML_MAJOR_VERSION, TIXML_MINOR_VERSION, TIXML_PATCH_VERSION);
		strcat(Text, Str);
		sprintf(Str, "\\3CG-Tools:\\0 %d\n", __TI_COMPILER_VERSION__);
		strcat(Text, Str);

		GUI_DlgAddTextBox(pDlg, 12, 36, 256, 140, Text, 0);
		GUI_SetTxtStyle(GUI_FSNORMAL);
		GUI_DlgAddButton(pDlg, 120, 204, 80, 24, "_OK", 100);
		GUI_DlgModal(pDlg, m_pApp->GetDispImage(), -1, -1, m_fKB);
		GUI_DlgFree(pDlg);
		delete pDlg;
	}

FnExit:
	delete [] Text;
	m_pApp->RecBackground(1);
}

/**************************************************************************/
