/*************************************************************************\
* "$RCSfile: CDlgCamExpert.cpp,v $"                                       *
***************************************************************************
* Information by CVS or VSS:                                              *
*     Last check in on: $Date: 2010/06/14 08:47:29 $                      *
*     by                $Author: schluckebier $
*     Revision        : $Revision: 1.20 $                                 *
\*************************************************************************/
/*! \file CDlgCamExpert.cpp
*	\brief Implementation CDlgCamExpert Class
**************************************************************************/

#include "VIC_PS.h"
#include "CRegion.h"
#include "CLog.hpp"
#include "CPSApp.hpp"
#include "CDlg.hpp"
#include "pfcam.h"
#include "pftypes.h"
#include "CFeature.hpp"
#include "CDlgCamExpert.hpp"

//!@cond SHOWALL
extern "C"
{
	TOKEN findProperty_ByName(TOKEN Parent, const char *pPropName);
	int WriteCom(int Port, unsigned char *pBuff, unsigned long Size);
	int ReadComWait(int Port, unsigned char *pBuff, unsigned long Size, unsigned long TimeMax);
	int resetCachedValues(int Port);
	int xsvfExecute();
	int JTAG_Init();
	int JTAG_Write(unsigned int TMS, unsigned int TDI, int BitCount);
	int JTAGInit();
}
TOKEN pfDevice_GetRoot(int);

enum ePROP
{
	PROP_VALUE_X = 50,
	PROP_VALUE_Y = 50,
	PROP_VALUE_WIDTH = 300,
	PROP_VALUE_HEIGHT = 24,
	PROP_VALUE_BORDER = 2
};

unsigned char *fwUpdateBuffer = NULL;
//!@endcond

PROPERTY CDlgCamExpert::m_PropertyList[CFeature::MAXPROPERTIES];	//!< List of camera properties
CDlgCamExpert *CDlgCamExpert::m_pThis = NULL;	//!< The one and only CDlgCamExpert instance

/*************************************************************************/
CDlgCamExpert::CDlgCamExpert(int x, int y, int Width, int Height) :
	CDlg(x, y, Width, Height, DialogId::CAMEX)
/*************************************************************************/
/*! @brief Constructor
**************************************************************************/
{
	TOKEN t;

	GUI_DlgSetTitle(&m_Dlg, m_pStrings->getValue("DlgCamTitle", "Camera Properties"));
	m_Sel = 1;

	m_PropText = (char*)VIB_MemAlloc(1024 * 8);

	t = pfDevice_GetRoot(m_pApp->GetCamSerialPort());
	GetChildren(m_pApp->GetCamSerialPort(), t, m_PropertyList);

	m_NrOfProperties = BuildPropListText();

	GUI_DlgAddSelectBox(&m_Dlg, 4, 36, 208, 420, m_PropText, &m_Sel, 1);
	GUI_DlgAddIconButton(&m_Dlg, 8, Height - 106, 98, 98, "_Edit",
		m_pApp->GetIcon(IconId::OK), 100);
	GUI_DlgAddIconButton(&m_Dlg, 110, Height - 106, 98, 98, m_pApp->GetStr(StringTable::BACK),
		m_pApp->GetIcon(IconId::CANCEL), DLG_ABORT);
}

/*************************************************************************/
CDlgCamExpert::~CDlgCamExpert()
/*************************************************************************/
/*! @brief Destructor.
**************************************************************************/
{
	VIB_MemFree(m_PropText);
}

/*************************************************************************/
CDlgCamExpert *CDlgCamExpert::CreateInstance(int x, int y, int Width, int Height)
/*************************************************************************/
/*! @brief Creates CDlgCamExpert 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 CDlgCamExpert instance
**************************************************************************/
{
	if (m_pThis == NULL)
		m_pThis = new CDlgCamExpert(x, y, Width, Height);
	return m_pThis;
}

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

/*************************************************************************/
int CDlgCamExpert::BuildPropListText()
/*************************************************************************/
{
	int i;

	m_PropText[0] = '\0';
	for (i = 0; m_PropertyList[i].Name[0] && i < CFeature::MAXPROPERTIES; i++)
	{
		sprintf(m_PropText, "%s%s\n", m_PropText, m_PropertyList[i].Name);
	}
	strcat(m_PropText, "**** Test.EXE ****\n**** PFFW_Update ****\n");
	i++;
	return i;
}

