
var Global_Non_EC_Lead_Digits = "^[018]"  // As of 2010, EC# start either with 2, 3, 4, 5, 6, 7, or 9
var Global_Accept_User_Incompatible_Search_Options = false

var Global_ECHA_Default_Database_Search = 'EchaPreRegSearchForm'

var Global_TextArea_Name = "TEXTAREA"

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_SearchDuplicates = "";
var Global_SearchDuplicatedCounter = 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 RESET_REG_TOP_POS = 0;
var RESET_REG_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.SubNumber ="";
	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 ResetRegWinLocation()
{
	Global_WinTopPosition = RESET_REG_TOP_POS;
	Global_WinLeftPosition = RESET_REG_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 GetBrowserSize() 
{
 	var Size = [];
  	var myWidth = 0, myHeight = 0;
  if( typeof( window.innerWidth ) == 'number' ) 
  {
    //Non-IE
    myWidth = window.innerWidth;
    myHeight = window.innerHeight;
  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) 
  {
    //IE 6+ in 'standards compliant mode'
    myWidth = document.documentElement.clientWidth;
    myHeight = document.documentElement.clientHeight;
  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) 
  {
    //IE 4 compatible
    myWidth = document.body.clientWidth;
    myHeight = document.body.clientHeight;
  }
	Size.push(myWidth)
	Size.push(myHeight)
	return Size
}


////////////////////////////////////////////
//
////////////////////////////////////////////
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 ContainDoubleQuote(Input)
{
	return Input.match(new RegExp('"', "g"))
}


////////////////////////////////////////////
//
////////////////////////////////////////////
function RemoveDoubleQuotes(Input)
{
 	if (Input)
 	{
		return Input.replace(/\"/g, '')
 	}
	else
	{
		return Input 
	}
}

////////////////////////////////////////////
//
////////////////////////////////////////////
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 ="-"}
		if (IsDigit(Char) || (Char == "_") || (Char == "-")|| (Char == "X") || (Char == "x")) {CompactNumber += Char}
	}
	return CompactNumber
}


function IsAbstractPattern(Input)
{
	return Input.match(new RegExp("[_Xx]", "g"))
}

function IsPureNumericPattern(Input)
{  
	return (! IsAbstractPattern(Input))
}



function MatchSubECPattern(Input)
{
	if (Input)
	{
		var MaxPattern = /[0-9_Xx]{0,3}([-_Xx][0-9_Xx]{3}([-_Xx][0-9_Xx]?)?)?/;
		var MatchList = Input.match(MaxPattern)
		var MaxMatchStr = GetMaxMatchFromMatchList(MatchList)
		//alert("EC1 MaxMatchStr: " +  MaxMatchStr + " MatchList :" + MatchList)		
		if (MaxMatchStr != Input)
		{
			var MaxPattern = /[0-9_Xx]{2}([-_Xx][0-9_Xx]{3}([-_Xx][0-9_Xx]?)?)?/;
			var MatchList = Input.match(MaxPattern)
			MaxMatchStr = GetMaxMatchFromMatchList(MatchList)
			//alert("EC2 MaxMatchStr: " +  MaxMatchStr + " MatchList :" + MatchList)
			if (MaxMatchStr != Input)
			{
				var MaxPattern = /[0-9_Xx]{1}([-_Xx][0-9_Xx]{3}([-_Xx][0-9_Xx]?)?)?/;
				var MatchList = Input.match(MaxPattern)
				MaxMatchStr = GetMaxMatchFromMatchList(MatchList)
				//alert("EC3 MaxMatchStr: " +  MaxMatchStr + " MatchList :" + MatchList)
				if (MaxMatchStr != Input)
				{
					var MaxPattern = /[-_Xx][0-9_Xx]{3}([-_Xx][0-9_Xx]?)?/;
					var MatchList = Input.match(MaxPattern)
					MaxMatchStr = GetMaxMatchFromMatchList(MatchList)
					//alert("EC4 MaxMatchStr: " +  MaxMatchStr + " MatchList :" + MatchList)
					if (MaxMatchStr != Input)
					{
						var MaxPattern = /[0-9_Xx]{0,3}([-_Xx][0-9_Xx]?)?/;
						var MatchList = Input.match(MaxPattern)
						MaxMatchStr = GetMaxMatchFromMatchList(MatchList)
						//alert("EC5 MaxMatchStr: " +  MaxMatchStr + " MatchList :" + MatchList)
						if (MaxMatchStr != Input)
						{
							var MaxPattern = /[-_Xx]?[0-9_Xx]/;
							var MatchList = Input.match(MaxPattern)
							MaxMatchStr = GetMaxMatchFromMatchList(MatchList)
							//alert("EC6 MaxMatchStr: " +  MaxMatchStr + " MatchList :" + MatchList)
							if (MaxMatchStr != Input)
							{
								var MaxPattern = /[0-9_Xx]{0,3}([-_Xx][0-9_Xx]{0,3})?/;
								var MatchList = Input.match(MaxPattern)
								MaxMatchStr = GetMaxMatchFromMatchList(MatchList)
								//alert("EC7 MaxMatchStr: " +  MaxMatchStr + " MatchList :" + MatchList)
							}
						}
					}
				}
	   		}
      	}
		
		return ((MaxMatchStr == Input) && (IsvalidECPatternPhase2(Input)))
	}
	else
	{
		return false
	}
}



function MatchSubECAbstractPattern(Input)
{
	var Pattern1 = /-[0-9]{3}/;  
	var Pattern2 = /-[0-9_Xx]{3}-/;  
	var Pattern3 = /-[0-9_Xx]{5}/;  

	var FoundECSpecificSubPattern1 = Input.match(Pattern1)
	var FoundECSpecificSubPattern2 = Input.match(Pattern2)
	var FoundECSpecificSubPattern3 = Input.match(Pattern3)

	return (FoundECSpecificSubPattern1 || FoundECSpecificSubPattern2 || FoundECSpecificSubPattern3)
}

function MatchECExactAbstractPattern(Input)
{
	//var Pattern1 = /[_]{3}-[_]{3}-[_]{1}/;
	var Pattern1 = /[0-9_Xx]{3}[-_Xx][0-9_Xx]{3}[-_Xx][0-9_Xx]{1}/;
	var Matching =  Input.match(Pattern1)
	if ((Matching) && MatchSubECAbstractPattern(Input))
	{
		return ((Matching[0] == Input) && IsvalidECPatternPhase2(Input));
	} 
	else return false;  // No match
}

