// Infopage.cpp : implementation file
//

#include "stdafx.h"
#include "DTC_C++Demo.h"
#include "MainSheet.h"
#include "Infopage.h"
#include "PrinterSettings.h"
#include "DriverSettings2.h"
#include "afxdialogex.h"

//#############################################################################

//************************************
//*** Rio Pro 360 Parameter Access ***
//************************************

//Rio Pro 360 Strings to be accessed using ID_AccessBuffer, not ID_AccessString
//Comment out the next line to access using CString
#define GET_BUFFER_AS_STRING

enum ParamType { AsBool, AsInt, AsString };

typedef struct
{
	CString      Text;
	PRO360_PARAM ID;
    ParamType    Type;
} PARAMSET, *PPARAMSET;

PARAMSET ParamSet[] = {
	{"Duplex",				 OP_CAPABILITY_DUPLEX,			AsBool}, 
	{"Mag Encoding",		 OP_CAPABILITY_MAG,				AsBool}, 
	{"Smart Encoding",		 OP_CAPABILITY_SMART,			AsBool}, 
	{"System Version",		 OP_VERSION_SYSTEM,				AsString}, 
	{"Printer App Vers.",	 OP_VERSION_PRINTER_APP,		AsString}, 
	{"Firmware Version",	 OP_VERSION_FIRMWARE,			AsString}, 
	{"Mag Firmware Vers.",	 OP_VERSION_MAG_FIRMWARE,		AsString}, 
	{"Printer Serial",		 OP_SERIAL_PRINTER,				AsString}, 
	{"Printhead Serial",	 OP_SERIAL_PRINTHEAD,			AsString}, 
	{"Main Board Serial",	 OP_SERIAL_BOARD,				AsString}, 
	{"Model Name",			 OP_MODEL_NAME,					AsString}, 
	{"Dealer Code",			 OP_PRINTER_DEALER_CODE,		AsInt}, 
	{"Project Code",		 OP_PRINTER_PROJECT_CODE,		AsInt}, 
	{"Total Cards",			 OP_STATS_TOTAL_CARDS,			AsInt}, 
	{"Total Panels",		 OP_STATS_TOTAL_PANELS,			AsInt}, 
	{"Cards on Printhead",	 OP_STATS_PRINTHEAD_CARDS,		AsInt}, 
	{"Panels on Printhead",	 OP_STATS_PRINTHEAD_PANELS,		AsInt}, 
	{"Cards since Clean",	 OP_STATS_CARDS_SINCE_CLEAN,	AsInt}, 
	{"Panels since Clean",	 OP_STATS_PANELS_SINCE_CLEAN,	AsInt}, 
	{"Cleaning Cycles",		 OP_STATS_CLEANS,				AsInt}, 
	{"Dyefilm Name",		 OP_DYE_NAME,					AsString}, 
	{"Dyefilm Serial",		 OP_DYE_SERIAL,					AsString}, 
	{"Dyefilm Prints",		 OP_DYE_PRINTS_TOTAL,			AsInt}, 
	{"Dyefilm Prints Left",	 OP_DYE_PRINTS_REMAINING,		AsInt}, 
	{"Dyefilm Manu.",		 OP_DYE_MANUFACTURER,			AsInt}, 
	{"Dyefilm YMC Length",	 OP_YMC_LENGTH,					AsInt}, 
	{"Dyefilm K Length",	 OP_K_LENGTH,					AsInt}, 
	{"Dyefilm O Length",	 OP_O_LENGTH,					AsInt}, 
	{"Cards between Cleans", OP_CLEAN_CARDS_INTERVAL,		AsInt}, 
	{"Clean Overdue",		 OP_CLEAN_OVERDUE,				AsBool}, 
	{"MAC Address",			 OP_NET_MAC_ADDRESS,			AsString}, 
	{"Use DHCP",			 OP_NET_USE_DHCP,				AsBool}, 
	{"IP Address",			 OP_NET_IP_ADDRESS,				AsString}, 
	{"IP Gateway",			 OP_NET_GATEWAY,				AsString}, 
	{"IP Subnet",			 OP_NET_SUBNET,					AsString}, 
	{"Static IP Address",	 OP_NET_STATIC_IP,				AsString}, 
	{"Static IP Gateway",	 OP_NET_STATIC_GATEWAY,			AsString}, 
	{"Static IP Subnet",	 OP_NET_STATIC_SUBNET,			AsString}, 
	{"Error Status",		 OP_ERROR,						AsString}, 
	{"Hand Feed",			 OP_HAND_FEED,					AsBool}, 
	{"Card Position",		 OP_CARD_LOCATION,				AsString}, 
	{"Mag Enc. Start",		 OP_MAG_START,					AsInt}, 
	{"Contactless Offset",	 OP_SMART_OFFSET,				AsInt}, 
	{"HoloKote Slots",	     OP_HOLOKOTE_SLOTS,				AsInt},
	{"600 dpi",	             OP_CAPABILITY_600DPI,			AsBool},
	{"Hopper Sensor",	     OP_HOPPER_SENSOR,  			AsBool},
	{"Exit Sensor",	         OP_EXIT_SENSOR,			    AsBool},
	{"Lid Sensor",	         OP_LID_SENSOR,     			AsBool},
	{"Manufacturer",         OP_MANUFACTURER,				AsString}, 
	{"Hopper Sensor Fitted", OP_HOPPER_SENSOR_FITTED,  		AsBool},
	{"Exit Sensor Fitted",	 OP_EXIT_SENSOR_FITTED,			AsBool},
	{"Region",				 OP_REGION,						AsInt},
};
#define MAX_PARAM _countof(ParamSet)

