//
// Per utilizzare questo file e' necessario includere i file inputs.js e message.js.
// I file date.js e SelectListObj.js sono necessari se si usano le date e le liste di selezione
//

// Graphic presentation data. To change graphic aspect override those variables
var INPUT_CLASS = "searchinput formcontentColor";
var FIELD_CLASS = "searchfield formcontentColor";
var TITLE_CLASS = "searchtitle formcontentColor";
var MULTI_CLASS = "searchmulti formcontentColor";
var DELETE_ICON = "/psixlocalization/images/filterremove.gif";
var ADD_ICON = "/psixlocalization/images/filteradd.gif";
var BLANK_ICON = "/psixlocalization/images/spacer18.gif";
var WIDTH_TEXT = "230";
var WIDTH_DATE = "200";
var WIDTH_MODE = "80";
var WIDTH_FIELD = "150";
var WIDTH_MULTI = "180";
var WIDTH_LOGIC = "50";
var WIDTH_SELECTION = 360;
var ROWS_SELECTION = 6;

// Defaults. To change search parameter override those variables
var OBJECT_ARRAY = new Array("asset");
var MAX_RESULTS = "105";
var MAX_PAGE_RESULTS = "15";
var ORDER = "title";
var ORDER_DIR = "ascending";

// Input names
var FIELD_INPUT = "NameFieldOption";
var MODE_INPUT = "ModeFieldOption";
var TYPE_INPUT = "TypeFieldOption";
var VALUE_INPUT = "TextFieldOption";
var LOGIC_INPUT = "LogicFieldOption";
var SEARCH_FORM = "SearchForm";

var MAX_RESULTS_INPUT = "MaxResultsSearch";
var MAX_PAGE_INPUT = "MaxPageSearch";
var ORDER_INPUT = "OrderSearch";
var ORDER_DIR_INPUT = "OrderDirSearch";
var OBJECTS_SELECT = "ObjectsToSearch";

var MULTI_INPUT = "MultiInput";
var STATIC_INPUT = "StaticCondition";
var SELECTION_INPUT = "Selection";
var SELECTED_INPUT = "Selected";

var RETURN_XML = false;

// Standard collection array
var arrOrderObject = new Array();
arrOrderObject[0] = new objectPair ("title", szMsgTitle)
arrOrderObject[1] = new objectPair ("createdate", szMsgCreationDate)
arrOrderObject[2] = new objectPair ("modifydate", szMsgModifyDate)

var arrOrderAccount = new Array();
arrOrderAccount[0] = new objectPair ("lastname", szMsgLastName)
arrOrderAccount[1] = new objectPair ("firstname", szMsgFirstName)
arrOrderAccount[2] = new objectPair ("userid", szMsgUsername)

var arrObjects = new Array();
arrObjects[0] = new objectPair ("asset", szMsgAssets)
arrObjects[1] = new objectPair ("container", szMsgContainers)
arrObjects[2] = new objectPair ("locator", szMsgLocators)
arrObjects[3] = new objectPair ("box", szMsgBoxes)

var arrAccounts = new Array();
arrAccounts[0] = new objectPair ("user", szMsgUsers)
arrAccounts[1] = new objectPair ("group", szMsgGroups)

var arrLogic = new Array();
arrLogic[0] = new objectPair ("and", szMsgLogicAnd);
arrLogic[1] = new objectPair ("or", szMsgLogicOr);

// Array with fields definition: one for objects and one for accounts
//                       field name   type      caption    mode array to use
var OBJECT = new Array();
//OBJECT[0] = new objectField ("text", "text", szMsgContentOfAsset, "content");
OBJECT[0] = new objectField ("title", "text", szMsgTitle, "text");
OBJECT[1] = new objectField ("description", "text", szMsgDescription, "text");
OBJECT[2] = new objectField ("createdby", "text", szMsgAuthor, "text");
OBJECT[3] = new objectField ("createdate", "date", szMsgCreationDate, "date");
OBJECT[4] = new objectField ("modifydate", "date", szMsgModifyDate, "date");
OBJECT[5] = new objectField ("attachment.title", "text", szMsgAttachTitle, "text");
OBJECT[6] = new objectField ("attachment.description", "text", szMsgAttachDescription, "text");
//OBJECT[5] = new objectField ("pn", "text", szMsgProtocolNumber, "text");
var ACCOUNT = new Array();
ACCOUNT[0] = new objectField ("lastname", "text", szMsgLastName, "text");
ACCOUNT[1] = new objectField ("firstname", "text", szMsgFirstName, "text");
ACCOUNT[2] = new objectField ("userid", "text", szMsgUsername, "text");
ACCOUNT[3] = new objectField ("registrationdate", "date", szMsgRegistrationDate, "date");

// mode arrays

// text field
var arrMode_text = new Array();
arrMode_text[0] = new objectPair ("contains", szMsgContains);
arrMode_text[1] = new objectPair ("startwith", szMsgStartWith);
arrMode_text[2] = new objectPair ("endwith", szMsgEndWith);
arrMode_text[3] = new objectPair ("notcontains", szMsgNotContains);
arrMode_text[4] = new objectPair ("like", szMsgEqualTo);
arrMode_text[5] = new objectPair ("null", szMsgNull);
arrMode_text[6] = new objectPair ("notnull", szMsgNotNull);
// number field
var arrMode_number = new Array();
arrMode_number[0] = new objectPair ("equal", szMsgEqualTo);
arrMode_number[1] = new objectPair ("notequal", szMsgNotEqual);
arrMode_number[2] = new objectPair ("greater", szMsgGreater);
arrMode_number[3] = new objectPair ("less", szMsgLess);
arrMode_number[4] = new objectPair ("greaterequal", szMsgGreaterEqual);
arrMode_number[5] = new objectPair ("lessequal", szMsgLessEqual);
arrMode_number[6] = new objectPair ("null", szMsgNull);
arrMode_number[7] = new objectPair ("notnull", szMsgNotNull);
// date field
var arrMode_date = new Array();
arrMode_date[0] = new objectPair ("equal", szMsgEqualTo);
arrMode_date[1] = new objectPair ("notequal", szMsgNotEqual);
arrMode_date[2] = new objectPair ("greater", szMsgAfter);
arrMode_date[3] = new objectPair ("less", szMsgBefore);
arrMode_date[4] = new objectPair ("delta-7", szMsgLastWeek);
arrMode_date[5] = new objectPair ("delta-30", szMsgLastMonth);
arrMode_date[6] = new objectPair ("delta-90", szMsgLast3Month);
arrMode_date[7] = new objectPair ("null", szMsgNull);
arrMode_date[8] = new objectPair ("notnull", szMsgNotNull);
// content field
var arrMode_content = new Array();
arrMode_content[0] = new objectPair ("all array", szMsgAllWords);
arrMode_content[1] = new objectPair ("some array", szMsgSomeWords);
arrMode_content[2] = new objectPair ("exact phrase", szMsgExactPhrase);
arrMode_content[3] = new objectPair ("intelligent phrase", szMsgIntelligentPhrase);
// profile multiple value
var arrMode_profileMultipleValue = new Array();
arrMode_profileMultipleValue[0] = new objectPair ("array", szMsgEqualTo);

// Internal array