/*************************************************************************/
int CDlgCamExpert::OnUserIO(int nKey)
/*************************************************************************/
/*! @brief Function processes the user inputs.
**************************************************************************/
{
	int Error;

	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 DLG_MOUSE_PRESSED:	// Handle mouse clicks in info and graph windows
			m_pApp->ChangeInfoArea(&m_Dlg);
			break;
		case 1:
		case 100:
			// Property selected
			GUI_DlgEnable(&m_Dlg, 0);
			GUI_DlgUpdate(&m_Dlg, m_pApp->GetDispImage(), m_Dlg.x, m_Dlg.y);
			Error = 0;
			if (m_Sel == m_NrOfProperties)
			{
				Error = TestEXE();
			}
			else if (m_Sel == m_NrOfProperties + 1)
			{
				/*Error =*/ PFFW_Update();
			}
			else
			{
				Error = ShowProperty(m_PropertyList[m_Sel - 1].Name);
			}
			if (Error < 0)
			{
				m_pApp->SetDlgNewFocus(DialogId::MAIN);
				m_bIsVisible = false;
			}
			break;
		}
		GUI_DlgEnable(&m_Dlg, 1);
	}
	return m_Activity;
}

/*************************************************************************/
int CDlgCamExpert::ShowProperty(char *PropertyName)
/*************************************************************************/
/*! @brief Shows property dialog.
**************************************************************************/
{
	const int Port = m_pApp->GetCamSerialPort();
	int i, di;
	int Error;
	int Id;
	unsigned int Flags;
	GUI_DLG *pDialog;
	TOKEN t;
	PFValue v;
	PropertyType Type;
	char Str[256];
	bool bShowDialog = true;
	PROPERTY Property, *PropertyList;

	PropertyList = (PROPERTY*)malloc(CFeature::MAXPROPERTIES * sizeof(PROPERTY));

	i = 0;
	// Get TOKEN of property
	t = pfProperty_ParseName(Port, PropertyName);
	// Get flags
	Flags = pfProperty_GetFlags(Port, t);
	// Get type of property
	Type = pfProperty_GetType(Port, t);
	// Get value of property
	pfDevice_GetProperty(Port, t, &v);
	
	// Create dialog
	pDialog = new GUI_DLG;
	GUI_DlgCreate2(pDialog, 400, 160, PropertyName);
	GUI_DlgSetGradCol(pDialog,  m_pApp->GetGradCol());

	switch (Type)
	{
	case PF_STRUCT:
		Error = ShowChildren(PropertyName);
		if (Error < 0)
			goto ShowPropertyExit;
		bShowDialog = false;
		break;

	case PF_STRING:
		std::snprintf(Str, 256, "%s\n", (char*)v.value.p);
		GUI_DlgAddTextBox(pDialog, PROP_VALUE_X, PROP_VALUE_Y, PROP_VALUE_WIDTH, PROP_VALUE_HEIGHT, Str, PROP_VALUE_BORDER);
		break;

	case PF_COMMAND:
		if (Flags & F_INACTIVE)
		{
			strcpy(Str, "Property is inactive\n");
			GUI_DlgAddTextBox(pDialog, PROP_VALUE_X, PROP_VALUE_Y, PROP_VALUE_WIDTH, PROP_VALUE_HEIGHT, Str, 2);
		}
		else
		{
			di = 0;
			GUI_DlgAddCheckBox(pDialog, PROP_VALUE_X, PROP_VALUE_Y, PROP_VALUE_WIDTH, PropertyName, &di, 21);
		}
		break;

	case PF_BOOL:
		if (Flags & F_INACTIVE)
		{
			std::snprintf(Str, 256, "Property is inactive\nValue: %d\n", v.value.i);
			GUI_DlgAddTextBox(pDialog, PROP_VALUE_X, PROP_VALUE_Y, PROP_VALUE_WIDTH, PROP_VALUE_HEIGHT, Str, 2);
		}
		else
		{
			di = v.value.i;
			GUI_DlgAddCheckBox(pDialog, PROP_VALUE_X, PROP_VALUE_Y, PROP_VALUE_WIDTH, PropertyName, &di, 21);
		}
		break;

	case PF_INT:
		if (Flags & F_INACTIVE)
		{
			std::snprintf(Str, 256, "Property is inactive\nValue: %d\n", v.value.i);
			GUI_DlgAddTextBox(pDialog, PROP_VALUE_X, PROP_VALUE_Y, PROP_VALUE_WIDTH, PROP_VALUE_HEIGHT, Str, 2);
		}
		else if (Flags & F_RO)
		{
			std::snprintf(Str, 256, "%d\n", v.value.i);
			GUI_DlgAddTextBox(pDialog, PROP_VALUE_X, PROP_VALUE_Y, PROP_VALUE_WIDTH, PROP_VALUE_HEIGHT, Str, 2);
		}
		else
		{
			di = (int)v.value.i;
			Error = GetPropMinMax(Port, t, &Property);
			if (Error < 0)
				goto ShowPropertyExit;
			GUI_DlgAddEditSlider(pDialog, PROP_VALUE_X, PROP_VALUE_Y, PROP_VALUE_WIDTH, PropertyName, &di, Property.Min.value.i, Property.Max.value.i, 21);
		}
		break;

	case PF_MODE:
		di = (int)v.value.i + 1;
		// Get all modes
		Error = GetChildren(Port, t, PropertyList);
		if (Error < 0)
			goto ShowPropertyExit;

		// Copy name of modes
		i = 0;
		Str[0] = '\0';
		while (PropertyList[i].Name[0])
		{
			sprintf(Str, "%s%s\n", Str, PropertyList[i].Name);
			i++;
		}
		if (Flags & F_INACTIVE)
		{
			std::snprintf(Str, 256, "Property is inactive\nValue: %s\n", PropertyList[v.value.i].Name);
			GUI_DlgAddTextBox(pDialog, PROP_VALUE_X, PROP_VALUE_Y, PROP_VALUE_WIDTH, PROP_VALUE_HEIGHT, Str, 2);
		}
		else
		{
			GUI_DlgAddChoiceBox(pDialog, PROP_VALUE_X, PROP_VALUE_Y, PROP_VALUE_WIDTH, PROP_VALUE_HEIGHT, Str, 0, &di, 21);
		}
		break;

	case PF_FLOAT:
		di = (int)(v.value.f * 1000.0);
		if (Flags & F_INACTIVE)
		{
			if (strcmp(PropertyName, "LUT.Value") == 0)
			{
				sprintf(Str, "Property is inactive\n(1200 = 1.2) Value: %d\n", di);
			}
			else
			{
				sprintf(Str, "Property is inactive\nValue [us]: %d\n", di);
			}
			GUI_DlgAddTextBox(pDialog, PROP_VALUE_X, PROP_VALUE_Y, PROP_VALUE_WIDTH, PROP_VALUE_HEIGHT, Str, 2);
		}
		else
		{
			Error = GetPropMinMax(Port, t, &Property);
			if (Error < 0)
				goto ShowPropertyExit;
			if (strcmp(PropertyName, "LUT.Value") == 0)
			{
				std::snprintf(Str, 256, "%s (1200 = 1.2)", PropertyName);
			}
			else
			{
				std::snprintf(Str, 256, "%s [us]", PropertyName);
			}
			GUI_DlgAddEditSlider(pDialog, PROP_VALUE_X, PROP_VALUE_Y, PROP_VALUE_WIDTH, Str, &di, (int)(Property.Min.value.f * 1000.0), (int)(Property.Max.value.f * 1000.0), 21);
		}
		break;
	}

	// Show dialog to change property
	if (bShowDialog)
	{
		GUI_DlgAddButton(pDialog,   8, 120, 188, 32, "_OK", 100);
		GUI_DlgAddButton(pDialog, 204, 120, 188, 32, m_pApp->GetStr(StringTable::CANCEL), DLG_ABORT);
		Id = GUI_DlgModal(pDialog, m_pApp->GetDispImage(), -1, -1, m_fKB);
	}

	// If property is not read only, write value to camera
	if (!(Flags & F_RO) && (Id != DLG_ABORT))
	{
		v.type = Type;
		switch (Type)
		{
		case PF_STRING:
			sprintf((char*)v.value.p, "%s", Str);
			//printf("PF_STRING: %s\n", (char*)v.value.p);
			break;
		case PF_COMMAND:
			v.value.i = di;
			//printf("PF_COMMAND: %d\n", v.value.i);
			break;
		case PF_BOOL:
			v.value.i = di;
			//printf("PF_BOOL: %d\n", v.value.i);
			break;
		case PF_INT:
			v.value.i = di;
			//printf("PF_INT: %d\n", v.value.i);
			break;
		case PF_MODE:
			v.value.i = di - 1;
			//printf("PF_MODE: %d\n", v.value.i);
			break;
		case PF_FLOAT:
			v.value.f = (float)di / 1000.0;
			//printf("PF_FLOAT: %f\n", v.value.f);
			break;
		}
		// Set property
		if (!(Type == PF_COMMAND && di == 0))
		{
			Error = pfDevice_SetProperty(Port, t, &v);
			//if (Error < 0) return Error;
		}
	}
	Error = 0;

ShowPropertyExit:
	GUI_DlgFree(pDialog);
	delete pDialog;
	free(PropertyList);
	return Error;
}