//#############################################################################

// CInfoPage dialog
IMPLEMENT_DYNAMIC(CInfoPage, CPropertyPage)

CInfoPage::CInfoPage() : CPropertyPage(CInfoPage::IDD)
{
}

CInfoPage::~CInfoPage()
{
}

void CInfoPage::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_INFOMSG, InfoMessage);
	DDX_Control(pDX, IDC_BTN_PRINTERMODEL, PrinterModelBtn);
	DDX_Control(pDX, IDC_PASSWORD1, Password1Edit);
	DDX_Control(pDX, IDC_PASSWORD2, Password2Edit);
	DDX_Control(pDX, IDC_PWDCMD_COMBO, PasswordCombo);
	DDX_Control(pDX, IDC_LABEL_PASSWORD1, Password1Label);
	DDX_Control(pDX, IDC_LABEL_PASSWORD2, Password2Label);
	DDX_Control(pDX, IDC_BTN_LASTMESSAGE, LastMessageBtn);
	DDX_Control(pDX, IDC_BTN_PRINTERINFO, PrinterInfoBtn);
	DDX_Control(pDX, IDC_BTN_PWD_CMD, PasswordBtn);
	DDX_Control(pDX, IDC_BTN_GETPARAM, ParamBtn);
	DDX_Control(pDX, IDC_PARAM_COMBO, ParamCombo);
	DDX_Control(pDX, IDC_PRO360PARAMS, Generation2GroupBox);
	DDX_Control(pDX, IDC_LABEL_PARAMETERS, ParameterLabel);
	DDX_Control(pDX, IDC_BTN_ALL_PARAMS, AllParamsBtn);
}

BEGIN_MESSAGE_MAP(CInfoPage, CPropertyPage)
	ON_BN_CLICKED(IDC_BTN_PRINTERSTATUS,  &CInfoPage::OnBnClickedPrinterStatusBtn)
	ON_BN_CLICKED(IDC_BTN_PRINTERINFO,    &CInfoPage::OnBnClickedPrinterInfoBtn)
	ON_BN_CLICKED(IDC_BTN_INFOMSG_CLR,    &CInfoPage::OnBnClickedInfoMsgClrBtn)
	ON_BN_CLICKED(IDC_BTN_GETVERSION,     &CInfoPage::OnBnClickedSDKVersionBtn)
	ON_BN_CLICKED(IDC_BTN_CONNECTIONTYPE, &CInfoPage::OnBnClickedConnectionTypeBtn)
	ON_BN_CLICKED(IDC_BTN_PRINTERMODEL,   &CInfoPage::OnBnClickedPrinterModelBtn)
	ON_BN_CLICKED(IDC_BTN_LASTMESSAGE,    &CInfoPage::OnBnClickedLastMessageBtn)
	ON_BN_CLICKED(IDC_BTN_PWD_CMD,        &CInfoPage::OnBnClickedPwdSendBtn)
	ON_CBN_SELCHANGE(IDC_PWDCMD_COMBO,    &CInfoPage::OnCbnSelchangePwdcmdCombo)
	ON_BN_CLICKED(IDC_BTN_SDKBITS,        &CInfoPage::OnBnClickedSDKBitsBtn)
	ON_BN_CLICKED(IDC_BTN_GETPARAM,       &CInfoPage::OnBnClickedParamBtn)
	ON_BN_CLICKED(IDC_BTN_ALL_PARAMS,     &CInfoPage::OnBnClickedAllParamsBtn)
	ON_BN_CLICKED(IDC_BTN_PRINTERTYPE, &CInfoPage::OnBnClickedBtnPrintertype)
	ON_BN_CLICKED(IDC_BTN_SENSORS, &CInfoPage::OnBnClickedBtnSensors)