// date initialization
var arrDay = new Array ();
arrDay[0] = new objectPair ("", "");
for (var i = 1; i < 32; i++)
	arrDay[i] = new objectPair (((i < 10) ? "0" + i : i) , i);
var arrYear = new Array();
arrYear[0] = new objectPair ("", "");
for (var i = 1; i < 15; i++)
	arrYear[i] = new objectPair (2000 + i, 2000 + i);
var arrMonth = new Array();
arrMonth[0] = new objectPair ("", "");		
arrMonth[1] = new objectPair ("01", szMsgJanuary);		
arrMonth[2] = new objectPair ("02", szMsgFebruary);		
arrMonth[3] = new objectPair ("03", szMsgMarch);		
arrMonth[4] = new objectPair ("04", szMsgApril);		
arrMonth[5] = new objectPair ("05", szMsgMay);		
arrMonth[6] = new objectPair ("06", szMsgJune);		
arrMonth[7] = new objectPair ("07", szMsgJuly);		
arrMonth[8] = new objectPair ("08", szMsgAugust);		
arrMonth[9] = new objectPair ("09", szMsgSeptember);		
arrMonth[10] = new objectPair ("10", szMsgOctober);		
arrMonth[11] = new objectPair ("11", szMsgNovember);		
arrMonth[12] = new objectPair ("12", szMsgDecember);		

var REMOVE_DYNAMIC = 0;
var REMOVE_SELECTION = 1;
var REMOVE_STATIC = 2;
var REMOVE_MULTIPLE = 4;
var REMOVE_ALL = 7;

var DEBUG_SEARCH = false;

var REGISTER = "register";
var LOGIC_AND = "logic_field_and";
var LOGIC_OR = "logic_field_or";
var LOGIC_FIELD = "logic_field";
	
// Internal Global variables
var XMLSearch = "";
var timeout = null;
var bIsOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;
var bIsNetscape = ((navigator.appName == "Netscape") || bIsOpera) ? true : false;
var arrConditions = new Array();
var arrMultiConditions = new Array();
var arrSelectList = new Array();
var arrPredicates = null;
var arrStatic = new Array();

var nObjectsIndex = -1;
var nConditionIndex = 0;
var nMultiConditionIndex = 0;
var nSelectionIndex = 0;
var today = new Date();
var szCurrentDate = today.getFullYear() + "-";
if (String(today.getMonth() + 1).length > 1) 
	szCurrentDate += (today.getMonth() + 1) + "-";
else 
	szCurrentDate += "0" + (today.getMonth() + 1) + "-";
if (String(today.getDate()).length > 1) 
	szCurrentDate += today.getDate();
else 
	szCurrentDate += "0" + today.getDate();
// Public global functions

// Use this function to start search.
function StartSearch(szTarget, bForm, nVista, szQuery, szAlias, szPath, szBpa, szToken)
{
	if (top.SearchWait)
		return;
	if (!nVista)
		nVista = 2;
	// objects and parameters
	var szObjects = "<objects>";
	var manualObjects = document.getElementById (OBJECTS_SELECT);
	if (manualObjects) {
		if (manualObjects.tagName == "SELECT") {
			for (var i = 0; i < manualObjects.options.length; i++)
				szObjects += '<object name="' + manualObjects.options[i].value + '"/>';
		}
		else
			szObjects += '<object name="' + manualObjects.value + '"/>';
	}
	else if (nObjectsIndex != -1) {   // Back-end only
		if (arrSelectList[nObjectsIndex].Selected.SelectList.options.length) {
			for (var i = 0; i < arrSelectList[nObjectsIndex].Selected.SelectList.options.length; i++)
				szObjects += '<object name="' + arrSelectList[nObjectsIndex].Selected.SelectList.options[i].value + '"/>';
		}
		else {
			for (var i = 0; i < arrSelectList[nObjectsIndex].Selection.SelectList.options.length; i++)
				szObjects += '<object name="' + arrSelectList[nObjectsIndex].Selection.SelectList.options[i].value + '"/>';
		}
	}
	else {
		for (var i = 0; i < OBJECT_ARRAY.length; i++)
			szObjects += '<object name="' + OBJECT_ARRAY[i] + '"/>';
	}
	szObjects += "</objects>";
	
	var szMaxResults = "<maxresults>";
	var oResult = document.getElementById (MAX_RESULTS_INPUT);
	if (oResult && oResult.tagName == "SELECT")
		szMaxResults += oResult.options[oResult.selectedIndex].value;
	else if (oResult && oResult.tagName == "INPUT")
		szMaxResults += oResult.value;
	else
		szMaxResults += MAX_RESULTS;
	szMaxResults += "</maxresults>";
	
	var szResultsPage = "<resultsperfile>";
	var oResult = document.getElementById (MAX_PAGE_INPUT);
	if (oResult && oResult.tagName == "SELECT")
		szResultsPage += oResult.options[oResult.selectedIndex].value;
	else if (oResult && oResult.tagName == "INPUT")
		szResultsPage += oResult.value;
	else
		szResultsPage += MAX_PAGE_RESULTS;
	szResultsPage += "</resultsperfile>";

	var szOrder = "";
	var oResult = document.getElementById (ORDER_INPUT);
	if (oResult && oResult.tagName == "SELECT")
		szOrder = oResult.options[oResult.selectedIndex].value;
	else if (oResult && oResult.tagName == "INPUT")
		szOrder = oResult.value;
	else
		szOrder = ORDER;

	var szOrderDir = "";
	var oResult = document.getElementById (ORDER_DIR_INPUT);
	if (oResult && oResult.tagName == "SELECT")
		szOrderDir = oResult.options[oResult.selectedIndex].value;
	else if (oResult && oResult.tagName == "INPUT")
		szOrderDir = oResult.value;
	else
		szOrderDir = ORDER_DIR;
	
	// fill arrPredicates
	arrPredicates = new Array();
	if (!PreparePredicates ()) {
		RemoveConditions (REMOVE_STATIC);
		return;
	}

	// XMLSearch header
	XMLSearch = "<search>" + szMaxResults + szResultsPage + szObjects + "<condition>";
	
	// Predicates
	for (var i = 0; i < arrPredicates.length; i++) {
		if (arrPredicates[i].XML == LOGIC_FIELD) {
			XMLSearch += '<logic operator="' + arrPredicates[i].Logic + '" />';
			iPCount = 0;
		}
		else {
			if (i && arrPredicates[i].Logic != REGISTER) {
				XMLSearch += arrPredicates[i].XML;
				XMLSearch += '<logic operator="' + arrPredicates[i].Logic + '" />';
			}
			else 
				XMLSearch += arrPredicates[i].XML;
		}
	}
	
	// XMLSearch footer
	XMLSearch += '<order by="' + szOrder + '" sort="' + szOrderDir + '" /></condition></search>'; 

	if(DEBUG_SEARCH) {
		var oWinDebug = window.open ("", "_blank");
		var oText = oWinDebug.document.createElement ('<TEXTAREA rows="15" style="width: 800px">');
		oText.value = XMLSearch;
		oWinDebug.document.body.appendChild (oText);
	}
	
	var theForm = null;
	if (!bForm) {
		if (document.getElementsByName("ContentForm")[0] != undefined)
			theForm = document.ContentForm;
		else if (document.getElementsByName("SearchForm")[0] != undefined)
			theForm = document.SearchForm;
		else 
			bForm = true;
	}		
	if (bForm) {
		CreateForm(nVista, szAlias, szPath, szBpa, szToken);
		theForm = document.ContentForm;
	}

	theForm.XMLInputs.value = XMLSearch;
	if (szQuery && szQuery.length) {
//		var szValInsideQuotes = szQuery;
//		if (IsExactPhrase (szQuery))
//			szValInsideQuotes = szQuery.substr (1, szQuery.length - 2);
//		theForm.appendChild (CreateTextInput ("r2b_query", "0", true, escape(szValInsideQuotes)));

		theForm.appendChild (CreateTextInput ("r2b_query", "0", true, escape(szQuery)));
	}
	
	if (top.SearchWait != undefined) {
		top.SearchWait = true;
		window.clearTimeout (timeout);
		timeout = window.setTimeout ("(top.SearchWait = false)", 2000);
	}
	if (szTarget)
		theForm.target = szTarget;
	if (RETURN_XML)
		return (XMLSearch);
	else
		theForm.submit();
}

