V 10
1
LANG:1 9 MainPanel
PANEL,258 100 780 648 N "_3DFace" 0
"/** fwInstallationMain.pnl

This panel checks whether it is opened for the first time 
( the dpts and dps are created , the user is asked to choose the installation directory ). 
The panel displays the information about the installed components (tblInstalledComponents_EventInitialize) in tblInstalledComponents table 
and available components (btnSelectSourceDir_EventClick or txtSourceDir_EventCommand) in tblAvailableComponents table. 
From the list of available components the user can choose the components to be installed ( tblAvailableComponents_EventClick ). 
The procedure of installing components starts on btnApplyInstall_EventClick. 
From the list of installed components the user can choose the components to be deleted ( tblInstalledComponents_EventClick). 
The procedure of deleting components starts on btnApplyDelete_EventClick. 
Functions for adding and deleting components are defined in this panel on actions btnApplyDelete_EventClick and btnApplyInstall_EventClick.

Required $-parameters: none

Panels called from this panel:

fwInstallationToInstall.pnl - btnApplyInstall_EventClick
fwInstallationToDelete.pnl - btnApplyDelete_EventClick
fwInstallationComponentDetails.pnl - tblInstalledComponents_EventDblClick, tblAvailableComponents_EventDblClick.
fwInstallationDependency.pnl - btnApplyDelete_EventClick and btnApplyInstall_EventClick if there are problems with the dependencies
fwInstallationAdvancedOptions.pnl - btnAdvanced_EventClick
fwInstallationRestart.pnl - btnApplyInstall_EventClick , btnApplyDelete_EventClick if the components were installed/deleted

*/



bool installationDirectorySet; // this variable is true - when installation directory is set in the data point, 
							   // 				   false - other cases