/*************************************************************************/
int CDlgCamExpert::ShowChildren(char *PropertyName)
/*************************************************************************/
/*! @brief Shows children of a property.
**************************************************************************/
{
	GUI_DLG *pDialog;
	int Id;
	int Sel = 1;
	int nrOfProperties, error;
	int nKey = 0;
	int Height;
	int PosX, PosY;
	bool bRunLoop;
	char *Text;
	char Str[64];
	TEXTPARAMETER TPOld;
	TOKEN t;
	PROPERTY *PropertyList;

	PropertyList = (PROPERTY*)malloc(CFeature::MAXPROPERTIES * sizeof(PROPERTY));

	GUI_GetTxtParam(&TPOld);
	GUI_SetTxtStyle(GUI_FSNORMAL);

	// Get token of this property
	t = pfProperty_ParseName(m_pApp->GetCamSerialPort(), PropertyName);
	// Get children of this property
	error = GetChildren(m_pApp->GetCamSerialPort(), t, PropertyList);
	if (error < 0)
	{
		free(PropertyList);
		return error;
	}

	Text = (char*)malloc(4096);

	nrOfProperties = 0;
	Text[0] = 0;
	while (PropertyList[nrOfProperties].Name[0])
	{
		sprintf(Text, "%s%s\n", Text, PropertyList[nrOfProperties].Name);
		nrOfProperties++;
	}

	GUI_DlgGetZeroZero(&m_Dlg, &PosX, &PosY);
	Height = m_Dlg.rgbDlg.Height - PosY;
	pDialog = new GUI_DLG;
	GUI_DlgCreate2(pDialog, 216, Height, PropertyName);
	GUI_DlgSetGradCol(pDialog,  m_pApp->GetGradCol());
	GUI_DlgAddSelectBox(pDialog, 4, 36, 208, 270, Text, &Sel, 1);
	GUI_DlgAddIconButton(pDialog,   8, Height - 106, 98, 98, "_OK",
		m_pApp->GetIcon(IconId::OK), 100);
	GUI_DlgAddIconButton(pDialog, 110, Height - 106, 98, 98, m_pApp->GetStr(StringTable::CANCEL),
		m_pApp->GetIcon(IconId::CANCEL), DLG_ABORT);
	GUI_DlgUpdate(pDialog, m_pApp->GetDispImage(), 0, 2 * PosY);

	bRunLoop = true;
	while (bRunLoop)
	{
		nKey = getc(m_fKB);
		if (nKey == EOF)
			_UNSET(m_fKB, _STATEOF);
		Id = GUI_DlgWork(pDialog, nKey);
		switch(Id)
		{
		case DLG_ABORT:
			bRunLoop = false;
			break;
		case 100:
		case 1:
			std::snprintf(Str, 64, "%s.%s", PropertyName, PropertyList[Sel - 1].Name);
			GUI_DlgEnable(pDialog, 0);
			GUI_DlgUpdate(pDialog, m_pApp->GetDispImage(), 0, 48);
			error = ShowProperty(Str);
			GUI_DlgEnable(pDialog, 1);
//			if (error < 0)
//				goto ShowChildrenExit;
			break;
		case DLG_MOUSE_PRESSED:	// *** Handle mouse clicks in info and graph windows
			m_pApp->ChangeInfoArea(pDialog);
			break;
		}
		if (Id != DLG_EOF)
		{
			GUI_DlgUpdate(pDialog, m_pApp->GetDispImage(), 0, 48);
		}
		else
		{
			m_pApp->DisplayDynamicElements();
			TSK_sleep(20);
		}
	}
	error = 0;

//ShowChildrenExit:
	GUI_DlgFree(pDialog);
	delete pDialog;
	free(Text);
	GUI_SetTxtParam(&TPOld);
	free(PropertyList);
	return error;
}