END_MESSAGE_MAP()

//#############################################################################

// CInfoPage message handlers
BOOL CInfoPage::OnInitDialog()
{
	CPropertyPage::OnInitDialog();

	Parent = (CMainSheet *)GetParent();

	PasswordCombo.SetCurSel(0);

	for (int i = 0; i < MAX_PARAM; i++)
	{
		ParamCombo.AddString(ParamSet[i].Text);
	}
	ParamCombo.SetCurSel(0);

	return TRUE;  // return TRUE  unless you set the focus to a control
}

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

BOOL CInfoPage::OnSetActive()
{
	CPropertyPage::OnSetActive();

	BOOL bControl = (Parent->PrinterType != ID_GENERATION2);

	//PasswordBtn.EnableWindow(bControl);
	//Password1Edit.EnableWindow(bControl);
	//Password2Edit.EnableWindow(bControl);
	//PasswordCombo.EnableWindow(bControl);
	//Password1Label.EnableWindow(bControl);
	//Password2Label.EnableWindow(bControl);

	Generation2GroupBox.ShowWindow(!bControl);
	ParameterLabel.ShowWindow(!bControl);
	ParamBtn.ShowWindow(!bControl);
	AllParamsBtn.ShowWindow(!bControl);
	ParamCombo.ShowWindow(!bControl);

	return TRUE;
}

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

void CInfoPage::OutputBurstMessage(TCHAR *str)
{
	int end;
	TCHAR temp[2] = {0, 0};

	while (*str != '\0')
	{
		end = InfoMessage.GetWindowTextLength();
		InfoMessage.SetSel(end, end);
		if (*str == '\n')
		{
			InfoMessage.ReplaceSel(_T("\r\n"));
		}
		else
		{
			temp[0] = *str;
			InfoMessage.ReplaceSel(temp);
		}
		str++;
	}

	//Extra Line Feed at end
	InfoMessage.ReplaceSel(_T("\r\n\r\n"));
}

void CInfoPage::OnBnClickedInfoMsgClrBtn()
{
	InfoMessage.SetWindowText(_T(""));
}

void CInfoPage::AddInfoMessage(CString pMessage)
{
	Parent->AddString(&InfoMessage, pMessage);
}

CString CInfoPage::TrueFalseString
(
	BOOL Bool
)
{
	return Bool ? _T("True") : _T("False");
}

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

void CInfoPage::OnCbnSelchangePwdcmdCombo()
{
	if ((ID_PASSWORDCMD)PasswordCombo.GetCurSel() == ID_PWDUSE)
	{
		Password2Label.EnableWindow(FALSE);
		Password2Edit.EnableWindow(FALSE);
	}
	else
	{
		Password2Label.EnableWindow(TRUE);
		Password2Edit.EnableWindow(TRUE);
	}
}

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