main()
{

	dyn_string dataPointTypes;
	int dataPointTypeExists;
	int dpCreateResult;
	dyn_string 	dynPostInstallFiles_all; // all the postInstall init files to be executed
	dyn_string dynScripts;
	int i;
	int iReturn;
	dyn_float dreturnf;
	dyn_string dreturns;
	string testString;
	string sPath;
	dyn_string sPaths;
	
	// get the dpts from the system	
	dataPointTypes = dpTypes();
	
	// check whether the _FwInstallationComponents dpt exists
	dataPointTypeExists = dynContains(dataPointTypes, \"_FwInstallationComponents\");
	
	
	if ( dataPointTypeExists > 0)
	{
		// if it exists
		
		// SMS: Perform a check if the new datapoint format has already been applied
		
		if(dynlen(dpNames(\"*.postDeleteFiles\",\"_FwInstallationInformation\")) == 0)		
		{
			// change the installation tool internal data points	
			fwInstallation_createDataPointTypes(FALSE, dpCreateResult);
		}	
		
		
		// check whether there are some postInstall or postDelete files to be executed

		
		if(dpExists(\"fwInstallationInfo\"))
		{
			
			if(access(getPath(SCRIPTS_REL_PATH) + \"fwScripts.lst\", F_OK) == 0)
			{
				if(fwInstallation_fwScriptsAddedToProgsFile() == -1)
				{
//SMS Why does a user want to know that?					Debug(\"\\n opening the fwInstallationScriptsAddedInfo.pnl\");
					ChildPanelOnCentralReturn(\"fwInstallation/fwInstallationScriptsAddedInfo.pnl\", \"fwInstallation_ScriptsAddedInfo\", \"\", dreturnf, dreturns);
				}
			}
			
			// get all the post install init files
			dpGet(\"fwInstallationInfo.postInstallFiles:_original.._value\", dynPostInstallFiles_all);
			
			// for each post install init file
			for(i = 1; i <= dynlen(dynPostInstallFiles_all); i++)
			{
				fwInstallation_showMessage(makeDynString(\"Executing post install init files ...\"));
				
				// execute the file	
				fwInstallation_evalScriptFile(dynPostInstallFiles_all[i] , iReturn);
				
				// check the return value
				if(iReturn == -1)
				{
					fwInstallation_showMessage(makeDynString(\"   Error executing : \" + dynPostInstallFiles_all[i] + \" file.\"));
				}
				else
				{
					fwInstallation_showMessage(makeDynString(\"  \" + dynPostInstallFiles_all[i] + \" - OK \"));

				}
					
			}
			
			// all the files were executed - if there were any errors the user has been informed
			// clearing the fwInstallationInfo.postInstallFiles:_original.._value
			
			dynClear(dynPostInstallFiles_all);
			
			dpSet(\"fwInstallationInfo.postInstallFiles:_original.._value\", dynPostInstallFiles_all);
			
			// get all the post delete files
			dpGet(\"fwInstallationInfo.postDeleteFiles:_original.._value\", dynPostInstallFiles_all);
			
			// for each post delete file
			for(i = 1; i <= dynlen(dynPostInstallFiles_all); i++)
			{
				fwInstallation_showMessage(makeDynString(\"Executing post delete  files ...\"));
				
				// execute the file	
				fwInstallation_evalScriptFile(dynPostInstallFiles_all[i] , iReturn);
				
				// check the return value
				if(iReturn == -1)
				{
					fwInstallation_showMessage(makeDynString(\"   Error executing : \" + dynPostInstallFiles_all[i] + \" file.\"));
				}
				else
				{
					fwInstallation_showMessage(makeDynString(\"  \" + dynPostInstallFiles_all[i] + \" - OK \"));
					fwInstallation_deleteFiles(dynPostInstallFiles_all[i], \"\");

				}
					
			}
			
			// all the files were executed - if there were any errors the user has been informed
			// clearing the fwInstallationInfo.postInstallFiles:_original.._value
			
			dynClear(dynPostInstallFiles_all);
			
			dpSet(\"fwInstallationInfo.postDeleteFiles:_original.._value\", dynPostInstallFiles_all);
			
		}
	}
	else
	{
		//	Debug(\"\\n The data point types for the installation tool do not exist\");
		// starting the installatio tool for the first time
		
		fwInstallation_showMessage(makeDynString(\"Starting the Installation Tool for the first time\"));
		fwInstallation_showMessage(makeDynString(\"Importing the Data Point Types ... \"));
	
		// create the installation tool internal data points	
		fwInstallation_createDataPointTypes(TRUE, dpCreateResult);
		
		// check the result
		if (dpCreateResult == 0)
		{
			// display the info for the user
			fwInstallation_showMessage(makeDynString(\"Internal data points for the installation tool created\"));
			
			// ask for the installation directory
			
				ChildPanelOnCentral(\"fwInstallation/fwInstallationSelectDirectory.pnl\", \"fwInstallation_SelectDirectory\", \"\");
				if(!dpExists(\"fwInstallationInfo.installationDirectoryPath\"))
				{
					dpCreate(\"fwInstallationInfo\" , \"_FwInstallationInformation\");
//					fwInstallation_loadProjPaths(sPaths);
//					sPath = sPaths[1];		
//					dpSet(\"fwInstallationInfo.installationDirectoryPath:_original.._value\", sPath);
				}
		}
		else
		{
			// display the error information
			fwInstallation_showMessage(makeDynString(\"ERROR: in creating the internal data points. Please restart the application\"));
		}
		
		// check if fwScripts.lst exists
		// if not generate it and add an entry to it
				
		if(access(getPath(SCRIPTS_REL_PATH) + \"fwScripts.lst\", F_OK) == 0)
		{
			if(fwInstallation_fwScriptsAddedToProgsFile() == -1)
			{
//SMS Why does a user want to know this?				DebugN(\"opening the fwInstallationScriptsAddedInfo.pnl\");
				ChildPanelOnCentralReturn(\"fwInstallation/fwInstallationScriptsAddedInfo.pnl\", \"fwInstallation_ScriptsAddedInfo\", \"\", dreturnf, dreturns);
			}
		}
		else
		{
		
			// the file does not exist - create it
			
			dynAppend(dynScripts, \"fwInstallationFakeScript.ctl\");
			fwInstallation_saveFile( dynScripts, getPath(SCRIPTS_REL_PATH) + \"fwScripts.lst\");

			
		}
	}
}

/*
	This function is not using the Framework exception handling because
	it is not installed yet.
*/

/** This function creates the Installation Component DPT and DP

@param result: this is the return value  0 - \"success\"   -1 - \"error\"

@author M.Sliwinski
*/

fwInstallation_createDataPointTypes(bool create, int & result)
{
	int n;
	dyn_dyn_string dynDynElements;
	dyn_dyn_int dynDynTypes;
	
	result = 0;
	
	dynDynElements[1] = makeDynString (\"_FwInstallationComponents\", \"\", \"\");
	dynDynElements[2] = makeDynString (\"\", \"componentFiles\", \"\");
	dynDynElements[3] = makeDynString (\"\", \"configFiles\", \"\");

	dynDynElements[4] = makeDynString (\"\", \"\", \"configWindows\");
	dynDynElements[5] = makeDynString (\"\", \"\", \"configLinux\");
	dynDynElements[6] = makeDynString (\"\", \"\", \"configGeneral\");

	dynDynElements[7] = makeDynString (\"\", \"initFiles\", \"\");
	dynDynElements[8] = makeDynString (\"\", \"postInstallFiles\", \"\");
	
	dynDynElements[9] = makeDynString (\"\", \"dplistFiles\", \"\");
	dynDynElements[10] = makeDynString (\"\", \"componentVersion\", \"\");
	dynDynElements[11] = makeDynString (\"\", \"date\", \"\");
	dynDynElements[12] = makeDynString (\"\", \"descFile\", \"\");
	dynDynElements[13] = makeDynString (\"\", \"installationDirectory\", \"\");
	dynDynElements[14] = makeDynString (\"\", \"requiredComponents\", \"\");
	dynDynElements[15] = makeDynString (\"\", \"requiredInstalled\", \"\");
	dynDynElements[16] = makeDynString (\"\", \"subComponents\", \"\");
	dynDynElements[17] = makeDynString (\"\", \"isItSubComponent\", \"\");
	dynDynElements[18] = makeDynString (\"\", \"scriptFiles\", \"\");
	dynDynElements[19] = makeDynString (\"\", \"componentVersionString\", \"\");

	dynDynElements[20] = makeDynString (\"\", \"deleteFiles\", \"\");
	dynDynElements[21] = makeDynString (\"\", \"postDeleteFiles\", \"\");

	dynDynTypes[1] = makeDynInt (DPEL_STRUCT);
	dynDynTypes[2] = makeDynInt (0, DPEL_DYN_STRING);
	dynDynTypes[3] = makeDynInt (0, DPEL_STRUCT);
	
	dynDynTypes[4] = makeDynInt (0, 0, DPEL_DYN_STRING);
	dynDynTypes[5] = makeDynInt (0, 0, DPEL_DYN_STRING);
	dynDynTypes[6] = makeDynInt (0, 0, DPEL_DYN_STRING);
	
	dynDynTypes[7] = makeDynInt (0, DPEL_DYN_STRING);
	dynDynTypes[8] = makeDynInt (0, DPEL_DYN_STRING);
	dynDynTypes[9] = makeDynInt (0, DPEL_DYN_STRING);
	dynDynTypes[10] = makeDynInt (0, DPEL_FLOAT);
	dynDynTypes[11] = makeDynInt (0, DPEL_STRING);
	dynDynTypes[12] = makeDynInt (0, DPEL_STRING);
	dynDynTypes[13] = makeDynInt (0, DPEL_STRING);
	dynDynTypes[14] = makeDynInt (0, DPEL_DYN_STRING);
	dynDynTypes[15] = makeDynInt (0, DPEL_BOOL);
	dynDynTypes[16] = makeDynInt (0, DPEL_DYN_STRING);
	dynDynTypes[17] = makeDynInt (0, DPEL_BOOL);
	dynDynTypes[18] = makeDynInt (0, DPEL_DYN_STRING);
	dynDynTypes[19] = makeDynInt (0, DPEL_STRING);

	dynDynTypes[20] = makeDynInt (0, DPEL_DYN_STRING);
	dynDynTypes[21] = makeDynInt (0, DPEL_DYN_STRING);

	// Create or change the datapoint type

	if(create)
	{
		n = dpTypeCreate(dynDynElements, dynDynTypes );
	} else {
		n = dpTypeChange(dynDynElements, dynDynTypes );
	}	
	// check the result of creating dpts
	if(n == -1)
	{
		result = -1;
	}

	
	dynClear(dynDynElements);
	dynClear(dynDynTypes);
	
	dynDynElements[1] = makeDynString (\"_FwInstallationInformation\" , \"\");
	dynDynElements[2] = makeDynString (\"\",\"installationDirectoryPath\");
	dynDynElements[3] = makeDynString (\"\",\"postInstallFiles\");
	dynDynElements[4] = makeDynString (\"\", \"postDeleteFiles\", \"\");

	dynDynTypes[1] = makeDynInt (DPEL_STRUCT);
	dynDynTypes[2] = makeDynInt (0, DPEL_STRING);
	dynDynTypes[3] = makeDynInt (0, DPEL_DYN_STRING);
	dynDynTypes[4] = makeDynInt (0, DPEL_DYN_STRING);
		
	// create or change the datapoint type	
	if(create)
	{
		n = dpTypeCreate(dynDynElements, dynDynTypes );
	} else {
		n = dpTypeChange(dynDynElements, dynDynTypes );
	}		
	
	// check the result of creating dpts
	if(n == -1)
	{
		result = -1;
	}
}" 0
EE E E 1 -1 -1 0  40 20
"" 0 1
E"/** This function gets the components data from the directory specified in the textBox and fills the graphic table with it.

@param tableName: the name of a graphic table to be filled with data 
@param sourceWidget: the name of a widget containing the directory from which the data about the components is taken
@return 0 - \"success\"  -1 - error 
@author M.Sliwinski
*/

int fwInstallation_getComponentsInfo(string tableName , string sourceWidget)
{


	string dirCurrentValue;
	dyn_string dynAvailableDescriptionFiles;
	string componentFileName;
	string strComponentFile;
	string tagName;
	string tagValue;

	string componentName;
	float componentVersion;
	string componentVersionString;
	
	shape shape_dirFromSourceWidget = getShape(sourceWidget);
	shape shape_destinationTable = getShape(tableName);
	int result;
	
	bool	fileLoaded;
	bool isItSubComponent = false;
	
	int i, j;

	// clear the graphical table with the component names
	shape_destinationTable.deleteAllLines();
	
	// get the directory name where the components are located	
	dirCurrentValue = shape_dirFromSourceWidget.text;
	
	// it the directory name is empty
	if (dirCurrentValue == \"\")
	{
		return 0;
	}
	
	// read the names of files that have the .xml extension in a directory specified by dirCurrentValue
	dynAvailableDescriptionFiles =  getFileNames( dirCurrentValue, \"*.xml\");
	
	// for each component description file, read the component name, version and display it in the graphic table
	
	for( i = 1; i <= dynlen(dynAvailableDescriptionFiles); i++)
	{
		// get the file name of an .xml description file
		componentFileName = dynAvailableDescriptionFiles[i];
		
		// load the description file
		fileLoaded = fileToString(dirCurrentValue + \"/\" + componentFileName, strComponentFile);
		
		if (! fileLoaded )
		{
			DebugN(\"fwInstallation: Cannot load \" + componentFileName + \" file \");	
		}
		else 
		{
			// the description file in now in string - strComponentFile
			
			// remove the root tag <component>
			
			strreplace(strComponentFile, \"<component>\", \"\");
			strreplace(strComponentFile, \"</component>\", \"\");
			
			// while there are some tags in the string - get the next tag		
			while( fwInstallation_getTagFromString(tagName, tagValue, strComponentFile) == 1 )
			{
				switch(tagName)
				{
												// retrieve the component name
							case \"name\": 		componentName = tagValue;
												break;
												
												// retrieve the component version
							case \"version\" :	componentVersionString = tagValue;
												componentVersion = tagValue;
												break;
												
													// retrieve the information - is it subcomponent
							case \"subComponent\":	if((tagValue == \"yes\") || (tagValue == \"Yes\") || (tagValue == \"YES\"))
													{
														isItSubComponent = true;
													}
												break;
				}
			}
			
			// check whether the description file contains the component name
			// and whether it is a subcomponent - if it is a subcomponent - do not display it in a table with available components
			
			if((componentName != \"\") && ((!isItSubComponent) || (isItSubComponent && ShowSubComponents.state(0))))
			// this component can be installed - put it in the table with available components. 
			{
				//if (componentName == \"\") - it means that the xml file does not contain the component name
				//							 or the component file does not describe a component				
				
				// Check if the component is already installed	
				fwInstallation_componentInstalled(componentName, componentVersionString, result);
				if (result == 1) // component is installed
				{
					// display the information about the component in a table with note that it is already installed
					if(isItSubComponent)
						shape_destinationTable.appendLine(\"componentName\", \"_\"+componentName, \"componentVersion\", componentVersionString, \"colStatus\" , \"Installed\" , \"descFile\", dirCurrentValue + \"/\" + componentFileName);
					else
						shape_destinationTable.appendLine(\"componentName\", componentName, \"componentVersion\", componentVersionString, \"colStatus\" , \"Installed\" , \"descFile\", dirCurrentValue + \"/\" + componentFileName);
				}
				else // component is not installed
				{
					// display the information about the component
					if(isItSubComponent)
						shape_destinationTable.appendLine(\"componentName\", \"_\"+componentName, \"componentVersion\", componentVersionString, \"descFile\", dirCurrentValue + \"/\" + componentFileName);
					else
						shape_destinationTable.appendLine(\"componentName\", componentName, \"componentVersion\", componentVersionString, \"descFile\", dirCurrentValue + \"/\" + componentFileName);
				}
			 	
			 	// reset the componentName
			 	componentName = \"\";
				
				
			 	
			}
		
		}
		
		// reset the isItSubComponent variable		
		isItSubComponent = false;
			
	}
}

/** This function checks if the component is already installed. It checks the PVSSDB.

@param componentName: the name of a component to be checked
@param availableComponentVersion: the version of a component to be checked
@return 1 - \"component installed\"  0 - \"component not installed\"
@author M.Sliwinski
	    16.12.2002 Sascha Schmeling		extended for unlimited version number components
*/


fwInstallation_componentInstalled(string componentName, string requestedComponentVersion, int &result)
{
	string installedComponentVersion,dummy;
	float installedComponentVersionOld;
	
	// check whether the component data point exists - if it exists it is installed
	
	if(dpExists(\"fwInstallation_\" + componentName))
	{
		// retrieve the version of installed component
		dpGet(\"fwInstallation_\" + componentName + \".componentVersionString:_original.._value\", installedComponentVersion);

		// Legacy
		if(installedComponentVersion == \"\")
		{
			DebugN(\"Correcting database of installed components for \"+componentName);
			dpGet(\"fwInstallation_\" + componentName + \".componentVersion:_original.._value\", installedComponentVersionOld);
			sprintf(dummy,\"%5.5f\",installedComponentVersionOld);
			installedComponentVersion = strltrim(strrtrim(dummy,\"0\"));
			if(strpos(installedComponentVersion,\".\") == strlen(installedComponentVersion)-1)
			{
				installedComponentVersion += \"0\";
			}
			dpSet(\"fwInstallation_\" + componentName + \".componentVersionString\", installedComponentVersion);
		}

		result = (_fwInstallation_CompareVersions(installedComponentVersion,requestedComponentVersion));
	}
	else
	{
		// return the component is not installed
		result = 0;
	}
	
}

/** This function retrieves the installed components from the PVSS database and 
fills the graphic table - \"tblInstalledComponents\"

@author M.Sliwinski
*/

fwInstallation_getInstalledComponents()
{
	dyn_string dynComponentNames;
	dyn_string systemName_Component;
	dyn_string dataPointTypes;
	
	string componentName;
	string componentVersionString;
	float componentVersion;
	bool requiredInstalled; 
	string descFile;
	string installationDirectory;
	shape shape_destinationTable;
	bool isItSubComponent;
	
	int row, column;
	int i;	

	// get shape of the graphic table	
	shape_destinationTable = getShape(\"tblInstalledComponents\");
	
	// clear the table
	shape_destinationTable.deleteAllLines();
	ErrorText.visible = FALSE;
	ErrorColor1.visible = FALSE;
	ErrorColor2.visible = FALSE;
	
	// get existing data point types
	dataPointTypes = dpTypes();
	
	// check whether the \"_FwInstallationComponents\" dpt exists
	if(dynContains(dataPointTypes, \"_FwInstallationComponents\") > 0)
	{
		// get the names of all installed components
		dynComponentNames = dpNames(\"*\", \"_FwInstallationComponents\");
		
		for ( i = 1; i <= dynlen(dynComponentNames); i++)
		{
			
			// remove the system name from the component name
			dynComponentNames[i] = dpSubStr( dynComponentNames[i], DPSUB_DP );
			
			// delete the fwInstallation_ prefix from the component name
			strreplace(dynComponentNames[i], \"fwInstallation_\" , \"\");
			
			// get the component name			
			componentName = dynComponentNames[i];
			
			// get the component version
			if(dpGet(\"fwInstallation_\" + componentName + \".componentVersionString:_original.._value\", componentVersionString) != 0)
			{
				componentVersionString = \"\";
			}	
//SMS
			if(componentVersionString == \"\")
			{
				dpGet(\"fwInstallation_\" + componentName + \".componentVersion:_original.._value\", componentVersion);
				if(componentVersion == floor(componentVersion))
				{
					sprintf(componentVersionString,\"%2.1f\",componentVersion);
				} else {
					componentVersionString = componentVersion;
				}
				dpSetWait(\"fwInstallation_\" + componentName + \".componentVersionString:_original.._value\", componentVersionString);
			}
//SMS	
			
			// get the information - are the required components installed
			dpGet(\"fwInstallation_\" + componentName + \".requiredInstalled:_original.._value\", requiredInstalled);
			
			// check if it is the sub component
			dpGet(\"fwInstallation_\" + componentName + \".isItSubComponent:_original.._value\", isItSubComponent);
			
			// if it is the subcomponent
			if(isItSubComponent)
			{
				if(ShowInstalledSubComponents.state(0))
					shape_destinationTable.appendLine(\"componentName\", \"_\"+componentName, \"componentVersion\", componentVersionString);
			}
			else
			{
				// this is not the sub-component - display it in a graphic table
				shape_destinationTable.appendLine(\"componentName\", componentName, \"componentVersion\", componentVersionString);
			}		
			
			// check if the components required by this component are installed
			if(requiredInstalled)
			{
				// do nothing
			}
			else
			{
				// set the colour of the cell into fwAlarmWarnUack colour
				
				getValue(shape_destinationTable, \"currentCell\", row, column);
				shape_destinationTable.currentCell(row, 0); // we set the current cell for the first column
				shape_destinationTable.cellBackCol(\"{255, 255, 51}\");  // the values of Framework colour  fwAlarmWarnUack 
				ErrorText.visible = TRUE;
				ErrorColor1.visible = TRUE;
				ErrorColor2.visible = TRUE;
			}
		}
	}	
		
	
}
/** this functions outputs the message into the log textarea of a panel

@param message: the message to be displayed

*/
	
fwInstallation_showMessage(dyn_string message)
{

	int i, length;
	
	length = dynlen(message);
	for (i = 1; i <= length; i++)
	{		
		list.appendItem(message[i]);	
		if(logFileName.text != \"\")
		{
			fwInstallation_writeToLog(message[i] + \"\\n\");
		}
	}
		
	length = list.itemCount();
	list.bottomPos(length);
	list.selectedPos(length);


}

/** this function saves the dyn_string  into PVSS project confg file

@param filename: the name of a file
@param configLines: the dyn_string containing the lines from the  file

@author M.Sliwinski
*/

int fwInstallation_saveFile( dyn_string & configLines, string filename)
{
	int i;
	string strLinesToSave;
	

	file fileHdlConfig;
	
	int writeResult;

			// open the file for writing
			fileHdlConfig = fopen(filename, \"w\");
			
			// if the file is not opened
			if(fileHdlConfig == 0)
			{
				DebugN(\"fwInstallation: File \" + filename + \" could not be opened\");
			}
			else
			{
					// copy each line from a dyn_string into string and separate the lines with newline character
					for(i = 1; i <= dynlen(configLines); i++)
					{
						strLinesToSave += configLines[i] + \"\\n\";
					}
					
					// save the string into the file
					writeResult = fputs(strLinesToSave , fileHdlConfig);
			
					// check the result of writing to a file
					if (writeResult == 0)
					{
						DebugN(\"fwInstallation: File \" + filename + \" has been saved\");
					}
					
					// close the file					
					fclose(fileHdlConfig);
			}
		
}

/** This function reads the xml tags from the component description file


@param tagName: the string with the tag name
@param tagValue: the string with the tag value
@param strComponentFile: the string with the XML info about the component
@param return: 1 it the tag was found, -1 - the tag was not found

@author M.Sliwinski
*/

int fwInstallation_getTagFromString(string & tagName, string & tagValue, string & strComponentFile)
{
	int pos1; // contains the position of an opening tag start 
	int pos2; // contains the position of an opening tag end
	int pos3; // contains the position of a closing tag start
	int pos4; // contains the position of a closing tag end
		
				// get the position of an opening tag start
				pos1 = strpos(strComponentFile, \"<\");
				
				// get the position of an opening tag end		
				pos2 = strpos(strComponentFile, \">\");
	
				//	get the tag name			
				tagName = substr(strComponentFile, pos1 + 1, pos2 - (pos1 + 1));
				
				// get the position of an closing tag start
				pos3 = strpos(strComponentFile, \"</\" + tagName + \">\");
				
				// get the position of an closing tag end
				pos4 = pos3 + strlen(\"</\" + tagName + \">\");
				
				// get the tag value
				tagValue = substr(strComponentFile, pos2+1, pos3-(pos2+1));
				
				// remove the bland spaces
				tagValue = strrtrim(strltrim(tagValue));
				
				// remove the tag and the tag value from the string
				strComponentFile = substr(strComponentFile, pos4);
				
				
		if(pos1 >=0)
		{
			// return that the tag was found
//SMS
//if(strtoupper(tagName) == \"NAME\") DebugN(\"*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\");
//DebugN(\"Tag found : <\"+tagName+\"> :\"+tagValue);
//SMS
			return 1;
		}
		else
		{
			// return that the tag was not found ( there are no more tags )	
			return -1;
		}				
}


/** This function executes a script from the component .init file

@param componentInitFile: the .init file with the functions to be executed
@param iReturn: sucess 0, in  the event of an error -1
@author M.Sliwinski
*/

 fwInstallation_evalScriptFile(string componentInitFile , int & iReturn)
{
	
	bool fileLoaded;
	string fileInString;
	anytype retVal;
	int result;
	
	fileLoaded = fileToString(componentInitFile, fileInString);
	
	if (! fileLoaded )
	{
	
		DebugN(\"fwInstallation: Cannot load \" + componentInitFile);
		iReturn =  -1;
	}
	else 
	{
		
		// the evalScript 
		iReturn = evalScript(retVal, fileInString, makeDynString(\"$value:12345\"));
		
	}
	

	
}

/** This function updates the fwScripts.lst file to be run by ctrl manager

@param dynScriptsToBeAdded: a dynamic string with file names of scripts to be added to fwScripts.lst file
@param strComponentName: the name of the component for which the scripts are added
@author M.Sliwinski
*/

fwInstallation_addScriptsIntoFile(dyn_string & dynScriptsToBeAdded, string strComponentName)
{

		dyn_string dynLoadedScripts;   // all the scripts that were loaded from fwScripts.lst
		dyn_string dynScriptsFileLines;
		string strScriptsFileName = getPath(SCRIPTS_REL_PATH) + \"fwScripts.lst\";
		string scriptsFileInString;
		string strScriptsFileLine;
		dyn_string dynLinesToBeAdded;
		dyn_string dynTmpDirFile;
		int idxOfScriptName;
		int i;
		bool fileLoaded;
		int canAccessFile;
				
		canAccessFile = access(strScriptsFileName, F_OK);
		
		if(canAccessFile == 0)
		{
			
			fileLoaded = fileToString(strScriptsFileName, scriptsFileInString);

			if (! fileLoaded )
			{
			
				DebugN(\"fwInstallation: Error loading the file: \" + strScriptsFileName);
				
			}
			else 
			{
				
				dynScriptsFileLines = strsplit(scriptsFileInString, \"\\n\");
				
				for( i = 1; i <= dynlen(dynScriptsFileLines); i++)
				{
					strScriptsFileLine = strrtrim(strltrim(dynScriptsFileLines[i]));
					
					if(strScriptsFileLine == \"\")
					{
						// this is a blank line
					}
					else if( strtok(strScriptsFileLine, \"#\") == 0)
					{
						// this is a comment
					}
					else
					{
						// this is a script entry
						dynAppend(dynLoadedScripts, strScriptsFileLine);
					}

				}
				

			}
		}
		else
		{
			DebugN(\"fwInstallation: The file : \" + strScriptsFileName + \" does not exist\");
		}
		
		// what should be added
		dynAppend(dynLinesToBeAdded, \"#begin \" + strComponentName);
		dynAppend(dynLinesToBeAdded, \"# if this parametrisation is empty that means that the scripts were already defined in the file\");
		dynAppend(dynLinesToBeAdded, \"\");
		
		for ( i = 1; i <= dynlen(dynScriptsToBeAdded); i++)
		{
			if(dynContains(dynLoadedScripts, dynScriptsToBeAdded[i]) > 0)
			{
				// the parametrisation is already done	
				DebugN(\"fwInstallation: The parametrisation is already done for: \" + dynScriptsToBeAdded[i]);	
			}
			else 
			{
				// update the loaded scripts - the scripts that were loaded from the old file
				dynAppend(dynLoadedScripts, dynScriptsToBeAdded[i]);
				
				// add the script file names to - the lines to be added
				
				// get the script name from the relative path
				
				dynTmpDirFile = strsplit(dynScriptsToBeAdded[i], \"/\");
				
				// get the index of the script file name
				idxOfScriptName = dynlen(dynTmpDirFile);
				
				// append the script file name to the lines to be added
				dynAppend(dynLinesToBeAdded, dynTmpDirFile[idxOfScriptName]);
				DebugN(\"fwInstallation: Adding the parametrisation for: \" + dynScriptsToBeAdded[i]);	
			}
		}
		
		dynAppend(dynLinesToBeAdded, \"\");
		dynAppend(dynLinesToBeAdded, \"#end \" + strComponentName);

		// add an empty line at the end of component definition - for readability
		dynAppend(dynLinesToBeAdded, \"\");		 
		
		// if the fwScripts.lst is empty the PVSS00ctl manager does not start
		// the fwInstallationFakeScript.ctl is added to correct this problem
		
		if(dynContains(dynLoadedScripts, \"fwInstallationFakeScript.ctl\"))
		{
		
		}
		else
		{
			dynAppend(dynLinesToBeAdded, \"fwInstallationFakeScript.ctl\");
		}
		
		// append the new lines to the dyn_string that contains lines from old file
		
		dynAppend(dynScriptsFileLines, dynLinesToBeAdded);
		
		fwInstallation_saveFile( dynScriptsFileLines, strScriptsFileName);

}

/** This function checks the progs file if the fwScripts.lst has been added to it

@return : 0 - if fwScripts.lst is added into progs file, -1 - if fwScripts.lst does not exist in progs file
@author M.Sliwinski
*/

int fwInstallation_fwScriptsAddedToProgsFile()
{

	bool fileLoaded;
	string strScriptsFileName = getPath(CONFIG_REL_PATH) + \"progs\";
	string scriptsFileInString;

			fileLoaded = fileToString(strScriptsFileName, scriptsFileInString);

			if (! fileLoaded )
			{
			
				return -1;
				
			}
			else 
			{
				if(strpos(scriptsFileInString, \"fwScripts.lst\") >= 0)
				{
					return 0;
				}
				else
				{
					return -1;
				}
				

			}
}

int _fwInstallation_CompareVersions(string installedComponentVersion, string requestedComponentVersion)
{
	dyn_uint installedComponentVersionLong,requestedComponentVersionLong;
	dyn_string installedComponentVersionStrings, requestedComponentVersionStrings;
	int result=1;
	int count,minCount,sameCount;

	requestedComponentVersionLong = strsplit(requestedComponentVersion,\".\");
	installedComponentVersionLong = strsplit(installedComponentVersion,\".\");

	if(dynlen(requestedComponentVersionLong) <= dynlen(installedComponentVersionLong))
	{
		minCount = dynlen(requestedComponentVersionLong);
		for(count=1;count<=minCount;count++)
		{
			if(installedComponentVersionLong[count] < requestedComponentVersionLong[count])
			{
				result = 0;
				break;
			}
			if(installedComponentVersionLong[count] > requestedComponentVersionLong[count])
			{
				break;
			}
		}
	} else {
		minCount = dynlen(installedComponentVersionLong);
		sameCount = 0;
		for(count=1;count<=minCount;count++)
		{
			if(installedComponentVersionLong[count] < requestedComponentVersionLong[count])
			{
				result = 0;
				break;
			}	
			if(installedComponentVersionLong[count] > requestedComponentVersionLong[count])
			{
				break;
			}
			if(installedComponentVersionLong[count] == requestedComponentVersionLong[count])
			{
				sameCount++;
			}
		}
		if((result == 1) && (sameCount == minCount))
		{
			result = 0;
		}
	}

	return result;

}		

/** This function reads the config file and retrieves the list of
proj_paths

@param proj_paths: the return value with a list of proj_paths

@author M.Sliwinski
*/

int fwInstallation_loadProjPaths(dyn_string & proj_paths)
{
	
	dyn_string parameter_Value;
	dyn_string configLines;
	
	bool fileLoaded = false;
	
	string fileInString;

	string tempLine;
	string tempParameter;
	string tempValue;
	string tempString; 

	string configPath = getPath(CONFIG_REL_PATH);
	string configFile = configPath + \"config\";
	
	int i, j ;
	

	
	fileLoaded = fileToString(configFile, fileInString);
	
	if (! fileLoaded )
	{
	
		Debug(\"\\n Cannot load \" + configFile + \" file\");
		return -1;
	}
	else 
	{
		Debug(\"\\n\" + configFile + \" - file loaded\");
	}

	configLines = strsplit(fileInString, \"\\n\");
	
// each line is loaded in a row of dyn_string configLines
	
	for(i = 1; i <= dynlen(configLines); i++)
	{
		tempLine = strltrim(strrtrim(configLines[i]));
		
		if(tempLine == \"\")
		{
		}
		else
		{				
				parameter_Value = strsplit(tempLine, \"=\");
				
				tempParameter = strltrim(strrtrim(parameter_Value[1]));
				
				if(tempParameter == \"proj_path\")
				{  
				
					tempValue = strltrim(strrtrim(parameter_Value[2]));
				
					strreplace(tempValue, \"\\\"\" , \"\");

				
				  // now value is without quotation marks
					
					dynAppend(proj_paths, tempValue);
				}
		}	
	}		
	return 1;				
}

/** this function deletes the component  files

@param componentFiles: the dyn_string with the names of the files to be deleted
@param installationDirectory: the name of the installation directory

@author M.Sliwinski
*/

int fwInstallation_deleteFiles(dyn_string & componentFiles, string installationDirectory)
{
	string fileToDelete;
	string cmd;
	string err;
	int x;
	int i;
	string result;
	int iReturn = 0;
	string logFile =  getPath(LOG_REL_PATH) + \"InstallationTool.log\";
	
	// Deleting the files
	
	for(i = 1; i <= dynlen(componentFiles); i++)
		{
			strreplace( installationDirectory, \"//\", \"/\" );
			
			// remove the first dot in file name
			fileToDelete = strltrim(componentFiles[i], \".\");
			
//SMS			Debug(\"\\n Deleting installationDir: \" + installationDirectory + \" file: \" + fileToDelete + \" - \");
			
			// on windows
			if (_WIN32) 
			{
				strreplace( installationDirectory , \"/\" , \"\\\\\");
				strreplace( fileToDelete , \"/\" , \"\\\\\");


				cmd = \"del \" +  installationDirectory + fileToDelete +  \" 2> \" + logFile;
				err = system(\"cmd /c \" + cmd);
				
				if (err != 0)
				{
						fwInstallation_showMessage(makeDynString(\"Could not delete file \" + installationDirectory + fileToDelete));
						iReturn = -1;
				}
			}
			else  // on linux
			{
				cmd = \"rm \" +  installationDirectory + fileToDelete +  \" 2> \" + logFile;
				err = system(cmd);
				if (err != 0)
				{
						fwInstallation_showMessage(makeDynString(\"Could not delete file \" + installationDirectory + fileToDelete));
						iReturn = -1;
				}
			}
			
//SMS			Debug(err);
			x = fileToString (logFile, result);
			
//SMS			Debug(x);
			
		}
		
		return iReturn;
}






fwInstallation_writeToLog(string message)
{
	file logFile;
	dyn_string tempPaths;
	string tempPath;
	int i;
	
	string fileName = logFileName.text;
	
	strreplace(fileName, \"\\\\\", \"/\");

	tempPaths = strsplit(fileName, \"/\");
	tempPath = \"\";
	for(i=1; i<dynlen(tempPaths); i++)
	{
		tempPath = tempPath + tempPaths[i] + \"/\";
	}	
	
	if( _WIN32 )
	{
		strreplace(fileName, \"/\", \"\\\\\");
		strreplace(tempPath, \"/\", \"\\\\\");
	}

	if(access(tempPath, F_OK) != 0)
	{
		system(\"mkdir \"+tempPath);
	}
	fileName = strrtrim(fileName, \"\\\"\");
	fileName = strrtrim(fileName, \"\\\\\");
	logFile = fopen(fileName,\"a\");
	if(ferror(logFile) != 0)
	{
		DebugN(\"fwInstallation: Cannot write to LogFile \"+fileName);
	} else {
		fprintf(logFile,\"%s\",message);
	}
	fclose(logFile);
}

fwInstallation_writeToMainLog(string message)
{
	file logFile;
	dyn_string tempPaths;
	string tempPath;
	int i;
	
	string fileName = getPath(LOG_REL_PATH) + \"/fwInstallation.log\";
	
	strreplace(fileName, \"\\\\\", \"/\");

	if( _WIN32 )
	{
		strreplace(fileName, \"/\", \"\\\\\");
		strreplace(tempPath, \"/\", \"\\\\\");
	}

	logFile = fopen(fileName,\"a\");
	if(ferror(logFile) != 0)
	{
		DebugN(\"fwInstallation: Cannot write to LogFile \"+fileName);
	} else {
		fprintf(logFile,\"%s\\n\",message);
	}
	fclose(logFile);
}

string _fwInstallation_baseDir(string filePath)
{
	string temp_string = filePath;
	dyn_string tempPath = strsplit(temp_string, \"/\");
	string returnString = \"\";	
	int i;

	if(dynlen(tempPath) > 1)
	{
		for (i=1; i<dynlen(tempPath); i++)
		{
			temp_string = tempPath[i];
			returnString += temp_string +\"/\";
		}
	}
	return returnString;
}

string _fwInstallation_fileName(string filePath)
{
	string temp_string = filePath;
	dyn_string tempPath = strsplit(strrtrim(strltrim(temp_string, \" \"), \" \"), \"/\");
	string returnString = \"\";	
	int i;

	if(dynlen(tempPath) > 0)
	{
		returnString = tempPath[dynlen(tempPath)];
	}
	return returnString;
}

fwInstallation_enablePanel()
{
	txtSourceDir.enabled = TRUE;
	tblInstalledComponents.enabled = TRUE;
	tblAvailableComponents.enabled = TRUE;
	list.enabled = TRUE;
	btnAdvanced.enabled = TRUE;
	btnApplyInstall.enabled = TRUE;
	btnApplyDelete.enabled = TRUE;
	btnClose.enabled = TRUE;
	btnRefresh.enabled = TRUE;
	btnSelectSourceDir.enabled = TRUE;
	Button1.enabled = TRUE;
}

fwInstallation_disablePanel()
{
	txtSourceDir.enabled = FALSE;
	tblInstalledComponents.enabled = FALSE;
	tblAvailableComponents.enabled = FALSE;
	list.enabled = FALSE;
	btnAdvanced.enabled = FALSE;
	btnApplyInstall.enabled = FALSE;
	btnApplyDelete.enabled = FALSE;
	btnClose.enabled = FALSE;
	btnRefresh.enabled = FALSE;
	btnSelectSourceDir.enabled = FALSE;
	Button1.enabled = FALSE;
}

" 0
 2
"CBRef""1"
"EClose""main()
{
	int i;	   
}" 0

""
DISPLAY_LAYER, 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
LAYER, 0 
1
LANG:1 6 Layer1
2 29
"logFileName"
""
1 0 590 E E E 0 E 0 E N {0,0,0} E N "_3DFace" E E
 E E
25 0 0 0 0 0
EE E
0
1
LANG:1 0 
1
"dashclr"N "_Transparent"
E E 0 1 1 0 1 E U  1 E 2 592 768 618
0 2 0 "s" 0 0 0 64 0 0  2 592
 1
1
LANG:1 117 -microsoft windows-Courier New-normal-r-normal-*-*-60-100-100-*-*-iso8859-1|-8,0,0,0,400,0,0,0,0,3,2,1,49,Courier New
0 ""
1
LANG:1 0 
6 28
"ErrorColor2"
""
1 520 416 E E E 1 E 0 E N "_Transparent" E N {255,255,0} E E
 E E
24 0 0 0 0 0
EE E
0
1
LANG:1 0 
1
"dashclr"N "_Transparent"
E E 0 1 1 0 1 E U  1 E 520 396 550 416
30 15
"frmDelete"
""
1 410 475 E E E 1 E 1 E N "_3DText" E N "_Transparent" E E
 E E
15 0 0 0 0 0
EE E
1
1
LANG:1 0 
0
E E 0 1 1 0 1 E U  0 E 410 40 760 480
1
LANG:1 107 -microsoft windows-Arial-normal-r-normal-*-*-120-100-100-*-*-iso8859-1|-13,0,0,0,400,0,0,0,0,3,2,1,34,Arial
0 ""
1
LANG:1 24 View / Delete Components
2 0
"Text1"
""
1 22 11 E E E 1 E 1 E N {0,0,0} E N "_Transparent" E E
 E E
1 0 0 0 0 0
EE E
0
1
LANG:1 0 
1
"dashclr"N "_Transparent"
E E 0 1 1 0 1 E U  0 E 24 13 255 35
0 2 0 "s" 0 0 0 192 0 0  24 13
 1
1
LANG:1 107 -microsoft windows-Arial-normal-r-normal-*-*-160-100-100-*-*-iso8859-1|-19,0,0,0,400,0,0,0,0,3,2,1,34,Arial
0 ""
1
LANG:1 27 Framework Installation Tool
2 10
"Text2"
""
1 30 59 E E E 1 E 1 E N {0,0,0} E N "_Transparent" E E
 E E
10 0 0 0 0 0
EE E
0
1
LANG:1 0 
1
"dashclr"N "_Transparent"
E E 0 1 1 0 1 E U  0 E 32 61 198 77
0 2 0 "s" 0 0 0 192 0 0  32 61
 1
1
LANG:1 107 -microsoft windows-Arial-normal-r-normal-*-*-120-100-100-*-*-iso8859-1|-13,0,0,0,400,0,0,0,0,3,2,1,34,Arial
0 ""
1
LANG:1 27 Look for new components in:
30 18
"frmInstall"
""
1 20 480 E E E 1 E 1 E N "_3DText" E N "_Transparent" E E
 E E
18 0 0 0 0 0
EE E
1
1
LANG:1 0 
0
E E 0 1 1 0 1 E U  0 E 20 40 390 480
1
LANG:1 107 -microsoft windows-Arial-normal-r-normal-*-*-120-100-100-*-*-iso8859-1|-13,0,0,0,400,0,0,0,0,3,2,1,34,Arial
0 ""
1
LANG:1 18 Install Components
2 23
"Text4"
""
1 30 120 E E E 1 E 1 E N {0,0,0} E N "_Transparent" E E
 E E
21 0 0 0 0 0
EE E
0
1
LANG:1 0 
1
"dashclr"N "_Transparent"
E E 0 1 1 0 1 E U  0 E 32 122 179 138
0 2 0 "s" 0 0 0 192 0 0  32 122
 1
1
LANG:1 105 -microsoft windows-Arial-bold-r-normal-*-*-120-100-100-*-*-iso8859-1|-13,0,0,0,700,0,0,0,0,3,2,1,34,Arial
0 ""
1
LANG:1 21 Available Components:
2 30
"Text6"
""
1 20 610 E E E 1 E 1 E N {0,0,0} E N "_Transparent" E E
 E E
25 0 0 0 0 0
EE E
0
1
LANG:1 0 
1
"dashclr"N "_Transparent"
E E 0 1 1 0 1 E U  0 E 22 612 148 628
0 2 0 "s" 0 0 0 64 0 0  22 612
 1
1
LANG:1 107 -microsoft windows-Arial-normal-r-normal-*-*-110-100-100-*-*-iso8859-1|-11,0,0,0,400,0,0,0,0,3,2,1,34,Arial
0 ""
1
LANG:1 13 Version 2.0.6
2 20
"Text3"
""
1 420 56 E E E 1 E 1 E N {0,0,0} E N "_Transparent" E E
 E E
19 0 0 0 0 0
EE E
0
1
LANG:1 0 
1
"dashclr"N "_Transparent"
E E 0 1 1 0 1 E U  0 E 422 58 563 74
0 2 0 "s" 0 0 0 192 0 0  422 58
 1
1
LANG:1 105 -microsoft windows-Arial-bold-r-normal-*-*-120-100-100-*-*-iso8859-1|-13,0,0,0,700,0,0,0,0,3,2,1,34,Arial
0 ""
1
LANG:1 21 Installed Components:
6 34
"ErrorColor1"
""
1 418 416 E E E 1 E 0 E N "_Transparent" E N {255,255,0} E E
 E E
27 0 0 0 0 0
EE E
0
1
LANG:1 0 
1
"dashclr"N "_Transparent"
E E 0 1 1 0 1 E U  1 E 418 396 498 416
2 27
"ErrorText"
""
1 420 396 E E E 1 E 0 E N {0,0,0} E N "_Transparent" E E
 E E
23 0 0 0 0 0
EE E
0
1
LANG:1 0 
1
"dashclr"N "_Transparent"
E E 0 1 1 0 1 E U  0 E 422 398 661 430
0 2 0 "s" 0 0 0 192 0 0  422 398
 2
1
LANG:1 107 -microsoft windows-Arial-normal-r-normal-*-*-120-100-100-*-*-iso8859-1|-13,0,0,0,400,0,0,0,0,3,2,1,34,Arial
0 ""
1
LANG:1 42 Components are  not   properly installed, 
1
LANG:1 107 -microsoft windows-Arial-normal-r-normal-*-*-120-100-100-*-*-iso8859-1|-13,0,0,0,400,0,0,0,0,3,2,1,34,Arial
0 ""
1
LANG:1 37 e.g. required components are missing.
20 33
"ShowInstalledSubComponents"
""
1 420 80 E E E 1 E 1 E N "_3DText" E N "_3DFace" E E
 E E
26 0 0 0 0 0
EE E
0
1
LANG:1 0 
0
1
LANG:1 107 -microsoft windows-Arial-normal-r-normal-*-*-120-100-100-*-*-iso8859-1|-13,0,0,0,400,0,0,0,0,3,2,1,34,Arial
0 ""
418 78 612 112
1
T 
1
LANG:1 24 Show also Sub-Components
 0
1
LANG:1 0 
 E  E  0 0 0 0 0
1
E E 
E"main(int button, bool state)
{
	// get all installed components and display it in a table
	fwInstallation_getInstalledComponents();
}" 0
20 32
"ShowSubComponents"
""
1 30 140 E E E 1 E 1 E N "_3DText" E N "_3DFace" E E
 E E
25 0 0 0 0 0
EE E
0
1
LANG:1 0 
0
1
LANG:1 107 -microsoft windows-Arial-normal-r-normal-*-*-120-100-100-*-*-iso8859-1|-13,0,0,0,400,0,0,0,0,3,2,1,34,Arial
0 ""
28 138 222 172
1
T 
1
LANG:1 24 Show also Sub-Components
 0
1
LANG:1 0 
 E  E  0 0 0 0 0
1
E E 
E"main(int button, bool state)
{
	fwInstallation_getComponentsInfo(\"tblAvailableComponents\", \"txtSourceDir\");
}" 0
25 1
"tblInstalledComponents"
""
1 331 -34 E E E 1 E 1 E N "_WindowText" E N "_Window" E E
 E "/**	if the user double clicks on the componentName column 
the panel with the component details is shown
*/
main()
{	
	
	int xpos;
	string columnName;
	int columnNr;
	string componentName;
	string descFile = \"\";
	string typeOfDescription = \"PVSSDB\";

	// get shape of the table	
	shape tab = getShape(\"tblInstalledComponents\");
	
	// get the coordinates of current cell	
	getValue(tab, \"currentCell\", xpos, columnNr);
	
	// get the column name
	columnName = tab.currentColumn();

	 if((columnName == \"componentName\") || (columnName == \"componentVersion\"))
	 {
		// get the name of a component  
		componentName += tab.cellValueRC(xpos, \"componentName\");
			 
			// display the panel with component details 
	 		ChildPanelOnCentral(\"fwInstallation/fwInstallationComponentDetails.pnl\", \"fwInstallation_ComponentDetails:PVSS\",
			 makeDynString(\"$componentName:\" + componentName, \"$descFile:\" + descFile , \"$typeOfDescription:\" + typeOfDescription, \"$sourceDir:\" + \" \"));
		 }
}" 0

2 0 0 0 0 0
EE E
0
1
LANG:1 0 
0
1
LANG:1 106 -microsoft windows-Arial-normal-r-normal-*-*-120-100-100-*-*-iso8859-1|-13,0,0,0,400,0,0,0,0,0,0,0,0,Arial
0 ""
418 108 752 392
"main()
{
	// get all installed components and display it in a table
	fwInstallation_getInstalledComponents();
}" 0
 "/**	if the user  clicks on the Status column 
the column value is changed ( Delete -> \"\" , or \"\" -> Delete
*/
main(int row, string column, string value)
{
		// check the name of column where the user clicked
		if (column == \"colStatus\") 
		{
		
			// check the value of the cell
			if (value == \"Delete\") 
			{
				// set the empty value
				setValue(\"\",\"cellValueRC\",row,\"colStatus\",\" \");
			}
			else 
			{
				// set the Delete value
				setValue(\"\",\"cellValueRC\",row,\"colStatus\",\"Delete\");
			}
		}
					
}" 0
 1 0 1 3 1 "componentName" 0 1 0 "s" 1
LANG:1 14 Component Name
E1
LANG:1 50 Subcomponents are shown with a leading underscore.
 182 "componentVersion" 0 -1 0 "s" 1
LANG:1 7 Version
E1
LANG:1 0 
 69 "colStatus" 0 1 0 "s" 1
LANG:1 8 Delete ?
E1
LANG:1 0 
 60 26 26 "" 1 1
LANG:1 2 #1
8 30 1
LANG:1 106 -microsoft windows-Arial-normal-r-normal-*-*-120-100-100-*-*-iso8859-1|-13,0,0,0,400,0,0,0,0,0,0,0,0,Arial
0 ""
0 2 0 3 0
1 0
13 19
"btnRefresh"
""
1 600 440 E E E 1 E 1 E N "_3DText" E N "_3DFace" E E
 E E
19 0 0 0 0 0
EE E
0
1
LANG:1 0 
0
1
LANG:1 107 -microsoft windows-Arial-normal-r-normal-*-*-120-100-100-*-*-iso8859-1|-13,0,0,0,400,0,0,0,0,3,2,1,34,Arial
0 ""
598 438 672 472
T 
1
LANG:1 7 Refresh
"main()
{
	// refresh the  table widget

	fwInstallation_getInstalledComponents();
}" 0
 E E E
13 3
"btnApplyDelete"
""
1 680 440 E E E 1 E 1 E N "_3DText" E N "_3DFace" E E
 E E
4 0 0 0 0 0
EE E
0
1
LANG:1 0 
0
1
LANG:1 107 -microsoft windows-Arial-normal-r-normal-*-*-120-100-100-*-*-iso8859-1|-13,0,0,0,400,0,0,0,0,3,2,1,34,Arial
0 ""
678 438 752 472
T 
1
LANG:1 6 Delete
"// Delete the components
main()
{
	string strComponentsNames;
	dyn_string dynComponentsNames;
	dyn_string componentsNamesInOrder;
	
	dyn_float dreturnf;
	dyn_string dreturns;
	int i;
	bool componentDeleted = false;
	fwInstallation_disablePanel();
	
	// look for all the components that have \"Delete\" in the colStatus column of a table with installed components
	// store them in a string strComponentsNames separated by '|' sign
	for(  i = 0 ; i < tblInstalledComponents.lineCount(); i++)
	{
		if(tblInstalledComponents.cellValueRC(i, \"colStatus\") == \"Delete\")
		{
			// store the component names in string		
			strComponentsNames += tblInstalledComponents.cellValueRC(i, \"componentName\") + \"|\";

		}

	}
	
	// show the panel that informs user about the components to be deleted
	
	ChildPanelOnCentralReturn(\"fwInstallation/fwInstallationToDelete.pnl\", \"fwInstallation_ToDelete\",
			 makeDynString(\"$componentsNames:\" + strComponentsNames) , dreturnf, dreturns);

	// check the return value
	if(dreturns[1] == \"Delete\") // it the return value of a panel is \"Delete\" - delete the components
	{
		
		// Delete the components
			
			// put the component names in dyn_string	
			dynComponentsNames = strsplit(strComponentsNames, \"|\");
			
			// put the components in order depending on dependencies between the components
			fwInstallation_putComponentsInOrder_Delete( dynComponentsNames,  componentsNamesInOrder);

			// delete the components - one by one
			for (i =1; i <= dynlen(componentsNamesInOrder); i++)
			{
				fwInstallation_deleteComponent(componentsNamesInOrder[i], componentDeleted);
				if(!componentDeleted)
				{
					fwInstallation_writeToMainLog(formatTime(\"[%Y-%m-%d_%H:%M:%S] \",getCurrentTime()) + componentsNamesInOrder[i] + \" not deleted\");
				}
			}	
	
		// refresh the main panel
		fwInstallation_getInstalledComponents();
		fwInstallation_getComponentsInfo(\"tblAvailableComponents\", \"txtSourceDir\");

		// show the restart panel
		if(componentDeleted)
		{
			ChildPanelOnCentral(\"fwInstallation/fwInstallationRestart.pnl\", \"fwInstallationRestart\", makeDynString(\"$action:\" + \"delete\"));
		}
	}

	fwInstallation_enablePanel(); 

}


/** This function puts the components to be deleted in order in which they should be deleted
The function only checks if the component chosen for deleting depend on each other.
The function operates on the component information contained in the PVSS DB

algorithm: suppose we have the following components to delete:  com1, com2, com3
the dependencies are following:
	com1: is required by com2
	com2: is required by com3
	com3: is nor required by them
We can first delete the com3 because it is not required by com1 i com3
	the dependencies are following:
	com1: is required by com2
	com2: is not required by any component
If there is a loop: com1 is required by com2 and com2 is required by com1 the components can not be ordered

@param componentsNames: the dyn_string of the components to be put in order before deleting 
@param componentsNamesInOrder: the dyn_string of the ordered components to be deleted

@author M.Sliwinski
*/

fwInstallation_putComponentsInOrder_Delete(dyn_string componentsNames, dyn_string & componentsNamesInOrder)
{
	dyn_dyn_string dependencies; //  first column - component name, next columns - components that require this component
	dyn_string dynDependentComponents;
	string tempComponentName;
	bool emptyListExists = true;
	int i, j, k;
	
	// build the dependencies table
	// for each compomponent
	for(i = 1; i <= dynlen(componentsNames); i++)
	{
		// build the dependencies table
		dynAppend(dependencies[i] , componentsNames[i]);
		
		// get the list of dependent components
		fwInstallation_getListOfDependentComponents(componentsNames[i], dynDependentComponents);
		
		// append the dependent components
		dynAppend(dependencies[i], dynDependentComponents);
	}
	 

	// put the components in order - algorithm is described in the comment before the function
	while(emptyListExists)
	{
		emptyListExists = false;
			
			// for each component	
			for(i = 1; i <= dynlen(componentsNames); i++)
			{
				// if it is not required by other components
				if((dynlen(dependencies[i]) == 1) && (dependencies[i][1] != \"EMPTY\"))
				{
					emptyListExists = true;

					tempComponentName = dependencies[i][1];
					
					// remove the component name from the dependencies table ( set it to EMPTY value )
					dependencies[i][1] = \"EMPTY\"; 
					
					// put it at the end of the  components in order
					dynAppend(componentsNamesInOrder, tempComponentName);
					
					// remove the component from the list
					for(j = 1; j <= dynlen(componentsNames); j++)
					{
						
						k = dynContains(dependencies[j], tempComponentName);
						
						if(k > 0)
						{
							// this component no longer requires other components
							dynRemove(dependencies[j], k);	
						}	
					}
				}
			}
	}
	
	// if there were unsolved dependencies copy the components to the end of the list
	
	for(i = 1; i <= dynlen(componentsNames); i++)
	{
		if(dependencies[i][1] != \"EMPTY\")
		{
			dynAppend(componentsNamesInOrder, dependencies[i][1]);
		}	
	}
		
}

/** This function gets the list of dependent components. This functions from the list of  all  installed components
 retrieves the list of components that require strComponentName

@param strComponentName: the name of the component for which we would like to find dependent components
@param dynDependentComponents: the dyn_string of components that require the strComponentName component
@author M.Sliwinski
*/

fwInstallation_getListOfDependentComponents(string strComponentName, dyn_string & dynDependentComponents)
{

	dyn_string dynInstalledComponents;
	dyn_string dynRequiredComponents;
	dyn_string dynTmpNameVersion;
	string strTmpName;
	int i, j, k;
	
	dynClear(dynDependentComponents);
	
	// get all the components installed in the system
	dynInstalledComponents =  dpNames(\"*\", \"_FwInstallationComponents\");
	
	// check all the components whether they require the strComponentName
	for(i = 1; i <= dynlen(dynInstalledComponents); i++) 
	{
		
		 // remove the system name
		dynInstalledComponents[i] = dpSubStr( dynInstalledComponents[i], DPSUB_DP ); 
		
		// remove the fwInstallation_ prefix
		strreplace(dynInstalledComponents[i], \"fwInstallation_\", \"\");
		
		
		if( dynInstalledComponents[i] != strComponentName)
		{
			// retrieve the required components		
			dpGet(\"fwInstallation_\" + dynInstalledComponents[i] + \".requiredComponents:_online.._value\", dynRequiredComponents);

				
			// check whether the strComponentName is required by this component
			for(j = 1; j <= dynlen(dynRequiredComponents); j++)
			{	
				// clear the tmp dyn_string
				dynClear(dynTmpNameVersion);
				
				// get the name and version
				dynTmpNameVersion = strsplit(dynRequiredComponents[j], \"=\");
				
				// get the name
				strTmpName = strltrim(strrtrim(dynTmpNameVersion[1]));
				
				
				if(strTmpName == strComponentName)
				{
					// add the component to the dynDependentComponents
					 
					dynAppend(dynDependentComponents, dynInstalledComponents[i]);	
				}
			}
		}				
	}
	

}

/** this function deletes the component files, the component information from the config file
	and the internal DP created by the installation tool with the description of a component. 
	This function does not delete the component data point types ( ETM is planning to 
	add the functionality of deleting the DPT, DP from the ASCII Manager ).

@param componentName: the name of a component to be deleted

@author M.Sliwinski, changed by S. Schmeling
*/

int fwInstallation_deleteComponent(string componentName, bool & componentDeleted)
{

	dyn_string componentFiles;
	dyn_string configFiles_general;
	dyn_string configFiles_windows;
	dyn_string configFiles_linux;	
	dyn_string initFiles;
	dyn_string postInstallFiles;
	dyn_string deleteFiles;
	dyn_string postDeleteFiles;
	dyn_string dplistFiles;
	dyn_string dynDescFile;
	dyn_string dynDependentComponents;
	dyn_string dynSubComponents;
	dyn_string dynScriptFiles;
	string descFile;
	string strDependentComponentsNames;
	dyn_string dreturns;
	dyn_float dreturnf;
	int iReturn;
	int	errorDeletingComponent;
	int i,k;
	dyn_string dynFileNames;		
	string installationDirectory, tempString;
	int error;
	int errorCounter = 0;
	string errorString,descFileName;
	dyn_string strErrors = \"\";
	bool deletionAborted = FALSE;

	dyn_string dynPostDeleteFiles_all, dynPostDeleteFiles_current;
	string componentDeleteFile;

	// get the installation directory
	dpGet(\"fwInstallation_\" + componentName + \".installationDirectory:_online.._value\", installationDirectory);
		
	//begin check the component dependencies - if it is required by other components 

		// get a list of components that require component being deleted
		fwInstallation_getListOfDependentComponents( componentName,   dynDependentComponents);

			if( dynlen(dynDependentComponents) >= 1)
			{
				// store the dependent components in a string 
				for(i = 1; i <= dynlen(dynDependentComponents); i++)
				{
					strDependentComponentsNames += dynDependentComponents[i] + \"|\";
				}					
				
					// ask the user if he wants to delete this component - other components are using it
							ChildPanelOnCentralReturn(\"fwInstallation/fwInstallationDependency.pnl\", \"fwInstallation_Dependency\",
					 makeDynString(\"$strDependentNames:\" + strDependentComponentsNames , \"$componentName:\" + componentName, \"$callingPanel:\" + \"ToDelete\"), dreturnf, dreturns);
			
						// check the return value of fwInstallationDependency .pnl
						if(dreturns[1] == \"Install_Delete\")
						{
							// delete the component and update other components
							for( i = 1; i <= dynlen(dynDependentComponents); i++)
							{
								// in all dependent components set the value that the required component is not installed
								dpSet(\"fwInstallation_\" + dynDependentComponents[i] + \".requiredInstalled:_original.._value\", false);
							}

						}
						else if(dreturns[1] == \"DoNotInstall_DoNotDelete\")
						{
							// do not delete the component
							deletionAborted = TRUE;
						}
			}


		// check if all files are deletable
		
		
			dpGet(\"fwInstallation_\" + componentName + \".componentFiles:_online.._value\", dynFileNames);
			for (k=1; k<=dynlen(dynFileNames); k++)
			{
				error = access(installationDirectory + \"/\" + dynFileNames[k],W_OK);
				if(error!=0)
				{
					errorCounter++;
					errorString = \"fwInstallation: the file \"+ installationDirectory + \"/\" + dynFileNames[k]+\" cannot be deleted\";
					dynAppend(strErrors, errorString);
					fwInstallation_showMessage(makeDynString(errorString));
				}
			}
			dpGet(\"fwInstallation_\" + componentName + \".configFiles.configGeneral:_online.._value\", dynFileNames);
			for (k=1; k<=dynlen(dynFileNames); k++)
			{
				error = access(installationDirectory + \"/\" + dynFileNames[k],W_OK);
				if(error!=0)
				{
					errorCounter++;
					errorString = \"fwInstallation: the file \"+ installationDirectory + \"/\" + dynFileNames[k]+\" cannot be deleted\";
					dynAppend(strErrors, errorString);
					fwInstallation_showMessage(makeDynString(errorString));
				}
			}
			dpGet(\"fwInstallation_\" + componentName + \".configFiles.configLinux:_online.._value\", dynFileNames);
			for (k=1; k<=dynlen(dynFileNames); k++)
			{
				error = access(installationDirectory + \"/\" + dynFileNames[k],W_OK);
				if(error!=0)
				{
					errorCounter++;
					errorString = \"fwInstallation: the file \"+ installationDirectory + \"/\" + dynFileNames[k]+\" cannot be deleted\";
					dynAppend(strErrors, errorString);
					fwInstallation_showMessage(makeDynString(errorString));
				}
			}
			dpGet(\"fwInstallation_\" + componentName + \".configFiles.configWindows:_online.._value\", dynFileNames);
			for (k=1; k<=dynlen(dynFileNames); k++)
			{
				error = access(installationDirectory + \"/\" + dynFileNames[k],W_OK);
				if(error!=0)
				{
					errorCounter++;
					errorString = \"fwInstallation: the file \"+ installationDirectory + \"/\" + dynFileNames[k]+\" cannot be deleted\";
					dynAppend(strErrors, errorString);
					fwInstallation_showMessage(makeDynString(errorString));
				}
			}
			dpGet(\"fwInstallation_\" + componentName + \".initFiles:_online.._value\", dynFileNames);
			for (k=1; k<=dynlen(dynFileNames); k++)
			{
				error = access(installationDirectory + \"/\" + dynFileNames[k],W_OK);
				if(error!=0)
				{
					errorCounter++;
					errorString = \"fwInstallation: the file \"+ installationDirectory + \"/\" + dynFileNames[k]+\" cannot be deleted\";
					dynAppend(strErrors, errorString);
					fwInstallation_showMessage(makeDynString(errorString));
				}
			}
			dpGet(\"fwInstallation_\" + componentName + \".deleteFiles:_online.._value\", dynFileNames);
			for (k=1; k<=dynlen(dynFileNames); k++)
			{
				error = access(installationDirectory + \"/\" + dynFileNames[k],W_OK);
				if(error!=0)
				{
					errorCounter++;
					errorString = \"fwInstallation: the file \"+ installationDirectory + \"/\" + dynFileNames[k]+\" cannot be deleted\";
					dynAppend(strErrors, errorString);
					fwInstallation_showMessage(makeDynString(errorString));
				}
			}
			dpGet(\"fwInstallation_\" + componentName + \".dplistFiles:_online.._value\", dynFileNames);
			for (k=1; k<=dynlen(dynFileNames); k++)
			{
				error = access(installationDirectory + \"/\" + dynFileNames[k],W_OK);
				if(error!=0)
				{
					errorCounter++;
					errorString = \"fwInstallation: the file \"+ installationDirectory + \"/\" + dynFileNames[k]+\" cannot be deleted\";
					dynAppend(strErrors, errorString);
					fwInstallation_showMessage(makeDynString(errorString));
				}
			}
			dpGet(\"fwInstallation_\" + componentName + \".descFile:_online.._value\", descFileName);
			error = access(installationDirectory + \"/\" + descFileName,W_OK);
			if(error!=0)
			{
				errorCounter++;
				errorString = \"fwInstallation: the file \"+ installationDirectory + \"/\" + descFileName +\" cannot be deleted\";
				dynAppend(strErrors, errorString);
				fwInstallation_showMessage(makeDynString(errorString));
			}
			dpGet(\"fwInstallation_\" + componentName + \".scriptFiles:_online.._value\", dynFileNames);
			for (k=1; k<=dynlen(dynFileNames); k++)
			{
				error = access(installationDirectory + \"/\" + dynFileNames[k],W_OK);
				if(error!=0)
				{
					errorCounter++;
					errorString = \"fwInstallation: the file \"+ installationDirectory + \"/\" + dynFileNames[k]+\" cannot be deleted\";
					dynAppend(strErrors, errorString);
					fwInstallation_showMessage(makeDynString(errorString));
				}
			}
			dpGet(\"fwInstallation_\" + componentName + \".postInstallFiles:_online.._value\", dynFileNames);
			for (k=1; k<=dynlen(dynFileNames); k++)
			{
				error = access(installationDirectory + \"/\" + dynFileNames[k],W_OK);
				if(error!=0)
				{
					errorCounter++;
					errorString = \"fwInstallation: the file \"+ installationDirectory + \"/\" + dynFileNames[k]+\" cannot be deleted\";
					dynAppend(strErrors, errorString);
					fwInstallation_showMessage(makeDynString(errorString));
				}
			}
			dpGet(\"fwInstallation_\" + componentName + \".postDeleteFiles:_online.._value\", dynFileNames);
			dynPostDeleteFiles_current = dynFileNames;
			for (k=1; k<=dynlen(dynFileNames); k++)
			{
				error = access(installationDirectory + \"/\" + dynFileNames[k],W_OK);
				if(error!=0)
				{
					errorCounter++;
					errorString = \"fwInstallation: the file \"+ installationDirectory + \"/\" + dynFileNames[k]+\" cannot be deleted\";
					dynAppend(strErrors, errorString);
					fwDeleteation_showMessage(makeDynString(errorString));
				}
			}

			if(errorCounter!=0)
			{
				ChildPanelOnCentralReturn(\"fwInstallation/fwInstallationDependency.pnl\", \"fwInstallation_Dependency\",
					 makeDynString(\"$strDependentNames:\" + strErrors , \"$componentName:\" + componentName, \"$callingPanel:\" + \"DeleteChecker\"), dreturnf, dreturns);
				// check the return value
				if(dreturns[1] == \"Install_Delete\")
				{
					errorString = \"fwInstallation: \"+errorCounter+\" error(s) found. De-Installation of \"+componentName+\" will continue on user request\";
					fwInstallation_showMessage(makeDynString(errorString));
				}
				else if(dreturns[1] == \"DoNotInstall_DoNotDelete\")
				{
					errorString = \"fwInstallation: \"+errorCounter+\" error(s) found. De-Installation of \"+componentName+\" is aborted\";
					fwInstallation_showMessage(makeDynString(errorString));
					deletionAborted = TRUE;
				}
			}


//end check the component dependencies	

	if(!deletionAborted)
	{
		logFileName.text = installationDirectory + \"/log/fwDeInstallation_\"+componentName+\"_\"+formatTime(\"%Y%m%d_%H%M%S\",getCurrentTime())+\".log\\\"\";
		fwInstallation_writeToMainLog(formatTime(\"[%Y-%m-%d_%H:%M:%S] \",getCurrentTime()) + \"Starting to delete \" + componentName);
	
		fwInstallation_showMessage(makeDynString(\"Deleting \" + componentName + \" ... \")); 
		
		
		// retrieve the information about the sub components
		
		dpGet(\"fwInstallation_\" + componentName + \".subComponents:_online.._value\", dynSubComponents);
		
		// delete all subcomponents
		for(i = 1; i <= dynlen(dynSubComponents); i++)
		{
			fwInstallation_showMessage(makeDynString(\"   Deleting sub components ..\"));
			
			// delete subcomponent
			fwInstallation_deleteComponent(dynSubComponents[i], componentDeleted);
		}	
		
		// retrieve the information about the files	to be deleted
		
		// retrieve  component files ( panels, scripts )
		
		dpGet(\"fwInstallation_\" + componentName + \".componentFiles:_online.._value\", componentFiles);
		
		// retrieve config files
		dpGet(\"fwInstallation_\" + componentName + \".configFiles.configGeneral:_online.._value\", configFiles_general);
		dpGet(\"fwInstallation_\" + componentName + \".configFiles.configLinux:_online.._value\", configFiles_linux);
		dpGet(\"fwInstallation_\" + componentName + \".configFiles.configWindows:_online.._value\", configFiles_windows);
			
		// retrieve init files
		dpGet(\"fwInstallation_\" + componentName + \".initFiles:_online.._value\", initFiles);
		
		// retrieve dplist files
		dpGet(\"fwInstallation_\" + componentName + \".dplistFiles:_online.._value\", dplistFiles);
		
		// retrieve description file
		dpGet(\"fwInstallation_\" + componentName + \".descFile:_online.._value\", descFile);
		
		// retrieve the script files
		
		dpGet(\"fwInstallation_\" + componentName + \".scriptFiles:_online.._value\", dynScriptFiles);
		
		
		// retrieve the postinstall files
		
		dpGet(\"fwInstallation_\" + componentName + \".postInstallFiles:_online.._value\", postInstallFiles);
		
		dynDescFile = makeDynString(descFile);

		// retrieve delete files
		dpGet(\"fwInstallation_\" + componentName + \".deleteFiles:_online.._value\", deleteFiles);
		// retrieve postDelete files
		dpGet(\"fwInstallation_\" + componentName + \".postDeleteFiles:_online.._value\", postDeleteFiles);
		
// begin store the postDelete files in a datapoint
			
		// get all the post delete files
		dpGet(\"fwInstallationInfo.postDeleteFiles:_online.._value\", dynPostDeleteFiles_all);
		
		dynClear(dynPostDeleteFiles_current);
		if(dynlen(postDeleteFiles)>0)
			for(i=1; i<=dynlen(postDeleteFiles); i++)
				dynAppend(dynPostDeleteFiles_current, installationDirectory +\"/\"+ postDeleteFiles[i]);
		// append the name of the current component post delete files
		dynAppend(dynPostDeleteFiles_all, dynPostDeleteFiles_current);
		
		// store all the post delete files				
		dpSet(\"fwInstallationInfo.postDeleteFiles:_original.._value\", dynPostDeleteFiles_all);			


// end store the postDelete files in a datapoint

		
		if(installationDirectory == \"\")
		{
			DebugN(\"ERROR: The installation directory for the \" + componentName + \" does not exist or is not specified!\");
		}
		else
		{
			
// execute the delete script

			if(dynlen(deleteFiles) > 0 ) 
			{
				fwInstallation_showMessage(makeDynString(\"    Executing the delete file ... \"));

				for(i =1; i <= dynlen(deleteFiles); i++)
				{
					componentDeleteFile = deleteFiles[i];
					// read the file and execute it
												
					fwInstallation_evalScriptFile( installationDirectory +\"/\"+ componentDeleteFile , iReturn);
					
					if(iReturn == -1)
					{
						fwInstallation_showMessage(makeDynString(\"    	Error: executing the delete file: \" + componentDeleteFile));
						
						errorDeletingComponent = -1;
		
		
					}
				}
			}

// end execute the delete script	


			fwInstallation_showMessage(makeDynString(\"    Deleting files ...\"));
	
			// delete all the files
			
			iReturn = fwInstallation_deleteFiles(componentFiles, installationDirectory);
			
			if(iReturn == -1) 
				errorDeletingComponent = -1;
				
			iReturn = fwInstallation_deleteFiles(configFiles_general, installationDirectory);
					
			if(iReturn == -1) 
				errorDeletingComponent = -1;
				
			iReturn = fwInstallation_deleteFiles(configFiles_linux, installationDirectory);
					
			if(iReturn == -1) 
				errorDeletingComponent = -1;
			
			iReturn = fwInstallation_deleteFiles(configFiles_windows, installationDirectory);
					
			if(iReturn == -1) 
				errorDeletingComponent = -1;
				
			iReturn = fwInstallation_deleteFiles(initFiles, installationDirectory);
					
			if(iReturn == -1) 
				errorDeletingComponent = -1;
			
			iReturn = fwInstallation_deleteFiles(deleteFiles, installationDirectory);
					
			if(iReturn == -1) 
				errorDeletingComponent = -1;
			
			iReturn = fwInstallation_deleteFiles(postInstallFiles, installationDirectory);
			
			if(iReturn == -1)
				errorDeletingComponent = -1;
					
			iReturn = fwInstallation_deleteFiles(dplistFiles, installationDirectory);
					
			if(iReturn == -1) 
				errorDeletingComponent = -1;
	
	
//SMS as most developers put the xml into the file list, we do not need to delete it twice			
/*			iReturn = fwInstallation_deleteFiles(dynDescFile, installationDirectory);
					
			if(iReturn == -1) 
				errorDeletingComponent = -1;
*/
			
			iReturn = fwInstallation_deleteFiles(dynScriptFiles, installationDirectory);
			
			if(iReturn == -1) 
				errorDeletingComponent = -1;
						
		}
		
		// now delete the component info from the config file
		
		fwInstallation_showMessage(makeDynString(\"    Updating the config file ...\" ));
		
		// delete the component from the config file	
		fwInstallation_deleteComponentFromConfigScriptsFile(componentName, 	getPath(CONFIG_REL_PATH) + \"config\");
		
		
		// delete the component from the fwScripts.lst file
		if(dynlen(dynScriptFiles) > 0)
		{
			fwInstallation_showMessage(makeDynString(\"    Updating the fwScripts.lst file ...\" ));
	
			fwInstallation_deleteComponentFromConfigScriptsFile(componentName, 	getPath(SCRIPTS_REL_PATH) + \"fwScripts.lst\");
		}
		
		
		fwInstallation_showMessage(makeDynString(\"    Updating the component database ...\"));
		
		// delete the DP
		dpDelete(\"fwInstallation_\" + componentName);
	}

	logFileName.text = \"\";

	if((errorDeletingComponent == -1) || (deletionAborted))
	{
		fwInstallation_showMessage(makeDynString(\"	  There were errors while deleting the components - see the log\"));		
		if(deletionAborted)
		{	
			fwInstallation_writeToMainLog(formatTime(\"[%Y-%m-%d_%H:%M:%S] \",getCurrentTime()) + componentName + \" de-installation aborted\");
		} else {
			fwInstallation_writeToMainLog(formatTime(\"[%Y-%m-%d_%H:%M:%S] \",getCurrentTime()) + componentName + \" deleted with errors\");
		}
		componentDeleted = FALSE;
	}
	else
	{
		fwInstallation_showMessage(makeDynString(\"    Component deleted.\"));
		fwInstallation_writeToMainLog(formatTime(\"[%Y-%m-%d_%H:%M:%S] \",getCurrentTime()) + componentName + \" deleted\");
		componentDeleted = true;
	}

	tempString = logFileName.text;
	if(tempString != \"\")
	{
		fwInstallation_showMessage(makeDynString(\"Please find the log file for this deinstallation operation in:\",tempString));
		fwInstallation_writeToMainLog(formatTime(\"[%Y-%m-%d_%H:%M:%S] \",getCurrentTime()) + \"Please find the log file for this de-installation operation in: \"+tempString);
	}	
}

/** this function deletes the component information from the PVSS project confg file.
It loads the config file into dyn_string ( each line in one row of a dyn_string )
Deletes the rows from the dyn_string and saves the dyn_string to the file

@param componentName: the name of a component to be deleted

@author M.Sliwinski
*/

fwInstallation_deleteComponentFromConfigScriptsFile(string componentName, string strFileName)
{
	int i;
	
	string fileInString;
	
	bool fileLoaded;
	
	int idxCurrent;
	int removeResult;
	dyn_string dynFileLines;
		
	dyn_dyn_int components; // 1st row - indexes of the beginning of the component in the dyn_string
							// 1nd row - indexes of the engs of the component in the dyn_string
	
	int idxBegin = 0;
	int idxEnd = 0;
	
	int scriptFileExists;


	scriptFileExists = access(strFileName, F_OK);
	
	if(scriptFileExists == 0)
	{
	
		fileLoaded = fileToString(strFileName, fileInString);
		
		if (! fileLoaded )
		{
		
			Debug(\"\\n Cannot load \" + strFileName + \" file\");
		}
		else 
		{
	
				dynFileLines = strsplit(fileInString, \"\\n\");

				components[1] = \"\"; // in this row there are indexes of the beginning of the components
				components[2] = \"\"; // in this row there are indexes of the ends of the components
				
			
			// find out where are the components situated and in which sections
				
				for(i = 1; i <= dynlen(dynFileLines); i++)
				{
				
					// find the beginings and ends of the components entries
					
						if(strpos(dynFileLines[i], \"#begin \" + componentName) >= 0)
						{
							// found the beginning of the component
							idxBegin = i;
						}
						
						if(strpos(dynFileLines[i], \"#end \" + componentName) >= 0)
						{
							// found the end of the component
							idxEnd = i;
							
							if(dynFileLines[i+1] == \"\")
							{
								// this is the blanki line after #end - it should be deleted
								idxEnd++;
							}
						}
						
						if(idxBegin < idxEnd)
						{
							// save the beginning and end of the component entry
							
							dynAppend(components[1], idxBegin);
							dynAppend(components[2], idxEnd);
							
							idxBegin = 0;
							idxEnd = 0;
						}
				}
				
			// delete the component from the  configLines dyn_string
			
				for(i = dynlen(components[1]); i >=1; i--)
				{
					idxBegin = components[1][i];
					idxEnd = components[2][i];
										
					for(idxCurrent = idxEnd; idxCurrent >= idxBegin; idxCurrent--)
					{
						// delete it from the configSectionTable
			
  					removeResult = dynRemove(dynFileLines, idxCurrent);

						if (removeResult == -1)
						{
							Debug(\"\\n ERROR: fwInstallation_deleteComponentFromConfigScriptsFile() - could not remove the line from table\");
						}
					
						
					}
					
				}
				
				// save the config file
				
				fwInstallation_saveFile(dynFileLines, strFileName);
		}
	}
}" 0
 E E E
13 2
"btnClose"
""
1 690 600 E E E 1 E 1 E N "_3DText" E N "_3DFace" E E
 E E
3 0 0 0 0 0
EE E
0
1
LANG:1 0 
0
1
LANG:1 107 -microsoft windows-Arial-normal-r-normal-*-*-120-100-100-*-*-iso8859-1|-13,0,0,0,400,0,0,0,0,3,2,1,34,Arial
0 ""
688 598 760 630
T 
1
LANG:1 5 Close
"main()
{
  ModuleOff(myModuleName());
}" 0
 E E E
14 11
"txtSourceDir"
""
1 30 86 E E E 1 E 1 E N "_WindowText" E N "_Window" E E
 E E
11 0 0 0 0 0
EE E
0
1
LANG:1 0 
0
1
LANG:1 107 -microsoft windows-Arial-normal-r-normal-*-*-110-100-100-*-*-iso8859-1|-12,0,0,0,400,0,0,0,0,3,2,1,34,Arial
0 ""
28 84 322 110
3 "s" 0 0 0 0 0 0 
E
E
"main()
{
	fwInstallation_getComponentsInfo(\"tblAvailableComponents\", \"txtSourceDir\");
}" 0

13 12
"btnSelectSourceDir"
""
1 340 80 E E E 1 E 1 E N "_3DText" E N "_3DFace" E E
 E E
12 0 0 0 0 0
EE E
0
1
LANG:1 0 
0
1
LANG:1 107 -microsoft windows-Arial-normal-r-normal-*-*-120-100-100-*-*-iso8859-1|-13,0,0,0,400,0,0,0,0,3,2,1,34,Arial
0 ""
338 78 382 112
P 
13160660
"pictures/fileselektor.xpm"
1
LANG:1 0 
"main()
{

string sPath;

int    iErr;

	
    sPath = txtSourceDir.text;   // Content of textfield

	fwInstallation_disablePanel();


  iErr = folderSelector( sPath );

  if(( iErr >= 1 ) && ( strlen( sPath ) > 0 ))

  {

	sPath += \"/\";

    if (_WIN32) strreplace( sPath, \"/\", \"//\" ); 
// if NT -> replace 

	strreplace( sPath, \"//\", \"/\" );
	
	// update the widget with the directory path
    txtSourceDir.text = sPath;  

  }
  
  // refresh the graphic tables with components
  
  fwInstallation_getComponentsInfo(\"tblAvailableComponents\", \"txtSourceDir\" );

	fwInstallation_enablePanel();


}" 0
 E E E
25 14
"tblAvailableComponents"
""
1 -110 -45 E E E 1 E 1 E N "_WindowText" E N "_Window" E E
 E "/**	if the user double clicks on the Status column 
the panel with the component details is shown
*/
main()
{	
	
	int xpos;
	string columnName;
	int columnNr;
	string componentName;
	string descFile;
	string directoryInfo;
	string typeOfDescription = \"xml\";
	
	// get the shape of the table
	shape tab = getShape(\"tblAvailableComponents\");
	
	// get the coordinates of the current cell
	getValue(tab, \"currentCell\", xpos, columnNr);
	columnName = tab.currentColumn();

	// check the column name
	 if((columnName == \"componentName\") || (columnName == \"componentVersion\"))
	 {
		
		// get the component name	 
		componentName = tab.cellValueRC(xpos, \"componentName\");
		
		// get the description file name - it is stored in a hidden column
		descFile = tab.cellValueRC(xpos, \"descFile\");	
			
			// open the panel with details of a component	 
	 		ChildPanelOnCentral(\"fwInstallation/fwInstallationComponentDetails.pnl\", \"fwInstallation_ComponentDetails:xml\",
			 makeDynString(\"$componentName:\" + componentName, \"$descFile:\" + descFile , \"$typeOfDescription:\" + typeOfDescription, \"$sourceDir:\" + txtSourceDir.text));
	}

}	" 0

14 0 0 0 0 0
EE E
0
1
LANG:1 0 
0
1
LANG:1 106 -microsoft windows-Arial-normal-r-normal-*-*-120-100-100-*-*-iso8859-1|-13,0,0,0,400,0,0,0,0,0,0,0,0,Arial
0 ""
28 168 382 432
E "/**	if the user  clicks on the Status column 
the column value is changed ( Install -> \"\" , or \"\" -> Install
*/
main(int row, string column, string value)
{

		// if user clicked on colStatus column
		if (column == \"colStatus\") 
		{
			// check the old value
			if (value == \"Install\") 
			{
				// set new value to empty
				setValue(\"\",\"cellValueRC\",row,\"colStatus\",\" \");
			}
			else if(value == \"Installed\")
			{
				// The component is already installed - do nothing
			}
			else 
			{
				// set new value to install
				setValue(\"\",\"cellValueRC\",row,\"colStatus\",\"Install\");
			}
		}
					

}" 0
 1 0 1 4 1 "componentName" 0 1 0 "s" 1
LANG:1 14 Component Name
E1
LANG:1 50 Subcomponents are shown with a leading underscore.
 188 "componentVersion" 0 1 0 "s" 1
LANG:1 7 Version
E1
LANG:1 0 
 72 "colStatus" 0 1 0 "s" 1
LANG:1 9 Install ?
E1
LANG:1 0 
 70 "descFile" 0 0 0 "s" 1
LANG:1 8 descFile
E1
LANG:1 0 
 70 26 26 "" 1 1
LANG:1 2 #1
8 30 1
LANG:1 106 -microsoft windows-Arial-normal-r-normal-*-*-120-100-100-*-*-iso8859-1|-13,0,0,0,400,0,0,0,0,0,0,0,0,Arial
0 ""
0 2 0 3 0
1 0
17 22
"list"
""
1 20 490 E E E 1 E 1 E N "_WindowText" E N "_Window" E E
 E E
20 0 0 0 0 0
EE E
0
1
LANG:1 0 
0
1
LANG:1 107 -microsoft windows-Arial-normal-r-normal-*-*-120-100-100-*-*-iso8859-1|-13,0,0,0,400,0,0,0,0,3,2,1,34,Arial
0 ""
18 488 762 592
0
E
E
E

3 1
13 24
"btnAdvanced"
""
1 630 10 E E E 1 E 1 E N "_3DText" E N "_3DFace" E E
 E E
22 0 0 0 0 0
EE E
0
1
LANG:1 0 
0
1
LANG:1 107 -microsoft windows-Arial-normal-r-normal-*-*-120-100-100-*-*-iso8859-1|-13,0,0,0,400,0,0,0,0,3,2,1,34,Arial
0 ""
628 8 762 42
T 
1
LANG:1 16 Advanced Options
"main()
{
	fwInstallation_disablePanel();
		ChildPanelOnCentral(\"fwInstallation/fwInstallationAdvancedOptions.pnl\", \"fwInstallation_AdvancedOptions\", \"\");
	fwInstallation_enablePanel();
}" 0
 E E E
13 25
"Button1"
""
1 230 440 E E E 1 E 1 E N "_3DText" E N "_3DFace" E E
 E E
22 0 0 0 0 0
EE E
0
1
LANG:1 0 
0
1
LANG:1 107 -microsoft windows-Arial-normal-r-normal-*-*-120-100-100-*-*-iso8859-1|-13,0,0,0,400,0,0,0,0,3,2,1,34,Arial
0 ""
228 438 302 472
T 
1
LANG:1 7 Refresh
"main()
{
	// refresh the  table widget
	fwInstallation_getComponentsInfo(\"tblAvailableComponents\", \"txtSourceDir\");
}" 0
 E E E
13 17
"btnApplyInstall"
""
1 310 440 E E E 1 E 1 E N "_3DText" E N "_3DFace" E E
 E E
17 0 0 0 0 0
EE E
0
1
LANG:1 0 
0
1
LANG:1 107 -microsoft windows-Arial-normal-r-normal-*-*-120-100-100-*-*-iso8859-1|-13,0,0,0,400,0,0,0,0,3,2,1,34,Arial
0 ""
308 438 382 472
T 
1
LANG:1 7 Install
"// Install the components
main()
{
	string componentsInfo;
	string descFilesInfo;
	string sourceDir;
	string destinationDir;
	dyn_float dreturnf; // the return value of a child panel
	dyn_string dreturns; // the return value of a child panel
	
	dyn_string componentsNames;
	dyn_string componentFiles;
	dyn_string componentsVersions;
	dyn_string componentFilesInOrder;
	dyn_string dynNamesVersions;
	dyn_string tmpDynParamValue;
	bool componentInstalled = false;
	
	string componentName, tempString;
	int dpGetResult;
	
	int i;

	fwInstallation_disablePanel();
	
	dpGetResult = dpGet(\"fwInstallationInfo.installationDirectoryPath:_original.._value\", destinationDir);
	
	if((destinationDir == \"\") || (dpGetResult == -1))
	{	
		// ask for the installation directory
			
		ChildPanelOnCentral(\"fwInstallation/fwInstallationSelectDirectory.pnl\", \"fwInstallation_SelectDirectory\", \"\");
	}
	
	dpGetResult = dpGet(\"fwInstallationInfo.installationDirectoryPath:_original.._value\", destinationDir);
	if((destinationDir != \"\") && (dpGetResult != -1))
	{
		destinationDir += \"/\";
	
		logFileName.text = destinationDir + \"/log/fwInstallation_\"+formatTime(\"%Y%m%d_%H%M%S\",getCurrentTime())+\".log\";
		fwInstallation_writeToMainLog(formatTime(\"[%Y-%m-%d_%H:%M:%S] \",getCurrentTime()) + \"Starting installation\");

		// retrieve the component names and the description files of the components to be installed
			for(  i = 0 ; i < tblAvailableComponents.lineCount(); i++)
			{
				if(tblAvailableComponents.cellValueRC(i, \"colStatus\") == \"Install\")
				{
					
					componentsInfo += tblAvailableComponents.cellValueRC(i, \"componentName\") + \"=\" + tblAvailableComponents.cellValueRC(i, \"componentVersion\") + \"|\";
					descFilesInfo += tblAvailableComponents.cellValueRC(i, \"descFile\") + \"|\";
				}
		
			}
		
			sourceDir = txtSourceDir.text;

			//show the panel with the components names to be installed
			// $componentsInfo - ( componentName=componentVersion [ | componentName=componentVersion  ] )
			ChildPanelOnCentralReturn(\"fwInstallation/fwInstallationToInstall.pnl\", \"fwInstallation_ToInstall\",
					 makeDynString(\"$componentsInfo:\" + componentsInfo , \"$descFilesInfo:\" + descFilesInfo, \"$sourceDir:\" + sourceDir), dreturnf, dreturns);
			
			if(dreturns[1] == \"Install\")
			{
				// install the components
				
				componentFiles = strsplit(descFilesInfo, \"|\");
				dynNamesVersions = strsplit(componentsInfo, \"|\");
				
				for(i = 1; i <= dynlen(dynNamesVersions); i++)
				{
					tmpDynParamValue = strsplit(dynNamesVersions[i], \"=\");
					
					dynAppend(componentsNames, tmpDynParamValue[1]);
					dynAppend(componentsVersions,tmpDynParamValue[2]);
				}
	
				// put the components in order for installing
			
				fwInstallation_putComponentsInOrder_Install(componentsNames, componentsVersions, componentFiles, componentFilesInOrder);
			
		
				// install every component
						
				for (i =1; i <= dynlen(componentFilesInOrder); i++)
				{
//					fwInstallation_showMessage(makeDynString(\"Starting component installation for \"+componentFilesInOrder[i]));
					fwInstallation_installComponent(componentFilesInOrder[i], sourceDir, false, componentName, componentInstalled);
//					fwInstallation_showMessage(makeDynString(\"Finished component installation for \"+componentFilesInOrder[i]));
				}
			
				// refresh the Main Panel
				fwInstallation_getComponentsInfo(\"tblAvailableComponents\", \"txtSourceDir\");
				fwInstallation_getInstalledComponents();

				// show the restart panel
				
				if(componentInstalled)
				{
					ChildPanelOnCentral(\"fwInstallation/fwInstallationRestart.pnl\", \"fwInstallationRestart\", makeDynString(\"$action:\" + \"install\"));
				}
				tempString = logFileName.text;
				logFileName.text = \"\";
				fwInstallation_showMessage(makeDynString(\"Please find the log file for this installation operation in:\",tempString));
				fwInstallation_writeToMainLog(formatTime(\"[%Y-%m-%d_%H:%M:%S] \",getCurrentTime()) + \"Finishing installation\");
				fwInstallation_writeToMainLog(formatTime(\"[%Y-%m-%d_%H:%M:%S] \",getCurrentTime()) + \"Please find the log file for this installation operation in: \"+tempString);
			}

	logFileName.text = \"\";
	}
	fwInstallation_enablePanel();			

}

/** This function puts the components to be installed in order in which they should be installed
The algorithm is similar to that used during deleting the components - look fwInstallation_putComponentsInOrder_Delete() function btn_ApplyDelete()
@param componentsNames: the names of the components to be installed
@param componentsVersions: the versions of components to be installed
@param componentFiles: the file names with the description of the components
@param componentFilesInOrder: the ordered file names with the description of the components

@author M.Sliwinski
*/

 fwInstallation_putComponentsInOrder_Install(dyn_string & componentsNames, dyn_string & componentsVersions, dyn_string & componentFiles, dyn_string & componentFilesInOrder)
{
	int i, j, k;
	dyn_dyn_string dependencies; //  first column - component name, next columns - components required by this component that will be installed later
	dyn_string tempDynRequired;
	dyn_string tempParamValue;
	dyn_string orderedComponentsNames;
	string tempRequiredName;
	string tempRequiredVersion;
	string tempComponentName;
	bool emptyListExists = true;
	
	// read the component requirements and fill the dependencies table
			
	for(i = 1; i <= dynlen(componentFiles); i++)
	{
		
		// put the components to be installed in 1st column of dependencies table
		dynAppend(dependencies[i] , componentsNames[i]);
		
		// get the list of components required by the component being installed
		fwInstallation_readComponentRequirements(componentFiles[i], tempDynRequired);
		
		// for each components that are required by component being installed		
		for (j =1; j <= dynlen(tempDynRequired); j++)
		{
			tempParamValue = strsplit(tempDynRequired[j], \"=\");
			
			// get its name
			tempRequiredName = tempParamValue[1];
			
			if(dynlen(tempParamValue) > 1)
			{
				// get its version
				tempRequiredVersion = tempParamValue[2];
			}
			else
			{
				tempRequiredVersion = 0;
			}
			// the required component will be installed later
			k = dynContains(componentsNames, tempRequiredName);
			
			if(k > 0)
			{
				if(componentsVersions[k] >= tempRequiredVersion)
				{
					dynAppend(dependencies[i], tempRequiredName);
				}
			}
		}	
	}
	
	k = 0;
	
	// put the components in order
	
	while(emptyListExists)
	{	
		emptyListExists = false;
				
				for(i =1; i <= dynlen(componentsNames); i++)
				{
					
					// if the component does not require any components
					if((dynlen(dependencies[i]) == 1) && (dependencies[i][1] != \"EMPTY\"))
					{
						
						emptyListExists = true;
						
						tempComponentName = dependencies[i][1];
						
						// set the component name to empty
						dependencies[i][1] = \"EMPTY\";
						
						// append the component name to a list of ordered components		
						dynAppend(componentFilesInOrder, componentFiles[i]);
						dynAppend(orderedComponentsNames, tempComponentName);
												
						for(j = 1; j <= dynlen(componentsNames); j++)
						{
						
							// update the dependencies table
							k = dynContains(dependencies[j], tempComponentName);
							
							if(k > 0)
							{
								 dynRemove(dependencies[j], k);
							}
							
						}
					}
					else
					{
					}
				} 
	}
	
		// if there were unsolved dependencies components depending on each other 
		// copy them to the end
		
		for(i = 1; i <= dynlen(componentsNames); i++)
		{
			if(dependencies[i][1] != \"EMPTY\")
			{
				dynAppend(componentFilesInOrder, componentFiles[i]);
			}
		}
		
		DebugN(\"Components put in order: \" + componentFilesInOrder);
}



/** This function reads the requirements from the component description file

@param descFile: the file with the description of a component 
@param requiredComponents: the dyn_string of requiredComponents
@author M.Sliwinski
*/

 fwInstallation_readComponentRequirements(string descFile, dyn_string & dynRequiredComponents)
{
	bool	fileLoaded;
	string strComponentFile;
	string tagName;
	string tagValue;
	int i;

	// clear the required components table
	dynClear(dynRequiredComponents);
	
	if(_WIN32)
	{
		strreplace(descFile, \"/\", \"\\\\\");
	}	
	
	// load the description file into strComponentFile string
		
	fileLoaded = fileToString(descFile, strComponentFile);
		
		
		if (! fileLoaded )
		{
		
			DebugN(\"Cannot load \" + descFile + \" file \");
			
		}
		else 
		{
			// remove the root tag <component>
			
			strreplace(strComponentFile, \"<component>\", \"\");
			strreplace(strComponentFile, \"</component>\", \"\");
				
				
		// read the requirements tag

			// while there are tags in the string 		
			while( fwInstallation_getTagFromString(tagName, tagValue, strComponentFile) == 1 )
			{

				switch(tagName)
				{
										//
										case \"required\":	tagValue = strltrim(tagValue); // remove the white characters
															tagValue = strrtrim(tagValue);
															dynAppend(dynRequiredComponents, tagValue);										
															break;
				}
			}
		}	
}


/** This function installs the component. It copies the files, imports the component DPs, DPTs, updates the project config file

@param descFile: the file with the description of a component 
@param sourceDir: the root directory with the component files
@param isItSubComponent: it is false - if it is the master component; it is true if it is the sub component
@param componentName: it is the return value - the name of the installed component
@author M.Sliwinski
*/

fwInstallation_installComponent(string descFile, string sourceDir, bool isItSubComponent, string & componentName, bool & componentInstalled)
{

	string destinationDir;  // the name of a directory where the component will be installed
	
	dyn_float dreturnf; // return value of a panel
	dyn_string dreturns; // return value of a panel
	
	string componentFileName; 
	string fileToCopy;
	string asciiManager;
	string infoFile;
	string logFile;
	string cmd;
	string strComponentFile; 
	string asciiFile;
	string result;
	string tmpResult;
	int dpCreated;
	int iReturn; // the return value of function fwInstallation_evalScriptFile;
	int errorInstallingComponent = 1; // has value -1 if there were any errors during the component installation, 1 if everything is OK
	dyn_string dynComponentFileLines;
	dyn_string dynFileNames;
	dyn_string dynComponentFiles;
	dyn_string dynPostDeleteFiles_current;
	dyn_string dynPostDeleteFiles_all;
	dyn_string dynPostInstallFiles_current;
	dyn_string dynPostInstallFiles_all;
	dyn_string dynPostDeleteFiles;
	dyn_string dynPostInstallFiles;
	dyn_string dynConfigFiles_general;
	dyn_string dynConfigFiles_linux;
	dyn_string dynConfigFiles_windows;
	dyn_string dynInitFiles;
	dyn_string dynDeleteFiles;
	dyn_string dynDplistFiles;
	dyn_string resultInLines;
	dyn_string dynScriptsToBeAdded; 

	// sub Components handling
	
	dyn_string dynSubComponents;
	
	// end sub Components handling

	string componentVersion;
	string date;
	string componentConfigFile = \"\";
	string dplistFile;
	bool requiredInstalled = true;
	
	// component dependencies
	
	dyn_string dynRequiredComponents;
	
	string strNotInstalledNames = \"\";
	

	float floatInstalledVersion;
	string strInstalledName; 
	dyn_string  dynNotProperlyInstalled;
	
	// end component dependencies
	
	string tagName;
	string tagValue;
	string filePath, filePattern, fileNameToAdd;
	dyn_string fileNames;
	
	bool	fileLoaded;
	bool x;
	string err;
	string componentInitFile;
	
	int i, j, k;
	int pos1, pos2, pos3, pos4;
	int dpGetResult;
	int fileCopied;

	int error, errorCounter;
	string errorString, strTestFile;
	dyn_string strErrors = \"\";

	asciiManager = PVSS_BIN_PATH + \"PVSS00ascii\";
   	infoFile = getPath(LOG_REL_PATH) + \"PVSS00ascii_info.log\";
   	logFile =  getPath(LOG_REL_PATH) + \"PVSS00ascii_log.log\";
   	
   	strreplace( sourceDir, \"//\", \"/\" );

	// get the destination dir
	dpGet(\"fwInstallationInfo.installationDirectoryPath:_original.._value\", destinationDir);


		// load the description file		
		fileLoaded = fileToString(descFile, strComponentFile);
		
		if (! fileLoaded )
		{
		
			fwInstallation_showMessage(makeDynString(\"Cannot load \" + descFile + \" file \"));
			
		}
		else 
		{
			
			strreplace(descFile, sourceDir, \"\");
			
			// add the description file to a dyn_string with file names to be copied
			dynAppend(dynFileNames, strrtrim(strltrim(descFile)));		

				

	// retrieving the values of the tags in xml file

		// delete the root tags: <component> and </component>
		
			strreplace(strComponentFile, \"<component>\", \"\");
			strreplace(strComponentFile, \"</component>\", \"\");
		
		// while the string strComponentFile contains more tags
					
		while( fwInstallation_getTagFromString(tagName, tagValue, strComponentFile) == 1 )
		{
			
			// check the tagName
			
			switch(tagName)
			{
				case \"file\" : 		
//SMS  changes to allow wildcards
									if(strpos(tagValue, \"*\") > 0)
									{
										filePath = _fwInstallation_baseDir(tagValue);
										filePattern = _fwInstallation_fileName(tagValue);
										fileNames = getFileNames(sourceDir +\"/\"+ filePath, filePattern);
//										DebugN(filePath, filePattern, getFileNames(sourceDir +\"/\"+ filePath, filePattern));
										for(i=1; i<=dynlen(fileNames); i++)
										{
											fileNameToAdd = filePath + \"/\" + fileNames[i];
											dynAppend(dynFileNames, fileNameToAdd);
											dynAppend(dynComponentFiles, fileNameToAdd);
										}
									} else {
//SMS
										dynAppend(dynFileNames, tagValue);
										dynAppend(dynComponentFiles, tagValue);
									}
									break;

				case \"name\": 		componentName = tagValue;
									break;
									
				case \"version\": 	componentVersion = tagValue;
									break;
									
				case \"date\": 		date = tagValue;
									break;
									
				case \"required\":	if(tagValue != \"\")
									dynAppend(dynRequiredComponents, tagValue);
									break;
				
				case \"script\": 		dynAppend(dynFileNames, tagValue);
									dynAppend(dynScriptsToBeAdded, tagValue);					
									break;
									
				case \"config\":		dynAppend(dynFileNames, tagValue);
									dynAppend(dynConfigFiles_general, tagValue);
									break;
									
				case \"init\": 		dynAppend(dynFileNames, tagValue);
									dynAppend(dynInitFiles, tagValue);
									break;
				case \"postInstall\": dynAppend(dynFileNames, tagValue);
									// this will be saved in a data point describing the component
									dynAppend(dynPostInstallFiles, tagValue);
									
									// save the full path to the init file
									tagValue = destinationDir + strltrim(tagValue, \".\");
									
									// this will be saved in a data point with all the postInstall files to be run
									dynAppend(dynPostInstallFiles_current, tagValue);
									break;
									
				case \"delete\": 		dynAppend(dynFileNames, tagValue);
									dynAppend(dynDeleteFiles, tagValue);
									break;
				case \"postDelete\":	dynAppend(dynFileNames, tagValue);
									// this will be saved in a data point describing the component
									dynAppend(dynPostDeleteFiles, tagValue);
									
									// save the full path to the init file
									tagValue = destinationDir + strltrim(tagValue, \".\");
									
									// this will be saved in a data point with all the postInstall files to be run
									dynAppend(dynPostDeleteFiles_current, tagValue);
									break;
									
				case \"config_windows\": 	dynAppend(dynFileNames, tagValue);
										dynAppend(dynConfigFiles_windows, tagValue);	
										break;
										
				case \"config_linux\" : 	dynAppend(dynFileNames, tagValue);
										dynAppend(dynConfigFiles_linux, tagValue);											
										break;
										
				case \"dplist\":		dynAppend(dynFileNames, tagValue);
									dynAppend(dynDplistFiles, tagValue);	
									break;
									
				case \"includeComponent\": 	strreplace(tagValue, \"./\", \"\");
											dynAppend(dynSubComponents, sourceDir + \"/\" + tagValue);
											break;
											
			} // end switch
			
		} // end while	


	// check the component dependencies
	// retrieve the component names that are required and not installed

	fwInstallation_getNotInstalledComponentsFromRequiredComponents(dynRequiredComponents, strNotInstalledNames);
	
	// show the panel that asks if it should be installed
	
			if( strNotInstalledNames != \"\")
			{	
					// show the panel informing the user about broken dependencies
							ChildPanelOnCentralReturn(\"fwInstallation/fwInstallationDependency.pnl\", \"fwInstallation_Dependency\",
					 makeDynString(\"$strDependentNames:\" + strNotInstalledNames , \"$componentName:\" + componentName, \"$callingPanel:\" + \"ToInstall\"), dreturnf, dreturns);
			
						// check the return value
						if(dreturns[1] == \"Install_Delete\")
						{
							requiredInstalled = false;
						}
						else if(dreturns[1] == \"DoNotInstall_DoNotDelete\")
						{
							return;
						}
			}
// end check the component dependencies

	if(isItSubComponent)
	{
		fwInstallation_showMessage(makeDynString(\"  Installing sub-component: \" + componentName)); 
	}
	else
	{
		fwInstallation_showMessage(makeDynString(\"Installing the component: \" + componentName)); 
	}


//SMS check if all scripts all valid, and all directories are writeable and if all source files exist

	errorCounter = 0;	


	if(dynlen(dynInitFiles) > 0)
	{
		for (k=1; k<=dynlen(dynInitFiles); k++)
		{
			fileLoaded = fileToString(sourceDir + dynInitFiles[k], strTestFile);
			if (! fileLoaded )
			{
				errorString = \"Cannot load \" + sourceDir + dynInitFiles[k] + \" file for testing\";
				dynAppend(strErrors, errorString);
				fwInstallation_showMessage(makeDynString(errorString));
				errorCounter++;
			} else {  
				if(!checkScript(strTestFile))
				{
					errorCounter++;
					errorString = \"fwInstallation: init script \"+sourceDir + dynInitFiles[k]+\" of component \"+componentName+\" is not valid\";
					dynAppend(strErrors, errorString);
					fwInstallation_showMessage(makeDynString(errorString));
				}
			}
		}
	}

	if(dynlen(dynPostInstallFiles) > 0)
	{
		for (k=1; k<=dynlen(dynPostInstallFiles); k++)
		{
			fileLoaded = fileToString(sourceDir + dynPostInstallFiles[k], strTestFile);
			if (! fileLoaded )
			{
				errorString = \"Cannot load \" + sourceDir + dynPostInstallFiles[k] + \" file for testing\";
				dynAppend(strErrors, errorString);
				fwInstallation_showMessage(makeDynString(errorString));
				errorCounter++;
			} else {
				if(!checkScript(strTestFile))
				{
					errorCounter++;
					errorString = \"fwInstallation: post install script \"+sourceDir + dynPostInstallFiles[k]+\" of component \"+componentName+\" is not valid\";
					dynAppend(strErrors, errorString);
					fwInstallation_showMessage(makeDynString(errorString));
				}
			}
		}
	}


	if(dynlen(dynDeleteFiles) > 0)
	{
		for (k=1; k<=dynlen(dynDeleteFiles); k++)
		{
			fileLoaded = fileToString(sourceDir + dynDeleteFiles[k], strTestFile);
			if (! fileLoaded )
			{
				errorString = \"Cannot load \" + sourceDir + dynDeleteFiles[k] + \" file for testing\";
				dynAppend(strErrors, errorString);
				fwInstallation_showMessage(makeDynString(errorString));
				errorCounter++;
			} else {  
				if(!checkScript(strTestFile))
				{
					errorCounter++;
					errorString = \"fwInstallation: deletion script \"+sourceDir + dynDeleteFiles[k]+\" of component \"+componentName+\" is not valid\";
					dynAppend(strErrors, errorString);
					fwInstallation_showMessage(makeDynString(errorString));
				}
			}
		}
	}

	if(dynlen(dynPostDeleteFiles) > 0)
	{
		for (k=1; k<=dynlen(dynPostDeleteFiles); k++)
		{
			fileLoaded = fileToString(sourceDir + dynPostDeleteFiles[k], strTestFile);
			if (! fileLoaded )
			{
				errorString = \"Cannot load \" + sourceDir + dynPostDeleteFiles[k] + \" file for testing\";
				dynAppend(strErrors, errorString);
				fwDeleteation_showMessage(makeDynString(errorString));
				errorCounter++;
			} else {
				if(!checkScript(strTestFile))
				{
					errorCounter++;
					errorString = \"fwDeleteation: post delete script \"+sourceDir + dynPostDeleteFiles[k]+\" of component \"+componentName+\" is not valid\";
					dynAppend(strErrors, errorString);
					fwDeleteation_showMessage(makeDynString(errorString));
				}
			}
		}
	}


	if(dynlen(dynFileNames) > 0)
	{
		error = access(destinationDir,W_OK);
		if(error!=0)
		{
			errorCounter++;
			errorString = \"fwInstallation: the folder \"+ destinationDir +\" is not write enabled\";
			dynAppend(strErrors, errorString);
			fwInstallation_showMessage(makeDynString(errorString));
		} else {
			for (k=1; k<=dynlen(dynFileNames); k++)
			{
				error = access(sourceDir + \"/\" + dynFileNames[k],R_OK);
				if(error!=0)
				{
					errorCounter++;
					errorString = \"fwInstallation: the file \"+ sourceDir + \"/\" + dynFileNames[k] +\" does not exist\";
					dynAppend(strErrors, errorString);
					fwInstallation_showMessage(makeDynString(errorString));
				}
				error = access(_fwInstallation_baseDir(destinationDir + \"/\" + dynFileNames[k]),W_OK);
				if(error!=0)
				{
					if(access(_fwInstallation_baseDir(destinationDir + \"/\" + dynFileNames[k]),F_OK) == 0)
					{
						errorCounter++;
						errorString = \"fwInstallation: the folder \"+ _fwInstallation_baseDir(destinationDir + \"/\" + dynFileNames[k]) +\" is not write enabled\";
						dynAppend(strErrors, errorString);
						fwInstallation_showMessage(makeDynString(errorString));
					}
				}
				error = access(destinationDir + \"/\" + dynFileNames[k],W_OK);
				if(error!=0)
				{
					error = access(destinationDir + \"/\" + dynFileNames[k],F_OK);
					if(error==0)
					{
						errorCounter++;
						errorString = \"fwInstallation: the file \"+ destinationDir + \"/\" + dynFileNames[k] +\" is not write enabled\";
						dynAppend(strErrors, errorString);
						fwInstallation_showMessage(makeDynString(errorString));
					}
				}
			}
		}
	}


	if(errorCounter!=0)
	{
		ChildPanelOnCentralReturn(\"fwInstallation/fwInstallationDependency.pnl\", \"fwInstallation_Dependency\",
			 makeDynString(\"$strDependentNames:\" + strErrors , \"$componentName:\" + componentName, \"$callingPanel:\" + \"Checker\"), dreturnf, dreturns);
		// check the return value
		if(dreturns[1] == \"Install_Delete\")
		{
			errorString = \"fwInstallation: \"+errorCounter+\" error(s) found. Installation of \"+componentName+\" will continue on user request\";
			fwInstallation_showMessage(makeDynString(errorString));
		}
		else if(dreturns[1] == \"DoNotInstall_DoNotDelete\")
		{
			errorString = \"fwInstallation: \"+errorCounter+\" error(s) found. Installation of \"+componentName+\" is aborted\";
			fwInstallation_showMessage(makeDynString(errorString));
			return;
		}
	}

// install the 	component
		
// install the subcomponents if they exist

	for(i = 1; i <= dynlen(dynSubComponents); i++)
	{
		fwInstallation_showMessage(makeDynString(\"     Installing sub Components ... \"));
		fwInstallation_installComponent(dynSubComponents[i], sourceDir, true, dynSubComponents[i], componentInstalled);
	}

// end install the subcomponents if they exist
												
// copy all the files
			
			if(sourceDir == destinationDir)
			{

			}
			else
			{
				if(dynlen(dynFileNames) > 0)
				fwInstallation_showMessage(makeDynString(\"    Copying files ....\"));
				
				for (i =1; i <= dynlen(dynFileNames); i++)
				{
						strreplace( destinationDir, \"//\", \"/\" );
						strreplace( sourceDir, \"//\", \"/\" );
						fileToCopy = strltrim(dynFileNames[i], \".\");
						
						fileCopied =  copyFile(sourceDir + fileToCopy, destinationDir + fileToCopy);
						
						
						if(!fileCopied) 
						{
							//...Error handling...; 
//SMS only print message if problems occurred
							DebugN(\"Error copying file - source: \" + sourceDir + fileToCopy + \" destination: \" + destinationDir + fileToCopy);
//SMS why print success code
							fwInstallation_showMessage(makeDynString(\"      Error copying file: \" + fileToCopy));
							errorInstallingComponent = -1;
						}
						else
						{
//SMS							DebugN(\" OK\", fileCopied); 
						}
				}
					
			}
// import the dplist files with the ASCII manager
		
		if(dynlen(dynDplistFiles) > 0)
		fwInstallation_showMessage(makeDynString(\"    Importing dplist file: \" + dplistFile + \"...\"));
			
		
		for( i = 1; i <= dynlen(dynDplistFiles); i++)
		{	
			dplistFile = dynDplistFiles[i];

			fileToCopy = strltrim(dplistFile, \".\");
					
			asciiFile = sourceDir + fileToCopy;
									
			if(asciiFile == \"\")
			{
					fwInstallation_showMessage(\"    The \" + asciiFile + 
					\"file could not be found.\\nCheck the path (proj_path) in your config file.\\nAlso check if the file exists.\");
			}
			else
			{
					cmd = asciiManager + \" -in \\\"\" + asciiFile + \"\\\" -yes -log +stderr -log -file > \"
							+ infoFile + \" 2> \" + logFile;								
					if (_WIN32) 
					{
							err = system(\"cmd /c \" + cmd);
							if (err != 0)
							{
								fwInstallation_showMessage(\"    Could not import properly the file \" + asciiFile + \" (Error number = \" + err +\")\");
								errorInstallingComponent = -1;
							}
					}
					else  //LIN
					{
							err = system(cmd);
							if (err != 0)
							{
								fwInstallation_showMessage(\"    Could not import properly the file \" + asciiFile + \" (Error number = \" + err +\")\");
								errorInstallingComponent = -1;
							}
					}
									
							// Show result of the import of the current file in the log text field
							x = fileToString (logFile, result);
							resultInLines = strsplit (result, \"\\n\");
							fwInstallation_showMessage(resultInLines);	
					}
			fwInstallation_showMessage(makeDynString(\"\"));
		}
		
// end import the dplist files

// import config files for linux

		for(i = 1; i <= dynlen(dynConfigFiles_linux); i++)
		{
					if(! _WIN32)
					{
						fwInstallation_showMessage(makeDynString(\"    Importing linux config file ... \"));

						componentConfigFile = sourceDir + strltrim(dynConfigFiles_linux[i], \".\");
						DebugN(\"componentConfigFile: \" + componentConfigFile + \"  componentName\" +  componentName);
						fwInstallation_AddComponentIntoConfig( componentConfigFile,  componentName);
					}
		}
// end import config files for linux

// import config files for windows
		
		for(i = 1; i <= dynlen(dynConfigFiles_windows); i++)
		{
					if(_WIN32)
					{
							
							fwInstallation_showMessage(makeDynString(\"    Importing windows config file ... \"));
							
							componentConfigFile = sourceDir + strltrim(dynConfigFiles_windows[i], \".\");
							fwInstallation_AddComponentIntoConfig( componentConfigFile,  componentName);
					}
		}
// end import config files for windows
		
// import config files

		if(dynlen(dynConfigFiles_general) > 0)
		fwInstallation_showMessage(makeDynString(\"    Importing general config file ... \"));
		
		for(i = 1; i <= dynlen(dynConfigFiles_general); i++)
		{			
					componentConfigFile = sourceDir + strltrim(dynConfigFiles_general[i], \".\");
					fwInstallation_AddComponentIntoConfig( componentConfigFile,  componentName);
//DebugN(componentName, componentConfigFile);
		}
		
// end import config files	

// add scripts to the fwScripts.lst file

	if(dynlen(dynScriptsToBeAdded) > 0)
	{
		fwInstallation_showMessage(makeDynString(\"    Updating the fwScripts.lst file ... \"));
		fwInstallation_addScriptsIntoFile(dynScriptsToBeAdded, componentName);
		
		// check if the progs file contains the fwScripts.lst file
		DebugN(\"checking the progs file ... if it contains fwScripts.lst\");
		
		if(fwInstallation_fwScriptsAddedToProgsFile() == -1)
		{
			Debug(\"\\n opening the fwInstallationScriptsAddedInfo.pnl\");
			ChildPanelOnCentralReturn(\"fwInstallation/fwInstallationScriptsAddedInfo.pnl\", \"fwInstallation_ScriptsAddedInfo\", \"\", dreturnf, dreturns);
		}
	}
	
// execute the init script
		if(dynlen(dynInitFiles) > 0)
		fwInstallation_showMessage(makeDynString(\"    Executing the init file ... \"));

		for(i =1; i <= dynlen(dynInitFiles); i++)
		{
			componentInitFile = sourceDir + strltrim(dynInitFiles[i], \".\");
			// read the file and execute it
										
			fwInstallation_evalScriptFile( componentInitFile , iReturn);
			
			if(iReturn == -1)
			{
				fwInstallation_showMessage(makeDynString(\"    	Error: executing the init file: \" + componentInitFile));
				
				errorInstallingComponent = -1;


			}
		}
// end execute the init script	

// begin store the postInstall files in a datapoint
			
			// get all the post install init files
			dpGet(\"fwInstallationInfo.postInstallFiles:_original.._value\", dynPostInstallFiles_all);
			
			// append the name of the current component post install init files
			dynAppend(dynPostInstallFiles_all, dynPostInstallFiles_current);
			
			// store all the post install init files				
			dpSet(\"fwInstallationInfo.postInstallFiles:_original.._value\", dynPostInstallFiles_all);			


// end store the postInstall files in a datapoint

				
			// save the component info into the PVSS database
					
			fwInstallation_showMessage(makeDynString(\"    Saving the component info into the database: \"));
						
			dpCreated = dpCreate(\"fwInstallation_\" + componentName, \"_FwInstallationComponents\");
			
			if (dpCreated == 0 )
			{
				dpSet(\"fwInstallation_\" + componentName + \".componentVersion:_original.._value\", componentVersion);
				dpSet(\"fwInstallation_\" + componentName + \".componentVersionString:_original.._value\", componentVersion);
				dpSet(\"fwInstallation_\" + componentName + \".descFile:_original.._value\", descFile);
				
				if(date != \"\")		
				dpSet(\"fwInstallation_\" + componentName + \".date:_original.._value\", date);
				dpSet(\"fwInstallation_\" + componentName + \".installationDirectory:_original.._value\", destinationDir);
				
				if(dynlen(dynComponentFiles) > 0)
				dpSet(\"fwInstallation_\" + componentName + \".componentFiles:_original.._value\", dynComponentFiles);
				
				if(dynlen(dynConfigFiles_general) > 0)
				dpSet(\"fwInstallation_\" + componentName + \".configFiles.configGeneral:_original.._value\", dynConfigFiles_general);
				
				if(dynlen(dynConfigFiles_linux) > 0)
				dpSet(\"fwInstallation_\" + componentName + \".configFiles.configLinux:_original.._value\", dynConfigFiles_linux);			
				
				if(dynlen(dynConfigFiles_windows) > 0)
				dpSet(\"fwInstallation_\" + componentName + \".configFiles.configWindows:_original.._value\", dynConfigFiles_windows);						
				
				if(dynlen(dynInitFiles) > 0)
				dpSet(\"fwInstallation_\" + componentName + \".initFiles:_original.._value\", dynInitFiles);
				
				if(dynlen(dynPostInstallFiles) > 0)
				dpSet(\"fwInstallation_\" + componentName + \".postInstallFiles:_original.._value\", dynPostInstallFiles);
				
				if(dynlen(dynDeleteFiles) > 0)
				dpSet(\"fwInstallation_\" + componentName + \".deleteFiles:_original.._value\", dynDeleteFiles);
				
				if(dynlen(dynPostDeleteFiles) > 0)
				dpSet(\"fwInstallation_\" + componentName + \".postDeleteFiles:_original.._value\", dynPostDeleteFiles);
				
				if(dynlen(dynDplistFiles) > 0)
				dpSet(\"fwInstallation_\" + componentName + \".dplistFiles:_original.._value\", dynDplistFiles);
				
				if(dynlen(dynRequiredComponents) > 0)
				dpSet(\"fwInstallation_\" + componentName + \".requiredComponents:_original.._value\", dynRequiredComponents);
				
				dpSet(\"fwInstallation_\" + componentName + \".requiredInstalled:_original.._value\", requiredInstalled);
				
				if(dynlen(dynSubComponents) > 0)
				dpSet(\"fwInstallation_\" + componentName + \".subComponents:_original.._value\", dynSubComponents);
				
				dpSet(\"fwInstallation_\" + componentName + \".isItSubComponent:_original.._value\", isItSubComponent);
				
				if(dynlen(dynScriptsToBeAdded) > 0)
				dpSet(\"fwInstallation_\" + componentName + \".scriptFiles:_original.._value\", dynScriptsToBeAdded);
				
				

			}
			else
			{
				fwInstallation_showMessage(makeDynString(\"    ERROR: The information cannot be saved into the database \"));
				errorInstallingComponent = -1;
			}
			
			if(errorInstallingComponent == -1)
			{	
				fwInstallation_writeToMainLog(formatTime(\"[%Y-%m-%d_%H:%M:%S] \",getCurrentTime()) + componentName + \" \" + componentVersion + \" installed with errors\");
				fwInstallation_showMessage(makeDynString(\"    Component installed with errors - check the log.\"));
				dpSet(\"fwInstallation_\" + componentName + \".requiredInstalled:_original.._value\", false);
			}				
			else
			{
		
		// the component has been installed - check whether it has corrected the broken dependencies
		
				fwInstallation_getListOfNotProperlyInstalledComponents(dynNotProperlyInstalled);
				
				for(i = 1; i <= dynlen(dynNotProperlyInstalled); i++)
				{
					dynClear(dynRequiredComponents);
					
					dpGet(\"fwInstallation_\" + dynNotProperlyInstalled[i] + \".requiredComponents:_original.._value\", dynRequiredComponents);

					fwInstallation_getNotInstalledComponentsFromRequiredComponents(dynRequiredComponents, strNotInstalledNames);
					
					if(strNotInstalledNames == \"\")
					{
						dpSet(\"fwInstallation_\" + dynNotProperlyInstalled[i] + \".requiredInstalled:_original.._value\", true);
					}	
				}
				fwInstallation_writeToMainLog(formatTime(\"[%Y-%m-%d_%H:%M:%S] \",getCurrentTime()) + componentName + \" \" + componentVersion + \" installed\");
				fwInstallation_showMessage(makeDynString(\"    Component installed.\"));
				componentInstalled = true;
			}
		}	
	
}

/** This function retrieves the list of components which were not properly installed - there was error in dependencies
and the user still wanted to install the component.

@param dynNotProperlyInstalled: the list of components which were installed with broken dependencies - .requiredInstalled:_original.._value is false
@author M.Sliwinski
*/

fwInstallation_getListOfNotProperlyInstalledComponents(dyn_string & dynNotProperlyInstalled)
{
		dyn_string dynInstalledComponents;
		int i;
		bool requiredInstalled;
		
		// retrieve all installed components
		
		dynInstalledComponents =  dpNames(\"*\", \"_FwInstallationComponents\");

		
		
		for(i = 1; i <= dynlen(dynInstalledComponents); i++)
		{	
			// cut the system name from the installed components
			dynInstalledComponents[i] = dpSubStr( dynInstalledComponents[i], DPSUB_DP );
			
			// delete the fwInstallation_ prefix
			strreplace(dynInstalledComponents[i], \"fwInstallation_\", \"\");
			
			dpGet(\"fwInstallation_\" + dynInstalledComponents[i] + \".requiredInstalled:_original.._value\", requiredInstalled);
			if(!requiredInstalled)
			{
				dynAppend(dynNotProperlyInstalled, dynInstalledComponents[i]);
			}

		}		
}

/** This function checks if all the required components are installed. It returns a string of components that are not
installed and required.

@param dynRequiredComponents: the name of a componentConfigFile
@param strNotInstalledNames: the name of a component
@author M.Sliwinski
*/

fwInstallation_getNotInstalledComponentsFromRequiredComponents(dyn_string & dynRequiredComponents, string & strNotInstalledNames)
{
	int i;
	dyn_string dynInstalledComponents;
	dyn_string dynTmpNameVersion;
	string strRequiredName;
	string stringInstalledVersion;
	string stringRequiredVersion;
	
	if (dynlen(dynRequiredComponents) > 0)
	{
	
	
		// retrieve all installed components
		
		dynInstalledComponents =  dpNames(\"*\", \"_FwInstallationComponents\");

		
		for(i = 1; i <= dynlen(dynInstalledComponents); i++)
		{	
		
			// cut the system name from the installed components

			dynInstalledComponents[i] = dpSubStr( dynInstalledComponents[i], DPSUB_DP );
			
			// cut the fwInstallation_ prefix 
			
			strreplace(dynInstalledComponents[i], \"fwInstallation_\" , \"\");		
		}
				
		for( i = 1; i <= dynlen(dynRequiredComponents); i++)
		{
		
			// retrieve the name and version of the component
				
			dynTmpNameVersion = strsplit(dynRequiredComponents[i] , \"=\");
			
			strRequiredName = strltrim(strrtrim(dynTmpNameVersion[1]));
			
			if(dynlen(dynTmpNameVersion) > 1)
			{
				stringRequiredVersion = strltrim(strrtrim(dynTmpNameVersion[2]));
			}
			else
			{	
				stringRequiredVersion = \"\";
			}
			
			
			// check whether the required component is installed
			
			if(dynContains(dynInstalledComponents, strRequiredName))
			{
				// the required component is installed
				
				// checking the version of the installed component
				
				 dpGet(\"fwInstallation_\" + strRequiredName + \".componentVersionString:_original.._value\", stringInstalledVersion);
				 
				 if(_fwInstallation_CompareVersions(stringInstalledVersion, stringRequiredVersion))
				 {
				 
				 	// the installed version of the component is greater than the required version - OK
				 }
				 else
				 {
				 	// the installed version is older than the required version
					
					strNotInstalledNames += strRequiredName + \"=\" + stringRequiredVersion + \"|\";

				 }
					
			}
			else
			{

				// the required component is not installed
				strNotInstalledNames += strRequiredName + \"=\" + stringRequiredVersion + \"|\";
				
			}
		}
	}
}

/** This function reads the information from the componentConfigFile and copies it into the project config file.
Function uses the following functions: fwInstallation_loadConfigIntoTables, fwInstallation_AddComponentIntoConfigIntoMemory
fwInstallation_saveFile

@param componentConfigFile: the name of a componentConfigFile
@param componentName: the name of a component
@author M.Sliwinski
*/

fwInstallation_AddComponentIntoConfig(string componentConfigFile, string componentName)
{
	
	string configPath = getPath(CONFIG_REL_PATH);
	string configFile = configPath + \"config\";
	
	dyn_string loadedSections;  // this table contains the sections loaded from the config file
	dyn_dyn_string configSectionTable; // the memory representation of a config file     [1][i] - [section:parameter] , [i+1][j] - [value]
	dyn_string configLines; // this table contains the config file - each row contains one line from config file
	
//	loadedSections = makeDynString(\"\");
	dynClear(loadedSections);
	configSectionTable [1] = \"\";
	configSectionTable [2] = \"\";
	configSectionTable [3] = \"\";

	// load the config file into its memory representation			
	fwInstallation_loadConfigIntoTables(loadedSections, configSectionTable, configLines, configFile);

	// add component into memory
	fwInstallation_AddComponentIntoConfigIntoMemory(loadedSections, configSectionTable, configLines, componentConfigFile , componentName);

	// save the config file
	fwInstallation_saveFile(configLines, configPath + \"config\");

//SMS
//SMSif(strtolower(componentName) == \"fwdeviceeditornavigator\")
//SMS	DebugN(\"<\"+componentName+\">: after insertion\", configLines);
//SMS

}


	

/** This function reads the information from the component config file and saves the information into memory:
loadedSections and configSectionTable - the tables containing the information about the sections:parameters:values
configLines: the table containing the lines of a config file

@param loadedSections: the list of loaded sections
@param configSectionTable: the memory representation of a config file     [1][i] - [section:parameter] , [i+1][j] - [value]
@param configLines: the dyn_string containing the lines of a config file
@param fileName: the name of a config file of a component
@param componentName: the name of a component
@author M.Sliwinski
*/

int fwInstallation_AddComponentIntoConfigIntoMemory(dyn_string & loadedSections, dyn_dyn_string & configSectionTable, dyn_string & configLines, string fileName, string componentName)
{
	string fileInString;
	string tempLine;
	string currentSection = \"NOT_YET_DEFINED\";
	dyn_string componentLines; // contains the lines from the component config file
	dyn_dyn_string componentParameters; // [1][i] - section name; [i + 1][j] - section parameters ( lines )
	bool fileLoaded = false;
	dyn_string linesToAdd;
	string tempParameter;
	string tempValue;
	string tempString,tempStringQuotes;
	
	dyn_string strValues;
	dyn_string parameterValue;
	
	int idxOfSection;
	int sectionExistsInConfig;
	int valueExistsInConfig;
	int i, j , k;
	int returnValue;
	
	
//	componentParameters[1] = \"\";
//	componentParameters[2] = \"\";
	dynClear(componentParameters[1]);
	dynClear(componentParameters[2]);
	
	// first delete the old information about the component from the config file
	fwInstallation_deleteComponentFromConfigInMemory(loadedSections, configSectionTable, configLines, componentName);
		
	
	// load the component config file
	fileLoaded = fileToString(fileName, fileInString);
	
	if (! fileLoaded )
	{
	
		DebugN(\"Cannot load \" + fileName + \" file\");
	}
	else 
	{

			componentLines = strsplit(fileInString, \"\\n\");
			
			
			for(i = 1; i <= dynlen(componentLines); i++)
			{
				tempLine = strltrim(strrtrim(componentLines[i]));
		
		
				if (tempLine == \"\" )
				{
		//			Debug(\"\\n The line is blank |\"  + tempLine + \"|\");
				}
				else if ( strtok(tempLine, \"#\") == 0)
				{
					if( currentSection == \"NOT_YET_DEFINED\")
					{
						// we do not know in which section to add the comment
					}
					else  // add the comment into the table
					{
						idxOfSection = dynContains(componentParameters[1], currentSection);
						
						dynAppend(componentParameters[idxOfSection + 1], tempLine);
					}
				}
				else if ( strtok(tempLine, \"[\") == 0)  // this is a section
				{
					
					dynAppend(componentParameters[1] ,tempLine);
					currentSection = tempLine;
							
				}
				else // this is parametrization
				{
					 if(currentSection == \"NOT_YET_DEFINED\")
					 {
					 	DebugN(\"Error: the component file has errors  section is not defined. line: \" + i);
					 }
					 else
					 {
					 	idxOfSection = dynContains(componentParameters[1], currentSection);
					 	
					 	dynAppend(componentParameters[idxOfSection + 1], tempLine);
					 }
				}
			} //end  for ( i = 1; i <= dynlen(componentLines)
			
			// the component information is now in the componentParameters table
		
			
		// adding the component into the config file
		
			for(i = 1; i <= dynlen(componentParameters[1]); i++)
			{
				currentSection = componentParameters[1][i];
				
		//		Debug(\"\\n adding the lines in section: \" + currentSection);
				
				sectionExistsInConfig = dynContains(loadedSections, currentSection);
				
				if(sectionExistsInConfig == 0) // the section does not exist - add the lines into the config table and into the memory
				{
							
					dynAppend(loadedSections, currentSection);
					dynAppend(configLines, currentSection);
					
					dynAppend(configLines, \"#begin \" + componentName);
					dynAppend(configLines, \"#This should not be edited manually\");
					dynAppend(configLines, \"#if the component is empty it means that the parametrization is already done in the section\\n\");

					for(j =1; j <= dynlen(componentParameters[i + 1]); j++)
					{
						tempLine = strltrim(strrtrim(componentParameters[i + 1][j]));
						
						if (tempLine == \"\")
						{
		//					 Debug(\"\\n The line is blank: |\" + tempLine + \"|\");
						}
						else if( strtok(tempLine, \"#\") == 0)
						{
		//					Debug(\"\\n The line is a comment: |\" + tempLine + \"|\");
							dynAppend(linesToAdd, tempLine);
		//
						}
						else  // this line is a parametrization - check if the value already exist, if not add it
						{
								parameterValue = strsplit(tempLine, \"=\");
								tempParameter = strltrim(strrtrim(parameterValue[1]));
								tempValue = strltrim(strrtrim(parameterValue[2]));
								
								tempStringQuotes = tempValue; //SMS
								tempString = strltrim(strrtrim(tempValue, \"\\\"\"), \"\\\"\");
								tempValue = tempString;
								
								strValues = strsplit(tempValue, \",\");
								
								for(k = 1; k <= dynlen(strValues); k++)
								{
									tempValue = strltrim(strrtrim(strValues[k]));
									
									returnValue = fwInstallation_configContainsValue(configSectionTable, currentSection, tempParameter, tempValue);
									if( returnValue == 1)
									{
										// the value is already defined for this section and parameter
//SMS tobedeleted								
										Debug(\"\\n config Contains Parameter: \" + tempParameter + \"  value: |\" + tempValue + \"|\");
									}
									else
									{
		//								(\"\\n Adding the Parameter: \" + tempParameter + \"  value: \" + tempValue);
										if(tempString == tempStringQuotes)	//SMS only if quotes where there before, put them again
										{
											dynAppend(linesToAdd, tempParameter + \" = \" + tempValue );	//SMS
										} else {
											dynAppend(linesToAdd, tempParameter + \" = \\\"\" + tempValue + \"\\\"\");	//SMS the original line
										}
		
										fwInstallation_addValueIntoMemory(configSectionTable, currentSection, tempParameter, tempValue); 
									}
								}	
						}

					}
					dynAppend(configLines, linesToAdd);
					dynAppend(configLines, \"#end \" + componentName + \"\\n\");
					
					// we have added the whole information into the section			
				}
				else if(sectionExistsInConfig == -1)
				{
					Debug(\"\\n ERROR: Cannot check if section exists in loadedSections table\");
				}
				else // add the lines into the config table and into the memory
				{
		//			Debug(\"\\n section exists in the config\");
					if(dynlen(componentParameters) >= i+1)
					{
						dynClear(linesToAdd);
					 	dynAppend(linesToAdd, \"#begin \" + componentName);
						dynAppend(linesToAdd, \"#This should not be edited manually\");
						dynAppend(linesToAdd, \"#if the component is empty it means that the parametrization is already done in the section\\n\");
						
						for(j = 1; j <= dynlen(componentParameters[i + 1]); j++)
						{
							tempLine = strltrim(strrtrim(componentParameters[i + 1][j]));
							
							if (tempLine == \"\")
							{
			//					 Debug(\"\\n The line is blank: |\" + tempLine + \"|\");
							}
							else if( strtok(tempLine, \"#\") == 0)
							{
			//					Debug(\"\\n The line is a comment: |\" + tempLine + \"|\");
								dynAppend(linesToAdd, tempLine);
			//
							}
							else  // this line is a parametrization - check if the value already exist, if not add it
							{
									parameterValue = strsplit(tempLine, \"=\");
									tempParameter = strltrim(strrtrim(parameterValue[1]));
									tempValue = strltrim(strrtrim(parameterValue[2]));
									
									tempStringQuotes = tempValue; //SMS
									tempString = strltrim(strrtrim(tempValue, \"\\\"\"), \"\\\"\");
									tempValue = tempString;
									
									strValues = strsplit(tempValue, \",\");
									
									for(k = 1; k <= dynlen(strValues); k++)
									{
										tempValue = strltrim(strrtrim(strValues[k]));
										
										returnValue = fwInstallation_configContainsValue(configSectionTable, currentSection, tempParameter, tempValue);
										if( returnValue == 1)
										{
											// the value is already defined for this section and parameter
											
			//								Debug(\"\\n config Contains Parameter: \" + tempParameter + \"  value: |\" + tempValue + \"|\");
										}
										else
										{
			//								(\"\\n Adding the Parameter: \" + tempParameter + \"  value: \" + tempValue);
											if(tempString == tempStringQuotes)	//SMS only if quotes where there before, put them again
											{
												dynAppend(linesToAdd, tempParameter + \" = \" + tempValue );	//SMS
											} else {
												dynAppend(linesToAdd, tempParameter + \" = \\\"\" + tempValue + \"\\\"\");	//SMS the original line
											}
			
											fwInstallation_addValueIntoMemory(configSectionTable, currentSection, tempParameter, tempValue); 
										}
									}	
							}
						}
						
						dynAppend(linesToAdd, \"#end \" + componentName + \"\\n\");
					}
		
		
		// we are adding the lines - linesToAdd   into the configLines table under  - currentSection
//SMS
//DebugN(\"<\"+componentName+\">: Inserting lines into section \"+currentSection, linesToAdd);
//SMS
					fwInstallation_addLinesIntoSection(configLines, currentSection, linesToAdd);
//SMS
//if(strtolower(componentName) == \"fwdeviceeditornavigator\")
//	DebugN(\"<\"+componentName+\">: after insertion\", configLines);
//SMS

					
				}
			}

	}
}


/** This function adds the lines from linesToAdd into the configLines under the section specified by currentSection

@param configLines: the dyn_string with file lines
@param currentSection: the name of a currentSection
@param linesToAdd: the lines to be added

@author M.Sliwinski
*/

int fwInstallation_addLinesIntoSection(dyn_string & configLines, string currentSection, dyn_string  linesToAdd)
{
	int idxOfLine;
	int i;
	int returnValue;
	
	string tempLine;
	
	for( i = 1; i <= dynlen(configLines); i++)
	{
		tempLine = strltrim(strrtrim(configLines[i]));
		
		// find the section where it should be inserted	
		if(tempLine == currentSection)
		{
			// insert the lines into the configLines
			returnValue = dynInsertAt(configLines, linesToAdd, ++i);
			
			if(returnValue == -1)
			{
				return -1;
			}
			else
			{
				return 1;
			}
		}	
	}
	
	
}

/** This function adds [section:parameter] , [value] data into the memory representation of a config file

@param configSectionTable: the memory representation of a config file     [1][i] - [section:parameter] , [i+1][j] - [value]
@param section: the value of a section
@param parameter: the value of a parameter
@param value: the value of a \"value\"

@author M.Sliwinski
*/

int fwInstallation_addValueIntoMemory(dyn_dyn_string & configSectionTable, string section, string parameter, string value)
{
	int	idxSectionParam;
	int idxValue;
	int idxTemp;
	
	// get the index of section:parameter
	idxSectionParam = dynContains(configSectionTable[1], section + \":\" + parameter);
	
	if (idxSectionParam == 0)
	{
		// add the section:parameter to the configSectionTable
		
		dynAppend(configSectionTable[1], section + \":\" + parameter);
		
		// find the index of section:parameter
		idxTemp	= dynContains(configSectionTable[1], section + \":\" + parameter);
		
		// add the value into memory
		dynAppend(configSectionTable[idxTemp + 1], value);	
	}
	else if(idxSectionParam == -1)
	{
		Debug(\"Error: fwInstallation_addValueIntoMemory\");
		return -1;
	}
	else
	{
		idxValue = dynContains(configSectionTable[idxSectionParam + 1], value);
		
		if (idxValue == 0)
		{
			dynAppend(configSectionTable[idxSectionParam + 1], value);	
		}
		else if(idxValue == -1)
		{
			Debug(\"Error: fwInstallation_addValueIntoMemory\");
		}
		else
		{	
			// This value already exists - do nothing
		}
	}
	return 1;

}

/** This function deletes the config info about a component from the memory representation of a config file - [section:parameter] , [value]
and from the configLines dyn_string

@param loadedSections: the list of sections loaded from the config file
@param configSectionTable: the memory representation of a config file     [1][i] - [section:parameter] , [i+1][j] - [value]
@param configLines: the dyn_string containing the lines from the config file
@param componentName: the name of a component to be deleted

@author M.Sliwinski
*/

int fwInstallation_deleteComponentFromConfigInMemory(dyn_string & loadedSections, dyn_dyn_string & configSectionTable, dyn_string & configLines, string componentName)
{
	int i, j;
	
	int configLength;
	int idxSectionParam;
	int idxSection;
	int idxValue;
	int idxCurrent;
	int removeResult;
	
	string currentSection;
	dyn_string sections;
	dyn_string configSectionRow;
	
	string tempLine;
	string tempParameter;
	string tempValue;
	string tempString;
	string tempSection;
	dyn_string parameter_Value;
	
	dyn_dyn_int components; // [1][i] index of beginning of a component definition;  [2][i] index of ending of a component definition
	dyn_string strValues;
	
	int idxBegin = 0;
	int idxEnd = 0;
	
	dynClear(sections);
	dynClear(components[1]);
	dynClear(components[2]);
	


// find out where are the components situated and in which sections
// we are interested in the indexes of #begin and #end lines

	for(i = 1; i <= dynlen(configLines); i++)
	{
	
		if ( strtok(configLines[i], \"[\") == 0)
		{
						currentSection = configLines[i];
		}
		
			if(strpos(configLines[i], \"#begin \" + componentName) >= 0)
			{
				idxBegin = i;
			}
			
			if(strpos(configLines[i], \"#end \" + componentName) >= 0)
			{
	//			Debug(\"\\n found end \");			
				idxEnd = i;
			}
			
			if(idxBegin < idxEnd)
			{
				dynAppend(components[1], idxBegin); 
				dynAppend(components[2], idxEnd);
				dynAppend(sections, currentSection);

				idxBegin = 0;
				idxEnd = 0;
			}
	}


// delete the component from the file ( the configLines table ) and from configSectionTable

	for(i = dynlen(components[1]); i >=1; i--)
	{
		idxBegin = components[1][i];
		idxEnd = components[2][i];
	
		idxCurrent = idxEnd;

		currentSection = sections[i];
		
//		Debug(\"\\n idxBegin: \" + idxBegin + \" ; idxEnd: \" + idxEnd + \" ; currentSection: \" + currentSection);
		
		for(idxCurrent = idxEnd; idxCurrent >= idxBegin; idxCurrent--)
		{
			// delete it from the configSectionTable

			
			tempLine = strltrim(strrtrim(configLines[idxCurrent]));
			
			removeResult = dynRemove(configLines, idxCurrent);
			
			if (removeResult == -1)
			{
				Debug(\"\\n ERROR: fwInstallation_deleteComponentFromConfigInMemory(): could not remove the line from table\");
			}
		
//			Debug(\"\\n Remove result of line : ( \" + idxCurrent + \" ) from Config Lines: \" + removeResult + \" line : \" + tempLine);
			
			if (tempLine == \"\" )
			{
//			Debug(\"\\n The line is blank n\"  + tempLine + \"|\");
			}
			else if ( strtok(tempLine, \"#\") == 0)
			{
//				Debug(\"\\n This line is a comment\"  + tempLine + \"| \");
			}
			else // the templine contains parameters
			{
				parameter_Value = strsplit(tempLine, \"=\");
				
				tempParameter = strltrim(strrtrim(parameter_Value[1]));
				
				tempValue = strltrim(strrtrim(parameter_Value[2]));
				
				tempString = strltrim(strrtrim(tempValue, \"\\\"\"));
				
				tempValue = tempString;  // now value is without quotation marks
				
				strValues = strsplit(tempValue, \",\");
				
				for(j = 1 ; j <= dynlen(strValues); j++)
				{
					tempValue = strValues[j];
					strValues[j] = strrtrim(strltrim(tempValue , \"\\\" \") , \"\\\" \");
				}
				
				tempString = currentSection + \":\" + tempParameter;
				
				// Deleting the values from memory
				
//				Debug(\"\\n Checking if configSectionTable[1] contains: \" + tempString);
				
				idxSectionParam = dynContains(configSectionTable[1], tempString);
					
				if(idxSectionParam == 0)
				{
					// The value does not exist 
				}
				else if (idxSectionParam == -1)
				{
					Debuf(\"\\n ERROR: fwInstallation_deleteComponentFromConfigInMemory(): can not read value from configSectionTable: \");
				}
				else{
				
//				 	Debug(\"\\n configSectionTable[1] contains: \" + tempString + \" on idx: \" + idxSectionParam);
//				 	Debug(\"\\n checking if strValues exist: \" + strValues);
				 	
					for(j = 1; j <= dynlen(strValues); j++)
					{
						idxValue = dynContains(configSectionTable[idxSectionParam + 1], strValues[j]);
//						Debug(\"\\n configSectionTable[idxSectionParam+1]: \" + configSectionTable[idxSectionParam + 1]);
						
						if(idxValue > 0)
						{
//							Debug(\"\\n removing the value: \" + strValues[j]);
							
							
							removeResult = dynRemove(configSectionTable[idxSectionParam + 1], idxValue);
							
							
//							Debug(\"\\n removeResult dynRemove(configSectionRow[idxSectionParam + 1] , idxValue): \" + removeResult);
						}					
					}

				} // else
			}
				
		}
		
	}
	
}


/** This function checks whether the section-parameter-value is defined in the memory


@param configSectionTable: the memory representation of a config file     [1][i] - [section:parameter] , [i+1][j] - [value]
@param section: the value of a section
@param parameter: the value of a parameter
@param value: the value of a \"value\"

@author M.Sliwinski
*/
	


int fwInstallation_configContainsValue(dyn_dyn_string & configSectionTable, string section , string parameter, string value)
{
	int idxOfParameter;
	int idxOfValue;
	
	idxOfParameter = dynContains(configSectionTable[1] , section + \":\" + parameter);
	
	if(idxOfParameter == 0)
	{
//		Debug(\"\\n fwInstallation_configContainsValue: There is no section_parameter:\" + section + \":\" + parameter);
		return 0;
	}
	else if (idxOfParameter == -1)
	{
		Debug(\"\\n ERROR: fwInstallation_configContainsValue: error in checking section_parameter\" );
		return 0;
	}
	else
	{	
		idxOfValue = dynContains(configSectionTable[idxOfParameter + 1], value);
		if(idxOfValue ==  0)
		{
			return 0;
		}
		else if (idxOfValue == -1)
		{
//			Debug(\"\\n fwInstallation_configContainsValue: error in checking value\" );
			return 0;
		}
		else
		{
//			Debug(\"\\n fwInstallation_configContainsValue: value exists: returning 1\");
			return 1;
		}
		
	}
}

						
/** This function builds the memory representation of a config file

@param loadedSections: the list of sections loaded from the config file
@param configSectionTable: the memory representation of a config file     [1][i] - [section:parameter] , [i+1][j] - [value]
@param configLines: dyn_string containing the lines from the config file 
@param fileName: the name of a config file

@author M.Sliwinski
*/
	
int fwInstallation_loadConfigIntoTables(dyn_string & loadedSections, dyn_dyn_string & configSectionTable, dyn_string & configLines, string fileName)
{
//	dyn_string knownSections = makeDynString(\"[ui]\" , \"[ctrl]\");
	
	dyn_string parameter_Value;

	int idxSectionParam;
	int idxSection;
	int idxValue;
	int sectionLength;

	bool fileLoaded = false;

	string fileInString;

	string tempLine;
	string tempParameter;
	string tempValue;
	string tempString; 

	dyn_string strValues;
	
	string currentSection = \"NOT_KNOWN\";
	string lineTrimmed;
	
	int i, j ;
	
	fileLoaded = fileToString(fileName, fileInString);
	
	if (! fileLoaded )
	{
	
		DebugN(\"Cannot load \" + fileName + \" file\");
	}
	else 
	{
//		Debug(\"\\n\" + fileName + \" - file loaded\");
	}

	configLines = strsplit(fileInString, \"\\n\");
	
	
// each line is loaded in a row of dyn_string configLines
	
	for(i = 1; i <= dynlen(configLines); i++)
	{
		tempLine = strltrim(strrtrim(configLines[i]));

					
		if (tempLine == \"\" )
		{
//			Debug(\"\\n The line is blank |\"  + tempLine + \"|\");
		}
		else if ( strtok(tempLine, \"#\") == 0)
		{
//			Debug(\"\\n This line is a comment |\"  + tempLine + \"|\");
		}
		else if ( strtok(tempLine, \"[\") == 0)
		{
//			Debug(\"\\n This line is a section |\"  + tempLine + \"|\");
		//	if(dynContains(knownSections, tempLine))
		//	{
//						Debug(\"\\n Adding new section into memory: \" + tempLine);
			
					dynAppend(loadedSections ,tempLine);
					currentSection = tempLine;
					
		//	}
		//	else
		//	{
			//	Debug(\"\\n This section is not known\");
		//				currentSection = \"NOT_KNOWN\";
		//	}
		}
		else // this is parametrization
		{ 
			if (currentSection == \"NOT_KNOWN\")
			{
				// Debug(\"\\n This section is not known: don't add parameter to memory\");
			}
			else // This section is already in memory
			{
//				Debug(\"\\n Adding the parameter into memory\" + tempLine + \"|\");
				
				parameter_Value = strsplit(tempLine, \"=\");
				
				tempParameter = strltrim(strrtrim(parameter_Value[1]));
				
				tempValue = strltrim(strrtrim(parameter_Value[2]));
				
				tempString = strltrim(strrtrim(tempValue, \"\\\"\"));
				
				tempValue = tempString;  // now value is without quotation marks
				
				strValues = strsplit(tempValue, \",\");
				
				for(j = 1 ; j <= dynlen(strValues); j++)
				{
					tempValue = strValues[j];
					strValues[j] = strrtrim(strltrim(tempValue , \"\\\" \") , \"\\\" \");
				}
				
				// we hava all the values in a dyn_string - strValues
								
				idxSection = dynContains(loadedSections, currentSection);
				
				if (idxSection > 0)  // this section is in loaded sections
				{
				
					tempString = currentSection + \":\" + tempParameter;
												
					idxSectionParam = dynContains(configSectionTable[1], tempString);
					
	//				Debug(\"\\n idxSection : \" + idxSection );
				
					if(idxSectionParam == 0)  // the parameter tempParameter is not defined
					{
						
						dynAppend(configSectionTable[1], tempString);
						
//						Debug(\"\\n Adding parameter: \" + tempString + \" and values: \" + strValues + \"for the first time\");
						
						idxSectionParam = dynContains(configSectionTable[1], tempString);
						
						for( j = 1; j<= dynlen(strValues); j++)
						{
							
							dynAppend(configSectionTable[idxSectionParam + 1], strValues[j]);
							
						}
							
	//					Debug(\"\\n adding the parameter: \" + tempParameter );			
					}
					else if( idxSectionParam == -1)
					{

					}
					else // the parameter is defined for the section add the value
					{
		
			
						for( j = 1; j<= dynlen(strValues); j++)
						{
									
							idxValue = dynContains(configSectionTable[idxSectionParam + 1], strValues[j]);
							
							if(idxValue == 0)
							{
								dynAppend(configSectionTable[idxSectionParam + 1], strValues[j]);
//								Debug(\"\\n Adding parameter: \" + tempString + \" and values: \" + strValues);
								
							}
							else if (idxValue == -1)
							{
								Debug(\"\\n ERROR: fwInstallation_loadConfigIntoTables():  Error in adding Value into memory\");
							}
							else
							{
//								Debug(\"\\n This value already exists: \" + tempValue);
							}
						}
					}
				} // if (dynContains(loadedSections, currentSection))
				else
				{	
					// This parameter is in a \"not known section\"
				}
				
			}
		
		} // else		
	} // end for	
}
" 0
 E E E
13 31
"viewLogfile"
""
1 590 600 E E E 1 E 1 E N "_3DText" E N "_3DFace" E E
 E E
25 0 0 0 0 0
EE E
0
1
LANG:1 0 
0
1
LANG:1 107 -microsoft windows-Arial-normal-r-normal-*-*-120-100-100-*-*-iso8859-1|-13,0,0,0,400,0,0,0,0,3,2,1,34,Arial
0 ""
588 598 680 630
T 
1
LANG:1 12 View Logfile
"main()
{
	string fileName = getPath(LOG_REL_PATH) + \"/fwInstallation.log\";
	if (_WIN32)
		system(\"write \\\"\" + fileName + \"\\\"\");
	else
		system(\"xterm -e vi \" + fileName + \" &\");
}" 0
 E E E
0
LAYER, 1 
1
LANG:1 6 Layer2
0
LAYER, 2 
1
LANG:1 6 Layer3
0
LAYER, 3 
1
LANG:1 6 Layer4
0
LAYER, 4 
1
LANG:1 6 Layer5
0
LAYER, 5 
1
LANG:1 6 Layer6
0
LAYER, 6 
1
LANG:1 6 Layer7
0
LAYER, 7 
1
LANG:1 6 Layer8
0
0