/*************************************************************************/
int CDlgCamExpert::TestEXE()
/*************************************************************************/
/*! @brief Internal camera test mode.
**************************************************************************/
{
	const int Port = m_pApp->GetCamSerialPort();
	int nKey = 0;
	int Error = 0;
	int Id;
	bool bRunLoop = true;
	char PropertyName[32], PropertyNameText[32], PropertyValue[32], PropertyValueText[32], PropertyTypeText[32];
	GUI_DLG *pDialog;
	TOKEN t;
	PropertyType Type;

	// Set default PropertyName
	strcpy(PropertyName, "CameraName");
	std::snprintf(PropertyNameText, 32, "Property: %s", PropertyName);

	// Get value of default Property
	t = pfProperty_ParseName(Port, PropertyName);
	if (t == INVALID_TOKEN)
	{
		strcpy(PropertyValueText, "Value: Invalid Property");
	}
	else
	{
		Error = pfDevice_GetProperty_String(Port, t, PropertyValue, 64);
		if (Error < 0)
		{
			strcpy(PropertyValueText, "Value: Invalid Property");
			strcpy(PropertyTypeText,  "Value: Invalid Property");
		}
		else
		{
			std::snprintf(PropertyValueText, 32, "Value: %s", PropertyValue);
			strcpy(PropertyTypeText,  "Type: PF_STRING");
		}
	}
	// Dialog
	pDialog = new GUI_DLG;
	GUI_DlgCreate2(pDialog, 260, 298, "Test.EXE");
	GUI_DlgSetGradCol(pDialog, m_pApp->GetGradCol());
	GUI_DlgAddDynamicText(pDialog, 20, 30, PropertyNameText);
	GUI_DlgAddDynamicText(pDialog, 20, 70, PropertyValueText);
	GUI_DlgAddDynamicText(pDialog, 20, 110, PropertyTypeText);
	GUI_DlgAddButton(pDialog, 20, 150, 220, 32, "Change Property _Name", 50);
	GUI_DlgAddButton(pDialog, 20, 200, 220, 32, "Change Property _Value", 51);
	GUI_DlgAddButton(pDialog, 8, 254, 244, 32, "_OK", 100);
	GUI_DlgUpdate(pDialog, m_pApp->GetDispImage(), -1, -1);

	while (bRunLoop)
	{
		// Get character of keyboard
		nKey = getc(m_fKB);
		if (nKey == EOF)
			_UNSET(m_fKB, _STATEOF);
		Id = GUI_DlgWork(pDialog, nKey);

		switch (Id)
		{
		case DLG_ABORT:
			bRunLoop = false;
			break;
		case 100:
			// OK pressed
			bRunLoop = false;
			break;
		case 50:
			// Change Property pressed
			if (GUI_EditBox2(m_pApp->GetDispImage(), pDialog->x + 50, pDialog->y + 50, 150, PropertyName, m_fKB, 5, 1) == 0)
				break;
			std::snprintf(PropertyNameText, MAX_PROPNAME, "Property: %s", PropertyName);

			t = pfProperty_ParseName(Port, PropertyName);
			if (t == INVALID_TOKEN)
			{
				strcpy(PropertyValueText, "Value: Invalid Property");
				strcpy(PropertyTypeText, "Type: Invalid Property");
			}
			else
			{
				Error = pfDevice_GetProperty_String(Port, t, PropertyValue, 64);
				if (Error < 0)
				{
					strcpy(PropertyValueText, "Value: Invalid Property");
					strcpy(PropertyTypeText, "Type: Invalid Property");
				}
				else
				{
					std::snprintf(PropertyValueText, MAX_PROPNAME, "Value: %s", PropertyValue);
					Type = pfProperty_GetType(Port, t);
					switch (Type)
					{
					case PF_STRING:
						strcpy(PropertyTypeText, "Type: PF_STRING");
						break;
					case PF_COMMAND:
						strcpy(PropertyTypeText, "Type: PF_COMMAND");
						break;
					case PF_BOOL:
						strcpy(PropertyTypeText, "Type: PF_BOOL");
						break;
					case PF_INT:
						strcpy(PropertyTypeText, "Type: PF_INT");
						break;
					case PF_MODE:
						strcpy(PropertyTypeText, "Type: PF_MODE");
						break;
					case PF_FLOAT:
						strcpy(PropertyTypeText, "Type: PF_FLOAT");
						break;
					}
				}
			}
			break;

		case 51:
			// Change Value pressed
			if (GUI_EditBox2(m_pApp->GetDispImage(), pDialog->x + 50, pDialog->y + 90, 150, PropertyValue, m_fKB, 5, 1) == 0)
				break;
			t = pfProperty_ParseName(Port, PropertyName);
			if (t == INVALID_TOKEN)
			{
				strcpy(PropertyValueText, "Value: Invalid Property");
			}
			else
			{
				Error = pfDevice_SetProperty_String(Port, t, PropertyValue);
				if (Error < 0)
				{
					strcpy(PropertyValueText, "Value: Invalid Value");
				}
				else
				{
					std::snprintf(PropertyValueText, MAX_PROPNAME, "Value: %s", PropertyValue);
				}
			}
			break;
		}
		if (Id != DLG_EOF)
			GUI_DlgUpdate(pDialog, m_pApp->GetDispImage(), -1, -1);
		else
			VIB_WaitBios(10);
	}
	GUI_DlgFree(pDialog);
	delete pDialog;
	m_pApp->RecBackground(1);
	return 0;
}

