
var START_SEARCH_CODE = 	1;
var CONTENT_SEARCH_CODE = 	2;
var EXACT_SEARCH_CODE = 	3;
var END_SEARCH_CODE = 		4;

var SEARCH_TYPE_EC = 	1; // EC
var SEARCH_TYPE_CAS = 	2; // CAS
var SEARCH_TYPE_NAME = 	3; // NAME
var SEARCH_TYPE_ALL = 	4; // ALL fields
var SEARCH_TYPE_ECCAS_INTERNAL = 5; // CAS & EC; Transient type

var Global_SearchErrors = "";
var Global_SearchErrorCounter = 0;

var Global_HasProcessedAllInputs = false;


var Global_DefaultBkgColor = "#CCD9FF"
var Global_StringProbabilityThreshold = 0.20
var Global_ECHA_Query_List = new Array();

var ControlCarRegEx = new RegExp("[%|*|?|\"]","g")
var SpacesRegEx = new RegExp("[\\s+]","g")
var Global_StringControlChar = '"'
var Global_CommentChar = '~'
var Global_PromptSign = Global_CommentChar + "> "

var RESET_TOP_POS = 0;
var RESET_LEFT_POS = 0;

var Global_WinTopPosition = RESET_TOP_POS;
var Global_WinLeftPosition = RESET_LEFT_POS;

var Global_AllFields_Warning = false;

if (document.all) /* for IE */{document.onmousedown=null;} else /* for FF */{document.onclick=null;}

////////////////////////////////////////////
// Query Object
////////////////////////////////////////////
function QueryObject()
{
	this.StartSearch = false;
	this.ContentSearch = true; // default
	this.EndSearch = false;
	this.ExactSearch = false;
	this.LeadingControlChar = "";
	this.ClosingControlChar = "";
	this.CharCounter = 0;
	this.DigitCounter = 0;
	this.Error = true;
	this.WarningLevel = -1;
	this.Message ="";
	this.FormatedInput = ""; // Search pattern + control cars
	this.CoreInput = "";    // Search pattern only
	this.InitialInput = "";
	this.CompactInput = "";
	this.UUID ="";
	this.SearchPattern = ""  // The actual search token
	this.SearchType = 0; // 1: EC, 2: CAS, 3: Name; 4: All; 5: CAS&EC
	this.IsStringSearch = false;
	this.MatchECSpecificPattern = 0;   // 0: No match; 1: Match sub pattern; 2: Exact match
	this.MatchCASSpecificPattern = 0;   // 0: No match; 1: Match sub pattern; 2: Exact match
	this.MatchPreRegPattern = 0;   // 0: No match; 1: Match
	this.ECPattern =""
	this.CASPattern =""
	this.SubstanceName = "";
	this.IsMutltiTokens= false;
	this.EnableQuery= false;
}



////////////////////////////////////////////
// ECHA Query Object
////////////////////////////////////////////
function ECHAQueryObject()
{
	this.Error = true;
	this.WarningLevel = -1;
	this.Message ="";

	this.StartSearchEnabled = false;   // Search code: 1
	this.ContentSearchEnabled = true;  // Search code: 2    - default mode;
	this.ExactSearchEnabled = false;   // Search code: 3
	this.EndSearchEnabled = false;     // Search code: 4
	
	this.AcceptedSearchSet = "";     // pattern (set)
	this.OptimalSearchCode = 0;  // O: none;  Range [0-4]
	
	this.UserSpecifiedStartSearch = false;
	this.UserSpecifiedContentSearch = false;
	this.UserSpecifiedExactSearch = false;	
	this.UserSpecifiedEndSearch = false;

	this.UserSpecifiedSearchCode = 0;  // O: none;  Range [0-4]
	
	this.CoreInput = ""
	
	this.SearchPattern = "";  // The actual search token
	this.SearchType = 0; // 1: EC, 2: CAS, 3: Name; 4: All
	this.IsMutltiTokens = false;
	this.EnableQuery = false;
}




var Global_SEARCH_QUERY = null;

////////////////////////////////////////////
//
////////////////////////////////////////////
function ResetQueryObject()
{
	delete Global_SEARCH_QUERY;
	Global_SEARCH_QUERY = new QueryObject();
}


////////////////////////////////////////////
//
////////////////////////////////////////////
function ResetECHAQuery()
{
	delete Global_ECHA_Query_List;
	Global_ECHA_Query_List = new Array();
}


////////////////////////////////////////////
//
////////////////////////////////////////////
function AddEchaQueryObjInList(EchaQueryObj)
{
	Global_ECHA_Query_List.push(EchaQueryObj)
}


function MakeEchaQueryObj(SearchQueryObj)
{
	var EchaQueryObj = new ECHAQueryObject();
	
	EchaQueryObj.Error = SearchQueryObj.Error;
	EchaQueryObj.WarningLevel = SearchQueryObj.WarningLevel;
	EchaQueryObj.Message = SearchQueryObj.Message;

	EchaQueryObj.StartSearchEnabled = SearchQueryObj.StartSearch;   
	//EchaQueryObj.ContentSearchEnabled = SearchQueryObj.ContentSearch; 
	EchaQueryObj.ExactSearchEnabled = SearchQueryObj.ExactSearch; 
	EchaQueryObj.EndSearchEnabled = SearchQueryObj.EndSearch; 
		
	EchaQueryObj.CoreInput = SearchQueryObj.CoreInput;
	EchaQueryObj.SearchPattern = SearchQueryObj.SearchPattern;
	EchaQueryObj.SearchType = SearchQueryObj.SearchType; 
	
	EchaQueryObj.IsMutltiTokens= SearchQueryObj.IsMutltiTokens;
	EchaQueryObj.IsStringSearch= SearchQueryObj.IsStringSearch;
	
	EchaQueryObj.EnableQuery= SearchQueryObj.EnableQuery;
	
	return EchaQueryObj;
}


function ResetWinLocation()
{
	Global_WinTopPosition = RESET_TOP_POS;
	Global_WinLeftPosition = RESET_LEFT_POS;
}

function IncrementWinLocation(LeftIncrement, TopIncrement)
{
	AddWinLeftIncrement(LeftIncrement)
	AddWinTopIncrement(TopIncrement)
}

function AddWinLeftIncrement(LeftIncrement)
{
	Global_WinLeftPosition += LeftIncrement
}

function AddWinTopIncrement(TopIncrement)
{
	Global_WinTopPosition += TopIncrement
}

function GetWinTopPos ()
{
	return Global_WinTopPosition
}

function GetWinLeftPos ()
{
	return Global_WinLeftPosition
}




function ResetInputsOnClick(Node)
{
	if (Global_HasProcessedAllInputs)
	{
		ResetInputBkg(Node);
		Global_HasProcessedAllInputs = false;
	}
}

////////////////////////////////////////////
//
////////////////////////////////////////////
function IsChar(Char)
{
	return ( 
			((Char.charCodeAt(0) >= 65) && (Char.charCodeAt(0) <= 90)) ||
			((Char.charCodeAt(0) >= 97) && (Char.charCodeAt(0) <= 122)) 
		  );

}

////////////////////////////////////////////
//
////////////////////////////////////////////
function IsDigit(Char)
{
	return ((Char.charCodeAt(0) >= 48) && (Char.charCodeAt(0) <= 57));
}

////////////////////////////////////////////
//
////////////////////////////////////////////
function IsControlCar(Char)
{
	return (Char.match(ControlCarRegEx));
}


////////////////////////////////////////////
//
////////////////////////////////////////////
function IsSpace(Char)
{
	return (Char.match(SpacesRegEx));
}

////////////////////////////////////////////
//
////////////////////////////////////////////
function QueryTrimString (str) {
  return str.replace(/^\s+/g, '').replace(/\s+$/g, '');
}



