/*
 * liwe.js
 *
 * Copyright (C) 2006 - OS3 srl - http://www.os3.it
 *
 * Written by: Fabio Rotondo - fabio.rotondo@os3.it
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation;
 * version 2 of the License ONLY.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this software; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * NOTE: this is the GPL version of the library. If you want to include this 
 *       library inside a CLOSED SOURCE / PROPRIETARY software, you need 
 *       to purchase a COMMERCIAL LICENSE. See http://www.os3.it/license/
 *       for more info.
 */

/*
 *	2009-03-06:	- $() and $v() are now here and not in utils.js
 *			- $() now can have a second optional argument to set the innerHTML.
 */

// PUBLIC: liwe
var liwe = {};
liwe.utils = {};
liwe.fx = {};

// Library base
liwe._libbase = "";

liwe.ajax_url = "/ajax.php";

// Try to be compatible with other browsers
// Only use firebug logging when available
// (this code is a modified version of firebugx.js, written
// by Joe Hewitt)
if ( ! window [ "console" ] ) window.console = {};

try
{
	liwe._console = window.console [ "debug" ];
} catch ( e ) {
	window.console = {};
	liwe._console = null;
}

if ( ! liwe._console )
{
	var names = [ "log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", 
		      "timeEnd", "count", "trace", "profile", "profileEnd" ];

	for ( var i = 0; i < names.length; ++i )
		window.console [ names [ i ] ] = function() {};
}

liwe.set_libbase = function ( libbase_url )
{
	if ( libbase_url )
	{
		liwe._libbase = libbase_url;
		return;
	}

	var scripts = document.getElementsByTagName ( "script" );
	var l = scripts.length;
	var t, s, pos, path = "";

	for ( t = 0; t < l; t ++ )
	{
		s = scripts [ t ].src;

		if ( ! s ) continue;

		if ( s.match ( /liwe.*js/ ) )
		{
			s = s.replace ( /.*os3phplib.send_gzip.php.fname=/, "" );
			pos = s.lastIndexOf ( "/" );
			if ( pos != -1 ) path = s.slice ( 0, pos + 1 );
		}
	}

	if ( path ) liwe._libbase = path;
	else liwe._libbase = "/os3jslib";
};

liwe.set_libbase ();

// =============================================================================
// UTILS
// =============================================================================
liwe.utils.WAIT_TIMEOUT = 2000; // Milli seconds
liwe.utils.WAIT_TIME = 50; // Milli seconds

liwe.utils.wait_def = function ( name, cback, vars, time )
{
	if ( ! liwe.utils.is_def ( name ) ) 
	{
		if ( ! time ) time = 0;
		if ( time > liwe.utils.WAIT_TIMEOUT )
		{
			alert ( "Failed: " + name );
			return;
		}

		setTimeout ( function () { liwe.utils.wait_def ( name, cback, vars, time + liwe.utils.WAIT_TIME ); }, liwe.utils.WAIT_TIME );
        } else {
		if ( typeof ( cback ) != 'object' ) cback ( vars );
	}
};

liwe.utils.append_js = function ( script_file )
{
        var head = document.getElementsByTagName ( "head" ) [ 0 ];
        var new_script = document.createElement ( "script" );

        new_script.src = script_file;
        new_script.type = "text/javascript";
        head.appendChild ( new_script );
};


liwe.utils.is_def = function ( name )
{
	var is_def = false;

	if ( typeof name == "string" )
	{
		var items = name.split ( "." );
		var l = items.length;
		var s = '';

		s = items [ 0 ];

		for ( t = 0; t < l; t ++ )
		{
			// console.debug ( "Check for: " + s );
			eval ( "is_def = ( typeof ( " + s + " ) != 'undefined' );" );
			if ( ! is_def ) return false;
			if ( ! items [ t + 1 ] ) break;

			s += "." + items [ t + 1 ];
		}
		return true;
	}

	var t, l = name.length;
	var n;

	for ( t = 0; t < l; t ++ )
	{
		n = name [ t ];
		eval ( "is_def = ( typeof ( " + n + " ) != 'undefined' );" );

		if ( ! is_def ) return false;
	}

	return true;
};