/*************************************************************************/
int CDlgCamExpert::GetPropMinMax(int Port, TOKEN t, PROPERTY *pProp)
/*************************************************************************/
/*! @brief Gets minimum and maximum value of a property.
**************************************************************************/
{
	int Error;
	TOKEN Child;

	Child = findProperty_ByName(t, "Min");
	if (Child == INVALID_TOKEN)
		return -1;

	Error = pfDevice_GetProperty(Port, Child, &pProp->Min);
	if (Error < 0)
		return Error;

	Child = findProperty_ByName(t, "Max");
	if (Child == INVALID_TOKEN)
		return -1;

	Error = pfDevice_GetProperty(Port, Child, &pProp->Max);
	if (Error < 0)
		return Error;
	return 0;
}

/*************************************************************************/
int CDlgCamExpert::GetChildren(int Port, TOKEN t, PROPERTY *PropertyList)
/*************************************************************************/
/*! @brief Gets children of property.
**************************************************************************/
{
	int i;
	TOKEN Child;

	for (i = 0; i < CFeature::MAXPROPERTIES; i++)
	{
		PropertyList[i].Name[0] = '\0';
	}

	i = 0;

	// Get first child of this property
	Child = pfProperty_Select(Port, t, t);

	while (Child && i < CFeature::MAXPROPERTIES)
	{
		std::snprintf(PropertyList[i].Name, MAX_PROPNAME, "%s", pfProperty_GetName(Port, Child));
		// Copy only true children (EVT_ are event handler)
		if (strstr(PropertyList[i].Name, "EVT_"))
		{
			PropertyList[i].Name[0] = '\0';
		}
		// Get next children
		Child = pfProperty_Select(Port, t, Child);
		i++;
	}
	return i;
}