////////////////////////////////////////////
//
////////////////////////////////////////////
function CompactCars(Input)
{
	return Input.replace(/\s+/g, '')
}

////////////////////////////////////////////
//
////////////////////////////////////////////
function CompactSubstanceName(Input)
{
	return Input.replace(/\s+/g, ' ')
}

////////////////////////////////////////////
//
////////////////////////////////////////////
function CompactNumberInput(Input)
{
	var CompactNumber = ""
	for (var i = 0; i< Input.length; ++i)
	{
		var Char = Input.charAt(i)
		if ((Char == "_") || (Char == ".")) {Char ="-"}
		if (IsDigit(Char) || (Char == "-")) {CompactNumber += Char}
	}
	return CompactNumber
}



function GetECExactPattern(Input)
{
	// Input is only made of digits and "-"
	var Pattern1 = /\d{3}-\d{3}-\d{1}/;
	var Matching =  Input.match(Pattern1)
	if (Matching) {return Matching[0];}  // First element in list
	else return null;  // No match

}


function MatchECExactPattern(Input)
{
	return  (GetECExactPattern(Input) == Input)
}



function IsValidECCASPattern (Input)
{
	var EC_CAS_Pattern = /\d{0,3}(-\d{2})?(-\d{0,1})?/;
	var Match1 = Input.match(EC_CAS_Pattern) // List!
	var Matching =  (Match1) ? Match1[0] : null ;
	if (Matching == Input) return Input
	else return null
}

////////////////////////////////////////////
//
////////////////////////////////////////////
function MatchECPattern(SearchObj)
{   // EC specific patterns
	var Input = SearchObj.CompactInput
	var Pattern2 = /-\d{3}/;
	//var Pattern3 = /^\d{3}-/;
	if (MatchECExactPattern(Input)) 
	{  // Exact match
		//alert("MatchECExactPattern"); 
		SearchObj.ECPattern = Input;
		SearchObj.SearchPattern = Input;
		return 2;
	}  
	else 
	{ 
		var FoundECSpecificSubPattern = Input.match(Pattern2)
		if (FoundECSpecificSubPattern) 
		{
			var MaxECPattern = /\d{0,3}-\d{3}(-\d{0,1})?/;
			var Match1 = Input.match(MaxECPattern) // List!
			var MaxECMatching = (Match1) ? Match1[0] : null ; 
			
			if (MaxECMatching == Input)
			{
				///alert("MatchECSubPattern : " + FoundECSpecificSubPattern);
				///alert("MAXMatchECSubPattern : " + MaxECMatching);
				SearchObj.ECPattern = MaxECMatching;
				SearchObj.SearchPattern = MaxECMatching;
				return 1;
			}
			else return 0
			
		} // Match sub pattern
		else return 0;  // No match
	}

}



function GetCASExactPattern(Input)
{
	// Input is only made of digits and "-"
	var Pattern1 = /\d{2,7}-\d{2}-\d{1}/;
	var Matching = Input.match(Pattern1)
	if (Matching) {return Matching[0];}  // First element in list
	else return null;  // No match
}


function MatchCASExactPattern(Input)
{
	return (GetCASExactPattern(Input) == Input)
}


function MatchCASPattern(SearchObj)
{   // CAS specific patterns
	var Input = SearchObj.CompactInput
	//var Pattern2 = /^\d{4,7}/;
	var Pattern2 = /^\d{4,7}-/;
	var Pattern3 = /-\d{2}-/;
	
	if (MatchCASExactPattern(Input)) 
	{  // Exact match
		//alert("MatchCASExactPattern: " + Input); 
		SearchObj.CASPattern = Input;
		SearchObj.SearchPattern = Input;
		return 2;
	}  
	else 
	{
		var FoundCASSpecificSubPattern2 = Input.match(Pattern2)
		var FoundCASSpecificSubPattern3 = Input.match(Pattern3)
		
		//alert("SubCASMatch :" + Input);
		//alert("FoundCASSpecificSubPattern2 : " + FoundCASSpecificSubPattern2 + "  FoundCASSpecificSubPattern3 : " + FoundCASSpecificSubPattern3);
		
		if (FoundCASSpecificSubPattern2 && ! FoundCASSpecificSubPattern3)
		{ // Match sub pattern
			
			//var MaxCASPattern2 = /^\d{1,7}((-\d{2})?-\d{0,1})?/;
			var MaxCASPattern2 = /^\d{0,7}(-\d{2})?(-\d{0,1})?/;
			var Match2 = Input.match(MaxCASPattern2) // List!
			var MaxCASMatching2 =  (Match2) ? Match2[0] : null ;
			
			if (MaxCASMatching2 == Input)
			{
				//alert("MaxCASMatching2 :" + MaxCASMatching2);
				SearchObj.CASPattern = MaxCASMatching2;
				SearchObj.SearchPattern = MaxCASMatching2;
				return 1;
			}
			else return 0
		}
		else if (FoundCASSpecificSubPattern3 && ! FoundCASSpecificSubPattern2)
		{ // Match sub pattern
		
			var MaxCASPattern3 = /^\d{0,7}-\d{2}-\d{0,1}/;
			var Match3 = Input.match(MaxCASPattern3) // List!
			var MaxCASMatching3 = (Match3) ? Match3[0] : null ;
			if (MaxCASMatching3 == Input)
			{
				///alert("MaxCASMatching3 :" + MaxCASMatching3);
				SearchObj.CASPattern = MaxCASMatching3;
				SearchObj.SearchPattern = MaxCASMatching3;
				return 1;
			}
			else return 0
		}
		else if (FoundCASSpecificSubPattern2 && FoundCASSpecificSubPattern3)
		{ // Match sub pattern

			var MaxCASPattern2 = /^\d{0,7}(-\d{2})?(-\d{0,1})?/;
			var MaxCASPattern3 = /^\d{0,7}-\d{2}-\d{0,1}/;
			var Match2 = Input.match(MaxCASPattern2) // List!
			var MaxCASMatching2 = (Match2) ? Match2[0] : null ;
			var Match3 = Input.match(MaxCASPattern3) // List!
			var MaxCASMatching3 = (Match3) ? Match3[0] : null ;

			if (MaxCASMatching2 == Input)
			{
				///alert("MaxCASMatching2 :" + MaxCASMatching2);
				SearchObj.CASPattern = MaxCASMatching2;
				SearchObj.SearchPattern = MaxCASMatching2;
				return 1;
			}
			else if (MaxCASMatching3 == Input)
			{
				///alert("MaxCASMatching3 :" + MaxCASMatching3);
				SearchObj.CASPattern = MaxCASMatching3;
				SearchObj.SearchPattern = MaxCASMatching3;
				return 1;
			}
			else return 0;
		}
		else 
		{
			return 0;  // No match
		}
		

	}

}


function MatchSubNumber(Input)
{
	var Pattern = /^([A-Z]){2}\d{6}-\d{2}$/;
	var Match = Input.match(Pattern)
	if (Match) {return Match[0];}  // Exact match
	else return null;  // No match
}

function MatchPreReg(Input)
{
	var Pattern = /\d{2}-\d{10}-\d{2}-\d{4}/;
	var Match = Input.match(Pattern)
	if (Match) {return Match[0];}  // Exact match
	else return null;  // No match

}

function MatchPreRegPattern(SearchObj)
{
	var Input = SearchObj.CompactInput
	return MatchPreReg(Input)
}

function MatchUUID(Input)
{
	var Pattern = /\w{4}-\w{8}-\w{4}-\w{4}-\w{4}-\w{12}/;
	var Match = Input.match(Pattern)
	if (Match) {return Match[0];}  // Exact match
	else return null;  // No match
}

