/*************************\
* ITALCOM S.p.A.          *
* Target:  IE 5.5, NE 6.0 *
* Library: Core.js        *
* Version: 1.0            *
* Require: none           *
* Objects: CQueryArgs     *
\*************************/

/* Definitions */
function EmptyFunction(){};
function NullFunction(){return null};

/*** IS FUNCTIONS ***/

var undefined;
function IsUndefined(v) { return (v == undefined); }
function IsEmptyString(v) { return (v == undefined || v === ""); }
//function IsEmpty(v) { try {	return (v == undefined || v == null || v === ""); } catch (e) {	return false; } }
function IsEmpty(o)
{
	if (o==null || o==="")
		return true;
	if (IsArray(o))
	{
		for(var i in o)
			return false;
		return true;
	}
	return false;
}
function IsBoolean(o){return typeof o=="boolean"}
function IsNumber(o){return typeof o=="number"}
function IsString(o){return typeof o=="string"}
function IsFunction(o){return typeof o=="function"}
function IsDate(o){return o instanceof Date}
function IsArray(o){return o instanceof Array}
function IsRegExp(o){return o instanceof RegExp}
function IsObject(o){return typeof o == "object"}
function IsStrictObject(o){return TypeOf(o) == "object"}
function TypeOf(o)
{
	if (o===null)
		return "null";
	var result = typeof o;
	if (result == "object")
	{
		if (o instanceof RegExp) return "regexp";
		if (o instanceof Date) return "date";
		if (o instanceof Array) return "array";
	}
	return result;
}
function IsInList(strItem, strListArray, sep)
{
	try
	{
		if (IsEmpty(strItem)) return false;
		if (IsEmpty(strListArray)) return false;
		if (IsEmpty(sep)) sep = ",";
		var l = IsArray(strListArray) ? strListArray : strListArray.toString().split(sep);
		strItem = Trim(strItem.toString());
		for (var i=0; i<l.length; i++)
			if (strItem == Trim(l[i].toString()))
				return true;
	}
	catch(e){Dump(e)}
	return false;
}


//==============
// CMessageList
//==============
// Esempio: ml = new CMessageList({key: {id: 1, msg: "message"}})
function CMessageList(entryList)
{
	if (IsEmpty(entryList)) entryList = {};

	this.all = entryList;
	return this;
}

CMessageList.prototype.isEmpty
=//===========================
function()
{
	for(var i in this.all) 
		return true;
	return false;
}

CMessageList.prototype.addMsgKey
=//=============================
// Es: add({key1: {id: 1, msg: ""}, key2: {id: 2, msg: ""}}, ["key1", "key2"])
function (messageList, keyList)
{
	var i;
	// Se non č specificato keyList si aggiungono tutti
	if (keyList==null)
	{
		for (i in messageList)
			this.all[i] = messageList[i];
	}
	else
	{
		for (var i=0; i<keyList.length; i++)
		this.all[keyList[i]] = messageList[keyList[i]];
	}
}

CMessageList.prototype.addMsgId
=//============================
// Es: add({key1: {id: 1, msg: ""}, key2: {id: 2, msg: ""}}, "1,2")
function (messageList, idList)
{
	// Se non č specificato keyList si aggiungono tutti
	for (var i in messageList)
		if (idList == null || IsInList(messageList[i].id, idList))
			this.all[i] = messageList[i];
}

CMessageList.prototype.getIdList
=//=============================
// Restituisce l'elenco degli id come stringa di interi separati da virgola es. "1,2"
function ()
{
	if (this.all.length == 0)
		return "";
	var result = [];
	for (var i in this.all)
		result[result.length] = this.all[i].id;
	return result.toString();
}

CMessageList.prototype.getMsgList
=//==============================
// Restituisce l'elenco dei messaggi come stringhe separate da \r
function (idList)
{
	if (this.all.length == 0)
		return "";
	var result = "";
	// Se non č specificato keyList si restituiscono tutti
	for (var i in this.all)
	{
		if (idList == null || IsInList(this.all[i].id, idList))
			result += this.all[i].msg + "\r";
	}
	return result;
}

function StringFormat(str, obj_args)
{
	// Es.:     StringFormat("{0}={1}", "v", 1) -> "v=1"
	// Oppure:  StringFormat("{a}={b}", {a: "v", b: 1}) -> "v=1"
	var arg = arguments;
	if (IsStrictObject(obj_args))
	{
		for (var i in obj_args)
			str = str.replace(new RegExp("{"+i+"}", "gi"), obj_args[i]);
		return str;
	}
	else
		return str.replace(StringFormat.regExp, function($0, $1){return arg[1+parseInt($1)]});
}
StringFormat.regExp = /\{(\d+)\}/g;

/* Macros */
function MacroReplace(str, list, flag)
{
	// Es.: MacroReplace(HTML, [["#id#", this.id], ["#cls#", this.cls]], "i")
	if (flag == null) flag = "g";
	var re = "("+ list[0][0] +")";
	var val = [];
	val[list[0][0]] = list[0][1]
	for (var i=1; i<list.length; i++)
	{
		re += "|("+ list[i][0] +")";
		val[list[i][0]] = list[i][1]
	}
	re = new RegExp(re, flag);
	return str.replace(re, function($0){return val[$0]});
}