void CInfoPage::OnBnClickedLastMessageBtn()
{
	//Get SDK function address
	PFNIDLASTMSG pFnLastMessage = (PFNIDLASTMSG)GetProcAddress(Parent->hLib, IDFN_LASTMESSAGE);
	if (!pFnLastMessage)
	{
		FUNCTION_NOT_ACCESSED(GetLastMessage);
	}

	else
	{
		//Call the SDK to get the buffer size
		DWORD dwMsgSize = 0;
		int SDKReturn = (*pFnLastMessage)(Parent->hSession, NULL, &dwMsgSize);
		if (SDKReturn != ID_MORE_DATA)
		{
			DISPLAY_ERROR(GetLastMessageSize, SDKReturn);
		}
		else
		{
			//Allocate the buffer
			TCHAR *szMessage = new TCHAR[dwMsgSize];

			//Call the SDK to get the last message
			int SDKReturn = (*pFnLastMessage)(Parent->hSession, szMessage, &dwMsgSize);
			if (SDKReturn != ID_SUCCESS)
			{
				DISPLAY_ERROR(GetLastMessage, SDKReturn);
			}
			else
			{
				//Update the message box
				OutputBurstMessage(szMessage);
			}

			delete[] szMessage;
		}
	}
}

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

void CInfoPage::OnBnClickedPrinterStatusBtn()
{
	CWaitCursor wait;

	//Get SDK function address
	PFNIDSTATUS pFnPrinterStatus = (PFNIDSTATUS)GetProcAddress(Parent->hLib, "ID_PrinterStatus");
	if (!pFnPrinterStatus)
	{
		FUNCTION_NOT_ACCESSED(GetPrinterStatus);
	}

	else
	{
		//Call the SDK to get the printer status
		int SDKReturn = (*pFnPrinterStatus)(Parent->hSession);

		//Update the message box
		CString temp_string;
		switch (SDKReturn)
		{
		case ID_STATUS_READY:   temp_string = _T("READY");   break;
		case ID_STATUS_OFFLINE: temp_string = _T("OFFLINE"); break;
		case ID_STATUS_ERROR:   temp_string = _T("ERROR");   break;
		case ID_STATUS_BUSY:    temp_string = _T("BUSY");    break;
		}

		AddInfoMessage(_T("Printer: ") + temp_string);
		AddInfoMessage(_T(""));
	}
}

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