liwe.browser = {};

liwe.browser.version = navigator.appVersion;
liwe.browser.has_dom = document.getElementById ? 1 : 0;
liwe.browser.ie = ( window.ActiveXObject != null );
liwe.browser.gecko = ( navigator.userAgent.toLowerCase().indexOf ( "gecko" ) != -1 ) ? 1 : 0;
liwe.browser.opera = ( navigator.userAgent.toLowerCase().indexOf ( "opera" ) != -1 ) ? 1 : 0;

// =============================================================================
// POSTLOADER
// =============================================================================

liwe.postload = {};

// The time (in millis) before a specified file is timedout
liwe.postload.WAIT_TIMEOUT = 30000; // 30 seconds (time is in millis)

// Millis to check for a specified file
liwe.postload.WAIT_TIME = 50; // 50 milli seconds
liwe.postload.events = {};

// This event is fired when a SINGLE SCRIPT has been loaded
// cback: script_loaded ( script_name )
liwe.postload.events [ 'script_load' ] = null;	

// This event is fired whenever PostLoader thinks it is good to
// update your load status info
// cback: script_update ( items_loaded, tot_items )
liwe.postload.events [ 'update' ] = null;

// This event is fired when PostLoader has finished to load
// ALL scripts defined.
// cback: script_completed ()
liwe.postload.events [ 'completed' ] = null;

/* FILES fields values:
#
#	0 - priority
#	1 - file name
#	2 - check_for
#	3 - cback
#	4 - vars
#	5 - is loaded
*/
liwe.postload._files = [];
liwe.postload._loaded_files = 0;

liwe.postload.add = function ( fname, check_for, pri, cback, vars )
{
	if ( ! pri ) pri = 1;

	if ( liwe.utils.is_def ( check_for ) ) return;

	liwe.postload._files.push ( [ pri, fname, check_for, cback, vars, 0 ] );
};

liwe.postload.load = function ()
{
	var t, l, itm;

	liwe.postload._files.sort ();

	l = liwe.postload._files.length;

	// keep count of loaded files
	liwe.postload._loaded_files = 0;

	for ( t = 0; t < l; t ++ )
	{
		itm = liwe.postload._files [ t ];
		// Files already in memory are skipped
		if ( itm [ 5 ] ) liwe.postload._loaded ( t ); 

		liwe.utils.append_js ( itm [ 1 ] );
		liwe.utils.wait_def ( itm [ 2 ], liwe.postload._loaded, t );
	}
};

liwe.postload._loaded = function ( pos )
{
	liwe.postload._loaded_files += 1;

	var itm = liwe.postload._files [ pos ];

	itm [ 5 ] = 1;

	if ( liwe.postload.events [ 'script_loaded' ] )
		liwe.postload.events [ 'script_loaded' ] ( itm [ 1 ] );

	if ( itm [ 3 ] ) itm [ 3 ] ( itm [ 4 ] );

	if ( liwe.postload.events [ 'update' ] )
		liwe.postload.events [ 'update' ] ( liwe.postload._loaded_files, liwe.postload._files.length );

	if ( ! ( liwe.postload._files.length - liwe.postload._loaded_files ) )
		if ( liwe.postload.events [ 'completed' ] ) liwe.postload.events [ 'completed' ] ();
};


liwe._clear_dom = function ( e )
{
	var i, l = e.childNodes.length;
	for ( i = 0; i < l; i ++ )
	{
		var el = e.childNodes [ i ];

		//PULIZIA
		var v;
		for ( v in el )
		{
			if ( v.charAt ( 0 ) != "_" ) continue;

			console.debug ( v );

			if ( v == "_listeners" )
			{
				var listeners = [].concat ( el [ v ] );
				var vi, vl = listeners.length;
				for ( vi = 0; vi < vl; vi ++ )
				{
					var lid = listeners [ vi ];
					var rec = _all [ lid ];
					if ( rec ) liwe.events.del ( rec.target, rec.type, rec.listener );
				}
			}

			try
			{
				el [ v ] = null;
			}
			catch (e)
			{
			}
		} 

		liwe._clear_dom ( el );
	}
};