function GetECExactPattern(Input, BasicCheck)
{
	var Pattern1 = /[0-9_Xx]{3}-[0-9_Xx]{3}-[0-9_Xx]{1}/;
	var Matching =  Input.match(Pattern1)
	if ((Matching) && (BasicCheck || IsvalidECPatternPhase2(Input))) {return Matching[0];}  // First element in list
	else return null;  // No match

}

function GetECApproxPattern(Input)
{
	var Pattern1 = /[0-9_Xx]{3,}-[0-9_Xx]{3}-[0-9_Xx]{1}[-0-9_Xx]*/;
	var Matching =  Input.match(Pattern1)
	if (Matching) 
	{
		var MaxMatchStr = GetMaxMatchFromMatchList(Matching, 1) // Iterate
		//alert(MaxMatchStr)
		return MaxMatchStr;
	} 
	else 
	return "";  // No match

}

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



function IsValidECCASPattern (Input)
{
	return (MatchSubECPattern(Input) && MatchSubCASPattern(Input))
}

////////////////////////////////////////////
//
////////////////////////////////////////////
function MatchECPattern(SearchObj)
{   // EC specific patterns
	var Input = SearchObj.CompactInput
	if (MatchECExactPattern(Input)) 
	{  // Exact match
		//alert("MatchECExactPattern"); 		
		
		SearchObj.ECPattern = Input;
		SearchObj.SearchPattern = Input;
		
		if (IsPureNumericPattern(Input)) // i.e: 212-825-5
		{
			var EINECS_Token = new TokenClass(Input, Parse_EINECS_Fct);
			if (! EINECS_Token.Error)  // With EC#, no sub EC can satisfy EC checksum !
			{
				SearchObj.Error = false;
				SearchObj.WarningLevel = 0;
				SearchObj.ExactSearch = true;
				SearchObj.SearchType = 1;  // 1: EC, 2: CAS, 3: Name; 4: All
				return 2;
			}
			else
			{  // Detected checksum error i.e: 212-825-9
				SearchObj.Error = true;
				SearchObj.SearchType = 1;
				return 0;
			}
		}
		else
		{  // Full generic pattern i.e: 2XX-825-X
			SearchObj.Error = false;
			SearchObj.WarningLevel = 0;
			SearchObj.ExactSearch = false;
			SearchObj.SearchType = 1;  // 1: EC, 2: CAS, 3: Name; 4: All
			return 1;
		}
	}  
	else if (MatchSubECPattern(Input)) // i.e: 212-825-
	{
		SearchObj.Error = false;
		SearchObj.WarningLevel = 1;
		SearchObj.ExactSearch = false;
		SearchObj.SearchType = 1;  // 1: EC, 2: CAS, 3: Name; 4: All
		SearchObj.ECPattern = Input;
		SearchObj.SearchPattern = Input;
		return 1;
	}
	else if ((IsPureNumericPattern(Input)) && (! MatchCASExactPattern(Input))) // i.e: 2128255 or 0000212-825-5
	{
		// Attempt to confirm Exact Match from pure digit pattern
		var EINECS_Token = new TokenClass(Input, Parse_EINECS_Fct);
		
		if (! EINECS_Token.Error)
		{
			SearchObj.Error = false;
			SearchObj.WarningLevel = 0;
			SearchObj.ExactSearch = true;
			SearchObj.SearchType = 1;  // 1: EC, 2: CAS, 3: Name; 4: All
			SearchObj.ECPattern = EINECS_Token.ParsedToken;   //Transform
			SearchObj.SearchPattern = EINECS_Token.ParsedToken; // Transform
			return 2;
		}
	}
	
	return 0
}



function GetMaxMatchFromMatchList(MatchList, Iterate)
{
	var MaxMatch  = "" // default
	if (MatchList)
	{
		for ( var k=0; k< MatchList.length ; ++k)
   		{
     		var Match = MatchList[k]
			if (Match)
			{
				MaxMatch += Match
				if (! Iterate) break;
			}
			else
			{
				break;  // exit
			}
		}
	
	}
	return MaxMatch
}