function IsExactPhrase (szString)
{
	var cExactPhraseChar = '"';
	if (szString.charAt(0) == '\'')
		cExactPhraseChar = '\'';

	//Si considera la stringa come "exact phrase" solo se: Inizia e finisce con un apice o un doppio apice (cExactPhraseChar) && al suo interno non ci sono altri caratteri cExactPhraseChar non duplicati ("" o '')
	if (szString.charAt(0) == cExactPhraseChar && szString.charAt (szString.length - 1) == cExactPhraseChar) {
		var nStartIndex = 0;
		var nMaxIndex = szString.length - 1;
		for (var nCount = 0; nStartIndex < nMaxIndex && nStartIndex != -1; nCount++) {
			nStartIndex = szString.indexOf (cExactPhraseChar, nStartIndex + 1);
			if (nStartIndex < (nMaxIndex - 1) && szString.charAt (nStartIndex+1) == cExactPhraseChar) {
				nCount--;	//escaped char (doubled)
				nStartIndex++;
			}
		}
		if (nCount == 1)
			return true;
	}	
	return false;
}

function ConvertToBoolean (szString, szOperation)
{
	var cExactPhraseChar = '"';
	if (szString.charAt(0) == '\'')
		cExactPhraseChar = '\'';

	var nIndex = 0;
	var nLength = szString.length;
	var szOut = "";
	var szSep = ""
	
	if (szOperation == "all array")
		szSep = " and ";
	else if (szOperation == "some array")
		szSep = " or ";
	else 
		szSep = " ";
	
	for (var i = 0; i < nLength; i++) {
		if (szString.charAt (i) == ' ') {
			if (i < (nLength - 1) && szString.charAt (i+1) != ' ')
				szOut += szSep;
		}
		else if (szString.charAt (i) == cExactPhraseChar) {
			if (i < (nLength -1) && szString.charAt (i+1) == cExactPhraseChar) {
				//escaped char (doubled)
				szOut += cExactPhraseChar;
				szOut += cExactPhraseChar;
				i++;
			}
			else {
				nIndex = i - 1;	//- 1 only because I must add 2
				do {
					nIndex = szString.indexOf (cExactPhraseChar, nIndex + 2);

				} while (nIndex != -1 && nIndex < (nLength -1) && szString.charAt (nIndex+1) == cExactPhraseChar);

				if (nIndex != -1) {
					//String
					szOut += szString.substring (i, nIndex + 1);
					i = nIndex;
				}
				else
					szOut += szString.charAt (i);
			}	
		}	
		else
			szOut += szString.charAt (i);
	}
	return (szOut);
}

// Use this function to create a new field or profile condition.
// parameters  (parent object, fields array, true for profile [fields array must be multiple like 'oProfiles' array], multi field value)
//      NewCondition (DIV_parent_element, OBJECT|ACCOUNT|oProfiles, true|false, "profile.code")
function NewCondition (oParent, arrFields, bMulti, szMultiConditionValue, bRemove)
{
	if (bMulti) {
		if (!arrFields.length) {
			alert (szMsgNoProfiles);
			return;
		}
		arrMultiConditions[nMultiConditionIndex] = new objectMultiCondition (oParent, arrFields, nMultiConditionIndex, szMultiConditionValue);
		nMultiConditionIndex++;
	}
	else {
		arrConditions[nConditionIndex] = new objectCondition (oParent, arrFields, nConditionIndex, bRemove);
		nConditionIndex++;
	}
}