function $ ( name, inner_html )
{
	var e = document.getElementById ( name );

	if ( ! e ) return null;

	if ( typeof inner_html == "undefined" )
		return e;

	// liwe._clear_dom ( e );

	e.innerHTML = inner_html;
	return e;
}

function $v ( name, def_val )
{
	var d = document.getElementById ( name );
	if ( ! d ) return def_val;

	return d.value;
}



/*
 * ajax_manager.js
 *
 * Copyright (C) 2006 - OS3 srl - http://www.os3.it
 *
 * Written by: Fabio Rotondo - fabio.rotondo@os3.it
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation;
 * version 2 of the License ONLY.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this software; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * NOTE: this is the GPL version of the library. If you want to include this 
 *       library inside a CLOSED SOURCE / PROPRIETARY software, you need 
 *       to purchase a COMMERCIAL LICENSE. See http://www.os3.it/license/
 *       for more info.
 *
 *       2009-01-24:	ADD: this.cbacks for:
 *
 *       			- serialize	serialize data
 *       			- req-start	request start
 *       			- req-end	request end
 *       			- req-error	request error
 *
 *       		ENH: AJAX Manager is now more "liwe"ized
 *       		ENH: removed String and Array enhancement dependencies
 *
 *       		DEP: error_handler has been DEPRECATED
 *       		DEP: start_req_handler has been DEPRECATED
 *       		DEP: end_req_handler has been DEPRECATED
 *
 */

// PUBLIC: ajax_response