function MatchSubCASPattern(Input)
{
	if (Input)
	{
		var MaxPattern = /[0-9_Xx]{0,7}([-_Xx][0-9_Xx]{2}([-_Xx][0-9_Xx]?)?)?/;
		var MatchList = Input.match(MaxPattern)
		var MaxMatchStr = GetMaxMatchFromMatchList(MatchList)
		//alert("CAS1 MaxMatchStr: " +  MaxMatchStr + " MatchList :" + MatchList)
		if (MaxMatchStr != Input)
		{
			var MaxPattern = /[0-9_Xx]{6}([-_Xx][0-9_Xx]{2}([-_Xx][0-9_Xx]?)?)?/;
			var MatchList = Input.match(MaxPattern)
			MaxMatchStr = GetMaxMatchFromMatchList(MatchList)
			//alert("CAS2 MaxMatchStr: " +  MaxMatchStr + " MatchList :" + MatchList)
			if (MaxMatchStr != Input)
			{
				var MaxPattern = /[0-9_Xx]{5}([-_Xx][0-9_Xx]{2}([-_Xx][0-9_Xx]?)?)?/;
				var MatchList = Input.match(MaxPattern)
				MaxMatchStr = GetMaxMatchFromMatchList(MatchList)
				//alert("CAS3 MaxMatchStr: " +  MaxMatchStr + " MatchList :" + MatchList)
				if (MaxMatchStr != Input)
				{
					var MaxPattern = /[0-9_Xx]{4}([-_Xx][0-9_Xx]{2}([-_Xx][0-9_Xx]?)?)?/;
					var MatchList = Input.match(MaxPattern)
					MaxMatchStr = GetMaxMatchFromMatchList(MatchList)
					//alert("CAS4 MaxMatchStr: " +  MaxMatchStr + " MatchList :" + MatchList)
					if (MaxMatchStr != Input)
					{
						var MaxPattern = /[0-9_Xx]{3}([-_Xx][0-9_Xx]{2}([-_Xx][0-9_Xx]?)?)?/;
						var MatchList = Input.match(MaxPattern)
						MaxMatchStr = GetMaxMatchFromMatchList(MatchList)
						//alert("CAS5 MaxMatchStr: " +  MaxMatchStr + " MatchList :" + MatchList)
						if (MaxMatchStr != Input)
						{
							var MaxPattern = /[0-9_Xx]{2}([-_Xx][0-9_Xx]{2}([-_Xx][0-9_Xx]?)?)?/;
							var MatchList = Input.match(MaxPattern)
							MaxMatchStr = GetMaxMatchFromMatchList(MatchList)
							//alert("CAS6 MaxMatchStr: " +  MaxMatchStr + " MatchList :" + MatchList)
							if (MaxMatchStr != Input)
							{
								var MaxPattern = /[0-9_Xx]{1}([-_Xx][0-9_Xx]{2}([-_Xx][0-9_Xx]?)?)?/;
								var MatchList = Input.match(MaxPattern)
								MaxMatchStr = GetMaxMatchFromMatchList(MatchList)
								//alert("CAS7 MaxMatchStr: " +  MaxMatchStr + " MatchList :" + MatchList)
								if (MaxMatchStr != Input)
								{
									var MaxPattern = /[-_Xx][0-9_Xx]{2}([-_Xx][0-9_Xx]?)?/;
									var MatchList = Input.match(MaxPattern)
									MaxMatchStr = GetMaxMatchFromMatchList(MatchList)
									//alert("CAS8 MaxMatchStr: " +  MaxMatchStr + " MatchList :" + MatchList)
									if (MaxMatchStr != Input)
									{
										var MaxPattern = /[0-9_Xx]{0,2}([-_Xx][0-9_Xx]?)?/;
										var MatchList = Input.match(MaxPattern)
										MaxMatchStr = GetMaxMatchFromMatchList(MatchList)
										//alert("CAS9 MaxMatchStr: " +  MaxMatchStr + " MatchList :" + MatchList)
										if (MaxMatchStr != Input)
										{
											var MaxPattern = /[-_Xx]?[0-9_Xx]/;
											var MatchList = Input.match(MaxPattern)
											MaxMatchStr = GetMaxMatchFromMatchList(MatchList)
											//alert("CAS10 MaxMatchStr: " +  MaxMatchStr + " MatchList :" + MatchList)
											if (MaxMatchStr != Input)
											{
												var MaxPattern = /[0-9_Xx]{0,7}([-_Xx][0-9_Xx]{0,2})?/;
												var MatchList = Input.match(MaxPattern)
												MaxMatchStr = GetMaxMatchFromMatchList(MatchList)
												//alert("CAS11 MaxMatchStr: " +  MaxMatchStr + " MatchList :" + MatchList)
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
		return (MaxMatchStr == Input)
	}
	else
	{
		return false
	}
}



function MatchSubCASAbstractPattern(Input)
{
	var Pattern1 = /^[0-9_Xx]{4,7}-/;
	var Pattern2 = /^[0-9]{4,7}/;
	var Pattern3 = /-[0-9_Xx]{2}-/;
	var FoundCASSpecificSubPattern1 = Input.match(Pattern1)
	var FoundCASSpecificSubPattern2 = Input.match(Pattern2)
	var FoundCASSpecificSubPattern3 = Input.match(Pattern3)
	return (FoundCASSpecificSubPattern1 || FoundCASSpecificSubPattern2 || FoundCASSpecificSubPattern3)
}


function MatchCASExactAbstractPattern(Input)
{
	//var Pattern1 = /[_]{2,7}-[_]{2}-[_]{1}/;
	var Pattern1 = /[0-9_Xx]{2,7}[-_Xx][0-9_Xx]{2}[-_Xx][0-9_Xx]{1}/;
	var Matching = Input.match(Pattern1)
	if ((Matching) && MatchSubCASAbstractPattern(Input))
	{
		return (Matching[0] == Input)
	}  
	else return false;  // No match
}


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


function GetCASApproxPattern(Input)
{
	// Input is only made of digits and "-"
	//var Pattern1 = /[0-9_Xx]{2,7}-[0-9_Xx]{2}-[0-9_Xx]{1}[-0-9_Xx]*/;
	var Pattern1 = /[0-9_Xx]{2,}-[0-9_Xx]{2}-[0-9_Xx]{1}[-0-9_Xx]*/;
	var Matching = Input.match(Pattern1)
	if (Matching) 
	{
		var MaxMatchStr = GetMaxMatchFromMatchList(Matching, 1) // Iterate
		//alert(MaxMatchStr)
		return MaxMatchStr;
	}  
	else return "";  // No match
}


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


////////////////////////////////////////////
//
////////////////////////////////////////////
function MatchCASPattern(SearchObj)
{   // CAS specific patterns
	var Input = SearchObj.CompactInput
	if (MatchCASExactPattern(Input)) 
	{  // Exact match
		//alert("MatchCASExactPattern"); 		
		
		SearchObj.CASPattern = Input;
		SearchObj.SearchPattern = Input;
		
		if (IsPureNumericPattern(Input)) // i.e: 8008-57-9
		{
			var CAS_Token = new TokenClass(Input, Parse_CAS_Fct);
			if (! CAS_Token.Error)  
			{
				SearchObj.Error = false;
				SearchObj.WarningLevel = 0;
				SearchObj.ExactSearch = true;
				SearchObj.SearchType = 2;  // 1: EC, 2: CAS, 3: Name; 4: All
				return 2;
			}
			else
			{  // Detected failed checksum, but that can be a sub pattern of a CAS
				if (ProbeUserSpecifiedSearchOptions() == EXACT_SEARCH_CODE)
				{
					SearchObj.Error = true;  
					SearchObj.SearchType = 2;  // 1: EC, 2: CAS, 3: Name; 4: All
					return 0;  
				}
				else
				{
					SearchObj.Error = false;  // False
					SearchObj.WarningLevel = 1;
					SearchObj.ExactSearch = false;
					return 1;  // Not declared a failure yet. (Only if search option: "exact")
				}
			}
		}
		else
		{  // Full generic pattern i.e: 8XX8-57-9
			SearchObj.Error = false;
			SearchObj.WarningLevel = 0;
			SearchObj.ExactSearch = false;
			SearchObj.SearchType = 2;  // 1: EC, 2: CAS, 3: Name; 4: All
			return 1;
		}
	}  
	else if (MatchSubCASPattern(Input)) // i.e: 8008-57- or 9003172 -> 9003-17-2
	{
		// Attempt to confirm Exact Match from pure digit pattern
		var CAS_Token = new TokenClass(Input, Parse_CAS_Fct);
		
		if (! CAS_Token.Error)
		{
			SearchObj.Error = false;
			SearchObj.WarningLevel = 0;
			SearchObj.ExactSearch = true;
			SearchObj.SearchType = 2;  // 1: EC, 2: CAS, 3: Name; 4: All
			SearchObj.CASPattern = CAS_Token.ParsedToken;   //Transform
			SearchObj.SearchPattern = CAS_Token.ParsedToken; // Transform
			return 2;
		}
		else
		{
			SearchObj.Error = false;
			SearchObj.WarningLevel = 1;
			SearchObj.ExactSearch = false;
			SearchObj.SearchType = 2;  // 1: EC, 2: CAS, 3: Name; 4: All
			SearchObj.CASPattern = Input;
			SearchObj.SearchPattern = Input;
			return 1;
		}
	}
	else if ((IsPureNumericPattern(Input)) && (!MatchECExactPattern(Input))) // i.e: 8008579 
	{
		// Attempt to confirm Exact Match from pure digit pattern
		var CAS_Token = new TokenClass(Input, Parse_CAS_Fct);
		
		if (! CAS_Token.Error)
		{
			SearchObj.Error = false;
			SearchObj.WarningLevel = 0;
			SearchObj.ExactSearch = true;
			SearchObj.SearchType = 2;  // 1: EC, 2: CAS, 3: Name; 4: All
			SearchObj.CASPattern = CAS_Token.ParsedToken;   //Transform
			SearchObj.SearchPattern = CAS_Token.ParsedToken; // Transform
			return 2;
		}
	}
	
	return 0
}


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

function MatchSubNumberPattern(SearchObj)
{
	var Input = SearchObj.CompactInput
	return MatchSubNumber(Input)
}

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.SubNumber)
		{
			Mess += " Submission number";
		}
		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;
	
	if (ContainDoubleQuote(Input)) { return true }

	for (var i = 0; i< Input.length; ++i)
	{
		Char = Input.charAt(i)		
		if (! IsControlCar(Char))
		{
			if (IsDigit(Char)) {++DigitCounter}
			if ((!IsDigit(Char)) && (Char != "-")) {++CharCounter}  // General approach			
			//if (IsDigit(Char) || Char == "-") {++DigitCounter}
			//else if (!IsDigit(Char)) {++CharCounter}  // General approach
		}
	}
	
	if (CharCounter > 0)
	{
		return true;
	}
	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 == "X" ||
			Char == "x" ||
			Char == "."
			) 
		{
			continue;
		}
		else
		{
			return false;
		}
	}
	
	return true;
}



////////////////////////////////////////////
//
////////////////////////////////////////////
function ParsePreRegSearchInput(Node, TextQuery)
{
	//alert(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 ="-"} */
			SearchQueryObj.CoreInput += Char;		
			if ((IsDigit(Char))) {++DigitCounter}
			if ((!IsDigit(Char)) && ((Char != "-")  && (Char != ".") && (Char != "_") && (Char != "X")&& (Char != "x") && (Char != " ")) ) {++CharCounter}  // General approach			
		}
	}
		
	SearchQueryObj.CharCounter = CharCounter
	SearchQueryObj.DigitCounter = DigitCounter
		
		
	//if (CharCounter+DigitCounter == 0)
	if (! SearchQueryObj.CoreInput)
	{
		//Node.value =""
		SetInputSearchBkgColor(Node, 0); // Reset BKG
		//alert(SearchQueryObj.InitialInput)
		return null;
	}

	if (
		(MatchCASExactAbstractPattern(SearchQueryObj.CoreInput)) 
		|| (MatchECExactAbstractPattern(SearchQueryObj.CoreInput)) 
		)
	{ SearchQueryObj.IsStringSearch = false; }
	else if (CharCounter > 0) 
	{ SearchQueryObj.IsStringSearch = true; } 
	else if (DigitCounter > 0) { SearchQueryObj.IsStringSearch = false; }
	else { SearchQueryObj.IsStringSearch = true; } 
	
	
	
	
	if (ContainDoubleQuote(SearchQueryObj.InitialInput)) 
	{
		//SearchQueryObj.CoreInput = RemoveDoubleQuotes(SearchQueryObj.CoreInput);
		SearchQueryObj.IsStringSearch = true;
	}
	else
	{
		SearchQueryObj.SubNumber = MatchSubNumber(SearchQueryObj.CoreInput) // Direct sub function call
		if (SearchQueryObj.SubNumber) 
		{ 
			//alert("Submission number: "+ SearchQueryObj.SubNumber) 
			SearchQueryObj.SearchPattern = SearchQueryObj.SubNumber;
			SearchQueryObj.WarningLevel = 4;
			////Node.value = SearchQueryObj.SearchPattern
			SetInputSearchBkgColor(Node, SearchQueryObj.WarningLevel)
			EvalMessageSearchQuery(SearchQueryObj) //Debug
			return SearchQueryObj;
		}
		
	}
	
	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)
		SearchQueryObj.CoreInput = CompactNumberInput(SearchQueryObj.CoreInput);   //// 
	}
	//alert(SearchQueryObj.CompactInput)
	
		
	SearchQueryObj.MatchPreRegPattern = MatchPreRegPattern(SearchQueryObj)
	if (SearchQueryObj.MatchPreRegPattern)
	{
		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)
	SearchQueryObj.MatchECSpecificPattern = MatchECPattern(SearchQueryObj)

	if ((SearchQueryObj.MatchECSpecificPattern) && (SearchQueryObj.MatchCASSpecificPattern))
	{
		if ((SearchQueryObj.MatchECSpecificPattern == 2) && (SearchQueryObj.MatchCASSpecificPattern == 2))
		{
			SearchQueryObj.Error = false;
			SearchQueryObj.WarningLevel = 3;
			SearchQueryObj.ExactSearch = true;
			SearchQueryObj.SearchType = 5; // 1: EC, 2: CAS, 3: Name; 4: All, 5: EC-CAS	
			
			SearchQueryObj.SearchPattern = Global_PromptSign + SearchQueryObj.ECPattern + " | " + SearchQueryObj.CASPattern;
		}
		else if (SearchQueryObj.MatchECSpecificPattern == 2)
		{
			SearchQueryObj.Error = false;
			SearchQueryObj.WarningLevel = 0;
			SearchQueryObj.ExactSearch = true;
			SearchQueryObj.SearchType = 1;  // 1: EC, 2: CAS, 3: Name; 4: All			
		}
		else if (SearchQueryObj.MatchCASSpecificPattern == 2)
		{
			SearchQueryObj.Error = false;
			SearchQueryObj.WarningLevel = 0;
			SearchQueryObj.ExactSearch = true;
			SearchQueryObj.SearchType = 2;  // 1: EC, 2: CAS, 3: Name; 4: All
		}
		else
		{
			SearchQueryObj.Error = false;
			SearchQueryObj.WarningLevel = 2;
			SearchQueryObj.ExactSearch = false;
			SearchQueryObj.SearchType = 5; // 1: EC, 2: CAS, 3: Name; 4: All, 5: EC-CAS			
		}
	}
	else if ((SearchQueryObj.MatchECSpecificPattern) && (!SearchQueryObj.MatchCASSpecificPattern))
	{
		if (SearchQueryObj.MatchECSpecificPattern == 2)
		{
			SearchQueryObj.Error = false;
			SearchQueryObj.WarningLevel = 0;
			SearchQueryObj.ExactSearch = true;
			SearchQueryObj.SearchType = 1;  // 1: EC, 2: CAS, 3: Name; 4: All			
		}
		else
		{
			SearchQueryObj.Error = false;
			SearchQueryObj.WarningLevel = 1;
			SearchQueryObj.ExactSearch = false;
			SearchQueryObj.SearchType = 1;  // 1: EC, 2: CAS, 3: Name; 4: All
		}
	}
	else if ((!SearchQueryObj.MatchECSpecificPattern) && (SearchQueryObj.MatchCASSpecificPattern))
	{
		if (SearchQueryObj.MatchCASSpecificPattern == 2)
		{
			SearchQueryObj.Error = false;
			SearchQueryObj.WarningLevel = 0;
			SearchQueryObj.ExactSearch = true;
			SearchQueryObj.SearchType = 2;  // 1: EC, 2: CAS, 3: Name; 4: All
		}
		else
		{
			SearchQueryObj.Error = false;
			SearchQueryObj.WarningLevel = 1;
			SearchQueryObj.ExactSearch = false;
			SearchQueryObj.SearchType = 2;  // 1: EC, 2: CAS, 3: Name; 4: All
		}
	}
	else if ((!SearchQueryObj.MatchECSpecificPattern) && (!SearchQueryObj.MatchCASSpecificPattern))
	{
		SearchQueryObj.SearchPattern = SearchQueryObj.CompactInput;
	}


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




function Substitute_X_From_Pattern(Input)
{   // X or x is being used as wild char, in place of "_"
	var StrInput = Input
	if (StrInput)
	{
		StrInput = StrInput.replace(/[Xx]/g, '_')
	}
	return StrInput
}


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, 1)    //
			var CAS_Pattern = GetCASApproxPattern(Token)  // Accept errors (incorretly formated inputs)
			var EC_Pattern = GetECApproxPattern(Token)    //Accept errors (incorretly formated inputs)
			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, 1)    //
		var CAS_Pattern = GetCASApproxPattern(Token)  // Accept errors (incorretly formated inputs)
		var EC_Pattern = GetECApproxPattern(Token)    //Accept errors (incorretly formated inputs)
		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;
		}
	}
	
	///if (CompactCars(ValidInput) == "-") {ValidInput = ""} // suppress single '-' query
	
	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, 1)) )
	{
		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)
		
		//alert(SearchQueryObj.SearchPattern)
		if (SearchQueryObj)
		{
			if (IsAllFieldsSearchActivated())
			{  // Bypass Query Nature
			
				switch (SearchQueryObj.SearchType)
				{
					case SEARCH_TYPE_EC: //EC
					case SEARCH_TYPE_CAS: // CAS
					case SEARCH_TYPE_ECCAS_INTERNAL: // CAS & EC; Transient type
					{
						SearchQueryObj.ECPattern = Substitute_X_From_Pattern(SearchQueryObj.ECPattern)
						SearchQueryObj.CASPattern = Substitute_X_From_Pattern(SearchQueryObj.CASPattern)
						SearchQueryObj.SearchPattern = Substitute_X_From_Pattern(SearchQueryObj.SearchPattern)
					}
				}

				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 == Global_TextArea_Name) {ResetInputBkg(Node);}
	//alert("ParseMultiQueries: " + Node.value)
	ResetSearchErrors();
	ResetSearchDuplicates();
	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()
	RemoveDuplicatedQueries()
	
	DisplayTextAreaOutputs(Node)
	if (Global_SearchErrorCounter) {SetInputSearchBkgColor(Node, 0)} // reset
	DisplaySearchErrors()
	DisplaySearchDuplicates()
	
	
	if (Node.nodeName == Global_TextArea_Name)
	{
		if (Global_SearchDuplicatedCounter > 0) 
		{
			var Report_Duplicated_queries = Global_PromptSign + ((Global_SearchDuplicatedCounter > 1) ? "Discarded duplicated queries: " : "Discarded duplicate query: ")  + Global_SearchDuplicatedCounter
			Node.value += "\n" + Report_Duplicated_queries
		}
	
		if (Global_ECHA_Query_List.length) 
		{
			var Report_valid_queries = Global_PromptSign + ((Global_ECHA_Query_List.length > 1) ? "Valid queries: " : "Valid query: ")  + Global_ECHA_Query_List.length
			Node.value += "\n" + Report_valid_queries
			Node.scrollTop = Node.scrollHeight;
		}
	}
		
	Global_HasProcessedAllInputs = true;
	
	QueryFormName = SelectECHAQueryForm(Node);
	
	SendingSearchRequestsToEcha(QueryFormName);
}