void CInfoPage::OnBnClickedPrinterInfoBtn()
{
	PRINTER_INFO PrinterInfo;
	CWaitCursor  wait;

	//Get SDK function address
	PFNIDPRINTERINFO pFnPrinterInfo = (PFNIDPRINTERINFO)GetProcAddress(Parent->hLib, "ID_PrinterInfo");
	if (!pFnPrinterInfo)
	{
		FUNCTION_NOT_ACCESSED(ID_PrinterInfo);
		return;
	}

	//Call the SDK to get the Printer Info
	int SDKReturn = (*pFnPrinterInfo)(Parent->hSession, &PrinterInfo);
	if (SDKReturn != ID_SUCCESS)
	{
		DISPLAY_ERROR(GetPrinterInfo, SDKReturn);
		return;
	}

	//Output to the message box
	AddInfoMessage(_T("PrinterConnected: ") + TrueFalseString(PrinterInfo.bPrinterConnected));

	CString temp_string;
	temp_string.Format(_T("Model Code: %d"), PrinterInfo.eModel);
	AddInfoMessage(temp_string);

	AddInfoMessage(_T("Model: ") + CString(PrinterInfo.sModel, sizeof(PrinterInfo.sModel)));

	temp_string.Format(_T("PrintheadType: %d"), PrinterInfo.ePrintheadType);
	AddInfoMessage(temp_string);

	AddInfoMessage(_T("PrinterSerial: ") + CString(PrinterInfo.sPrinterSerial, sizeof(PrinterInfo.sPrinterSerial)));

	AddInfoMessage(_T("PrintheadSerial: ") + CString(PrinterInfo.sPrintheadSerial, sizeof(PrinterInfo.sPrintheadSerial)));

	AddInfoMessage(_T("PCBSerial: ") + CString(PrinterInfo.sPCBSerial, sizeof(PrinterInfo.sPCBSerial)));

	AddInfoMessage(_T("FirmwareVersion: ") + CString(PrinterInfo.sFirmwareVersion, sizeof(PrinterInfo.sFirmwareVersion)));

	temp_string.Format(_T("Density: %d"), PrinterInfo.iDensity);
	AddInfoMessage(temp_string);

	AddInfoMessage(_T("HandFeed: ") + TrueFalseString(PrinterInfo.iHandFeed));

	temp_string.Format(_T("CardsPrinted: %d"), PrinterInfo.iCardsPrinted);
	AddInfoMessage(temp_string);

	temp_string.Format(_T("CardsOnPrinthead: %d"), PrinterInfo.iCardsOnPrinthead);
	AddInfoMessage(temp_string);

	temp_string.Format(_T("DyePanelsPrinted: %d"), PrinterInfo.iDyePanelsPrinted);
	AddInfoMessage(temp_string);

	temp_string.Format(_T("CleansSinceShipped: %d"), PrinterInfo.iCleansSinceShipped);
	AddInfoMessage(temp_string);

	temp_string.Format(_T("DyePanelsSinceClean: %d"), PrinterInfo.iDyePanelsSinceClean);
	AddInfoMessage(temp_string);

	temp_string.Format(_T("CardsSinceClean: %d"), PrinterInfo.iCardsSinceClean);
	AddInfoMessage(temp_string);

	temp_string.Format(_T("CardsBetweenCleans: %d"), PrinterInfo.iCardsBetweenCleans);
	AddInfoMessage(temp_string);

	temp_string.Format(_T("PrintHeadPosn: %d"), PrinterInfo.iPrintHeadPosn);
	AddInfoMessage(temp_string);

	temp_string.Format(_T("ImageStartPosn: %d"), PrinterInfo.iImageStartPosn);
	AddInfoMessage(temp_string);

	temp_string.Format(_T("ImageEndPosn: %d"), PrinterInfo.iImageEndPosn);
	AddInfoMessage(temp_string);

	temp_string.Format(_T("MajorError: %d"), PrinterInfo.iMajorError);
	AddInfoMessage(temp_string);

	temp_string.Format(_T("MinorError: %d"), PrinterInfo.iMinorError);
	AddInfoMessage(temp_string);

	AddInfoMessage(_T("TagUID: ") + CString(PrinterInfo.sTagUID, sizeof(PrinterInfo.sTagUID)));

	temp_string.Format(_T("ShotsOnFilm: %d"), PrinterInfo.iShotsOnFilm);
	AddInfoMessage(temp_string);

	temp_string.Format(_T("ShotsUsed: %d"), PrinterInfo.iShotsUsed);
	AddInfoMessage(temp_string);

	AddInfoMessage(_T("DyeFilmType: ") + CString(PrinterInfo.sDyeFilmType, sizeof(PrinterInfo.sDyeFilmType)));

	temp_string.Format(_T("DyeFilmManuf: %d"), PrinterInfo.eDyeFilmManuf);
	AddInfoMessage(temp_string);

	temp_string.Format(_T("ColourLength: %d"), PrinterInfo.iColourLength);
	AddInfoMessage(temp_string);

	temp_string.Format(_T("ResinLength: %d"), PrinterInfo.iResinLength);
	AddInfoMessage(temp_string);

	temp_string.Format(_T("OvercoatLength: %d"), PrinterInfo.iOvercoatLength);
	AddInfoMessage(temp_string);

	AddInfoMessage(_T("Eject Mode: ") + Parent->OnOffString(PrinterInfo.iBitFields & ID_MASK_EJECTMODE));
	temp_string.Format(_T("DyeFlags: %d"), PrinterInfo.eDyeFlags);
	AddInfoMessage(temp_string);

	temp_string.Format(_T("CommandCode: %d"), PrinterInfo.iCommandCode);
	AddInfoMessage(temp_string);

	temp_string.Format(_T("DOB: %d"), PrinterInfo.iDOB);
	AddInfoMessage(temp_string);

	temp_string.Format(_T("DyeFilmProg: %d"), PrinterInfo.eDyeFilmProg);
	AddInfoMessage(temp_string);

	switch (PrinterInfo.iBitFields & ID_MASK_ENCODEMODE)
	{
	case ID_MASK_ENCODEDEFAULT: temp_string = CPrinterSettings::SmartModeString(ID_SMART_DEFAULT); break;
	case ID_MASK_ENCODEPLATEN:  temp_string = CPrinterSettings::SmartModeString(ID_SMART_PLATEN);  break;
	case ID_MASK_ENCODEXLI:     temp_string = CPrinterSettings::SmartModeString(ID_SMART_XLI);     break;
	default:					temp_string = CPrinterSettings::SmartModeString((ID_SMARTMODE)-1); break;
	}
	AddInfoMessage(_T("Smart Mode: ") + temp_string);

	temp_string.Format(_T("Smart Offset: %d"), PrinterInfo.iSmartOffset);
	AddInfoMessage(temp_string);

	AddInfoMessage(_T("Eject Mode: ") + Parent->OnOffString(PrinterInfo.iBitFields & ID_MASK_EJECTMODE));

	AddInfoMessage(_T("Horz Eject Mode: ") + Parent->OnOffString(PrinterInfo.iBitFields & ID_MASK_HORZEJECT));

	AddInfoMessage(_T("Erase Speed: ") + Parent->EraseSpeedString((ID_ERASESPEED)((PrinterInfo.iBitFields & ID_MASK_ERASESPEED) >> 2)));

	AddInfoMessage(_T(" "));
}

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