/*************************************************************************/
int CDlgCamExpert::PFFW_Update()
/*************************************************************************/
/*! @brief Firmware update.
**************************************************************************/
{
	int Error;
	int fwUpdateFileSize;
	char Filename[32];

	// Open file dialog
	m_pApp->SetTP(TextStyle::MONOSPACE);
	GUI_OpenFileBox(VIB_Drive[1], NULL, "Select File", Filename, "XSV", m_fKB);
	m_pApp->SetTP(TextStyle::NORMAL);

	// Get file size and read file
	fwUpdateFileSize = VIB_FindFile2(VIB_Drive[1], Filename);
	if (fwUpdateFileSize <= 0)
	{
		m_pApp->RecBackground(1);
		return -1;
	}

	fwUpdateBuffer = new unsigned char[fwUpdateFileSize];
	Error = VIB_ReadFile(VIB_Drive[1], Filename, fwUpdateBuffer);
	if (Error < 0)
	{
		delete [] fwUpdateBuffer;
		return Error;
	}

	// Init xilinx c-code
	JTAGInit();
	// Init JTAG chain
	Error = JTAG_Init();
	if (Error < 0)
	{
		delete [] fwUpdateBuffer;
		return Error;
	}

	// Start FW update
	Error = xsvfExecute();

	delete [] fwUpdateBuffer;
	m_pApp->RecBackground(1);
	return Error;
}

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