function RemoveDuplicatedQueries()
{
	var List = Global_ECHA_Query_List
	var No_Duplicated_List = []
	var UniqueKeyList = new Array();
	
	for ( var k=0; k< List.length ; ++k)
   	{
     	var EchaQueryObj = List[k]
		var SearchParams = MakeSearchParameters(EchaQueryObj)
		var Key = CompactCars(SearchParams[1]+SearchParams[0]+SearchParams[2])
		
		if (UniqueKeyList[Key])
		{
			// Found duplicated Key
			UpdateSearchDuplicated(SearchParams[0] + " (Pattern: " + SearchParams[1]+")")
		}
		else
		{
			UniqueKeyList[Key] = true;
			No_Duplicated_List.push(EchaQueryObj)
		}
   	}
	
	Global_ECHA_Query_List = No_Duplicated_List
}


function SelectECHAQueryForm(Node)
{
	var List = Global_ECHA_Query_List
	var SearchTypeRadioValue = GetSearchTypeSpecifiedRadioValue()
	var Int_SearchTypeRadioValue = parseInt(SearchTypeRadioValue)
	var QueryFormName = Global_ECHA_Default_Database_Search  //Default
	
	if (IsSearchRegisteredActivated())
	{
		QueryFormName = 'EchaRegSearchForm'
		var theForm = document.forms[QueryFormName];
		
		//var BrowserSizeArray = GetBrowserSize(); // [W, H] 
		//theForm.__EVENTTARGET.value = 'ctl00$ctl00$CPHContent$CPHPageContent$GridView1'; 
		//theForm.__EVENTARGUMENT.value = 'Sort$CAS_NUMBER';
		//RESET_REG_LEFT_POS = Math.round(BrowserSizeArray[0]/4.0)
		RESET_REG_LEFT_POS = 200 ;
		//alert(RESET_REG_LEFT_POS)
		ResetRegWinLocation()
		
		if (!List.length)  // Empty request
		{
			// Default behavior: Find all substances
			var SearchQueryObj = ParsePreRegSearchInput(Node, "Empty")
			SearchQueryObj.WarningLevel = 0;
			SearchQueryObj.CoreInput = "";
			SearchQueryObj.SearchPattern = "";
			SearchQueryObj.SearchType = SEARCH_TYPE_ALL;
			SetInputSearchBkgColor(Node, SearchQueryObj.WarningLevel) 
			BuildECHAQuery(SearchQueryObj)
		}
	}
	else
	if (Int_SearchTypeRadioValue)
	{
		switch(Int_SearchTypeRadioValue)
		{
			case 1:
  					{
						QueryFormName = 'EchaPreRegSearchForm'
					}
  					break;
			case 2:
  					{
						QueryFormName = 'EchaRegSearchForm'
						var theForm = document.forms[QueryFormName];
		
						//var BrowserSizeArray = GetBrowserSize(); // [W, H] 
						//theForm.__EVENTTARGET.value = 'ctl00$ctl00$CPHContent$CPHPageContent$GridView1'; 
						//theForm.__EVENTARGUMENT.value = 'Sort$CAS_NUMBER';
						//RESET_REG_LEFT_POS = Math.round(BrowserSizeArray[0]/4.0)
						RESET_REG_LEFT_POS = 200 ;
						//alert(RESET_REG_LEFT_POS)
						ResetRegWinLocation()
		
						if (!List.length)  // Empty request
						{
							// Default behavior: Find all substances
							var SearchQueryObj = ParsePreRegSearchInput(Node, "Empty")
							SearchQueryObj.WarningLevel = 0;
							SearchQueryObj.CoreInput = "";
							SearchQueryObj.SearchPattern = "";
							SearchQueryObj.SearchType = SEARCH_TYPE_ALL;
							SetInputSearchBkgColor(Node, SearchQueryObj.WarningLevel) 
							BuildECHAQuery(SearchQueryObj)
						}
					}
  					break;
			default:
  					QueryFormName = 'EchaPreRegSearchForm'
		}		
	}
	return QueryFormName
}


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 ProbeUserSpecifiedSearchOptions()
{
	return (parseInt(GetUserSpecifiedRadioValue()))
}

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
						
		}
		else if (Global_Accept_User_Incompatible_Search_Options)
		{    // Accept incompatible user command. This query will fail!
			EchaQueryObj.UserSpecifiedSearchCode = Int_RadioValue
		}
	}
	return Int_RadioValue
}


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