// Use this function to create a fixed field condition.
// if bHidden = true no array are allowed.
// If oParent is null default 'document.body' is used.
// Op and Logic can be array of objectPair or single value (if array they are visible)
// Static condition can't be removed
function NewStaticCondition (oParent, szField, szType, Operation, Logic, bHidden, szCaption, Value, fonClickEvent, fonChangeEvent)
{
	if (!oParent)
		oParent = document.body;
	if (!Value)
		Value = "";
	else if (Operation != "boolean") {
/*	
		IsExactPhrase restituira' true se: la stringa da ricercare e' inserita tra doppi apici 
		("stringa") && al suo interno i doppi apici se presenti sono escaped (ossia preceduti 
		dal carattere '\\')
		Es.	"pippo pluto paperino"		restituisce true
			"pippo \" pluto paperino"	restituisce true
			"pippo" "pluto paperino"	restituisce false (due stringhe in and se)
		
		Sono ammessi anche i caratteri speciali: < > " ' &
		
		ConvertToBoolean converte una stringa in boolean
		
		Se stiamo ricercando il contenuto nel testo (szType == "content") && 
		L'Operation e' "all array" (and) oppure "some array" (or) && 
		La stringa contiene il carattere '"' o '\'
		ALLORA
		La stringa viene convertita in boolean usando AND se "all array" oppure OR se "some array"
		ALTRIMENTI 
		come in precedenza
		
		Es. pippo pluto "aaa > <' " "aaa > < ' &" "& pippo"
			DIVENTA
			Se "all array":		pippo and pluto and "aaa > <' " and "aaa > < ' &" and "& pippo"
			Se "some array":	pippo or pluto or "aaa > <' " or "aaa > < ' &" or "& pippo"
*/ 
		if (IsExactPhrase (Value)) {
			//If the search is not boolean, then if the string to be searched is inside quotes ("...") we search for the exact phrase 
			if (szType == "content" && (Operation == "all array" || Operation == "some array" || Operation == "intelligent phrase"))
				Operation = "exact phrase";

			var szValInsideQuotes = Value.substr (1, Value.length - 2);
			if (Operation == "contains" && szType == "text") {
				var szTmp = "";
				var indexPrev = 0;
				for (var i = szValInsideQuotes.indexOf ('*'); i != -1; i = szValInsideQuotes.indexOf ('*', indexPrev)) {
					szTmp += szValInsideQuotes.substring (indexPrev, i);
					szTmp += "%";
					indexPrev = i + 1;
				}
				szTmp += szValInsideQuotes.substring (indexPrev);
				
				szValInsideQuotes = szTmp;
				Operation = "like";
			}
			Value = szValInsideQuotes;
		}
		else {
			if (szType == "content" && (Operation == "all array" || Operation == "some array") && (Value.indexOf ('"') != -1 || Value.indexOf ('\'') != -1)) {
				Value = ConvertToBoolean (Value, Operation);
				Operation = "boolean";
			}
		}
	}
		
	if (!fonClickEvent)
		fonClickEvent = null;
	if (!fonChangeEvent)
		fonChangeEvent = null;
	
	if (szField == LOGIC_AND) {
		szField = LOGIC_FIELD;
		Logic = "and"
	}
	else if (szField == LOGIC_OR) {
		szField = LOGIC_FIELD;
		Logic = "or"
	}
	if (szField == LOGIC_FIELD) {
		szType = "logic";
		Operation = "logic";
		bHidden = true;
	}
	
	var oDiv = null;
	if (bIsNetscape) {
		oDiv = document.createElement ("div");
		oDiv.setAttribute("name", STATIC_INPUT);
	}
	else 
		oDiv = document.createElement ('<div name="' + STATIC_INPUT + '">');
	var oAtt = document.createAttribute ("class");
	oAtt.value = FIELD_CLASS;
	oDiv.setAttributeNode (oAtt);
	if (bHidden) 
		oDiv.style.display = "none";
	if (szCaption) {
		var oObj = document.createElement ("span");
		oAtt = document.createAttribute ("class");
		oAtt.value = TITLE_CLASS;
		oObj.setAttributeNode (oAtt);
		oObj.style.verticalAlign = "bottom";
//		oAtt = document.createAttribute ("align");
//		oAtt.value = "center";
//		oObj.setAttributeNode (oAtt);
		//oObj.style.width = WIDTH_FIELD + "px";
		var objText = document.createTextNode(szCaption);
		oObj.appendChild(objText); 
		oDiv.appendChild(oObj); 
	}
	
	var oField = null;
	if (Logic == "select")
		oField = CreateSelectInput (LOGIC_INPUT, WIDTH_LOGIC, arrLogic, null, null, INPUT_CLASS);
	else
		oField = CreateTextInput (LOGIC_INPUT, "0", true, Logic);
	oDiv.appendChild (oField);
	
	oField = CreateTextInput (FIELD_INPUT, "0", true, szField);
	if (szCaption)
		oField.setAttribute ("caption", szCaption);
	oDiv.appendChild (oField);
	
	if (Operation == "select")
		oField = CreateSelectInput (MODE_INPUT, WIDTH_MODE, eval ("arrMode_" + szType), null, null, INPUT_CLASS);
	else
		oField = CreateTextInput (MODE_INPUT, "0", true, Operation);
	
	if (szType == "content")
		szType = "text";
	oDiv.appendChild (oField);
	oField = CreateTextInput (TYPE_INPUT, "0", true, szType);
	oDiv.appendChild (oField);

	if (bHidden) {
		oField = CreateTextInput (VALUE_INPUT, "0", true, Value);
		oDiv.appendChild (oField);
	}
	else {
		//oField = document.createElement ("BR");
		//oDiv.appendChild (oField);
		if (szType == "date") {
			oField = CreateDateInputs (VALUE_INPUT, WIDTH_DATE, Value);
			oDiv.appendChild (oField[0]);
			oDiv.appendChild (oField[1]);
			oDiv.appendChild (oField[2]);
		}
		else {
			if (Value.constructor == Array)
				oField = CreateSelectInput (VALUE_INPUT, WIDTH_TEXT, Value, fonClickEvent, fonChangeEvent, INPUT_CLASS);
			else
				oField = CreateTextInput (VALUE_INPUT, WIDTH_TEXT, false, Value, fonClickEvent, fonChangeEvent);
			oDiv.appendChild (oField);
		}
	}
//	oField = document.createElement ('br');
//	oDiv.appendChild (oField);
	
	oParent.appendChild (oDiv);
	
	arrStatic[arrStatic.length] = oDiv;
}

// Use this function to create a selection list.
// szCondition = "objects" means that the list selects the objects to search
function NewSelectionList (oParent, arrList, szLeftTitle, szRightTitle, szCondition, szLogic, bMultiple)
{
        if (szCondition == "objects")
			nObjectsIndex = nSelectionIndex;
        var szNameSelected = "s" + nSelectionIndex + SELECTED_INPUT;
        var szNameSelection = "s" + nSelectionIndex + SELECTION_INPUT;
        var szName = "s" + nSelectionIndex;

        var szMultiple = "";
        if (bMultiple)
			szMultiple = "MULTIPLE";
        
        // Create inline selection/selected list
        var szHTML = '<table border="0" cellpadding="1" cellspacing="0" width="' + WIDTH_SELECTION + '"><tr>' +
        '<td width="42%"><p class="' + TITLE_CLASS + '">' + szLeftTitle + '</p></td><td>&nbsp;</td>' +
        '<td width="42%"><p class="' + TITLE_CLASS + '">' + szRightTitle + '</p></td></tr><tr><td width="42%">' +
		'<SELECT class="' + INPUT_CLASS + '" ID="' + szNameSelection + '" SIZE="' + (ROWS_SELECTION / (350 / WIDTH_SELECTION)) + 
		'" ' + szMultiple + ' style="width:' + (WIDTH_SELECTION / 2.18) + 'px"></SELECT></td><td><table border="0" cellpadding="1" cellspacing="1" align="center">' +
		'<tr><td><img id="' + szName + 'Add" src="/psixlocalization/Images/right_small.gif"' + 
		' onmousedown="document.getElementById(\'' + szName + 'Add\').src=\'/psixlocalization/Images/right_small_on.gif\';"' +
		' onmouseout="document.getElementById(\'' + szName + 'Add\').src=\'/psixlocalization/Images/right_small.gif\';" onclick="' + 
		'arrSelectList[' + nSelectionIndex + '].Selected.AddToList(arrSelectList[' + nSelectionIndex + '].Selection);" /></td></tr><tr><td>' +
		'<img id="' + szName + 'Remove" src="/psixlocalization/Images/left_small.gif"' + 
		' onmousedown="document.getElementById(\'' + szName + 'Remove\').src=\'/psixlocalization/Images/left_small_on.gif\';"' +
		' onmouseout="document.getElementById(\'' + szName + 'Remove\').src=\'/psixlocalization/Images/left_small.gif\';" onclick="' + 
		'arrSelectList[' + nSelectionIndex + '].Selection.AddToList(arrSelectList[' + nSelectionIndex + '].Selected);" /></td> </tr></table></td><td width="42%">' +
		'<SELECT class="' + INPUT_CLASS + '" ID="' + szNameSelected + '" SIZE="' + (ROWS_SELECTION / (350 / WIDTH_SELECTION)) +
		'"' + szMultiple + ' style="width:' + (WIDTH_SELECTION / 2.18) + 'px"></SELECT></td></tr></table>';

		var oDiv = null;
		if (bIsNetscape) {
			oDiv = document.createElement ("div");
			oDiv.setAttribute("name", szName);
			oDiv.setAttribute("id", szName);
		}
		else 
			oDiv = document.createElement ('<div id="' + szName + '" name="' + szName + '">');

		oParent.appendChild (oDiv);
		oDiv.innerHTML = szHTML;
		arrSelectList[nSelectionIndex] = new objectSel (new SelectListObj(document.getElementById(szNameSelection)), 
														new SelectListObj(document.getElementById(szNameSelected)),
														szCondition, szLogic, oDiv, oParent);
		//arrSelectList[nSelectionIndex].Selected.Add(arrList[0].szCaption, arrList[0].szValue);
		for (var i = 0; i < arrList.length; i++)
			arrSelectList[nSelectionIndex].Selection.Add(arrList[i].szCaption, arrList[i].szValue);
		arrSelectList[nSelectionIndex].Selection.View ();			
		arrSelectList[nSelectionIndex].Selected.View ();			
        nSelectionIndex++;
        return (nSelectionIndex - 1);
}
// Remove conditions
function RemoveConditions (nRemove)
{
	if (nRemove == REMOVE_DYNAMIC || nRemove == REMOVE_ALL) {
		for (var i = 0; i < nConditionIndex; i++) {
			if (arrConditions[i].oBlock)
				arrConditions[i].Remove();
		}
		arrConditions = new Array();
		nConditionIndex = 0;
	}
	if (nRemove == REMOVE_MULTIPLE || nRemove == REMOVE_ALL) {
		for (var i = 0; i < nMultiConditionIndex; i++) {
			if (arrMultiConditions[i].oBlock)
				arrMultiConditions[i].Remove();
		}
		arrMultiConditions = new Array();
		nMultiConditionIndex = 0;
	}
	if (nRemove == REMOVE_SELECTION || nRemove == REMOVE_ALL) {
		for (var i = 0; i < nSelectionIndex; i++)
			arrSelectList[i].Parent.removeChild (arrSelectList[i].Div);	
		arrSelectList = new Array();
		nObjectsIndex = -1;
		nSelectionIndex = 0;
	}
	if (nRemove == REMOVE_STATIC || nRemove == REMOVE_ALL) {
		for (var i = 0; i < arrStatic.length; i++)
			arrStatic[i].parentElement.removeChild(arrStatic[i]);
		arrStatic = new Array();
	}
}