function ErrorAlert(e, fName)
{
	try
	{
		var msg = "";
		if ( arguments.length > 1 )
			msg += fName;
		msg += "\n"+ e.name +" "+ e.number;
		msg += "\n"+ e.description;
		if ( e.description != e.message )
			msg += "\n"+ e.message;
		window.alert(msg);		
	}
	catch(e)
	{	
		window.alert("Unknown exception event");
	}
}


/*** BROWSER IDENTIFICATION ***/

/*
Per i nostri scopi il browser č:
Internet Explorer < 5.5
Internet Explorer >= 5.5
Netscape < 6.0
Netscape >= 6.0
*/

var IE = 0;
var NE = 0;
function BrowserIdentification()
{
	var pos, tmp;
    var userAgent = navigator.userAgent.toLowerCase();
    var majorVersion = parseInt(navigator.appVersion, 10);
    var minorVersion = parseFloat(navigator.appVersion);
    
    // Internet Explorer -> 5 o x.x
	var tmp = userAgent.match(/msie\s*(\d*)\D(\d*)/);
	if (tmp != null)
	{
		IE = parseInt(tmp[1], 10);
		if (IE==5)
			 IE = parseFloat(tmp[1]+"."+tmp[2]);
	}
	// Netscape Navigator -> 4 o 6
	else
	{
		NE = 4;
		if (majorVersion >= 5)
			NE = 6;
	}
}
try {BrowserIdentification()}catch(e){};

function BrowserAlert(verb)
{
	if (arguments.length<1) 
		verb = "knos dynweb cookie";
	else
		verb = verb.toLowerCase();

	if (verb.indexOf("knos")!=-1)
	{	
		if (IE<5.5)
		{
			window.alert("Funzionalitą accessibile solo con Microsoft Internet Explorer ver. 5.5 o successive.");
			return false;
		}
		verb += "cookie";
	}

	if (verb.indexOf("dynweb")!=-1)
	{
		if (IE<5.5 && NE<6)
		{
			window.alert("Funzionalitą accessibile solo con Microsoft Internet Explorer ver. 5.5 o successive o Netscape Navigator versione 6.0 o successive.");
			return false;
		}
	}

	if (verb.indexOf("cookie")!=-1)
	{
		if ( !navigator.cookieEnabled )
		{
			window.alert("Per accedere al servizio occorre abilitare i Cookie.");
			return false;
		}
	}
	
	return true;
}


function GetLicense(drvpath)
{
	var result = null;
	try
	{
		var fso, d, s, t;
		fso = new ActiveXObject("Scripting.FileSystemObject");
		if (IsEmpty(fso))
			result = "Error 1";
		d = fso.GetDrive(fso.GetDriveName(fso.GetAbsolutePathName("c:")));
		result = d.SerialNumber;
	}
	catch(e)
	{
		result = null;
	}
	return result;
}


//============
// CQueryArgs
//============
function CQueryArgs()
{
	this.args = [];
	this.init();
}

CQueryArgs.prototype.init
=//======================
function ()
{
try
{
	var str = document.location.search;
	if ( IsEmpty(str) )
		return [];
	var tmp = str.split(/[\?&]/);
	this.args = [];
	for (var i=0; i<tmp.length; i++)
	{
		var pos = tmp[i].indexOf("=");
		if (pos <0)
			continue;
		var arg = tmp[i].substr(0, pos);
		var val = tmp[i].substr(pos+1);
		this.args[this.args.length] = [unescape(arg), unescape(val)];
	}
}
catch(e)
{
	this.args = [];
}
}

CQueryArgs.prototype.getArg
=//========================
function (name, defValue)
{
	if (arguments.length < 2) defValue = null;

	var tmp = name.toLowerCase();
	for (var i=0; i<this.args.length; i++)
	{
		if ( this.args[i][0].toLowerCase() == tmp )
			return this.args[i][1];
	}		
	return defValue;
}


function GetPageName(url)
{
	if ( IsEmpty(url) )
		return "";
	url = unescape(url);
	var pos1 = url.lastIndexOf('/') + 1;
	var pos2 = url.lastIndexOf('\\') + 1;
	var pos = pos1 > pos2 ? pos1 : pos2;
	return url.slice(pos).toLowerCase();
}


function GetStyleAttribute(style, attribute, defValue)
{
try
{
	if ( IsEmpty(style) )
		return defValue;
	var tmp = style.split(/;/);
	for (var i=0; i<tmp.length; i++)
	{
		tmp[i] = tmp[i].split(":");
		if (tmp[i][0] == attribute)
			return tmp[i][1];
	}
}
catch(e)
{}
	return defValue;
}


/* CLIPBOARD */
function ClipboardGet(idClip)
{
	var result = "";
	try
	{
		var clip = window.clipboardData.getData("Text");
		if (!IsEmpty(idClip))
		{
			if ( clip.slice(0, idClip.length) == idClip )
				result = clip.slice(idClip.length);
		}
		else
			result = clip;
	}
	catch (e)
	{
		result = "";
	}
	return result;
}

function ClipboardSet(idClip, value)
{
	try
	{
		window.clipboardData.clearData("Text");
		if (arguments.length == 0)
		    return true;
		window.clipboardData.setData("Text", idClip+value);
		return true;
	}
	catch(e)
	{
		return false;
	}
}

 //////////