void CInfoPage::OnBnClickedSDKVersionBtn()
{
	CWaitCursor wait;

	//Get SDK function address
	PFNIDVERSION pFnVersion = (PFNIDVERSION)GetProcAddress(Parent->hLib, "ID_SDKVersion");
	if (!pFnVersion)
	{
		FUNCTION_NOT_ACCESSED(GetSDKVersion);
	}

	else
	{
		//Call the SDK to get the version information
		SDKVERSION SDKVersion;
		int SDKReturn = (*pFnVersion)(Parent->hSession, &SDKVersion);
		if (SDKReturn != ID_SUCCESS)
		{
			DISPLAY_ERROR(GetVersion, SDKReturn);
		}

		else
		{
			//Update the message box
			CString sMsg;
			sMsg.Format(_T("Version: %d.%d.%d.%d"), SDKVersion.Major,
													SDKVersion.Minor,
													SDKVersion.Build,
													SDKVersion.Private);
			AddInfoMessage(sMsg);
			AddInfoMessage(_T(" "));
		}
	}
}

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

void CInfoPage::OnBnClickedConnectionTypeBtn()
{
	CWaitCursor wait;

	//Get SDK function address
	PFNIDCONNECTION pFnConnection = (PFNIDCONNECTION)GetProcAddress(Parent->hLib, "ID_ConnectionType");
	if (!pFnConnection)
	{
		FUNCTION_NOT_ACCESSED(ConnectionType);
	}

	else
	{
		//Call the SDK to get the connection type
		int SDKReturn = (*pFnConnection)(Parent->hSession);

		//Update the message box
		switch (SDKReturn)
		{
		case ID_PORT_USB: 	AddInfoMessage(_T("Connection: USB"));      break;
		case ID_PORT_TCPIP: AddInfoMessage(_T("Connection: ETHERNET")); break;
		case ID_PORT_FILE:  AddInfoMessage(_T("Connection: FILE"));     break;
		default:            AddInfoMessage(_T("Connection: UNKNOWN"));  break;
		}

		AddInfoMessage(_T(" "));
	}
}

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

void CInfoPage::OnBnClickedBtnPrintertype()
{
	//Get the SDK function address
	PFNIDPRNTYPE pFnPrnType = (PFNIDPRNTYPE)GetProcAddress(Parent->hLib, "ID_PrinterType");
	if (!pFnPrnType)
	{
		FUNCTION_NOT_ACCESSED(PrinterType);
	}

	else
	{
		//Call the SDK to get the printer model
		switch ((*pFnPrnType)(Parent->hSession))
		{
		case ID_RIOTANGO:    AddInfoMessage(_T("Printer Type - RioTango"));            break;
		case ID_AOTA:        AddInfoMessage(_T("Printer Type - Aota"));                break;
		case ID_ENDURO:      AddInfoMessage(_T("Printer Type - Enduro Family"));       break;
		case ID_ULTIMA:      AddInfoMessage(_T("Printer Type - Ultima"));              break;
		case ID_GENERATION2: AddInfoMessage(_T("Printer Type - Generation 2 Family")); break;
		default:             AddInfoMessage(_T("Printer Type - UNKNOWN"));             break;
		}
		AddInfoMessage(_T(" "));
	}
}

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