function MatchUUIDExactPattern(SearchObj)
{
	var Input = CompactCars(SearchObj.CoreInput)
	return MatchUUID(Input)
}

////////////////////////////////////////////
//
////////////////////////////////////////////
function ResetInputBkg(Node)
{
 	Node.value = ""
 	SetInputSearchBkgColor(Node, 0) //default
}

////////////////////////////////////////////
//
////////////////////////////////////////////
function SetInputSearchBkgColor(Node, ColorMode)
{
		switch (ColorMode)
		{
			case -1:
			{
				Node.style.background="#FC1B1B";  // Error
			}
			break;
			case 0:
			{
				Node.style.background=Global_DefaultBkgColor;  // Default
			}
			break;

			case 1:
			{
				Node.style.background="orange"; // Warning level 1  // CAS or EC sub pattern
			}
			break;
			case 2:
			{
				Node.style.background="#CC99CC"; // Warning level 2  // Mixed sub pattern (Both CAS AND EC)
			}
			break;
			case 3:
			{
				Node.style.background="#FFFF33"; // Warning level 3  // CAS/EC full pattern
			}
			break;
			case 4:
			{
				Node.style.background="#BCBCBC"; // Warning level 4  // Pattern not supported
			}
			break;
			default:		
		}
}



////////////////////////////////////////////
//
////////////////////////////////////////////
function EvalMessageSearchQuery(SearchQueryObj)
{
	var Mess = ""
	if (SearchQueryObj.Error)
	{
		Mess += "Error:";
		if (SearchQueryObj.UUID)
		{
			Mess += " UUID";
		}
		else if (SearchQueryObj.MatchPreRegPattern)
		{
			Mess += " Pre-Reg";
		}
		else
		{
			Mess += " Unknown"
		}
		
		Mess += " pattern: " + SearchQueryObj.SearchPattern
	}
	else
	{
		
		if (SearchQueryObj.ExactSearch)
		{
			Mess += "Exact pattern search, ";
		}
		else
		{
			Mess += "Sub pattern search, ";
		}
	
		switch (SearchQueryObj.SearchType)
		{
			case 1:
			{
				Mess += "<EC> ";
			}
			break;
			case 2:
			{
				Mess += "<CAS> ";
			}
			break;
			case 3:
			{
				Mess += "<Name> ";
			}
			break;
			case 4:
			{
				Mess += "<All fields> ";
			}
			break;
			case 5:
			{
				Mess += "<CAS/EC> ";
			}
			break;
			default:		
			Mess += "<UNKNOWN> ";
		}
		
		Mess += "pattern: " + SearchQueryObj.SearchPattern
	}
	
	SearchQueryObj.Message = Mess;
	//alert(SearchQueryObj.Message)
}