// Cookie
//
//	date = null: cookie di sessione
//	date = "":   scadenza di default 30/10/2029
function CookieSet(name, value, date, path, domain, bSecure) 
{
	var result = escape(name) + "=" + escape(value) + ";";	
	if (date !== null) // se null viene omessa, passare "" per il default
	{
		if (IsEmpty(date)) 
			date = new Date(2029,10,30);
		result += " expires=" + date.toGMTString() + ";";
	}
	if (path !== null)
	{
		if (IsEmpty(path)) 
			path = "/";
		result += " path=" + path + ";";
	}
	if (!IsEmpty(domain))
		result += " domain=" + domain + ";";
	if (!IsEmpty(bSecure) && bSecure)
		result += " secure;";
	document.cookie = result;
	return result;
}
function CookieGet(name) 
{
	if (IsEmpty(name)) return document.cookie;
	
	// cookies are separated by semicolons
	var aCookie = document.cookie.split(/;\s*/);
	var aCrumb;
	for (var i=0; i < aCookie.length; i++)
	{
		// a name/value pair (a crumb) is separated by an equal sign
		aCrumb = aCookie[i].split("=");
		if (name == aCrumb[0])
		{
			if (aCrumb.length > 1)
				return unescape(aCrumb[1]);
			else
				return "";
		}
	}
	// a cookie with the requested name does not exist
	return null;
}
function CookieDel(name) 
{
	var date=new Date(2000,10,30); 
	return CookieSet(name, "", date);
}


/*** DEBUGGING ***/

function Debug(expr)
{
	window.alert(expr);
}

function DebugPoint()
{
	if ( window.confirm("Debug?") )
		window.ale();
    // next statement	
}

function DebugProperties(target)
{
	var p;
	var str = "";
	for (p in target)
		if (typeof target[p] != "function")
			str += "\n" + p + " = " + target[p];
	return str;
}

function Dump(object_text)
{	
	var HTML = '<div style="font-size: 8pt;">'+ object_text +'</div>';
	if (IsObject(object_text))
		for (var i in object_text)
			if (!IsFunction(object_text[i]))
				HTML += '<div style="font-size: 8pt; padding-left: 20px;">'+ i +'='+ object_text[i] +'</div>';
	Response.Write(HTML);
}


/*** LOW LEVEL ***/
function ODD_INT(i)    	{ return (i & 0x01) ? true : false };
function EVEN_INT(i)    { return (i & 0x00) ? true : false };
var NIBBLE_TO_ESA =     "0123456789ABCDEF";
var ESA_CHAR =          ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];

function StringToEsa(str)
{
	var strEsa = "";
	for (i=0; i<str.length; i++)
	{
		h = (str.charCodeAt(i) & 0xf0) >> 4;
		l = (str.charCodeAt(i) & 0x0f);
		strEsa += ESA_CHAR[h];
		strEsa += ESA_CHAR[l];
	}
	return strEsa;
}


function EsaToString(esaChar)
{
	if (IsEmpty(esaChar)) return "";
	var str = "";
	var currByte = EsaToByte(esaChar, 0, esaChar.length);
	for (var i=0; i<currByte.length; i++)
		str += String.fromCharCode(currByte[i]);
	return str;
}


function ByteToEsa(byteArray, start, nLong)
{
	var h, l;
	var end = start+nLong;
	var strEsa = "";
	for (i=start; i<end; i++)
	{
		h = (byteArray[i] & 0xf0) >> 4;
		l = (byteArray[i] & 0x0f);
		strEsa += ESA_CHAR[h] + ESA_CHAR[l];
	}
	return strEsa;
}


function EsaToByte(esaChar, start, nChar)
{   
    var i, j, c;
    var low, high;    
    var outByte = new Array(nChar/2);
        
    esaChar = esaChar.toUpperCase();
    for (i=start, j=0; i<nChar; i++)
    {		
		c = esaChar.charAt(i);
        if ( (('0' <= c) && (c <= '9')) || (('A' <= c) && (c <= 'F')) )
        {
            if ( ODD_INT(i) )
                low = NIBBLE_TO_ESA.indexOf(c);
            else
                high = NIBBLE_TO_ESA.indexOf(c) << 4;
        }
        else 
        {
			return null;
        }
        if ( ODD_INT(i) )
            outByte[j++] = high | low;
    }    
    return outByte;
}


function StringPadding(str, padStr, mod)
{
	var n = str.length % mod;
	if ( n == 0 )
		n = str.length;
	else
		n = str.length + (mod - n);
	while ( str.length < n )
			str += padStr;
	return str.slice(0, n);
}



// Unione insiemistica degli elementi di due liste.
// Le due liste possono essere indifferentemente array oppure stringhe (con gli elementi separati da virgola).
// L'unione č restituita come array.
function Union(list1, list2)
{
	if (list1 == null) list1 = [];
	if (list2 == null) list2 = [];

	// Se list1 č una stringa non vuota la riconduco ad un array.
	if (IsString(list1))
		list1 = IsEmpty(list1) ? [] : list1.split(",");

	// Se list2 č una stringa lo riconduco ad un array.
	if (IsString(list2))
		list2 = IsEmpty(list2) ? [] : list2.split(",");

	// Se list1 č vuoto allora il risultato č list2.
	if (list1.length == 0)
		return list2;
	
	// (list1 non č vuoto) Se list2 č vuoto allora il risultato č list1.
	if (list2.length == 0)
		return list1;

	// Copio list1 in result.
	var result = list1.concat();

	// Merge di list1 e list2.
	for (var i = 0; i < list2.length; i++)
	{
		var found = false;
		for (var j = 0; j < list1.length; j++)
		{
			if (list2[i] == list1[j])
			{
				found = true;
				break;
			}
		}
		
		if (!found)
			result[result.length] = list2[i];
	}
	
	return result;
}