function ResetSearchDuplicates()
{
	Global_SearchDuplicates = "";
	Global_SearchDuplicatedCounter = 0;
}

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

function UpdateSearchDuplicated(Message)
{
	if (!Message) {return }
	if (Global_SearchDuplicates) { Global_SearchDuplicates += "\n" + Message } else { Global_SearchDuplicates = Message;}
	Global_SearchDuplicatedCounter += 1;
}

function DisplaySearchErrors()
{
	if (Global_SearchErrors) 
	{ 
		alert("Discarded erroneous search(es): \n" + Global_SearchErrors)
	} 
}

function DisplaySearchDuplicates()
{
	if (Global_SearchDuplicates) 
	{ 
		alert("Discarded search duplicate(s): \n" + Global_SearchDuplicates)
	} 
}


function BuildECHAQuery(SearchQueryObj)
{
	if (SearchQueryObj.Error)
	{
		var Mess = "Error:";
		if (SearchQueryObj.UUID)
		{
			Mess += " UUID";
		}
		else if (SearchQueryObj.SubNumber)
		{
			Mess += " Submission number";
		}
		else if (SearchQueryObj.MatchPreRegPattern)
		{
			Mess += " Pre-Reg";
		}
		else if (SearchQueryObj.SearchType == 1)
		{
			Mess += " EC";
		}
		else if (SearchQueryObj.SearchType == 2)
		{
			Mess += " CAS";
		}
		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 != Global_TextArea_Name) || (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] + " (Matching: " + SearchParams[2]+")"
		BreakLine = "\n" + Global_PromptSign;
   	}
}