// Private functions:

// Check valid data and prepare predicates
function PreparePredicates ()
{
	// conditions inputs
	var arrName = document.getElementsByName(FIELD_INPUT);
	var arrType = document.getElementsByName(TYPE_INPUT);
	var arrValue = document.getElementsByName(VALUE_INPUT);
	var arrMode = document.getElementsByName(MODE_INPUT);
	var arrLogic = document.getElementsByName(LOGIC_INPUT);
	if (arrType.length != arrValue.length || arrName.length != arrMode.length || arrLogic.length != arrType.length || arrLogic.length != arrName.length) 
		alert (szMsgSearchProblem);
	
	for (var i = 0; i < arrSelectList.length; i++) {
		if (i == nObjectsIndex)
			continue;
		if (arrSelectList[i].Selected.SelectList.options.length) {
			var szArray = "";
			for (var j = 0; j < arrSelectList[i].Selected.SelectList.options.length; j++)
				szArray += "<array>" + arrSelectList[i].Selected.SelectList.options[j].value + "</array>";
			arrPredicates[arrPredicates.length] = new Predicate ('<predicate at="' + arrSelectList[i].szCondition + '" op="array">' + szArray + "</predicate>", arrSelectList[i].szLogic);
		}
	}
	for (var i = 0; i < nMultiConditionIndex; i++) {
		if (arrMultiConditions[i].oBlock) {
			if (!arrMultiConditions[i].hasConditions) {
				if (arrMultiConditions[i].szConditionValue != '') {
					var obj = document.getElementById(MULTI_INPUT + i);
					var szVal = obj.options[obj.selectedIndex].value;
					if (szVal)
						arrPredicates[arrPredicates.length] = new Predicate ('<predicate at="' + arrMultiConditions[i].szConditionValue + '" op="equal">' + szVal + "</predicate>", "or");
				}
			}
		}
	}
	for (var i = 0; i < arrType.length; i++) {
		var szName = "";
		var szValue = "";
		var szMode = "";
		var szLogic = "";
		var szCaption = arrName[i].getAttribute ("caption");
		
		// this check allows to use input (for hidden condition) or select without problem
		// note: type is always an hidden input
		if (arrName[i].tagName == "SELECT")
			szName = arrName[i].options[arrName[i].selectedIndex].value;
		else
			szName = arrName[i].value;
			
		if (!szCaption)
			szCaption = szName;
			
		// code for advanced logic features			
		if (szName == LOGIC_FIELD) {
			arrPredicates[arrPredicates.length] = new Predicate (LOGIC_FIELD, arrLogic[i].value);
			continue;
		}
		// end advanced code
		
		if (arrMode[i].tagName == "SELECT")
			szMode = arrMode[i].options[arrMode[i].selectedIndex].value;
		else
			szMode = arrMode[i].value;
		if (arrLogic[i].tagName == "SELECT")
			szLogic = arrLogic[i].options[arrLogic[i].selectedIndex].value;
		else
			szLogic = arrLogic[i].value;

		if (arrType[i].value == "date") {
			if (arrValue[i].tagName == "SELECT") {
				szValue = GetDateControlByElem(arrValue[i], arrValue[i].nextSibling, arrValue[i].nextSibling.nextSibling, szName, false, true); 
				if (szValue == "NO")
					return (false);
			}
			else
				szValue = arrValue[i].value;
		}
		else {
			if (arrValue[i].tagName == "SELECT")
				szValue = arrValue[i].options[arrValue[i].selectedIndex].value;
			else
				szValue = arrValue[i].value;
		}
		
		if (arrType[i].value == "text") {
			if (arrValue[i].tagName == "SELECT")
				szValue = arrValue[i].options[arrValue[i].selectedIndex].value;
			else {
				if (!CheckField (arrValue[i], szCaption, "", false, true, false))//"&'<>\""
					return (false);
				szValue = arrValue[i].value;
			}
		}
		if (arrType[i].value == "number") {
			if (arrValue[i].tagName == "SELECT")
				szValue = arrValue[i].options[arrValue[i].selectedIndex].value;
			else {
				if (!CheckNumField (arrValue[i], szCaption, false, true))
					return (false);
				szValue = arrValue[i].value;
			}
		}
		var szType = arrType[i].value;
		
		if (szMode == "null" || szMode == "notnull") {
			if (szMode == "null")
				szMode = "equal";
			else
				szMode = "notequal";
			SetPredicate (szName, szMode, szType, "", szLogic)
		}
		else if (szValue.length || (arrType[i].value == "date" && szMode.indexOf ("delta") != -1)) {
			if (szName == "text")
				szType = "";
			SetPredicate (szName, szMode, szType, szValue, szLogic)
		}
	}
	return (true);
}
// Set an XML predicate in arrPredicates
function SetPredicate (szField, szOp, szType, szValue, szLogic)
{
	szValue = XMLEscaping (szValue);
	var szPredicate = '<predicate at="' + szField + '"';
	if (szType.length)
		szPredicate += ' type="' + szType + '"';
	szPredicate += ' op="';
	
	// check custom modes
	if (szOp == "startwith" || szOp == "endwith" || szOp == "contains")
		szPredicate += "like";
	else if (szOp == "notcontains")
		szPredicate += "notlike";
	else if (szOp.indexOf("delta") != -1)
		szPredicate += "greater";
	else
		szPredicate += szOp;
	szPredicate += '">';		
	if (szOp.indexOf("array") != -1)
		szPredicate += ParseArray (szValue, szOp);
	else if (szOp.indexOf("delta") != -1)
		szPredicate += '<date delta="' + szOp.substr(5) + '" unit="day">' + szCurrentDate + '</date>';
	else if (szOp.indexOf("contains") != -1)
		szPredicate += "%" + szValue + "%";
	else if (szOp == "startwith")
		szPredicate += szValue + "%";
	else if (szOp == "endwith")
		szPredicate += "%" + szValue;
	else
		szPredicate += szValue;

	szPredicate += '</predicate>';
	arrPredicates[arrPredicates.length] = new Predicate (szPredicate, szLogic);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////

// custom type data objects
function objectField (szValue, szType, szCaption, szMode, szProfileMultipleValue)
{
	this.szValue = szValue;
	this.szCaption = szCaption;
	this.szType = szType;
	this.szMode = szMode;
	this.szProfileMultipleValue = szProfileMultipleValue ? szProfileMultipleValue : "";
}
function objectMultiField (szValue, szCaption, arrFields)
{
	this.szValue = szValue;
	this.szCaption = szCaption;
	this.arrFields = arrFields;
}
function objectPair (szValue, szCaption)
{
	this.szValue = szValue;
	this.szCaption = szCaption;
}
function objectSel (oSelection, oSelected, szCondition, szLogic, oDiv, oParent)
{
	this.Selection = oSelection;
	this.Selected = oSelected;
	this.szCondition = szCondition;
	this.szLogic = szLogic;
	this.Div = oDiv;
	this.Parent = oParent;
}
function Predicate (szXML, szLogic)
{
	this.XML = szXML;
	this.Logic = szLogic;
}

// structure objects
function objectCondition (oParentObj, arrFields, nIndex, bRemove)
{
	this.oParent = oParentObj;
	this.oBlock = null;
	this.nIndex = nIndex;
	this.arrFields = arrFields;
	
	this.SetInputs = _InternalSetInputs;
	this.RemoveAll = _InternalRemoveAll;
	this.Remove = _InternalRemove;
	
	if (bIsNetscape) {
		this.oBlock = document.createElement ("div");
		this.oBlock.setAttribute("name", "block" + nIndex);
	}
	else 
		this.oBlock = document.createElement ('<div name="block' + nIndex + '">');
	var obj = document.createAttribute ("class");
	obj.value = FIELD_CLASS;
	this.oBlock.setAttributeNode (obj);
	if (bRemove) {
		obj = CreateButton ("img" + nIndex, DELETE_ICON, OnRemove, szMsgRemoveField);
		this.oBlock.appendChild (obj);
	}

	obj = CreateSelectInput (LOGIC_INPUT, WIDTH_LOGIC, arrLogic, null, null, INPUT_CLASS);
	this.oBlock.appendChild (obj);
	obj = CreateSelectInput (FIELD_INPUT, WIDTH_FIELD, this.arrFields, null, OnChangeCondition);
	this.oBlock.appendChild (obj);
	this.oParent.appendChild (this.oBlock);
	this.SetInputs(bRemove);
}
function objectMultiCondition (oParentObj, arrMultiFields, nIndex, szMultiConditionValue)
{
	this.oParent = oParentObj;
	this.oBlock = null;
	this.nIndex = nIndex;
	this.arrMultiFields = arrMultiFields;
	this.szConditionValue = szMultiConditionValue

	this.hasConditions = false;
	
	this.AddCondition = _InternalAddCondition;
	
	this.GetFields = _InternalGetFields;
	this.RemoveAll = _InternalRemoveAll;
	this.Remove = _InternalRemove;
	
	if (bIsNetscape) {
		this.oBlock = document.createElement ("div");
		this.oBlock.setAttribute("name", "mblock" + nIndex);
	}
	else 
		this.oBlock = document.createElement ('<div name="mblock' + nIndex + '">');
	var obj = document.createAttribute ("class");
	obj.value = FIELD_CLASS;
	this.oBlock.setAttributeNode (obj);
	if (NotFirst()) {
		obj = document.createElement ('hr');
		this.oBlock.appendChild (obj);
	}
	else {
		obj = document.createElement ('span');  // dummy element
		this.oBlock.appendChild (obj);
	}
	obj = CreateButton ("img" + nIndex, DELETE_ICON, OnMultiRemove, szMsgRemoveProfileField);
	this.oBlock.appendChild (obj);
	obj = CreateSelectInput (MULTI_INPUT + nIndex, WIDTH_MULTI, this.arrMultiFields, null, OnChangeMultiCondition, MULTI_CLASS);
	this.oBlock.appendChild (obj);
	obj = CreateButton ("img" + nIndex, ADD_ICON, OnAdd, szMsgAddProfileField);
	this.oBlock.appendChild (obj);
	obj = document.createElement ('br');
	this.oBlock.appendChild (obj);

	this.oParent.appendChild (this.oBlock);
}

// objects' internal functions
function _InternalSetInputs(bRemove)
{
	var nIndex;
	if (bRemove)
		nIndex = this.oBlock.firstChild.nextSibling.nextSibling.selectedIndex;
	else
		nIndex = this.oBlock.firstChild.nextSibling.selectedIndex;
	var szMode = this.arrFields[nIndex].szMode;
	var szType = this.arrFields[nIndex].szType;
	var szProfileMultipleValue = this.arrFields[nIndex].szProfileMultipleValue;
	
	if (bRemove)
		this.RemoveAll(3);
	else
		this.RemoveAll(2);
	
//	var oField = CreateSelectInput (LOGIC_INPUT, WIDTH_LOGIC, arrLogic, null, null, INPUT_CLASS);
//	this.oBlock.appendChild (oField);
	
	if (szProfileMultipleValue == "yes")
		oField = CreateSelectInput (MODE_INPUT, WIDTH_MODE, arrMode_profileMultipleValue, null, null, INPUT_CLASS);
	else
		oField = CreateSelectInput (MODE_INPUT, WIDTH_MODE, eval ("arrMode_" + szMode), null, null, INPUT_CLASS);
	this.oBlock.appendChild (oField);
	if (bRemove){
		oField = document.createElement ('br');
		this.oBlock.appendChild (oField);
		oField = CreateButton ("blank" + nIndex, BLANK_ICON);
		this.oBlock.appendChild (oField);
	}
	oField = CreateTextInput (TYPE_INPUT, "0", true, szType)
	this.oBlock.appendChild (oField);
	if (szType == "date") {
		//oField = document.createElement ("BR");
		//this.oBlock.appendChild (oField);
		oField = CreateDateInputs (VALUE_INPUT, WIDTH_DATE);
		this.oBlock.appendChild (oField[0]);
		this.oBlock.appendChild (oField[1]);
		this.oBlock.appendChild (oField[2]);
	}
	else {
		oField = CreateTextInput (VALUE_INPUT, WIDTH_TEXT);
		this.oBlock.appendChild (oField);
	}
}	
function _InternalRemove()
{
	this.oParent.removeChild (this.oBlock);
	this.oBlock = null;
}
function _InternalRemoveAll(nInputs)
{
	var arrChildren = this.oBlock.childNodes;
	var nChildren = arrChildren.length; 
	for (var i = nInputs; i < nChildren; i++) {
		this.oBlock.removeChild (arrChildren.item(nInputs));
	}
}
function _InternalAddCondition()
{
	var nIndex = this.oBlock.firstChild.nextSibling.nextSibling.selectedIndex;
	if (nIndex >= 0) {
		if (!this.arrMultiFields[nIndex].arrFields[0])
			return;
		arrConditions[nConditionIndex] = new objectCondition (this.oBlock, this.GetFields(nIndex), nConditionIndex);
		nConditionIndex++;
	}
	this.hasConditions = true;
}
function _InternalGetFields(nIndex)
{
	var szPrefix = this.arrMultiFields[nIndex].szValue + ".";
	var arrFields = this.arrMultiFields[nIndex].arrFields;
	var nCount = arrFields.length;
	var arrResult = new Array();

	for (var i = 0; i < nCount; i++) {
		arrResult[arrResult.length] = new objectField (szPrefix + arrFields[i].szValue, 
														arrFields[i].szType,
														arrFields[i].szCaption,
														arrFields[i].szMode,
														arrFields[i].szProfileMultipleValue);
	}
	return (arrResult);
}
// inputs' creating functions
function CreateTextInput(szName, szWidth, bHidden, szInitValue, fonClickEvent, fonChangeEvent)
{
	var oAtt = null;
	var oInput = null;
	if (bIsNetscape) {
		oInput = document.createElement ("INPUT");
		oInput.setAttribute("name", szName);
	}
	else 
		oInput = document.createElement ('<INPUT name="' + szName + '">');
	oAtt = document.createAttribute("type");
	if (bHidden)
		oAtt.value = "hidden";
	else
		oAtt.value = "text";
	oInput.setAttributeNode(oAtt);
	oAtt = document.createAttribute ("class");
	oAtt.value = INPUT_CLASS;
	oInput.setAttributeNode (oAtt);

	if (!szInitValue)
		szInitValue = "";
	oAtt = document.createAttribute ("value");
	oAtt.value = szInitValue;
	oInput.setAttributeNode (oAtt);
	oInput.style.width = szWidth + "px";
	if (fonClickEvent)
		oInput.onclick = fonClickEvent;
	if (fonChangeEvent)
		oInput.onchange = fonChangeEvent;
	return oInput;
}
function CreateSelectInput (szName, szWidth, arrValues, fonClickEvent, fonChangeEvent, szClass)
{
	var oAtt = null;
	var oInput = null;
	if (bIsNetscape) {
		oInput = document.createElement ("SELECT");
		oInput.setAttribute("name", szName);
	}
	else 
		oInput = document.createElement ('<SELECT name="' + szName + '">');
	oInput.style.width = szWidth + "px";
	oAtt = document.createAttribute ("class");
	if (szClass)
		oAtt.value = szClass;
	else
		oAtt.value = INPUT_CLASS;
	oInput.setAttributeNode (oAtt);
	for (var i = 0; i < arrValues.length; i++) {
		var oElement = document.createElement ("option");
		oAtt = document.createAttribute ("value");
		oAtt.value = arrValues[i].szValue;
		oElement.setAttributeNode (oAtt);
		var oText = document.createTextNode (arrValues[i].szCaption);
		oElement.appendChild(oText);
		oInput.appendChild (oElement);
	}
	if (fonClickEvent)
		oInput.onclick = fonClickEvent;
	if (fonChangeEvent)
		oInput.onchange = fonChangeEvent;
	return oInput;
}
function CreateDateInputs (szName, szWidth, szInitValue)
{
	var arrInputs = new Array();
	arrInputs[0] = CreateSelectInput (szName, parseInt(szWidth) / 5, arrDay);
	arrInputs[1] = CreateSelectInput (szName + "M", parseInt(szWidth) / 2, arrMonth);
	arrInputs[2] = CreateSelectInput (szName + "Y", parseInt(szWidth) / 3, arrYear);
	if (szInitValue && szInitValue.length)
		SetDateControlByElem (arrInputs[0], arrInputs[1], arrInputs[2], szInitValue)
	return arrInputs;
}
function CreateButton (szName, szIcon, fEvent, szAlt)
{
	var oAtt = null;
	var oInput = null;
	if (bIsNetscape) {
		oInput = document.createElement ("IMG");
		oInput.setAttribute("name", szName);
	}
	else 
		oInput = document.createElement ('<IMG name="' + szName + '">');
	oAtt = document.createAttribute ("src");
	oAtt.value = szIcon;
	oInput.setAttributeNode (oAtt);
	if (fEvent) {
		oInput.onclick = fEvent;
	}
	if (szAlt) {
		oAtt = document.createAttribute ("alt");
		oAtt.value = szAlt;
		oInput.setAttributeNode (oAtt);
	}
	return oInput;
}

// internal events handler
function OnChangeCondition (evt)
{
	evt = (evt) ? evt : window.event;
	oSrcElement = (evt.target) ? evt.target : evt.srcElement;
	var szIndex = oSrcElement.parentNode.getAttribute("name");
	if (szIndex.indexOf("block") != -1) {
		var nIndex = parseInt(szIndex.substr(5));
		arrConditions[nIndex].SetInputs();
	}			
}
function OnChangeMultiCondition (evt)
{
	evt = (evt) ? evt : window.event;
	oSrcElement = (evt.target) ? evt.target : evt.srcElement;
	var szIndex = oSrcElement.parentNode.getAttribute("name");
	if (szIndex.indexOf("mblock") != -1) {
		var nIndex = parseInt(szIndex.substr(6));
		arrMultiConditions[nIndex].RemoveAll(4);
	}			
}
function OnRemove (evt)
{
	evt = (evt) ? evt : window.event;
	oSrcElement = (evt.target) ? evt.target : evt.srcElement;
	var szIndex = oSrcElement.getAttribute("name");
	if (szIndex.indexOf("img") != -1) {
		var nIndex = parseInt(szIndex.substr(3));
		arrConditions[nIndex].Remove();
	}			
}
function OnMultiRemove (evt)
{
	evt = (evt) ? evt : window.event;
	oSrcElement = (evt.target) ? evt.target : evt.srcElement;
	var szIndex = oSrcElement.getAttribute("name");
	if (szIndex.indexOf("img") != -1) {
		var nIndex = parseInt(szIndex.substr(3));
		var arrChildren = arrMultiConditions[nIndex].oBlock.childNodes;
		var nChildrens = arrChildren.length; 
		if (nChildrens > 5) {
			//If there are more conditions then remove only the last one
			arrMultiConditions[nIndex].RemoveAll(nChildrens - 1);
		}
		else
			arrMultiConditions[nIndex].Remove();
	}			
}
function OnAdd (evt)
{
	evt = (evt) ? evt : window.event;
	oSrcElement = (evt.target) ? evt.target : evt.srcElement;
	var szIndex = oSrcElement.getAttribute("name");
	if (szIndex.indexOf("img") != -1) {
		var nIndex = parseInt(szIndex.substr(3));
		arrMultiConditions[nIndex].AddCondition();
	}			
}

// Miscellaneous functions
function ParseArray (szString, szOp)
{
	var retString = "";
	if (szOp == "array") {	
		//Profile multiple value
		if (szString.length)
			retString += "<array>" + szString + "</array>";
		return (retString);
	}

	var arrString = szString.split(" ");
	for (var i = 0; i < arrString.length; i++) {
		var nIndex = arrString[i].indexOf('"');
		if (nIndex != -1) {
			if (arrString[i].indexOf('"', nIndex + 1) == -1) {
				var szPhrase = arrString[i] + " ";
				i++;
				for (var j = i; j < arrString.length; j++, i++) {
					szPhrase += arrString[j] + " ";
					if (arrString[j].indexOf('"') != -1) {
						szPhrase = szPhrase.substring (0, szPhrase.length - 1);
						break;
					}
				}
				retString += "<array>" + szPhrase.substring(1, retString.length - 1) + "</array>";
			}
			else if (arrString[i].length)
				retString += "<array>" + arrString[i] + "</array>";
		}
		else if (arrString[i].length)
			retString += "<array>" + arrString[i] + "</array>";
	}
	return (retString);
}
function NotFirst()
{
	for (var i = 0; i < arrMultiConditions.length; i++)
		if (arrMultiConditions[i].oBlock)
			return true;
	return false;
}
function FindKey(szString) 
{
	for (var i = 0; i < arrKeywords.length; i++) {
		if ((arrKeywords[i].Value.toLowerCase()).indexOf(szString.toLowerCase()) != -1)
			return arrKeywords[i].Id;
	}
	return 0;
}
function CreateInput(szName, szValue)
{
	var oElement = null;
	var oAtrribute = null;
	if (bIsNetscape) {
		oElement = document.createElement ("input");
		oElement.setAttribute("name", szName);
	}
	else 
		oElement = document.createElement ('<input name="' + szName + '">');
	oAtrribute = document.createAttribute("type");
	oAtrribute.value = "hidden";
	oElement.setAttributeNode(oAtrribute);
	oElement.setAttribute("value", szValue);
	return oElement;
}
function CreateForm(nVista, szAlias, szPath, szBpa, szToken)
{
	if (document.SearchForm)
		return;
	var oForm = null;
	var bAppendForm = true;
	var Alias;
	var Path;
	if (szAlias && szAlias.length)
		Alias = szAlias;
	else
		Alias = objContextData.Get(CONTEXT_ALIAS);
	if (szPath && szPath.length)
		Path = szPath;
	else
		Path = objContextData.Get(CONTEXT_PARTIAL_PATH);
	
	var arrForms = document.getElementsByName("ContentForm");
	if (!arrForms.length) {
		if (bIsNetscape) {
			oForm = document.createElement ("form");
			oForm.setAttribute("name", "ContentForm");
			oForm.setAttribute("style", "display:none");
		}
		else 
			oForm = document.createElement ('<form name="ContentForm" style="display:none">');
	}
	else {
		oForm = arrForms[0];
		bAppendForm = false;
	}

	oForm.method = "post";
	if (szToken == undefined)
		szToken = objContextData.Get(CONTEXT_TOKEN);
	oForm.action = szToken + "/psix/quintetto.aspx";		
	if (oForm.Operation)
		oForm.Operation.value = "search";
	else
		oForm.appendChild (CreateInput("Operation", "search"));
	if (oForm.Return)
		oForm.Return.value = "HTML";
	else
		oForm.appendChild (CreateInput("Return", "HTML"));
	if (oForm.XMLInputs)
		oForm.XMLInputs.value = "";
	else
		oForm.appendChild (CreateInput("XMLInputs", ""));
	if (oForm.RCD_XML)
		oForm.RCD_XML.value = "_descriptor.xml?id=0";
	else
		oForm.appendChild (CreateInput("RCD_XML", "_descriptor.xml?id=0"));
	if (oForm.XSL)
		oForm.XSL.value = "/psixtheme/_Framework/searchredirect.xsl";
	else
		oForm.appendChild (CreateInput("XSL", "/psixtheme/_Framework/searchredirect.xsl"));
	if (oForm.r2b_alias)
		oForm.r2b_alias.value = Alias;
	else
		oForm.appendChild (CreateInput("r2b_alias", Alias));
	if (oForm.r2b_path)
		oForm.r2b_path.value = Path;
	else
		oForm.appendChild (CreateInput("r2b_path", Path));
	if (oForm.r2b_token)
		oForm.r2b_token.value = szToken;
	else
		oForm.appendChild (CreateInput("r2b_token", szToken));
	if (oForm.r2b_searchvista)
		oForm.r2b_searchvista.value = nVista;
	else
		oForm.appendChild (CreateInput("r2b_searchvista", nVista));
	if (szBpa) {
		if (szBpa == true)
			szBpa = "no";
		
		if (oForm.BpaFilter)
			oForm.BpaFilter.value = szBpa;
		else		
			oForm.appendChild (CreateInput("BpaFilter", szBpa));
	}
	else if (oForm.BpaFilter)
		oForm.BpaFilter.value = "yes";	
	if (bAppendForm)
		document.body.appendChild (oForm);
}

function GetXMLInput (szElementName, szValue, fInsertCDATA)
{	
	var szInput = "<input name=\"" + szElementName + "\">";
	if (fInsertCDATA || fInsertCDATA == undefined)
		szInput += "<![CDATA[" + szValue + "]]>";
	else 
		szInput += szValue;
	szInput += "</input>";
	return szInput;	
}

function LoadPage ()
{
	window.clearTimeout (timeout);
	window.location.replace(window.location.href);
}
	
function PageTimeOut ()
{
	document.body.style.cursor = "wait";
	window.clearTimeout (timeout);
	timeout = window.setTimeout("LoadPage()", 2000);
}

// Use this function if you want to use XML or SQL string request
var ST_XML = 0;
var ST_SQL = 1;

function SearchQuery (nVista, szTarget, szQuery, nType, szBpa, szR2bQuery)
{
	if (!nVista)
		nVista = 2;
	if (nType == ST_XML) {
		CreateForm(nVista, null, null, szBpa);
	}
	else if (nType == ST_SQL) {
		//
		return;
	}
	else
		return;

	var theForm = document.ContentForm;
	theForm.action = objContextData.Get(CONTEXT_TOKEN) + "/psix/quintetto.aspx";
	theForm.method = "post";
	if (szTarget && szTarget.length)
		theForm.target = szTarget;
	else
		theForm.target = "_self";

	theForm.XMLInputs.value = szQuery;

	if (szR2bQuery && szR2bQuery.length)
		theForm.appendChild (CreateTextInput ("r2b_query", "0", true, escape(szR2bQuery)));
	
	// debug
	//theForm.Return.value = "XML";
	//alert (szQuery);
	
	theForm.submit();
}

function XMLEscaping (szString)
{
	var szEscapedString = "";
	for (var i = 0; i < szString.length; i++) {
		var cChar = szString.charAt (i);
		switch (cChar) {
			case '&':
				szEscapedString += "&amp;";
				break;
			case '<':
				szEscapedString += "&lt;";
				break;
			case '>':
				szEscapedString += "&gt;";
				break;
			case '"':
				szEscapedString += "&quot;";
				break;
			case "'":
				szEscapedString += "&apos;";
				break;
			default:
				szEscapedString += cChar;
		}
	}
	return szEscapedString;
}