void CInfoPage::OnBnClickedPrinterModelBtn()
{
	//Get the SDK function address
	PFNIDPRNMODEL pFnPrnModel = (PFNIDPRNMODEL)GetProcAddress(Parent->hLib, "ID_PrinterModel");
	if (!pFnPrnModel)
	{
		FUNCTION_NOT_ACCESSED(PrinterModel);
	}

	else
	{
		//Call the SDK to get the printer model
		DWORD model = (*pFnPrnModel)(Parent->hSession);

		if      (model & ID_MOD_PRONTO)    AddInfoMessage(_T("Printer - Pronto"));
		else if (model & ID_MOD_RIOPRO)    AddInfoMessage(_T("Printer - Rio Pro"));
		else if (model & ID_MOD_ULTIMA)    AddInfoMessage(_T("Printer - Ultima"));
		else if (model & ID_MOD_ENDURO)    AddInfoMessage(_T("Printer - Enduro"));
		else if (model & ID_MOD_PRO360)    AddInfoMessage(_T("Printer - Rio Pro 360"));
		else if (model & ID_MOD_600)       AddInfoMessage(_T("Printer - 600"));
		else if (model & ID_MOD_300)       AddInfoMessage(_T("Printer - 300"));
		else if (model & ID_MOD_GEN2)      AddInfoMessage(_T("Printer - Generation 2"));
		else if (model & ID_MOD_PRONTO100) AddInfoMessage(_T("Printer - Pronto 100"));
		else                               AddInfoMessage(_T("Printer - Unknown"));

		AddInfoMessage(_T("Capability:"));
		if (model & ID_FN_MAGNETIC)    AddInfoMessage(_T("  - Mag Encoding"));
		if (model & ID_FN_DUPLEX)      AddInfoMessage(_T("  - Duplex"));
		if (model & ID_FN_REWRITE)     AddInfoMessage(_T("  - Rewrite"));
		if (model & ID_FN_CHIP)        AddInfoMessage(_T("  - Chip Encoding"));
		if (model & ID_FN_XTENDED)     AddInfoMessage(_T("  - Extended"));
		if (model & ID_FN_ETHERNET)    AddInfoMessage(_T("  - Ethernet"));
		if (model & ID_FN_CONTACTLESS) AddInfoMessage(_T("  - Contactless Encoding"));
		if (model & ID_FN_LAMINATE)    AddInfoMessage(_T("  - Laminator"));
		if (model & ID_FN_600DPI)      AddInfoMessage(_T("  - 600 dpi"));

		AddInfoMessage(_T(" "));
	}
}

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

void CInfoPage::OnBnClickedSDKBitsBtn()
{
	//Get the SDK function address
	PFNIDSDKBITS pFnSDKBits = (PFNIDSDKBITS)GetProcAddress(Parent->hLib, "ID_SDKBits");
	if (!pFnSDKBits)
	{
		FUNCTION_NOT_ACCESSED(SDKBits);
	}
	else
	{
		CString tempString;
		tempString.Format(_T("%d"), (*pFnSDKBits)());
		AddInfoMessage(tempString + _T(" Bit SDK"));
		AddInfoMessage(_T(""));
	}
}

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

void CInfoPage::OnBnClickedPwdSendBtn()
{
	//Get the SDK function address
	PFNIDPASSWORD pFnPassword = (PFNIDPASSWORD)GetProcAddress(Parent->hLib, IDFN_PASSWORD);
	if (!pFnPassword)
	{
		FUNCTION_NOT_ACCESSED(Password);
	}

	else
	{
		CString Pwd1, Pwd2;
		Password1Edit.GetWindowText(Pwd1);
		Password2Edit.GetWindowText(Pwd2);

		//Call the SDK to send the password command to the printer
		ID_RETURN SDKReturn = (*pFnPassword)(Parent->hSession,
											 (ID_PASSWORDCMD)PasswordCombo.GetCurSel(),
											 Pwd1.GetBuffer(),
											 Pwd2.GetBuffer());
		if (SDKReturn != ID_SUCCESS)
		{
			DISPLAY_ERROR(ErrorResponse, SDKReturn);
		}
	}
}

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