function IsECStartPattern(Input)
{
	var ECStartPattern = /^[0-9_Xx]{3}[-_Xx][0-9_Xx]{2}/;
	var Match1 = Input.match(ECStartPattern)
	//var Result = (Match1) ? (Match1[0].charAt(0) != "0") : false;  // reject lead zero ie: 077-23
	var Result = (Match1) ? (Match1[0].match(new RegExp(Global_Non_EC_Lead_Digits)) == null) : 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 (Input.match(new RegExp(Global_Non_EC_Lead_Digits)) != null) {return false;} // reject lead zero, etc. ie: 077-23
	if (IsECStartPattern(Input)) {return true;}
	else
	{		
		var ECStartPattern1 = /^[0-9_Xx]{1,3}/;
		var Match1 = Input.match(ECStartPattern1)
		var Result1 = (Match1) ? (Match1[0] == Input) : false;  
		if (Result1) {return true}
		else
		{
			var ECStartPattern2 = /^[0-9_Xx]{3}-[0-9_Xx]{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 = /-[0-9_Xx]{3}-[0-9_Xx]{1}/;
	var Match1 = Input.match(ECEndPattern)
	var Result = (Match1) ? true : false;  
	
	return Result;
}

function MightBeECEndPattern(Input)
{
	var ECEndPattern = /([0-9_Xx]{0,3}-)?[0-9_Xx]{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 = /^[0-9_Xx]{2,7}-[0-9_Xx]{2}/;
	var CASStartPattern = /^[0-9_Xx]{7}-[0-9_Xx]{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 = /^[0-9_Xx]{1,7}/;
		var Match1 = Input.match(CASStartPattern1)
		var Result1 = (Match1) ? (Match1[0] == Input) : false;  
		if (Result1) {return true}
		else
		{
			var CASStartPattern2 = /^[0-9_Xx]{2,7}-[0-9_Xx]{0,2}/;
			var Match2 = Input.match(CASStartPattern2)
			var Result2 = (Match2) ? (true) : false;  
			return Result2;
		}
	}
}


function IsCASEndPattern(Input)
{
	var CASEndPattern = /-[0-9_Xx]{2}-[0-9_Xx]{1}/;
	var Match1 = Input.match(CASEndPattern)
	var Result = (Match1) ? true : false;
	
	return Result;
}

function MightBeCASEndPattern(Input)
{
	var CASEndPattern = /([0-9_Xx]{0,2}-)?[0-9_Xx]{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 OK_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) // Expanded query ! i.e: 9003172; 2128255, with "start" or "content" 
				{ 
					//alert("SearchPattern : " + EchaQueryObj.SearchPattern + " |  CoreInput: " +   EchaQueryObj.CoreInput + " EchaQueryObj.UserSpecifiedSearchCode: " + EchaQueryObj.UserSpecifiedSearchCode)
					if ((EchaQueryObj.SearchType == 1) && (EchaQueryObj.WarningLevel == 3)) //EC
					{
						continue;  // Drop the expanded EC entry (Initially Type 5), when both CAS & EC (9003172), from the final list
					}
					if (EchaQueryObj.WarningLevel == 3) {EchaQueryObj.WarningLevel = 1}  // Adjust warning level
					if (EchaQueryObj.SearchType == 2) {EchaQueryObj.SearchPattern = EchaQueryObj.CoreInput;}  // 9003172 -> 9003-17-2 ==> 9003172 (cancel expansion only for CAS)
				}
			}
		}
		OK_List.push(EchaQueryObj) // Valid query
   	}
	Global_ECHA_Query_List = OK_List;
}


function SendingSearchRequestsToEcha(QueryFormName)
{
	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;
		
		switch (EchaQueryObj.SearchType)
		{
			case SEARCH_TYPE_EC: //EC
			case SEARCH_TYPE_CAS: // CAS
			{
				EchaQueryObj.SearchPattern = Substitute_X_From_Pattern(EchaQueryObj.SearchPattern)
			}
		}
		
		SearchParams = MakeSearchParameters(EchaQueryObj)
		QueryEchaDatabase(SearchParams, QueryFormName, 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 (InputNodeName, Value)
{
	var InputNode = null;
	var NodeOnTheFly = null;
	
	if (InputNodeName) {InputNode = document.getElementById(InputNodeName);}

	if (! InputNode)
	{
		InputNode = document.getElementById("blands_input_search_echa_node")
		if (! InputNode) { InputNode = document.getElementById("blands_preregistration_inputs__1")} // Legacy name
		if (! InputNode)
		{
			var NodeName =  ( (InputNodeName) ? InputNodeName : "TransientName" )
			var NodeValue = ( (Value) ? Value : "" )
			NodeOnTheFly = CreateTransientInputNode(NodeName, NodeValue)
			InputNode = NodeOnTheFly
		}
	}
	
	
	if ((Value) &&(InputNode)) {InputNode.value = Value}
	
	ParseMultiQueries(InputNode);
	
	if (NodeOnTheFly) { delete NodeOnTheFly } // Housekeeping
}



function QueryECHAOnTheFly (InputNodeName, Value, Database)
{
	var DefaultRadioSelect = GetSearchTypeSpecifiedRadioValue()
	if (Database)
	{
		var DatabaseSelect = parseInt(Database)
		switch (DatabaseSelect)
		{
			case 1:
			{
				PresetSpecifiedSearchTypeRadioValue(1)
				Global_ECHA_Default_Database_Search = 'EchaPreRegSearchForm'
			}
			break;
			case 2:
			{
				PresetSpecifiedSearchTypeRadioValue(2)
				Global_ECHA_Default_Database_Search = 'EchaRegSearchForm'
			}
			break;
			default:
			{
				PresetSpecifiedSearchTypeRadioValue(1)
				Global_ECHA_Default_Database_Search = 'EchaPreRegSearchForm'
			}
		
		}
		
	}
	QueryECHA (InputNodeName, Value)
	
	//if (DefaultRadioSelect) {PresetSpecifiedSearchTypeRadioValue(DefaultRadioSelect)} // Restore previous setting
}

function PreloadECHAQueryOnTheFly (InputNodeName, Value, Database, Message)
{
	var DefaultRadioSelect = GetSearchTypeSpecifiedRadioValue()
	var InputNode = null;
	
	if (InputNodeName) {InputNode = document.getElementById(InputNodeName);}

	if (! InputNode)
	{
		InputNode = document.getElementById("blands_input_search_echa_node")
		if (! InputNode) { InputNode = document.getElementById("blands_preregistration_inputs__1")} // Legacy name
	}
	
	if ((! InputNode) || (! Value)) { return } // failed !

	if (Database)
	{
		var DatabaseSelect = parseInt(Database)
		switch (DatabaseSelect)
		{
			case 1:
			{
				PresetSpecifiedSearchTypeRadioValue(1)
				Global_ECHA_Default_Database_Search = 'EchaPreRegSearchForm'
			}
			break;
			case 2:
			{
				PresetSpecifiedSearchTypeRadioValue(2)
				Global_ECHA_Default_Database_Search = 'EchaRegSearchForm'
			}
			break;
			default:
			{
				PresetSpecifiedSearchTypeRadioValue(1)
				Global_ECHA_Default_Database_Search = 'EchaPreRegSearchForm'
			}
		
		}
		
	}
	
	if (Value) 
	{
		//alert("Value: " + Value)
		var RegSep = new RegExp("[;\n]", "g");
  		var QueryList = Value.split(RegSep);
		var NodeValue = "";
		var BreakLine = "";
		for (var k=0; k< QueryList.length; ++k)
   		{
     		var TextQuery = QueryList[k]
			if (TextQuery)
			{
				NodeValue += BreakLine + QueryTrimString(TextQuery);
			}
			BreakLine = "\n"
		}
		
		if (NodeValue)
		{
			NodeValue += BreakLine + Global_PromptSign + Message;
		}
		
		InputNode.value = NodeValue
		InputNode.scrollTop = InputNode.scrollHeight;  // Scroll down
	}
	
}



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


function IsSearchRegisteredActivated()
{
	var CheckNode = document.getElementById("blands_search_registered_box") 
	if (CheckNode)
	{
		return (CheckNode.checked)
	}
	return false;
}


function UpdateDefaultDBID()
{
	var DatabaseSelect = parseInt(GetSearchTypeSpecifiedRadioValue())
	switch (DatabaseSelect)
	{
		case 1:
		{
			Global_ECHA_Default_Database_Search = 'EchaPreRegSearchForm'
		}
		break;
		case 2:
		{
			Global_ECHA_Default_Database_Search = 'EchaRegSearchForm'
		}
		break;
		default:
		{
			Global_ECHA_Default_Database_Search = 'EchaPreRegSearchForm'
		}
	}
}

function GetSearchTypeSpecifiedRadioValue()
{
	//var UserSpecificSearchForm = FetchUserSpecificSearchForm()
	var SearchTypeRadioNode = document.getElementsByName("blands_search_type_radio")

		if (SearchTypeRadioNode)  
		{
			var Len = SearchTypeRadioNode.length
			for ( var i=0; i< Len; ++i)
			{
				var Node = SearchTypeRadioNode[i]
				if (Node.checked == true)
				{
						return Node.value
				}
			}
		}
		
	return 0; // failed
}


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 PresetSpecifiedSearchTypeRadioValue(Select)
{
	var SearchTypeRadioNode = document.getElementsByName("blands_search_type_radio")
	var ValueIndex = parseInt(Select)
	var SuccessFlag = false;
	if (SearchTypeRadioNode)  
	{
		var Len = SearchTypeRadioNode.length
			
		for ( var i=0; i< Len; ++i)
		{
			var Node = SearchTypeRadioNode[i]
			Node.checked = false; // Reset all, Is that necessary for radio buttons? Then no early return
			if (Node.value == ValueIndex)
			{
				Node.checked = true
				SuccessFlag = true // success
				// return SuccessFlag // early return
			}
		}
	}
	return SuccessFlag; // 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)
   			)
		{
			//i.e: 67-56-3
			var CAS_Token = new TokenClass(EchaQueryObj.SearchPattern, Parse_CAS_Fct); 
			//////if ((! CAS_Token.Error) || MatchCASExactAbstractPattern(EchaQueryObj.SearchPattern))
			//alert("EchaQueryObj.SearchPattern: " + EchaQueryObj.SearchPattern + " CAS_Token.Error: "+ CAS_Token.Error + "  IsAbstractPattern: "+ IsAbstractPattern(EchaQueryObj.SearchPattern))
			if ((! CAS_Token.Error) || IsAbstractPattern(EchaQueryObj.SearchPattern))
			{
				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;
}



function IsvalidECPatternPhase2(Input)
{
	if (Input)
	{
		if (Input.length < 6)
		{
			return true;
		}
		else if (Input.match(new RegExp(Global_Non_EC_Lead_Digits))) // EC# start either with 2, 3, 4, 5, 6, 7, or 9
		{
			var ECStartPattern = /^[0-9_Xx]{3}[-_Xx][0-9_Xx]{2}/;
			var Match1 = Input.match(ECStartPattern)
			if (Match1)
			{
				return false
			}
			else
			{
				return true
			}
		}
		else
		{
			return true
		}
		
	}
	else
	{
		return false;
	}
}


function CreateTransientInputNode(Name, Value)
{
	var InputNode = document.createElement('input');
    InputNode.name = Name;
    InputNode.value = Value;
	return InputNode
}


function GetURLSearchParams(Sep) 
{
  //var URL = window.location.search.substring(1);
  var URL = window.location.href;
  if (URL)
  {
  	var Params = URL.split(Sep);
	//alert(Params)
  	if (Params.length < 2) { return null; }
	return Params
  }
  return null;
} 

function ProcessQueryFromURL()
{
	var Params = GetURLSearchParams("#")
	if (Params)
	{ 
		var Len = Params.length
		var Query = unescape(Params[1])
		//alert("Query: " + Query + "unescape: " + unescape(Query))
		var DatabaseSelect = 1
		if (Len > 2)
		{
			var DBID = Params[2]
			DatabaseSelect = parseInt(DBID)
		}
		
		QueryECHAOnTheFly(null, Query, DatabaseSelect)
	}
}


function InitiateQueryFromURL(Message)
{
	var Params = GetURLSearchParams("#")
	if (Params)
	{ 
		var Len = Params.length
		var Query = unescape(Params[1])
		//alert("Query: " + Query + "unescape: " + unescape(Query))
		var DatabaseSelect = 1
		if (Len > 2)
		{
			var DBID = Params[2]
			DatabaseSelect = parseInt(DBID)
		}
		
		PreloadECHAQueryOnTheFly(null, Query, DatabaseSelect, Message)
	}
}