// PUBLIC: AJAXManager
// PUBLIC  easy
// PUBLIC: request
function AJAXManager ()
{
	this._reqs = [];
	this._in_list = 0;
	this._in_abort = false;

	this.url = liwe.ajax_url;

	this.cbacks = {	"serialize" : null, 
			"req-start" : null, 
			"req-end" : null, 
			"req-error" : null 
		      };

	// {{{ request ( url, vars, callback, easy, sync )
	this.request = function ( url, vars, callback, easy, sync ) 
	{
		var req = null;
		var id = '';
		var t;
		var res = '';
		var self = this;
		var s;

		if ( ! url ) url = this.url;

		if ( vars ) 
		{
			for ( t in vars ) 
			{
				if ( typeof ( vars [ t ] ) == 'undefined' ) continue;
				if ( typeof ( vars [ t ] ) == 'function' ) continue;
				if ( ( typeof ( vars [ t ] ) == 'object' ) && ( vars [ t ] == null ) ) continue;

				/*
					This is a hack for IE, since it considers functions as objects (!!!)
				*/
				if ( typeof ( vars [ t ] ) == 'object' )
				{
					s = vars [ t ].toString ();
					if ( s.match ( /^function/ ) ) continue;
				}

				if ( vars [ t ] == '__arr' ) continue;

				if ( ( typeof ( vars [ t ] ) == 'string' ) || ( typeof ( vars [ t ] ) == 'number' ) )
				{
					res += t + "=" + this._ajax_escape ( vars [ t ] ) + "&";
				} else {
					try 
					{
						res += t + "=" + this._ajax_escape ( vars [ t ].toJSONString() ) + "&";
					} catch ( e ) {
						res += t + "=" + this._ajax_escape ( vars [ t ] ) + "&";
					}
				}
			}

			res = res.substr ( 0, res.length - 1 ); //  + "&";
		}

		req = this._build_req_obj ();


		// The request callback
		var _obj = this;
		if ( this.error_handler )
		{
			console.warn ( "AJAXManager.error_handler is DEPRECATED. Use cbacks [ 'req-error' ] instead." );
			req.onreadystatechange = function () { _obj._req_change ( req, callback, easy, _obj.error_handler ); };
		} else
			req.onreadystatechange = function () { _obj._req_change ( req, callback, easy, _obj.cbacks [ 'req-error' ] ); };

		var async = true;
		if ( sync ) async = false;

		// if (erroneously) the url starts with two "//", Firefox throws a security error
		url = url.replace ( /^\/\//g, "/" );

		req.open ( "POST", url, async );
		req.setRequestHeader ( 'Content-Type', 'application/x-www-form-urlencoded' );
		req.send ( res );

		if ( easy )
		{
			if ( this.start_req_handler ) 
			{
				console.warn ( "AJAXManager.start_req_handler is DEPRECATED. Use cbacks [ 'req-start' ] instead." );
				this.start_req_handler ( req );
			}

			if ( this.cbacks [ 'req-start' ] ) this.cbacks [ 'req-start' ] ( req );
		}
	};
	// }}}
	// {{{ easy ( arr, cback )
	this.easy    = function ( arr, cback ) { this.request ( null, arr, cback, true ); };
	// }}}
	// {{{ _build_req_obj ()
	this._build_req_obj = function ()
	{
		var req;

		/*@cc_on @*/
		/*@if (@_jscript_version >= 5)
		try {
			req = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e) {
			try {
				req = new ActiveXObject("Microsoft.XMLHTTP");
			} catch ( E ) {
				req = false;
			}
		}
		@end @*/

		if ( ! req && typeof XMLHttpRequest != 'undefined' ) 
		{
			try {
				req = new XMLHttpRequest();
			} catch (e) {
				req=false;
			}
		}

		if ( ! req && window.createRequest ) 
		{
			try {
				req = window.createRequest();
			} catch (e) {
				req=false;
			}
		}

		/*
		if ( window.XMLHttpRequest )		// Mozilla, Safari, Konqueror, Netscape...
		{
			req = new XMLHttpRequest ();
		} else {
			try {
				req = new ActiveXObject("Msxml2.XMLHTTP");
			} catch(e) {
				try {
					req = new ActiveXObject("Microsoft.XMLHTTP");
				} catch ( e ) {
					req = null;
					console.error ( "XMLHTTP Request object not available." );
				}
			}
		}

		*/

		this._reqs.push ( req );

		return req;
	};
	// }}}
	// {{{ _req_change ( req, callback, easy, err_handler )
	this._req_change = function ( req, callback, easy, err_handler )
	{
		if ( ! easy ) 
		{
			if ( callback ) callback ( req );
		} else {
			var in_abort = this._in_abort;

			// Remove the req from the Request Pool
			if ( req.readyState == 4 ) 
			{
				if ( this.end_req_handler ) 
				{
					console.warn ( "AJAXManager.end_req_handler is DEPRECATED. Use cbacks [ 'req-end' ] instead." );
					this.end_req_handler ( req );
				}

				if ( this.cbacks [ 'req-end' ] ) this.cbacks [ 'req-end' ] ( req );


				this._remove_req ( req );

				if ( in_abort ) return;

				var resp_txt = req.responseText.replace ( /^\s+/, "" );

				if ( resp_txt.substr ( 0, "var ajax".length ) == 'var ajax' )
				{
					try {
						eval ( resp_txt );
						if ( ajax_response [ 'err_code' ] )
						{
							if ( ! err_handler )
							{
								if ( ajax_response [ 'err_descr' ] )
								{
									console.error ( ajax_response [ 'err_descr' ] );
									alert ( ajax_response [ 'err_descr' ] );
								
								} else {
									console.error ( "Generic Request error. Error code: " + ajax_response [ 'err_code' ] );
								}
							} else
								err_handler ( ajax_response );

							return;
						}
					} catch ( e ) {
						console.error ( "ERROR IN EVAL: " + req.responseText );
						return;
					}

					if ( callback && typeof ( callback ) == 'function' ) callback ( ajax_response );
				} else
					console.error ( "Request ERROR: " + req.responseText );
			}
		}
	};
	// }}}

	this.error_handler = null;		// DEPRECATED
	this.start_req_handler = null;		// DEPRECATED
	this.end_req_handler = null;		// DEPRECATED

	// {{{ _remove_req ( req )
	this._remove_req = function ( req )
	{
		var t, l = this._reqs.length;

		if ( this._in_list ) 
		{
			var obj = this;

			setTimeout ( function () { obj._remove_req ( req ); }, 100 );
			return;
		}

		this._in_list = 1;

		for ( t = 0; t < l; t ++ )
		{
			if ( this._reqs [ t ] == req ) break;
		}
		if ( t < l )
			this._reqs.splice ( t, 1 );

		this._in_list = 0;
	};
	// }}}
	// {{{ abort ( cback )
	this.abort = function ( cback )
	{
		var t, l = this._reqs.length;

		if ( this._in_list ) 
		{
			var obj = this;

			//console.debug ( "In list: " + this._in_list );
			setTimeout ( function () { obj.abort (); }, 100 );
			return;
		}

		this._in_list = 2;
		this._in_abort = true;

		for ( t = 0; t < l; t ++ )
		{
			try
			{
				this._reqs [ t ].abort ();
			} catch ( e ) {
			}
		}

		this._in_abort = false;
		this._in_list = 0;

		if ( cback ) cback ();
	};
	// }}}
	
	this._ajax_escape = function ( s )
	{
		if ( this.cbacks [ 'serialize' ] )
			s = this.cbacks [ 'serialize' ] ( s );

		s = escape ( s );
		s = s.replace ( /\+/g, "%2B" );
		return s;
	};
}

liwe.AJAX = new AJAXManager ();

liwe.AJAX._multi = {};
liwe.AJAX._multi_data = {};

liwe.AJAX.add = function ( name, action, dict, cback )
{
	var multi;
	var data;

	if ( ! name   ) name = "AJAX";
	if ( ! action ) action = null;


	multi = this._multi [ name ];
	if ( ! multi ) 
	{
		multi = [];
		data  = {};
	} else {
		data = this._multi_data [ name ];
	}

	if ( data [ 'running' ] ) 
	{
		console.error ( "Requests are already running for: %s", name );
		return;
	}

	multi.push ( [ action, dict, cback ] );
	this._multi [ name ] = multi;
	this._multi_data [ name ] = data;

	console.debug ( "Multi: %s - Len: %d", name, multi.length );
};

liwe.AJAX.start = function ( name, cback )
{
	var multi, data, t, l, req, func;

	multi = this._multi [ name ];
	if ( ! multi ) 
	{
		console.error ( "There is no multi group called: %s", name );
		return;
	}

	data = this._multi_data [ name ];
	data [ 'running' ] = true;
	data [ 'len' ] = multi.length;
	data [ 'count' ] = 0;

	l = multi.length;
	var i;
	for ( t = 0; t < l; t ++ )
	{
		req = multi [ t ];

		liwe.AJAX._send ( name, req, cback );
	}
};

liwe.AJAX._send = function ( name, req, cback ) 
{
	this.request ( req [ 0 ], req [ 1 ], function ( v ) { liwe.AJAX._req_cback ( name, v, req, cback ); }, true );
};

liwe.AJAX._req_cback = function ( name, v, req, cback )
{
	var multi = liwe.AJAX._multi [ name ];
	var data = liwe.AJAX._multi_data [ name ];

	if ( req [ 2 ] ) req [ 2 ] ( v );
	

	data [ 'count' ] += 1;

	if ( data [ 'count' ] == data [ 'len' ] ) 
	{
		if ( cback ) cback ();
		liwe.AJAX._multi [ name ] = null;
		liwe.AJAX._multi_data [ name ] = null;
	}
};


/*
 * array_enh.js
 *
 * Copyright (C) 2006 - OS3 srl - http://www.os3.it
 *
 * Written by: Fabio Rotondo - fabio.rotondo@os3.it
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation;
 * version 2 of the License ONLY.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this software; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * NOTE: this is the GPL version of the library. If you want to include this 
 *       library inside a CLOSED SOURCE / PROPRIETARY software, you need 
 *       to purchase a COMMERCIAL LICENSE. See http://www.os3.it/license/
 *       for more info.
 */
// PUBLIC: toSourceString
Array.prototype.toSourceString = function ( include_funcs )
{
	var s = '{';
	var k, v;
	var is_first = true;

	for ( k in this )
	{
		if ( ( typeof ( this [ k ] ) == 'function' ) && ( ! include_funcs ) ) continue;

		if ( ! is_first ) s += ", ";
		s += "'" + k + "' : '" + this [ k ] + "'";
		is_first = false;
	}

	s += "}";

	return s;
};

// PUBLIC: count
Array.prototype.count = function ()
{
	var k;
	var res = 0;
	
	for ( k in this )
	{
		if ( ( typeof ( this [ k ] ) == 'function' ) ) continue;
		if ( k == '__arr' ) continue;
		res ++;
	}

	return res;
};

// PUBLIC: fromObject
Array.fromObject = function ( a, include_funcs )
{
	var arr = new Array ();
	var k, v;

	for ( k in a ) 
	{
		if ( ( ! include_funcs ) && ( typeof ( a [ k ] ) == 'function' ) ) continue;

		arr [ k ] = a [ k ];
	}

	return arr;
};

// PUBLIC: fromForm
Array.fromForm = function ( form_id, max_depth )
{
	var arr = new Array ();
	var f = document.getElementById ( form_id );
	
	if ( ! max_depth ) max_depth = 0;

	_form_add_elems ( f, arr, max_depth, 0 );

	return arr;
};

// PUBLIC: find
Array.prototype.find = function ( key, case_sens, include_funcs )
{
	var k;
	var c = 0;

	if ( ! case_sens ) key = key.toLowerCase ();

	for ( k in this )
	{
		if ( ( typeof ( this [ k ] ) == 'function' ) && ( ! include_funcs ) ) continue;

		k = this [ k ];
		if ( ! case_sens ) k = k.toLowerCase ();
		if ( k == key ) return c;
			
		c++;
	}

	return -1;
};

// PUBLIC: toObject
Array.toObject = function ( arr )
{
	var res = {};
	var k;

	for ( k in arr )
	{
		if ( ( typeof ( arr [ k ] ) == 'function' ) ) continue;
		
		res [ k ] = arr [ k ];
	}

	return res;
};

// PUBLIC: del
Array.prototype.del = function ( pos, how_many )
{
	if ( ! how_many ) how_many = 1;

	var to_del = Array();

	var start = pos;
	var stop = pos + how_many;

	var k, count = -1, i;
	for ( k in this )
	{
		count++;

		if ( count < start ) 	  continue;
		else if ( count >= stop ) break;

		to_del.push ( k );
	}

	for ( i = 0; i < to_del.length; i++ )
	{
		delete this [ to_del [ i ] ];
	}
};

// PUBLIC: delKey
Array.prototype.delKey = function ( k )
{
	delete this [ k ];
};


if ( Array.prototype.indexOf == null )
{
	Array.prototype.indexOf = function ( item )
	{
		var t, l = this.length;
		for ( t = 0; t < l; t ++ )
			if ( this [ t ] == item ) return t;
		return -1;
	};
}


function _form_add_elems( node, arr, max_depth, curr_depth )
{
	var inps, sels, txts, t, n;

	inps = node.getElementsByTagName ( "input" );
	sels = node.getElementsByTagName ( "select" );
	txts = node.getElementsByTagName ( "textarea" );

	for ( t = 0; t < inps.length; t ++ )
	{
		n = inps [ t ];
		if ( ( ( n.type == 'radio' ) || ( n.type == 'checkbox' ) ) && ( n.checked == false ) ) continue;
		arr [ n.name ] = n.value;
	}

	for ( t = 0; t < sels.length; t ++ ) arr [ sels [ t ].name ] = sels [ t ].value;
	for ( t = 0; t < txts.length; t ++ ) arr [ txts [ t ].name ] = txts [ t ].value;
}


/* Implement array.push for browsers which don't support it natively. 
   Copyright 2005 Mark Wubben 
*/
if ( Array.prototype.push == null )
{
	Array.prototype.push = function() 
	{
		for( var i = 0; i < arguments.length; i++ )
			this [ this.length ] = arguments [ i ];

		return this.length;
	};
}



/*
 * string_enh.js
 *
 * Copyright (C) 2006 - OS3 srl - http://www.os3.it
 *
 * Written by: Fabio Rotondo - fabio.rotondo@os3.it
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation;
 * version 2 of the License ONLY.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this software; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * NOTE: this is the GPL version of the library. If you want to include this 
 *       library inside a CLOSED SOURCE / PROPRIETARY software, you need 
 *       to purchase a COMMERCIAL LICENSE. See http://www.os3.it/license/
 *       for more info.
 *
 *  2009-01-14:	Added the String.buffer class
 */

// PUBLIC: startsWith
String.prototype.startsWith = function ( str )
{
	if ( this.substr ( 0, str.length ) == str ) return ( true );
	
	return ( false );
};

// PUBLIC: endsWith
String.prototype.endsWith = function ( str )
{
	if ( this.substr ( this.length - str.length ) == str ) return ( true );
	
	return ( false );
};

// PUBLIC: buffer
String.buffer = function ()
{
	this._buf = [];

	this.add = function ( str )
	{
		this._buf.push ( str );
		return this;
	};

	this.get = function ( sep )
	{
		if ( ! sep ) sep = "";

		return this._buf.join ( sep );
	};

	this.toString = function () { return this.get ( "" ); };
};

String._re_htmlentities_invalid = /([^a-zA-Z0-9,.:!?+\/_ |@\n()-])/g;
String.prototype.htmlEntities = function ()
{
        function _ch ( m )
        {
                return ( "&#" + m.charCodeAt ( 0 ) + ";" );
        }

        return this.replace ( String._re_htmlentities_invalid, _ch );
};


// PUBLIC: join
String.prototype.join = function ( arr )
{
	var l = arr.length;
	var k, t;
	var s = '';
	var is_first = true;

	for ( t = 0; t < l; t ++ )
	{
		if ( typeof ( arr [ t ] ) == 'function' ) continue;
		if ( ! is_first ) s += this;
		s += arr [ t ];
		is_first = false;
	}

	return s;
};

// PUBLIC: LStrip
String.prototype.LStrip = function ()
{
	return this.replace ( /^\s+/, "" );
};

// PUBLIC: RStrip
String.prototype.RStrip = function ()
{
	return this.replace ( /\s+$/, "" );
};

// PUBLIC: Strip
String.prototype.Strip = function () { return this.replace ( /^\s+|\s+$/,"" ); };

// PUBLIC: isUpper
String.prototype.isUpper = function () 
{
	var l = this.length;
	var c, t;

	if ( ! l ) return false;

	for ( t = 0; t < l; t ++ )
	{
		c = this [ t ].toUpperCase ();
		if ( c != this [ t ] ) return false;
	}

	return true;
	
};

// PUBLIC: isLower
String.prototype.isLower =  function () 
{
	var l = this.length;
	var c, t;

	if ( ! l ) return false;

	for ( t = 0; t < l; t ++ )
	{
		c = this [ t ].toLowerCase ();
		if ( c != this [ t ] ) return false;
	}

	return true;
	
};

String.basename = function ( s, sep )
{
	if ( ! sep ) sep = "/";

	return s.split ( sep ).slice ( -1 );
};

String.dirname = function ( s, sep )
{
	if ( ! sep ) sep = "/";

	return sep.join ( ( s.split ( sep ) ).slice ( 0, -1 ) );
};

// PUBLIC: format
String.format = function ()
{
	function re_replace ( v )
	{
		var m = v.match ( _re_replace );
		var val = args [ ++count ];

		return _string_re_replace ( m, val );
	}

	var _re_replace = /%([0+#-]*)([0-9]*)(\.{0,1})([0-9]*)([dsqm])/;
	var re = /%[0+#-]*[0-9]*\.{0,1}[0-9]*[dsqm]/gi;
	var fmt = arguments [ 0 ];	// The first param is the string format
	var count = 0;
	var args = arguments;

	return fmt.replace ( re, re_replace );
};

// PUBLIC: formatDict
String.formatDict = function ( fmt, dict )
{
	function re_replace ( v )
	{
		var m = v.match ( _re_replace );
		var val = dict [ m [ 1 ] ];
		var p1 = m.shift ();

		m.shift ();
		m.unshift ( p1 );
		return _string_re_replace ( m, val );
	}

	var _re_replace = /%\(([^)]*)\)([0+#-]*)([0-9]*)(\.{0,1})([0-9]*)([dsqm])/;
	var re = /%\([a-z0-9_-]+\)[0+#-]?[0-9]*\.?[0-9]*[dsqm]/gi;

	if ( fmt == "" ) return "";

	if ( ! fmt )
	{
		console.warn ( "No FMT for the following dict (from: %s)", arguments.caller );
		console.warn ( dict );

		return "";

		// fmt = "";
	}
	
	return fmt.replace ( re, re_replace );
};

function _string_re_replace ( matches,  value )
{
	var flags = matches [ 1 ];
	var width = ( matches [ 2 ] ? parseInt ( matches [ 2 ] ) : 0 );
	var precision = ( matches [ 4 ] ? parseInt ( matches [ 4 ] ) : 0 );
	var type = matches [ 5 ];
	var res = '';
	var pad_char = ' ';
	var pad_left = false;
	var show_sign = false;

	if ( flags.indexOf ( '-' ) >= 0 ) pad_left = true;
	if ( flags.indexOf ( '0' ) >= 0 ) pad_char = '0';
	if ( flags.indexOf ( '+' ) >= 0 ) show_sign = true;

	if ( pad_char == '0' && pad_left ) pad_char = ' ';

	switch ( type )
	{
		case 'm':	// Money
			if ( typeof ( Money ) != 'undefined' )
			{
				res = Money.fromLongInt ( value );
			} else
				res = value;

			break;
			
		case 'd':
			res  = _string_mkpad ( true, value, precision, width, pad_char, false, pad_left, show_sign );
			break;

		case 'q':
			value = value.replace ( /'/g, "\\'" );
			// Non mettere break, deve finire al case 's'

		case 's':
			res  = _string_mkpad ( false, value, precision, width, pad_char, true, pad_left, false );
			break;
	}

	return res;
}

function _string_mkpad ( is_num, v, prec, width, pad_char, trunc, pad_left, show_sign )
{
	var sign = '';

	if ( is_num )
	{
		v = parseInt ( v );
		if ( v < 0 ) sign = '-';
		else if ( show_sign ) sign = '+';

		v = Math.abs ( v );
	}

	v = String ( v );

	if ( ! width && ! prec ) return v;

	var len, t, i;

	if ( is_num )
	{
		len = prec - v.length;
		if ( len > 0 ) for ( t = 0; t < len; t ++ ) v = "0" + v;
	}

	v = sign + v;

	len = width - v.length;
	if ( len > 0 )
	{
		for ( t = 0; t < len; t ++ )
			v = ( pad_left ? v + pad_char : pad_char + v );
	}

	if ( ! is_num && prec )
	{
		return v.slice ( 0, prec );
	}

	return  v;
}



var footer = {};

footer.btn = {
	'credits':   '<a class="footer_btn" href="javascript:footer.credits()">Credits<\/a>',
	'copyright': '<a class="footer_btn" href="javascript:footer.copyright()">Copyright<\/a>',
	'up': 	     '<a class="footer_btn" href="javascript:footer.to_up()">Torna su <img src="gfx/freccia_su.gif" alt="Torna su" title="Torna su" border="0"/><\/a>'
};

footer.to_up = function ()
{
	window.scrollTo ( 0, 0 );
};

footer.render = function ( credits, copyright, up )
{
	var s = '';
	var cnt = document.getElementById ( 'footer' );

	if ( credits )
		s += footer.btn [ 'credits' ];

	if ( copyright )
		s += footer.btn [ 'copyright' ];

	if ( up ) 
		s += footer.btn [ 'up' ];


	if ( cnt )
		cnt.innerHTML = s;
};

footer.credits = function ()
{
	alert( 'Credits' );
};

footer.copyright = function ()
{
	alert( 'Copyright');
};