////////////////////////////////////////////
//
////////////////////////////////////////////
function IsStringPattern(Input)
{
	var StringProbability = 0 ;
	var CharCounter = 0;
	var DigitCounter = 0;

	for (var i = 0; i< Input.length; ++i)
	{
		Char = Input.charAt(i)		
		if (! IsControlCar(Char))
		{
			if (IsDigit(Char) || Char == "-") {++DigitCounter}
			else if (!IsDigit(Char)) {++CharCounter}  // General approach
		}
	}
	
	if (CharCounter > 0)
	{
		StringProbability = Math.max((CharCounter - DigitCounter)/ CharCounter, 0)
		if (StringProbability > Global_StringProbabilityThreshold)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	else
	{
		return false;
	}
	
}


////////////////////////////////////////////
//
////////////////////////////////////////////
function IsPureDigitPattern(Input)
{
	var CharCounter = 0;
	var DigitCounter = 0;
	if (Input.length == 0) return false;
	
	for (var i = 0; i< Input.length; ++i)
	{
		Char = Input.charAt(i)		
		if (
			IsDigit(Char) || 
			Char == "-" ||
			Char == "_" ||
			Char == "."
			) 
		{
			continue;
		}
		else
		{
			return false;
		}
	}
	
	return true;
}



////////////////////////////////////////////
//
////////////////////////////////////////////
function ParsePreRegSearchInput(Node, TextQuery)
{
	var SearchQueryObj = new QueryObject();
	SearchQueryObj.InitialInput = QueryTrimString(TextQuery)
	if (! SearchQueryObj.InitialInput) {return null;} 
		
	//var InitialControlChar = ""
	var CharCounter = 0;
	var DigitCounter = 0;
	
	for (var i = 0; i< SearchQueryObj.InitialInput.length; ++i)
	{
		Char = SearchQueryObj.InitialInput.charAt(i)
		
		if (Char == Global_CommentChar) 
		{  // Hit a comment char - Remove any trailing white spaces
			SearchQueryObj.CoreInput = QueryTrimString(SearchQueryObj.CoreInput);
			break;
		}  
		
		if (! IsControlCar(Char))
		{
			if ((Char == "_") || (Char == ".")) {Char ="-"}
			SearchQueryObj.CoreInput += Char;		
			if (!IsDigit(Char)) {++CharCounter}  // General approach
			if (IsDigit(Char)) {++DigitCounter}
		}
	}
		
	SearchQueryObj.CharCounter = CharCounter
	SearchQueryObj.DigitCounter = DigitCounter
		
	if (CharCounter+DigitCounter == 0)
	{
		//Node.value =""
		SetInputSearchBkgColor(Node, 0); // Reset BKG
		//alert(SearchQueryObj.InitialInput)
		return null;
	}
	
	
	// Suppress multi spacing
	SearchQueryObj.CoreInput = SearchQueryObj.CoreInput.replace(/\s+/g, ' ');
	// Suppress trailing white spaces
	SearchQueryObj.CoreInput = QueryTrimString(SearchQueryObj.CoreInput)
	//SearchQueryObj.FormatedInput = SearchQueryObj.LeadingControlChar + SearchQueryObj.CoreInput + SearchQueryObj.ClosingControlChar

	
	var StringProbability = 0 ;
	if (CharCounter > 0)
	{
		StringProbability = Math.max((CharCounter - DigitCounter)/ CharCounter, 0)
		if (StringProbability > Global_StringProbabilityThreshold)
		{
			SearchQueryObj.IsStringSearch = true;
		}
		else
		{
			SearchQueryObj.IsStringSearch = false;
		}
	}
	else
	{
		SearchQueryObj.IsStringSearch = false;
	}
	//alert("String probability: "+ StringProbability)
	
	if (SearchQueryObj.IsStringSearch)
	{
		SearchQueryObj.CompactInput = CompactSubstanceName(SearchQueryObj.CoreInput)
		SearchQueryObj.IsMutltiTokens = (SearchQueryObj.CompactInput.match(' ')) ? 1 : 0;
		SearchQueryObj.Error = false;
		SearchQueryObj.WarningLevel = 0;
		SearchQueryObj.SearchType = 3; // 1: EC, 2: CAS, 3: Name; 4: All
		SearchQueryObj.SubstanceName = SearchQueryObj.CompactInput
		SearchQueryObj.SearchPattern = SearchQueryObj.CompactInput
		////Node.value = SearchQueryObj.SearchPattern
		SetInputSearchBkgColor(Node, SearchQueryObj.WarningLevel)
		EvalMessageSearchQuery(SearchQueryObj) //Debug
		return SearchQueryObj
		
	} else
	{
		SearchQueryObj.CompactInput = CompactNumberInput(SearchQueryObj.CoreInput)
	}
	//alert(SearchQueryObj.CompactInput)
	
	
		
	SearchQueryObj.MatchPreRegPattern = MatchPreRegPattern(SearchQueryObj)
	if (SearchQueryObj.MatchPreRegPattern)
	{
		//alert("Pre-Reg Pattern: " + SearchQueryObj.CompactInput)
		SearchQueryObj.SearchPattern = SearchQueryObj.MatchPreRegPattern;
		SearchQueryObj.WarningLevel = 4;
		////Node.value = SearchQueryObj.SearchPattern
		SetInputSearchBkgColor(Node, SearchQueryObj.WarningLevel)
		EvalMessageSearchQuery(SearchQueryObj) //Debug
		return SearchQueryObj;
	}

	SearchQueryObj.UUID = MatchUUIDExactPattern(SearchQueryObj)
	if (SearchQueryObj.UUID) 
	{ 
		//alert("UUID: "+ SearchQueryObj.UUID) 
		SearchQueryObj.SearchPattern = SearchQueryObj.UUID;
		SearchQueryObj.WarningLevel = 4;
		////Node.value = SearchQueryObj.SearchPattern
		SetInputSearchBkgColor(Node, SearchQueryObj.WarningLevel)
		EvalMessageSearchQuery(SearchQueryObj) //Debug
		return SearchQueryObj;
	}


	SearchQueryObj.MatchCASSpecificPattern = MatchCASPattern(SearchQueryObj)
	var CAS_Token = new TokenClass(SearchQueryObj.CASPattern, Parse_CAS_Fct); 
	if ((SearchQueryObj.MatchCASSpecificPattern == 2) && (! CAS_Token.Error))
	{
		//alert("CAS Pattern: " + SearchQueryObj.CASPattern)
		// Attempt to confirm Exact Match
			SearchQueryObj.Error = false;
			SearchQueryObj.WarningLevel = 0;
					
			SearchQueryObj.ExactSearch = true;
			SearchQueryObj.SearchType = 2;  // 1: EC, 2: CAS, 3: Name; 4: All
			SearchQueryObj.CASPattern = CAS_Token.ParsedToken;
			SearchQueryObj.SearchPattern = CAS_Token.ParsedToken;
	}
	else
	{				
		//alert("CAS SUB Pattern: " + SearchQueryObj.CASPattern)
		if ((! CAS_Token.Error) && (!SearchQueryObj.CASPattern.match('-'))) // success in parsing CAS
		{
			SearchQueryObj.Error = false;
			SearchQueryObj.WarningLevel = 0;
					
			SearchQueryObj.ExactSearch = true;
			SearchQueryObj.SearchType = 2;  // 1: EC, 2: CAS, 3: Name; 4: All
			SearchQueryObj.CASPattern = CAS_Token.ParsedToken;
			SearchQueryObj.SearchPattern = CAS_Token.ParsedToken;
		}
		else
		{
			// Try EC parsing
			var EINECS_Token = new TokenClass(SearchQueryObj.CASPattern, Parse_EINECS_Fct);
					
			if ((! EINECS_Token.Error) && (!SearchQueryObj.CASPattern.match('-')))// success in parsing EC
			{
				SearchQueryObj.Error = false;
				SearchQueryObj.WarningLevel = 0;
					
				SearchQueryObj.ExactSearch = true;
				SearchQueryObj.SearchType = 1;  // 1: EC, 2: CAS, 3: Name; 4: All
				SearchQueryObj.ECPattern = EINECS_Token.ParsedToken;
				SearchQueryObj.SearchPattern = EINECS_Token.ParsedToken;
			}
			else if (SearchQueryObj.MatchCASSpecificPattern) //
			{
				SearchQueryObj.Error = false;
				SearchQueryObj.WarningLevel = 1;
				SearchQueryObj.SearchType = 2;  // 1: EC, 2: CAS, 3: Name; 4: All
			}
		}
			
	}
		
 

	SearchQueryObj.MatchECSpecificPattern = MatchECPattern(SearchQueryObj)
	var EINECS_Token = new TokenClass(SearchQueryObj.ECPattern, Parse_EINECS_Fct); 
	if ((SearchQueryObj.MatchECSpecificPattern == 2) && (! EINECS_Token.Error))
	{
		//alert("EC Pattern: " + SearchQueryObj.ECPattern)
		// Attempt to confirm Exact Match
			SearchQueryObj.Error = false;
			SearchQueryObj.WarningLevel = 0;
					
			SearchQueryObj.ExactSearch = true;
			SearchQueryObj.SearchType = 1;  // 1: EC, 2: CAS, 3: Name; 4: All
			SearchQueryObj.ECPattern = EINECS_Token.ParsedToken;
			SearchQueryObj.SearchPattern = EINECS_Token.ParsedToken;
	}
	else
	{				
		//alert("EC SUB Pattern: " + SearchQueryObj.ECPattern)
		if ((! EINECS_Token.Error) && (!SearchQueryObj.ECPattern.match('-'))) // success in parsing EC
		{
			SearchQueryObj.Error = false;
			SearchQueryObj.WarningLevel = 0;
					
			SearchQueryObj.ExactSearch = true;
			SearchQueryObj.SearchType = 1;  // 1: EC, 2: CAS, 3: Name; 4: All
			SearchQueryObj.ECPattern = EINECS_Token.ParsedToken;
			SearchQueryObj.SearchPattern = EINECS_Token.ParsedToken;
		}
		else
		{
			// Try CAS parsing
			var CAS_Token = new TokenClass(SearchQueryObj.ECPattern, Parse_CAS_Fct);
					
			if ((! CAS_Token.Error) && (!SearchQueryObj.ECPattern.match('-')))// success in parsing CAS
			{
				SearchQueryObj.Error = false;
				SearchQueryObj.WarningLevel = 0;
					
				SearchQueryObj.ExactSearch = true;
				SearchQueryObj.SearchType = 2;  // 1: EC, 2: CAS, 3: Name; 4: All
				SearchQueryObj.CASPattern = CAS_Token.ParsedToken;
				SearchQueryObj.SearchPattern = CAS_Token.ParsedToken;
			}
			else if (SearchQueryObj.MatchECSpecificPattern == 1) //
			{
				SearchQueryObj.Error = false;
				SearchQueryObj.WarningLevel = 1;
				SearchQueryObj.SearchType = 1;  // 1: EC, 2: CAS, 3: Name; 4: All
			}
		}
			
	}


	if (
		(! SearchQueryObj.MatchCASSpecificPattern) &&
		(! SearchQueryObj.MatchECSpecificPattern)
		)
	{
		
		var CAS_Token = new TokenClass(SearchQueryObj.CompactInput, Parse_CAS_Fct); 
		var EINECS_Token = new TokenClass(SearchQueryObj.CompactInput, Parse_EINECS_Fct);
		
		if ((!CAS_Token.Error) && (!EINECS_Token.Error) && (!SearchQueryObj.CompactInput.match('-'))) // success in parsing both CAS, EC
		{
			SearchQueryObj.Error = false;
			SearchQueryObj.WarningLevel = 3;
			SearchQueryObj.SearchType = 5; // 1: EC, 2: CAS, 3: Name; 4: All, 5: EC-CAS
			SearchQueryObj.ExactSearch = true;
			
			SearchQueryObj.CASPattern = CAS_Token.ParsedToken
			SearchQueryObj.ECPattern = EINECS_Token.ParsedToken
			SearchQueryObj.SearchPattern = Global_PromptSign + EINECS_Token.ParsedToken + " | " + CAS_Token.ParsedToken;
		}
		else if ((!CAS_Token.Error) && (!SearchQueryObj.CompactInput.match('-')))
		{
			SearchQueryObj.Error = false;
			SearchQueryObj.WarningLevel = 0;
			SearchQueryObj.ExactSearch = true;
			SearchQueryObj.SearchType = 2; // 1: EC, 2: CAS, 3: Name; 4: All
			
			SearchQueryObj.CASPattern = CAS_Token.ParsedToken
			SearchQueryObj.SearchPattern = CAS_Token.ParsedToken;
		}
		else if ((!EINECS_Token.Error) && (!SearchQueryObj.CompactInput.match('-')))
		{
			SearchQueryObj.Error = false;
			SearchQueryObj.WarningLevel = 0;
			SearchQueryObj.ExactSearch = true;
			SearchQueryObj.SearchType = 1; // 1: EC, 2: CAS, 3: Name; 4: All
			
			SearchQueryObj.ECPattern = EINECS_Token.ParsedToken
			SearchQueryObj.SearchPattern = EINECS_Token.ParsedToken;
		}
		else if (IsValidECCASPattern(SearchQueryObj.CompactInput))
		{
			// default
			SearchQueryObj.Error = false;
			SearchQueryObj.WarningLevel = 2;
			SearchQueryObj.SearchType = 5; // 1: EC, 2: CAS, 3: Name; 4: All			
			SearchQueryObj.CASPattern = SearchQueryObj.CompactInput
			SearchQueryObj.ECPattern = SearchQueryObj.CompactInput
			SearchQueryObj.SearchPattern = SearchQueryObj.CompactInput;
		}
		else
		{  // store default search pattern
			SearchQueryObj.SearchPattern = SearchQueryObj.CompactInput;
			
			var PatternCAS = /^\d{4,7}/;
			var PatternCAS_EC = /^\d{1,3}/;
			
			var MatchCAS = SearchQueryObj.CompactInput.match(PatternCAS) // List!
			var CASMatching = (MatchCAS) ? MatchCAS[0] : null ;

			var MatchCAS_EC = SearchQueryObj.CompactInput.match(PatternCAS_EC) // List!
			var CAS_EC_Matching = (MatchCAS_EC) ? MatchCAS_EC[0] : null ;

			if (CASMatching == SearchQueryObj.CompactInput)
			{
				if (! ((CASMatching.length == 7) && (CASMatching[0] == "0")))
				{
					SearchQueryObj.Error = false;
					SearchQueryObj.WarningLevel = 1;
					SearchQueryObj.SearchType = 2; // 1: EC, 2: CAS, 3: Name; 4: All				
					SearchQueryObj.MatchCASSpecificPattern = 1
					SearchQueryObj.CASPattern = SearchQueryObj.CompactInput;
					SearchQueryObj.SearchPattern = SearchQueryObj.CompactInput;
				}

			}
			else if (CAS_EC_Matching == SearchQueryObj.CompactInput)
			{
				SearchQueryObj.Error = false;
				SearchQueryObj.WarningLevel = 2;
				SearchQueryObj.SearchType = 5; // 1: EC, 2: CAS, 3: Name; 4: All
				SearchQueryObj.MatchECSpecificPattern = 1
				SearchQueryObj.MatchCASSpecificPattern = 1
				SearchQueryObj.ECPattern = SearchQueryObj.CompactInput;
				SearchQueryObj.CASPattern = SearchQueryObj.CompactInput;
				SearchQueryObj.SearchPattern = SearchQueryObj.CompactInput;
			}
			
			//SearchQueryObj.SearchPattern = "";
			//SetInputSearchBkgColor(Node, 0)
		}

	}

	SetInputSearchBkgColor(Node, SearchQueryObj.WarningLevel) 
	
	EvalMessageSearchQuery(SearchQueryObj) // Debug
	
	return SearchQueryObj
}


function FetchNumericPatternOnlyList (TokenList)
{
	var Numerical_Token_List = [];
	
	for ( var k=0; k< TokenList.length ; ++k)
   	{
     	var Token = TokenList[k]
		if (IsPureDigitPattern(Token))
		{
			Numerical_Token_List.push(Token);
		}
		else
		{
			// Solve case like (no white spaces): Monosodiumglutamate(205-538-1)
			if (MatchSubNumber(Token)) {UpdateSearchError("Submission ref. pattern: " + Token); continue;}   // Drop UUID
			if (MatchUUID(Token)) {UpdateSearchError("UUID pattern: " + Token); continue;}   // Drop UUID
			if (MatchPreReg(Token)) {UpdateSearchError("Pre-Reg pattern: " + Token); continue;} // Drop Pre-reg
			
			var CAS_Pattern = GetCASExactPattern(Token)  //
			var EC_Pattern = GetECExactPattern(Token)    //
			var Num_Pattern = (CAS_Pattern) ? CAS_Pattern : EC_Pattern
			if (Num_Pattern)
			{
				Numerical_Token_List.push(Num_Pattern);  //
			}

		}
		
	}
	return Numerical_Token_List
}


function FetchExactECCASPatternOnlyList (TokenList)
{
	var Numerical_Token_List = [];
	
	for ( var k=0; k< TokenList.length ; ++k)
   	{
     	var Token = TokenList[k]
		if (MatchSubNumber(Token)) {UpdateSearchError("Submission ref. pattern: " + Token); continue;}   // Drop UUID
		if (MatchUUID(Token)) {UpdateSearchError("UUID pattern: " + Token); continue;}   // Drop UUID
		if (MatchPreReg(Token)) {UpdateSearchError("Pre-Reg pattern: " + Token); continue;} // Drop Pre-reg
		var CAS_Pattern = GetCASExactPattern(Token)  //
		var EC_Pattern = GetECExactPattern(Token)    //
		var Num_Pattern = (CAS_Pattern) ? CAS_Pattern : EC_Pattern
		if (Num_Pattern)
		{
			Numerical_Token_List.push(Num_Pattern);  // 
		}
		else if (IsPureDigitPattern(Token))
		{
			// TO DO: Try CAS or EC i.e: 50000, if successful, add "Token" in list: Numerical_Token_List.push(Token);
		}
		
	}
	return Numerical_Token_List
}


function DismissCommentedInput(Input)
{
	var ValidInput = "";
	for (var i = 0; i< Input.length; ++i)
	{
		var Char = Input.charAt(i)
		if (Char == Global_CommentChar) 
		{  // Hit a comment char -
			break;
		}  
		else
		{
			ValidInput += Char;
		}
	}
	return ValidInput
}


function ParsePreRegSearchInputs(Node, Input)
{
	var SearchQueryObjList = [];
	var Accepted_Token_List = []
  	var RegSepBlanks = new RegExp("\\s+", "g");
	var ValidInput = DismissCommentedInput(Input)
  	var TokenList = ValidInput.split(RegSepBlanks);	
	
	if ((GetCASExactPattern(ValidInput)) || (GetECExactPattern(ValidInput)) )
	{
		Accepted_Token_List =  FetchExactECCASPatternOnlyList (TokenList)
	}
	else if ( (IsStringPattern(ValidInput)) || (IsAllFieldsSearchActivated()) )
	{
		Accepted_Token_List.push(ValidInput)
	}
	else
	{
		Accepted_Token_List =  FetchNumericPatternOnlyList (TokenList)
	}

	for ( var k=0; k< Accepted_Token_List.length ; ++k)
   	{
		var Token = Accepted_Token_List[k];
		var SearchQueryObj = ParsePreRegSearchInput(Node, Token)
		if (SearchQueryObj)
		{
			if (IsAllFieldsSearchActivated())
			{  // Bypass Query Nature
				SearchQueryObj.WarningLevel = 0;
				SearchQueryObj.SearchPattern = SearchQueryObj.CoreInput;
				SearchQueryObj.SearchType = SEARCH_TYPE_ALL;
				SetInputSearchBkgColor(Node, SearchQueryObj.WarningLevel) 
			}
			SearchQueryObjList.push(SearchQueryObj)
		}
	}
	
	return SearchQueryObjList
}


function ParseMultiQueries(Node)
{
	Node.value = QueryTrimString(Node.value)
  	var RegSep = new RegExp("[;\n]", "g");
  	var QueryList = Node.value.split(RegSep);
		
	if (Node.nodeName == "TEXTAREA") {ResetInputBkg(Node);}
	//alert("ParseMultiQueries: " + Node.value)
	ResetSearchErrors()
	ResetECHAQuery();
	ResetWinLocation();
	
	for ( var k=0; k< QueryList.length ; ++k)
   	{
		//if (k == 0) {ResetWinLocation() }
     	var TextQuery = QueryList[k]
     	var SearchQueryObjList = ParsePreRegSearchInputs(Node, TextQuery)
		
		for ( var l=0; l< SearchQueryObjList.length ; ++l)
   		{
			var SearchQueryObj = SearchQueryObjList[l]			
			if (SearchQueryObj)
			{
				BuildECHAQuery(SearchQueryObj)
			}
		}
   	}

	AssessSearchOptions()
	AssessUserCommands()
	DeepCASValidityChecking()
	
	DisplayTextAreaOutputs(Node)
	if (Global_SearchErrorCounter) {SetInputSearchBkgColor(Node, 0)} // reset
	DisplaySearchError()
	
	var Report_valid_queries = Global_PromptSign + "Valid query(ies): " + Global_ECHA_Query_List.length
	if ( (Global_ECHA_Query_List.length) && (Node.nodeName == "TEXTAREA")) {Node.value += "\n" + Report_valid_queries}
		
	Global_HasProcessedAllInputs = true;
	
	SendingSearchRequestsToEcha();
}




function BuildSearchAcceptedSet(SearchQueryObj)
{
	var Pattern =""
	
	if (SearchQueryObj.StartSearchEnabled)
	{
		var Car = ""+ START_SEARCH_CODE;
		Pattern += Car;
	}
	
	if (SearchQueryObj.ContentSearchEnabled)
	{
		var Car = ""+ CONTENT_SEARCH_CODE;
		Pattern += Car;
	}

	if (SearchQueryObj.ExactSearchEnabled)
	{
		var Car = ""+ EXACT_SEARCH_CODE;
		Pattern += Car;
	}

	if (SearchQueryObj.EndSearchEnabled)
	{
		var Car = ""+ END_SEARCH_CODE;
		Pattern += Car;
	}

	SearchQueryObj.AcceptedSearchSet = Pattern;
}


function IsAcceptedSearchRadioValue(EchaQueryObj, SpecifiedSearchCode)
{
	var Command = "" + SpecifiedSearchCode  // convert to string
	return EchaQueryObj.AcceptedSearchSet.match(Command);
}


function CaptureUserSpecifiedSearchOptions(EchaQueryObj)
{
	var RadioValue = GetUserSpecifiedRadioValue()
	var Int_RadioValue = parseInt(RadioValue)
	if ((Int_RadioValue > 0) && (Int_RadioValue < 5))
	{
		if (IsAcceptedSearchRadioValue(EchaQueryObj, Int_RadioValue))
		{
			EchaQueryObj.UserSpecifiedSearchCode = Int_RadioValue
			
			/*
			// BUG in ECHA (Nov 09) - "Exact" search for name not working
			if ((EchaQueryObj.IsStringSearch) && (Int_RadioValue == 3))
			{
				EchaQueryObj.UserSpecifiedSearchCode = 2; // temporaty FIX exact with "contain"
			}
			*/
			
		}
		else
		{    // Accept incompatible user command. This query will fail!
			EchaQueryObj.UserSpecifiedSearchCode = Int_RadioValue
		}
	}
	return Int_RadioValue
}


function ResetSearchErrors()
{
	Global_SearchErrors = "";
	Global_SearchErrorCounter = 0;
}

function UpdateSearchError(Message)
{
	if (!Message) {return }
	if (Global_SearchErrors) { Global_SearchErrors += "\n" + Message } else { Global_SearchErrors = Message;}
	Global_SearchErrorCounter += 1;
}

function DisplaySearchError()
{
	if (Global_SearchErrors) 
	{ 
		alert("Discarded Search Error(s): \n" + Global_SearchErrors)
	} 
}



function BuildECHAQuery(SearchQueryObj)
{
	if (SearchQueryObj.Error)
	{
		var Mess = "Error:";
		if (SearchQueryObj.UUID)
		{
			Mess += " UUID";
		}
		else if (SearchQueryObj.MatchPreRegPattern)
		{
			Mess += " Pre-Reg";
		}
		else
		{
			Mess += " Unknown"
		}
		
		Mess += " pattern: " + SearchQueryObj.SearchPattern
		SearchQueryObj.Message = Mess;
		UpdateSearchError(SearchQueryObj.Message); //
	}
	else
	{
		var EchaQueryObj = MakeEchaQueryObj(SearchQueryObj);
		switch (SearchQueryObj.SearchType)
		{
			case 1:  // EC
			{
				AddEchaQueryObjInList(EchaQueryObj)
			}
			break;
			case 2: // CAS
			{
				AddEchaQueryObjInList(EchaQueryObj)
			}
			break;
			case 3: // Substance Name
			{
				AddEchaQueryObjInList(EchaQueryObj)
			}
			break;
			case 4: // ALL fields
			{
				AddEchaQueryObjInList(EchaQueryObj)
			}
			break;
			case 5:  // CAS/EC
			{
				var ECQuery = EchaQueryObj
				var CASQuery = MakeEchaQueryObj(SearchQueryObj)
								
				// Process EC
				ECQuery.SearchType = 1
				ECQuery.SearchPattern = SearchQueryObj.ECPattern
				AddEchaQueryObjInList(ECQuery)
				
				// Process CAS
				CASQuery.SearchType = 2
				CASQuery.SearchPattern = SearchQueryObj.CASPattern
				AddEchaQueryObjInList(CASQuery)
								
			}
			break;
			default:		
		}
		
	}
	
}


function AssessSearchOptions()
{
	var List = Global_ECHA_Query_List
	for ( var k=0; k< List.length ; ++k)
   	{
     	var EchaQueryObj = List[k]
		ProbeSearchLimits(EchaQueryObj)
   	}
	
}


function DisplayTextAreaOutputs(Node)
{
	var List = Global_ECHA_Query_List
	if ((Node.nodeName != "TEXTAREA") || (List.length == 0)) { return } else { Node.value = ""; }
	var BreakLine = Global_PromptSign;
	for ( var k=0; k< List.length ; ++k)
   	{
     	var EchaQueryObj = List[k]
		var SearchParams = MakeSearchParameters(EchaQueryObj)
		//Node.value += BreakLine + EchaQueryObj.SearchPattern
		Node.value += BreakLine + SearchParams[3] + " (Option: " + SearchParams[2]+")"
		BreakLine = "\n" + Global_PromptSign;
   	}
}

function IsECStartPattern(Input)
{
	var ECStartPattern = /^\d{3}-\d{2}/;
	var Match1 = Input.match(ECStartPattern)
	var Result = (Match1) ? (Match1[0].charAt(0) != "0") : false;  // reject lead zero ie: 077-23
	
	return Result;
}

function MightBeECStartPattern(Input)
{
	if (!Input) return false;
	if (Input.charAt(0) == "0") {return false;} // reject lead zero ie: 077-23
	if (IsECStartPattern(Input)) {return true;}
	else
	{		
		var ECStartPattern1 = /^\d{1,3}/;
		var Match1 = Input.match(ECStartPattern1)
		var Result1 = (Match1) ? (Match1[0] == Input) : false;  
		if (Result1) {return true}
		else
		{
			var ECStartPattern2 = /^\d{3}-\d{0,2}/;
			var Match2 = Input.match(ECStartPattern2)
			//var Result2 = (Match2) ? (Match2[0] == Input) : false;  
			var Result2 = (Match2) ? (true) : false;  
			return Result2;
		}
	}
}

function IsECEndPattern(Input)
{
	var ECEndPattern = /-\d{3}-\d{1}/;
	var Match1 = Input.match(ECEndPattern)
	var Result = (Match1) ? true : false;  
	
	return Result;
}

function MightBeECEndPattern(Input)
{
	var ECEndPattern = /(\d{0,3}-)?\d{1}$/;
	var Match1 = Input.match(ECEndPattern)
	var Result = (Match1) ? (Match1[0] == Input) : false;  
	//alert ("MightBeECEndPattern: " + Input + " Match: " + Result )
	return Result;
}


function IsCASStartPattern(Input)
{
	//var CASStartPattern = /^\d{2,7}-\d{2}/;
	var CASStartPattern = /^\d{7}-\d{1,2}/;  // almost always fail
	var Match1 = Input.match(CASStartPattern)
	var Result = (Match1) ? (Match1[0].charAt(0) != "0") : false; // reject lead zero ie: 01-00
	//alert("IsCASStartPattern: " + Input + "  : " + Result)
	return Result;
}

function MightBeCASStartPattern(Input)
{
	if (!Input) return false;
	if (Input.charAt(0) == "0") {return false;} // reject lead zero ie: 07-23

	if (IsCASStartPattern(Input)) {return true;}
	else
	{		
		var CASStartPattern1 = /^\d{1,7}/;
		var Match1 = Input.match(CASStartPattern1)
		var Result1 = (Match1) ? (Match1[0] == Input) : false;  
		if (Result1) {return true}
		else
		{
			var CASStartPattern2 = /^\d{2,7}-\d{0,2}/;
			var Match2 = Input.match(CASStartPattern2)
			var Result2 = (Match2) ? (true) : false;  
			return Result2;
		}
	}
}


function IsCASEndPattern(Input)
{
	var CASEndPattern = /-\d{2}-\d{1}/;
	var Match1 = Input.match(CASEndPattern)
	var Result = (Match1) ? true : false;
	
	return Result;
}

function MightBeCASEndPattern(Input)
{
	var CASEndPattern = /(\d{0,2}-)?\d{1}$/;
	var Match1 = Input.match(CASEndPattern)
	var Result = (Match1) ? (Match1[0] == Input) : false;
	//alert ("MightBeCASEndPattern: " + Input + " Match: " + Result + "Match1[0] : " + ((Match1) ? (Match1[0]) : false) )
	return Result;
}



function ProbeSearchLimits(EchaQueryObj)
{
		switch (EchaQueryObj.SearchType)
		{
			case 1:  // EC
			{
				EchaQueryObj.StartSearchEnabled = IsECStartPattern(EchaQueryObj.SearchPattern) // Search for optimum
				EchaQueryObj.EndSearchEnabled =  IsECEndPattern(EchaQueryObj.SearchPattern) // Search for optimum
				if (EchaQueryObj.ExactSearchEnabled)
				{
					EchaQueryObj.OptimalSearchCode = EXACT_SEARCH_CODE
				} else if (EchaQueryObj.StartSearchEnabled)
				{
					EchaQueryObj.OptimalSearchCode = START_SEARCH_CODE
				} else if (EchaQueryObj.EndSearchEnabled)
				{
					//EchaQueryObj.OptimalSearchCode = END_SEARCH_CODE  // END search not supported
					EchaQueryObj.OptimalSearchCode = CONTENT_SEARCH_CODE					
				} else if (EchaQueryObj.ContentSearchEnabled)  // Default
				{
					EchaQueryObj.OptimalSearchCode = CONTENT_SEARCH_CODE
					EchaQueryObj.StartSearchEnabled = MightBeECStartPattern(EchaQueryObj.SearchPattern);  // Force that option
					EchaQueryObj.EndSearchEnabled = MightBeECEndPattern(EchaQueryObj.SearchPattern); // Force that option
				}
				
				BuildSearchAcceptedSet(EchaQueryObj)
			}
			break;
			case 2: // CAS
			{
				EchaQueryObj.StartSearchEnabled = IsCASStartPattern(EchaQueryObj.SearchPattern)
				EchaQueryObj.EndSearchEnabled =  IsCASEndPattern(EchaQueryObj.SearchPattern)
				if (EchaQueryObj.ExactSearchEnabled)
				{
					EchaQueryObj.OptimalSearchCode = EXACT_SEARCH_CODE
					EchaQueryObj.StartSearchEnabled = MightBeCASStartPattern(EchaQueryObj.SearchPattern);  // Force that option
				} else if (EchaQueryObj.StartSearchEnabled)
				{
					EchaQueryObj.OptimalSearchCode = START_SEARCH_CODE
				} else if (EchaQueryObj.EndSearchEnabled)
				{
					//EchaQueryObj.OptimalSearchCode = END_SEARCH_CODE  // END search not supported
					EchaQueryObj.OptimalSearchCode = CONTENT_SEARCH_CODE					
				}else if (EchaQueryObj.ContentSearchEnabled)  // default
				{
					EchaQueryObj.OptimalSearchCode = CONTENT_SEARCH_CODE
					EchaQueryObj.StartSearchEnabled = MightBeCASStartPattern(EchaQueryObj.SearchPattern);  // Force that option
					EchaQueryObj.EndSearchEnabled = MightBeCASEndPattern(EchaQueryObj.SearchPattern); // Force that option

				} 
			
				BuildSearchAcceptedSet(EchaQueryObj)
			}
			break;
			case 3: // Substance Name
			{
				EchaQueryObj.StartSearchEnabled = true;
				EchaQueryObj.EndSearchEnabled = true
				EchaQueryObj.ExactSearchEnabled = true; // ex-BUG
				BuildSearchAcceptedSet(EchaQueryObj)

				EchaQueryObj.OptimalSearchCode = CONTENT_SEARCH_CODE
			}
			break;
			default:	// 4: // ALL fields
				EchaQueryObj.StartSearchEnabled = true;
				EchaQueryObj.EndSearchEnabled = true
				EchaQueryObj.ExactSearchEnabled = true; 
				BuildSearchAcceptedSet(EchaQueryObj)

				EchaQueryObj.OptimalSearchCode = CONTENT_SEARCH_CODE
		}

	EchaQueryObj.UserSpecifiedStartSearch = EchaQueryObj.StartSearchEnabled
	EchaQueryObj.UserSpecifiedContentSearch = EchaQueryObj.ContentSearchEnabled
	EchaQueryObj.UserSpecifiedExactSearch = EchaQueryObj.ExactSearchEnabled
	EchaQueryObj.UserSpecifiedEndSearch = EchaQueryObj.EndSearchEnabled

	EchaQueryObj.UserSpecifiedSearchCode = EchaQueryObj.OptimalSearchCode



 	//var Type = (EchaQueryObj.SearchType == SEARCH_TYPE_NAME) ? "Name " : (EchaQueryObj.SearchType == SEARCH_TYPE_EC) ? "EC " : (EchaQueryObj.SearchType == SEARCH_TYPE_CAS) ? "CAS " : "ALL"
	//alert ( Type + "Pattern: " + EchaQueryObj.SearchPattern + "  Accepted set: " + EchaQueryObj.AcceptedSearchSet + "  Optimal: " + EchaQueryObj.OptimalSearchCode)
}


function AssessUserCommands()
{
	var List = Global_ECHA_Query_List
	var Len = List.length
	for ( var k=0; k< Len ; ++k)
   	{
     	var EchaQueryObj = List[k] 
		var Int_FormRadioValue = CaptureUserSpecifiedSearchOptions(EchaQueryObj) // User specified radio button value
		
		// Disable automated search expansion in manual mode
		if ((! EchaQueryObj.IsStringSearch) && (Int_FormRadioValue != 5)) 
		{
			// START_SEARCH_CODE or CONTENT_SEARCH_CODE or EXACT_SEARCH_CODE
			if (
				(EchaQueryObj.UserSpecifiedSearchCode == START_SEARCH_CODE)
				|| (EchaQueryObj.UserSpecifiedSearchCode == CONTENT_SEARCH_CODE)
				// || (EchaQueryObj.UserSpecifiedSearchCode == EXACT_SEARCH_CODE)
				)
			{
				if (EchaQueryObj.SearchPattern != EchaQueryObj.CoreInput)
				{  // Force a CAS search setup
					////alert("SearchPattern : " + EchaQueryObj.SearchPattern + " |  CoreInput: " +   EchaQueryObj.CoreInput + " EchaQueryObj.UserSpecifiedSearchCode: " + EchaQueryObj.UserSpecifiedSearchCode)
					EchaQueryObj.SearchType = 2;  // 1: EC, 2: CAS, 3: Name; 4: All
					EchaQueryObj.SearchPattern = EchaQueryObj.CoreInput;
				}
			}
			
		}

		
   	}
}


function SendingSearchRequestsToEcha()
{
	var List = Global_ECHA_Query_List
	var Len = List.length
	for ( var k=0; k< Len ; ++k)
   	{
     	var EchaQueryObj = List[(Len-k) - 1]  // reversed order
		var SearchParams = MakeSearchParameters(EchaQueryObj)
		
		QueryEchaDatabase(SearchParams, null)
   	}
	ResetECHAQuery(); //
	ResetUserSpecifiedRadioValue()
	UncheckAllFieldsSearchBox()
}



function MakeSearchParameters(EchaQueryObj)
{
	var SearchParam = ['', '', '', '',];  // 4-element array
	var PatternNature = ""
	
	SearchParam[0] = EchaQueryObj.SearchPattern
		
	switch (EchaQueryObj.SearchType)
	{
		case SEARCH_TYPE_EC:  // EC
		{
			SearchParam[1] = "EC";
			PatternNature = "EC pattern: "
		}
		break;
		case SEARCH_TYPE_CAS: // CAS
		{
			SearchParam[1] = "CAS";
			PatternNature = "CAS pattern: "
		}
		break;
		case SEARCH_TYPE_NAME: // Substance Name
		{
			SearchParam[1] = "NAMEORSYNONYM";
			PatternNature = "Substance name pattern: "
		}
		break;
		case SEARCH_TYPE_ALL: // ALL fields
		{
			SearchParam[1] = "ALL";
			PatternNature = "Search on all fields (EC, CAS, Name): "
		}
		break;
		default:	
	}
	
	switch (EchaQueryObj.UserSpecifiedSearchCode)
	{
		case START_SEARCH_CODE:  
		{
			SearchParam[2] = "start";
		}
		break;
		case CONTENT_SEARCH_CODE:
		{
			SearchParam[2] = "contain";
		}
		break;
		case EXACT_SEARCH_CODE: 
		{
			SearchParam[2] = "exact";
		}
		break;
		case END_SEARCH_CODE: 
		{
			SearchParam[2] = ""; // Search not supported by ECHA
		}
		break;
		default:	
	}
	
	
	SearchParam[3] = PatternNature + EchaQueryObj.SearchPattern;
	
	return SearchParam
}

function QueryECHA ()
{
	var InputNode = document.getElementById("blands_preregistration_inputs__1")
	ParseMultiQueries(InputNode);
}


function FetchUserSpecificSearchForm()
{
	var Form = document.forms['BLandsUserSpecificSearchForm'];
	if (!Form) { Form = document.BLandsUserSpecificSearchForm;}	
	return Form
}

function GetUserSpecifiedRadioValue()
{
	var UserSpecificSearchForm = FetchUserSpecificSearchForm()
	//alert("UserSpecificSearchForm: " + UserSpecificSearchForm)
	if (UserSpecificSearchForm)
	{
		if (UserSpecificSearchForm.blands_search_user_radio)  // by name
		{
			var Len = UserSpecificSearchForm.blands_search_user_radio.length
			for ( var i=0; i< Len; ++i)
			{
				var Node = UserSpecificSearchForm.blands_search_user_radio[i]
				if (Node.checked == true)
				{
						//alert("Node.value: "+ Node.value)
						return Node.value
				}
			}
		}
	}
	return 0; // failed
}

function IsAllFieldsSearchActivated()
{
	var CheckNode = document.getElementById("blands_search_all_fields_box") 
	if (CheckNode)
	{
		//alert("CheckNode.checked : " + CheckNode.checked)
		return (CheckNode.checked)
	}
	return false;
}



function CheckAllFieldsSearchBox()
{
	var CheckNode = document.getElementById("blands_search_all_fields_box") 
	if (CheckNode)
	{
		CheckNode.checked = true;
	}
}

function UncheckAllFieldsSearchBox()
{
	var CheckNode = document.getElementById("blands_search_all_fields_box") 
	if (CheckNode)
	{
		CheckNode.checked = false;
	}
}




function CheckAllFieldsSearchBox()
{
	if (Global_AllFields_Warning) {return; /* No warning repeated */}
	
	var CheckNode = document.getElementById("blands_search_all_fields_box") 
	var Warning = "FORCE SEARCHING ON ALL FIELDS \n\n"
	Warning += "Warning:\n"
	Warning += "You are about to temporary activate a non-optimal (Brute Force) search option.\n"
	Warning += "The search will be carried out irrespectively on all fields (CAS RNs, EC#, Substance names, Synonyms) resulting in dramatically prolonged execution time.\n\n"
	Warning += "This option will be deactivated immediately upon completion of the search command.\n\n"
	Warning += "Please confirm."
	
	if (! confirm(Warning))
	{
		UncheckAllFieldsSearchBox();
	}
	else
	{
		Global_AllFields_Warning = true;  // Will not repeat warning
	}
}


function ResetUserSpecifiedRadioValue()
{
	var UserSpecificSearchForm = FetchUserSpecificSearchForm()
	if (UserSpecificSearchForm)
	{
		if (UserSpecificSearchForm.blands_search_user_radio)  // by name
		{
			var Len = UserSpecificSearchForm.blands_search_user_radio.length
			for ( var i=0; i< Len; ++i)
			{
				var Node = UserSpecificSearchForm.blands_search_user_radio[i]
				if (Node.value == "5") // Default - Automatic
				{
					Node.checked = true
				} else
				{
					Node.checked = false
				}
			}
			
		}
	}
}


function DeepCASValidityChecking()
{  // Checking CAS with respect to user specification (exact query!)
	var List = Global_ECHA_Query_List
	var OK_List = []
	var ErrorMessage = "CAS pattern: " 
	var Len = List.length
	
	for ( var k=0; k< Len ; ++k)
   	{
     	var EchaQueryObj = List[k] 
		
		if (
			(EchaQueryObj.SearchType == SEARCH_TYPE_CAS) && 
			(EchaQueryObj.UserSpecifiedSearchCode == EXACT_SEARCH_CODE)
   			)
		{
			var CAS_Token = new TokenClass(EchaQueryObj.SearchPattern, Parse_CAS_Fct); 
			if (! CAS_Token.Error)
			{
				OK_List.push(EchaQueryObj)  // Valid exact CAS search pattern
			}
			else
			{
				UpdateSearchError(ErrorMessage + EchaQueryObj.SearchPattern); //
			}
		}
		else
		{
			OK_List.push(EchaQueryObj) // Valid query
		}
		
   	}
	Global_ECHA_Query_List = OK_List;
}