/*** TRIM ***/

function TrimLeft(s, c, nMax)
{
	s = s.toString();
	if (!IsEmpty(c))
	{
		var re;
		if (IsEmpty(nMax))
		{
			re = new RegExp("(^"+ c +"*)","");
			return s.replace(re, ""); 
		}
		else
		{
			var result = s;
			re = new RegExp("(^"+ c +")","");
			for (var i=0; i<nMax; i++)
				result = result.replace(re, "");
			return result;
		}
	}
	else
		return s.replace(/(^\s*)/, "");
}
function TrimRight(s, c, nMax) 
{
	s = s.toString();
	if (!IsEmpty(c))
	{
		var re;
		if (IsEmpty(nMax))
		{
			re = new RegExp("("+ c +"*$)","");
			return s.replace(re, "");
		}
		else
		{
			var result = s;
			re = new RegExp("("+ c +"$)","");
			for (var i=0; i<nMax; i++)
				result = result.replace(re, "");
			return result;
		}
	}
	else
		return s.replace(/(\s*$)/, "");
}
function Trim(s, c, nMax)
{
	if (!IsEmpty(c))
		return TrimRight(TrimLeft(s, c, nMax), c, nMax);
	else
		return TrimRight(TrimLeft(s));
}

function TrimSearchExpression(s)
{
	// Sostituzione di cr, tab, ecc. con spazi singoli
	s = s.replace(/(\f|\n|\r|\t|\v)+/g, " ");
	// Raddoppio degli apici e trim degli spazi
	return Trim(s.replace(/'/g, "''"));
}

function NormalizeString(s)
{
	// Semplificazione whitespace
	return s.replace(/\s+/g, " ");
}

function LikeSearchExpression(field, value)
{
	var s = ""+ value;
	return "["+ field +"] LIKE '%<!_CDATA_"+ s.replace(/'/g, "''") +"__>%'";
}

function WildDateExpression(colName, stdDateTime_Date)
{
	if (stdDateTime_Date === null || stdDateTime_Date === "")
		return "";
	var d = new Object();
	StdDateTimeObject(stdDateTime_Date, d);
	return "dbo.fn_ReplaceWildDate("+ colName +",'"+ d.year +"','"+ d.month +"','"+ d.day +"','"+ (parseInt(d.year, 10)+1) +"')";
}

function AppendSearchExpression(s1, s2)
{
	if (!IsEmpty(s1) && !IsEmpty(s2))
		s1 = "("+ s1 +") AND ";
	return s1 += s2;
}


/* ParseSearchText

Lo switch automatico su LIKE č ammesso solo su singoli attributi ed č attivato dalla
presenza di un % nella stringa di ricerca. 
Rispetto alla CONTAINS c'č la possibilitą di specificare prefissi con % e caratteri jolly con _
Perchč la contains trovi anche sigle tipo S.p.A. bisogna svuotare il file:
(SQL SERVER 2000) C:\Program Files\Microsoft SQL Server\MSSQL\FTDATA\SQLServer\Config\noise.dat (lingua neutrale)
(SQL SERVER 2005) C:\Program Files\Microsoft SQL Server\MSSQL\FTDATA\SQLServer\Config\noiseneu.txt (lingua neutrale)
Il risultato del parsing ritorna l'oggetto:
{
	 result : <stringa di ricerca se ok>
	,error1 : <parte di str fino all'errore riscontrato>
	,error2 : <parte restante di str>
	,ok: <true se ok>
}
*/
function ParseSearchText(str, colName, bAlert)
{
	if (IsEmpty(colName)) colName = "*";
	if (IsEmpty(bAlert)) bAlert = true;
	
	var bLike = (colName != "*" && str.indexOf("%") >= 0) ? true : false;
	colName = "Object_Index."+colName;

	// Parsing dei token
	// item | + | - 
	var re = /("[^"]+")|(\+|\-)|([^ \f\n\r\t\v\+\-]+)/g
	var i, c, s, t, bFirst = true;
	var token = [];
	while ((t = re.exec(str)) != null)
	{
		for (i=0; i<t.length; t++)
			if (t[i] != "")
				token[token.length] = t[i];
	}

	function filterToken(t)
	{
		if (t.charAt(0) != '"')
			t = '"'+ t +'"';
		if (t.charAt(t.length-1) != '"')
			t = t + '"';
		if (bLike)
		{
			t = Trim(t, '"', 1);
			if (bFirst)
				bFirst = false;
			else
				t = "%"+t+"%";
		}
		t = t.replace(/'/g, "''");
		return t;
	}

	var status =
	{
		item : 0,
		near : 1,
		end : -1,
		error : -2
	}
	var result = "";
	var error1 = "";
	var error2 = "";
	s = status.item;
	i = 0;
	while (s != status.end && i<token.length)
	{		
		lookahead = token[i+1] == null ? null : token[i+1].charAt(0);
		switch (s)
		{
			case status.item:
				switch (token[i].charAt(0))
				{
					case '+':
						s = status.error;
						break;
					case '-':
						if (result == "")
						{
							result = bLike 
								? "("+ colName +" NOT LIKE '" 
								: "NOT CONTAINS("+ colName +", '";
							s = status.item;
							i++;
						}
						break;
					default:
						if (result == "")
						{
							result = bLike
								? "("+ colName +" LIKE '"
								: "CONTAINS("+ colName +", '";
						}
						switch (lookahead)						
						{
							case null:
								result += filterToken(token[i]) + "')";
								s = status.end;
								break;
							case '-':
								result += bLike
									? filterToken(token[i]) + "%') AND ("+ colName +" NOT LIKE '" 
									: filterToken(token[i]) + "') AND NOT CONTAINS("+ colName +", '";
								s = status.item;
								i += 2;
								break;
							case '+':
								result += bLike
									? filterToken(token[i]) + "%"
									: filterToken(token[i]) + " NEAR ";
								s = status.near;
								i += 2;
								break;
							default:
								result += bLike 
									? filterToken(token[i]) + "%') AND ("+ colName +" LIKE '" 
									: filterToken(token[i]) + "') AND CONTAINS("+ colName +", '";
								s = status.item;
								i += 1;
								break;
						}
				}
				break;

			case status.near:
				switch (token[i].charAt(0))
				{
					case '+':
					case '-':
						s = status.error;
						break;
					default:
						switch (lookahead)
						{
							case null:
								result += filterToken(token[i]) + "')";
								s = status.end;
								break;
							case '-':
								result += bLike
									? filterToken(token[i]) + "%') AND ("+ colName +" NOT LIKE '"
									: filterToken(token[i]) + "') AND NOT CONTAINS("+ colName +", '";
								s = status.item;
								i += 2;
								break;
							case '+':
								result += bLike
									? filterToken(token[i]) + "%"
									: filterToken(token[i]) + " NEAR ";
								s = status.near;
								i += 2;
								break;
							default:
								result += bLike
									? filterToken(token[i]) + "%') AND ("+ colName +" LIKE '"
									: filterToken(token[i]) + "') AND CONTAINS("+ colName +", '";
								s = status.item;
								i += 1;
								break;
						}
				}
				break;
			
			case status.error:
			default:
				var j;
				for (j=0; j<i; j++)
					error1 += token[j] + " ";
				for (j=i; j<token.length; j++)
					error2 += token[j] + " ";	
				s = status.end;
				break;
		}
	}
	result = { result : result, error1 : error1, error2 : error2, ok : (error1 == "" && error2 == "") }
	if (!result.ok && bAlert)
		try { window.alert("Errore nell'espressione di ricerca:\n  ..."+ result.error2) }catch(e){}
	if (result.ok && bLike)
	{
		result.result = result.result.replace(/\*+/g, "%");
		result.result = result.result.replace(/\%+/g, "%");
	}
	return result;
}

function OpenUrl(url, target, features)
{
	if ( IsEmpty(url) )
		return;
	
	switch ( target )
	{
		case "_same": 
			window.location = url;
			break;
		
		case "_replace":
			window.location.replace(url);
			break;
		
		default:	
			if ( IsEmpty(features) )
				window.open(url, target);
			else
				window.open(url, target, features);
	}	
}


/* CHECKED INPUT */

function ParseInt(v, def, radix)
{
	if (radix==null) radix = 10;
	var result = parseInt(v, radix);
	if (isNaN(result) && arguments.length > 1)
		return def;
	return result;
}

function ParseFloat(v, def)
{
	var result = parseFloat(v)
	if (isNaN(result) && arguments.length > 1)
		return def;
	return result;
}

// Ottenimento di un valore intero
// Ritorna:
//	"" se il valore e' in bianco
//	null se non č un intero valido
//	
function GetCheckedInteger(target, bAlert)
{
	if (IsEmpty(bAlert)) bAlert = true;
	
	target.value = Trim(target.value+"");
	if (IsEmptyString(target.value))
		return "";
	if (isNaN(target.value) || parseInt(target.value,10) != target.value)
	{
		if (bAlert)
		{
			window.alert("Inserire un'espressione numerica intera valida");
			target.focus();
		}
		return null;
	}
	return target.value;
}


// Ottenimento di un valore float
// Ritorna:
//	"" se il valore e' in bianco
//	null se non č un float valido
//
function GetCheckedFloat(target, bAlert)
{
	if (IsEmpty(bAlert)) bAlert = true;	
	target.value = Trim(target.value);
	if (IsEmptyString(target.value))
		return "";
	if (isNaN(target.value))
	{
		if (bAlert)
		{
			window.alert("Inserire un'espressione numerica valida (come separatore decimali usare il punto '.')");
			target.focus();
		}
		return null;
	}
	return target.value;
}


/* ARROTONDAMENTO */

// Arrotondamento di un numero con nDecimali specificati
// se sono indicati cPoint o bZero ritorna una stringa
function Round(value, nDecimal, cPoint, bZero)
{
try
{
	var defZero = false;
	if (IsEmpty(nDecimal)) nDecimal = 4;
	if (IsEmpty(cPoint)) { cPoint = null; } else { defZero = true; }
	if (!IsEmpty(bZero)) defZero = bZero;
	bZero = defZero;
	
	var dec = Math.pow(10, nDecimal);
	var result = Math.round(value * dec) / dec;
	if ( !bZero && cPoint === null )
		return result;

	strResult = result.toString();
	if (bZero)
	{
		var z = strResult.lastIndexOf(".");
		if (z < 0 && nDecimal > 0)
		{
			strResult += ".";
			z = nDecimal;
		}
		else
			z = z + nDecimal + 1 - strResult.length;
		for (var i=0; i<z; i++)
			strResult += "0";
	}

	if (!IsEmpty(cPoint))
		strResult = strResult.replace(/\./g, cPoint);

	return strResult;
}
catch(e)
{
	return 0;
}
}


/*** FORMATI STANDARD ***/

// Format
var Format_bool_x = ["", "x", "", "x"];
var Format_bool_1 = ["0", "1", "0", "1"];
var Format_bool_t = ["F", "V", "F", "T"];
var Format_bool_T = ["Falso", "Vero", "False", "True"];
var Format_bool_y = ["N", "S", "N", "Y"];
var Format_bool_Y = ["No", "Si", "No", "Yes"];
var Format_month = ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];

function Format(str, fmt)
{
	var val, result;

	// Formato		
	if ( IsEmptyString(fmt) )
		return str;
	var result = fmt.match(/\s*([^:]*):([^|]*)\|*([^$]*)/);
	if ( result == null )
		return "?";
	var tipo = result[1].toLowerCase();
	var campi = result[2];
	var opzioni = result[3].toLowerCase();

	// Lettura Opzioni
	
	// lang + separatori decimali e migliaia
	var o_lang = opzioni.match(/\S*lang=([^ ,]*)/);
	var o_dsep = ",";
	var o_tsep = ".";
	if ( o_lang == null )
		o_lang = "it";
	else
	{
		o_lang = o_lang[1];
		if ( o_lang == "en" )
		{
			o_dsep = ",";
			o_tsep = ".";
		}
	}
	// case
	var o_case = opzioni.match(/\S*case=([^ ,]*)/);
	if ( o_case == null )
		o_case = "c";
	else
		o_case = o_case[1];
	// curr
	var o_curr = opzioni.match(/\S*curr=([^ ,]*)/);
	if ( o_curr == null )
		o_curr = "";
	else
		o_curr = o_curr[1];
	
	// Costruzione del risultato
	switch (tipo)
	{
		case "bool":	// Es. "bool:%Y|lang=it"
			val = parseInt(str, 10);
			if ( !isNaN(val) )
				val = val ? 1 : 0;
			else
				val = ( str.search(/^t|v|s|y/i) >= 0 )? 1 : 0;
			// Opzione lang
			if ( o_lang == "en" )
				val += 2;
			result = campi.replace(/%x/, Format_bool_x[val]);
			result = result.replace(/%1/, Format_bool_1[val]);
			result = result.replace(/%t/, Format_bool_t[val]);
			result = result.replace(/%T/, Format_bool_T[val]);
			result = result.replace(/%y/, Format_bool_y[val]);
			result = result.replace(/%Y/, Format_bool_Y[val]);
			// Opzione case
			switch ( o_case )
			{
				case "l": result = result.toLowerCase(); break;
				case "u": result = result.toUpperCase(); break;
			}
			break;
						
		case "dt":
			// Il valore da rappresentare e' in formato fisso:
			//	YYYY-MM-DDThh:mm:ss 
			//	1    2  3  4  5  6
			var val = str.match(/(\d*)-(\d*)-(\d*)T(\d*):(\d*):(\d*)/);			
			if ( val == null )
				return "";
			result = campi.replace(/%Y/, val[1]);
			result = result.replace(/%y/, val[1].slice(-2));
			result = result.replace(/%mm/, Format_month[val[2]-1+(o_lang=="en"?12:0)]);
			result = result.replace(/%m/, val[2]);
			result = result.replace(/%d/, val[3]);			
			result = result.replace(/%H/, val[4]);
			result = result.replace(/%M/, val[5]);
			result = result.replace(/%S/, val[6]);
			// Opzione case
			switch ( o_case )
			{
				case "l": result = result.toLowerCase();
				case "u": result = result.toUpperCase();
			}
			break;

		case "enum":
			// L'elenco si suppone in formato Vs V
			result = GetCollectionList(str, campi == "li");
			break;

		case "int":
			result = str;
			break;
			
		case "dec":
			var nDecimal = parseInt(campi, 10);
			if (isNaN(nDecimal))
				result = str;
			else
				result = Round(str, nDecimal, o_dsep, true);
			break;
		
		default:
			result = "?";
	}		
	return result;
}

// Funzione utilizzata per l'estrazione dei riferimenti al glossario
function GetCollectionList(arg, bList)
{
	if ( arguments.length < 2 ) bList = true;
	
	var HTML = "";
	var l = GetCollectionValue(arg);
	if ( bList )
	{
		for (var i=0; i<l.length; i++)
		{
			if ( Trim(l[i]) != "" )
				HTML += "{_<_}LI{_>_}" + l[i] + "{_<_}/LI{_>_}";
		}
		if (!IsEmpty(HTML))
			HTML = "{_<_}UL{_>_}"+ HTML +"{_<_}/UL{_>_}";
		else
			HTML = "";
	}
	else
	{
		for (var i=0; i<l.length; i++)
		{
			if ( Trim(l[i]) != "" )
			{
				if ( HTML != "" )
					HTML += ", ";
				HTML += l[i];
			}
		}
	}	
	return HTML;
}

// Ritorna un array con i valori della collection
// Se non c'e' nulla ritorna un array con un solo elemento stringa vuota
function GetCollectionValue(arg)
{
	var i, s; 
	if ( !IsEmptyString(arg) )
	{
		s = arg.match(/<Vs>([^$]*)<\/Vs>/g);
		if ( s != null )
		{
			s = arg.split("<!\[CDATA\[");
			if ( s != null )
			{
				if ( s.length > 1 )
				{ 
					s = s.slice(1);
					for (i=0; i<s.length; i++)
						s[i] = s[i].replace(/\]\]>.*/, "");
					return s;
				}
			}
		}
	}
	return [""];
}


/* Text conversion */

function TextToHTML(text)
{
	if (IsEmpty(text)) return "&nbsp;";
	
	var result = "" + text;
	result = result.replace(/&/g, "&amp;");
	result = result.replace(/\s\s/g, " &nbsp;");
	result = result.replace(/"/g, "&quot;");
	result = result.replace(/</g, "&lt;");
	return result.replace(/>/g, "&gt;");
}

function TextToXHTML(text)
{
	var result = "" + text;
		if (result==null) return "";
	// ' vs &apos; non č necessario
	return result.replace(/(&)|(")|(<)|(>)/g, 
	function(c)
	{
		switch (c)
		{
			case "&": return "&amp;";
			case '"': return "&quot;";
			case "<": return "&lt;";
			case ">": return "&gt;";
		}
		return c;
	});
}

function XHTMLToText(text)
{
	var result = "" + text;
		if (result==null) return "";
	return result.replace(/(&amp;)|(&quot;)|(&lt;)|(&gt;)/g, 
	function(c)
	{
		switch (c)
		{
			case "&amp;": return "&";
			case "&quot;": return '"';
			case "&lt;": return "<";
			case "&gt;": return ">";
		}
		return c;
	});
}

/* XML */

function XMLAttributeValue(attr, def){if (arguments.length<2) def = ""; try {return attr.text;} catch(e) {return def}}

function XMLAttributeValueToHTML(attr)
{
	var result;
	try
	{
		result = attr.xml.replace(/[^"]*"/, "");
		result = result.replace(/\"[^$]*/, "");
	} 
	catch(e)
	{
		result = ""
	} 
	if (IsEmpty(result))
		result = "&nbsp;";
	return result;
}

function XMLCreateNode(dom, name, data, attributes)
{
try
{
	var node = dom.createElement(name);
	if (data !== null)
		node.appendChild(dom.createCDATASection(data));
	if (!IsEmpty(attributes))
		for (var i=0; i<attributes.length; i++)
			node.setAttribute(attributes[i][0], attributes[i][1]);
	return node;
}
catch(e)
{
	return null;
}
}

function XMLAppendNode(dom, parentName, childName, data, attributes)
{
try
{
	var parent = dom.selectSingleNode(parentName);
	var node = XMLCreateNode(dom, childName, data, attributes);
	parent.appendChild(node);
	return node;
}
catch(e)
{
	return null;
}
}

function XMLGetNodeText(dom, nodeName, defaultResult)
{
	if (arguments.length<3) defaultResult = null; 
	try
	{
		return dom.selectSingleNode("//"+nodeName).text
	}
	catch(e)
	{
		return defaultResult;
	}
}

function XMLGetAttributeText(node, attrName, defaultResult)
{
	if (arguments.length<3) defaultResult = null; 
	try
	{
		return node.attributes.getNamedItem(attrName).text;
	}
	catch(e)
	{
		return defaultResult;
	}
}

function XMLGetNodeAttributeText(dom, nodeName, attrName, defaultResult)
{
	if (arguments.length<4) defaultResult = null; 
	try
	{		
		return dom.selectSingleNode("//"+nodeName).attributes.getNamedItem(attrName).text;
	}
	catch(e)
	{
		return defaultResult;
	}
}

function XMLEnumString(list, colValue)
{
	if (IsEmpty(colValue)) colValue = null;

	var result = "<Vs>";
	for (i=0; i<list.length; i++)
		result += "<V><![CDATA["+ ((colValue==null) ? list[i] : list[i][colValue]) +"]]></V>";
	result += "</Vs>";
	return result;
}

function XMLEnumValues(enumString)
{
	var result = [];
	var t, s = enumString.split("]]></V>");
	for (var i=0; i<s.length-1; i++)
	{
		t = s[i].split("<![CDATA[");
		if (t.length>1)
			result[result.length] = t[1];
	}
	return result;
}


function ArrayListToRow(arrayList, propList, def)
{
	if (IsEmpty(def)) def = "";

	var result = [];
	var v, row;
	for (var i in arrayList)
	{
		row = [];
		for (var j=0; j<propList.length; j++)
		{
			v = arrayList[i][propList[j]];
			if (v != null)
				row[row.length] = v;
			else
				row[row.length] = def;
		}
		result[result.length] = row.slice(0);
	}
	return result;
}

/* DATETIME */

function StdDateString(y, m, d) { y = "0000"+ y; m = "00"+ m; d = "00"+ d; return y.slice(-4) +"-"+ m.slice(-2) +"-"+ d.slice(-2); }
function StdTimeString(h, m, s) { h = "00"+ h; m = "00"+ m;	s = "00"+ s; return h.slice(-2) +":"+ m.slice(-2) +":"+ s.slice(-2); }
function StdDateTimeString(year, month, day, hour, min, sec) { if (IsEmpty(hour)) hour = 0; if (IsEmpty(min)) min = 0; if (IsEmpty(sec)) sec = 0; return StdDateString(year, month, day) +" "+ StdTimeString(hour, min, sec) }
function DateToStdDateString(date) { return StdDateString(date.getFullYear(), 1+date.getMonth(), date.getDate()) };
function DateToStdTimeString(date) { return StdTimeString(date.getHours(), date.getMinutes(), date.getSeconds()) };
function DateToStdDateTimeString(date) { return StdDateTimeString(date.getFullYear(), 1+date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds()) };
function StdDateTimeObject(stdDateTime_Date, object)
{
	var d = stdDateTime_Date;
	if (IsEmpty(object)) object = new Object();
	if (IsEmpty(d)) 
	{
		object.year = "";
		object.month = "";
		object.day = "";
		object.hour = "";
		object.min = "";
		object.sec = "";
	}
	else
	{		
		if (IsEmpty(d.getDate))
		{
			object.year = d.slice(0,4);
			object.month = d.slice(5,7);
			object.day = d.slice(8,10);
			object.hour = d.slice(11,13);
			object.min = d.slice(14,16);
			object.sec = d.slice(17,19);
		}
		else
		{
			var d = new Date();
			object.year = d.getFullYear();
			object.month = 1+d.getMonth();
			object.day = d.getDate();
			object.hour = d.getHours();
			object.min = d.getMinutes();
			object.sec = d.getSeconds();
		}
	}
	return object;
}

/* OBJECT */

function ObjectClone(obj)
{
	var result = {};
	for (var i in obj)
		result[i] = obj[i];
	return result;
}

function ObjectCompare(partial, complete)
{
	for (var i in partial)
		if (partial[i] != complete[i])
			return false;
	return true;
}

function ObjectSerialize(obj, defObj)
{
	var sep = "";
	var result = "";
	for (var i in obj)
	{		
		if (defObj != null && obj[i] != null && obj[i] == defObj[i])
			continue;
		if (IsObject(obj[i]))
		{
			var sub = ObjectSerialize(obj[i]);
			var defSub = ObjectSerialize(defObj[i]);
			if (sub == defSub)
				continue;
			result += sep + i +':'+ sub;
		}
		else if (parseInt(obj[i]) == obj[i] || parseFloat(obj[i]) == obj[i])
			result += sep + i +':'+ obj[i];
		else
			result += sep + i +':"'+ obj[i] +'"';
		sep = ','
	}
	if (result != "")
		result = "{"+ result +"}";
	return result;
}

function ObjectNormalize(obj, defObj)
{
	try
	{
		if (IsString(obj))
			eval("obj="+obj);
		if (IsEmpty(obj))
			return ObjectClone(defObj);
		for (var i in defObj)
			if (obj[i] == null)
				obj[i] = defObj[i];
		return obj;
	}
	catch(e)
	{
		return defObj;
	}
}


//===========
// CSelection
//===========
function CSelection()
{
	this.all = [];
	this.get = function(id){return this.all[id]};
	this.add = function(id, object)
	{
		if (IsEmpty(id)) return;
		if (object == null) object = true;
		var tmp = id.toString().split(",");
		for (var i=0; i<tmp.length; i++)
			this.all[tmp[i]] = object
	};
	this.del = function(id){delete this.all[id]};
	this.reset = function(id, object){this.all=[]; this.add(id, object)};
	this.serialize = function(emptyDef)
	{
		var result = "";
		for (var i in this.all)
		{
			if (result != "")
				result += ",";
			result += i;
		}
		if (IsEmpty(result))
			result = emptyDef;		
		return result;
	}
}


/* PLACE HOLDER */

function OpenInnerLink(){}
function OpenInnerRef(){}
function OpenExternal(url)
{
    if (url.indexOf("file:") == 0)
    {
        try
        {
        	var fileName = url.replace("file:", "");
        	fileName = fileName.replace(/\\/g, "\\");
            fileEditObj = new ActiveXObject("FileEditCtrl.FileEdit");
            fileEditObj.OpenFile(url);
        }
        catch(e)
        {
            if (e.number == -2146827859)
            {
                // ActiveX can't create object.
                if (!window.confirm("Questa funzionalitą richiede l'installazione di un componente ActiveX.\nProcedere con l'installazione?"))
                    return null;

                // Download del setup.
                window.open("/knos/plugin/FileEditSetup2.msi", "_blank");
            }
            else
                throw e;
        }
    }
	else
		window.open(url, "External").focus()
}