void CInfoPage::Get360Param
(
	void *paramptr
)
{
	ID_RETURN SDKReturn = ID_ERROR;
	CString	  tempString;
	PPARAMSET ptr = (PPARAMSET)paramptr;
	PFNIDACCINT    pFnAccInt    = (PFNIDACCINT)GetProcAddress(Parent->hLib,    "ID_AccessInt");
	PFNIDACCBOOL   pFnAccBool   = (PFNIDACCBOOL)GetProcAddress(Parent->hLib,   "ID_AccessBool");
	PFNIDACCSTRING pFnAccString = (PFNIDACCSTRING)GetProcAddress(Parent->hLib, "ID_AccessString");
	PFNIDACCBUFF   pFnAccBuffer = (PFNIDACCBUFF)GetProcAddress(Parent->hLib,   "ID_AccessBuffer");
	if (!pFnAccInt || !pFnAccBool || !pFnAccString || !pFnAccBuffer)
	{
		FUNCTION_NOT_ACCESSED(Get360pParam);
		return;
	}

	switch (ptr->Type)
    {
    case AsInt:
		{
			int tempint;
			SDKReturn = (*pFnAccInt)(Parent->hSession, ID_READ, ptr->ID, &tempint);
			tempString.Format(_T("%d"), tempint);
		}
        break;

    case AsBool:
		{
			bool tempbool;
			SDKReturn = (*pFnAccBool)(Parent->hSession, ID_READ, ptr->ID, &tempbool);
			tempString = tempbool ? _T("TRUE") : _T("FALSE");
		}
        break;

    default:
#ifdef GET_BUFFER_AS_STRING
		SDKReturn = (*pFnAccString)(Parent->hSession, ID_READ, ptr->ID, tempString);
#else
		{
			int size = 0;
			SDKReturn = (*pFnAccBuffer)(Parent->hSession, ID_READ, ptr->ID, NULL, &size);
			if (SDKReturn == ID_MORE_DATA)
			{
				char *buffer = new char[size];
				SDKReturn = (*pFnAccBuffer)(Parent->hSession, ID_READ, ptr->ID, buffer, &size);
				tempString = CString(buffer, size);
			}
		}
#endif
		break;
    }

    if (SDKReturn != ID_SUCCESS)
    {
		DISPLAY_ERROR(Get360Param, SDKReturn);
    }
    else
    {
        AddInfoMessage(ptr->Text + Parent->Separator(ID_READ) + tempString);
    }
}

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

void CInfoPage::OnBnClickedParamBtn()
{
	Get360Param(&ParamSet[ParamCombo.GetCurSel()]);
	AddInfoMessage(_T(""));
}

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

void CInfoPage::OnBnClickedAllParamsBtn()
{
    for (int i = 0; i < MAX_PARAM; i++)
    {
		Get360Param(&ParamSet[i]);
    }
    AddInfoMessage(_T(""));
}

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

void CInfoPage::OnBnClickedBtnSensors()
{
	PFNIDSENSORS pFnSensors = (PFNIDSENSORS)GetProcAddress(Parent->hLib, "ID_Sensors");
	if (!pFnSensors)
	{
		FUNCTION_NOT_ACCESSED(Sensors);
	}

	else
	{
		DWORD response = 0;
		ID_RETURN SDKReturn = (*pFnSensors)(Parent->hSession, &response);
		if (SDKReturn != ID_SUCCESS)
		{
			DISPLAY_ERROR(Sensors, SDKReturn);
		}
		else
		{
			AddInfoMessage(_T("Sensors:"));
			if (response & ID_LID_SENSOR) 
				AddInfoMessage(_T("- Lid Closed"));
			else
				AddInfoMessage(_T("- Lid Open"));
			
			if ((response & ID_HOPPER_SENSOR_VALID) == 0)
				AddInfoMessage(_T("- Hopper Sensor Not Fitted\n"));
			else if (response & ID_HOPPER_SENSOR)
				AddInfoMessage(_T("- Cards in Hopper"));
			else 
				AddInfoMessage(_T("- Cards Low"));
			
			if ((response & ID_EXIT_SENSOR_VALID) == 0)
				AddInfoMessage(_T("- Exit Sensor Not Fitted\n"));
			else if (response & ID_EXIT_SENSOR)
				AddInfoMessage(_T("- Exit Blocked"));
			else 
				AddInfoMessage(_T("- Exit Clear"));

			AddInfoMessage(_T(" "));
		}
	}
}
