var banner = {};

banner.timeout_banner = function ( dest, container, timeout )
{
	// Blocca la query del banner se il div dest non esiste.
	// FIXME: ci vuole una funzione per far ripartire il tutto non
	// 	  appena il div "riappare" (es. navigazione)
	if ( ! $( dest ) ) return;

	setTimeout ( function ()
	{
		liwe.AJAX.easy ( { action: "banner.ajax.banner_fetch", container: container }, function ( v )
		{
			var b = v [ "banner" ];
			var media = b [ "media" ];
			var html = String.formatDict ( media [ "html" ], { _size: "orig", _ext: media [ 'ext' ] } );

			$ ( dest, html );

			if ( b [ "view_time" ] ) banner.timeout_banner ( dest, container, b [ "view_time" ] );
		} );
	}, timeout * 1000 );
};

banner.templates = {};
/*
 * 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-04-16:	- Added the ``strong_debug`` flag to the liwe base class (default to ``false``).
 *
 *
 *	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 = {};

liwe.strong_debug = false;

// 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 )
		{
			if ( liwe.strong_debug ) 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;
	var l;

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

		s = items [ 0 ];
		l = items.length;

		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;
	var n;

	l = name.length;

	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 = ( typeof window [ "ActiveXObject" ] != "undefined" ); //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, warn )
{
	var e = document.getElementById ( name );

	if ( ! e ) 
	{
		if ( warn ) console.warn ( "Element: %s not found", name );
		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;
}

/*
 * dom.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-09-07:	Added the $c() function is like a getAllElementsByClassName ( element, class_name, [ starting_container == document ] )
 */

liwe.dom = {};

// PUBLIC: get_offset_top
liwe.dom.get_offset_top = function ( elm )
{
  	var o_top    = elm.offsetTop;
  	var o_parent = elm.offsetParent;

  	while ( o_parent && o_parent.tagName != "HTML" )
	{
		// if ( o_parent.style.position == 'absolute' ) return o_top;
    		o_top += o_parent.offsetTop;
    		o_parent = o_parent.offsetParent;
  	}
 
  	return o_top;
};

// PUBLIC: get_offset_left
liwe.dom.get_offset_left = function ( elm )  
{
	var o_left = elm.offsetLeft;
  	var o_parent = elm.offsetParent;

  	while ( o_parent )
	{
		// if ( o_parent.style.position == 'absolute' ) return o_left;
		// console.debug ( "parent: %o - o_parent: %s - left: %s", o_parent, o_parent.offsetParent, o_left );
		// if ( ! o_parent.offsetParent.offsetParent ) break;
    		o_left += o_parent.offsetLeft;
    		o_parent = o_parent.offsetParent;
  	}
 
  	return o_left;
};

// PUBLIC: append_css
liwe.dom.append_css = function ( css_file, id, as_first )
{
	var head = document.getElementsByTagName ( "head" ) [ 0 ];
	var new_css = document.createElement ( "link" );

	new_css.href = css_file;
	new_css.type = "text/css";
	new_css.rel  = "stylesheet";
	if ( id ) new_css.id = id;

	if ( as_first )
		head.insertBefore ( new_css, head.firstChild );
	else
		head.appendChild ( new_css );
};


// PUBLIC: get_padding_width
liwe.dom.get_padding_width = function ( el )
{
	var oldw = el.clientWidth;
	var neww;

	el.style.width = "0px";
	neww = el.clientWidth;

	el.style.width = ( oldw - neww ) + "px";

	return neww;
};

// PUBLIC: get_padding_height
liwe.dom.get_padding_height = function ( el )
{
	var oldh = el.clientHeight;
	var newh;

	el.style.height = "0px";
	newh = el.clientHeight;

	el.style.height = ( oldh - newh ) + "px";

	return newh;
};

liwe.dom.get_size = function ( el )
{
	return [ el.clientWidth, el.clientHeight ];
};

// PUBLIC: os3_get_window_size
liwe.dom.get_window_size = function ()
{
	var s = document.createElement ( "div" );
	s.style.position = "absolute";
	s.style.bottom = "0px";
	s.style.right  = "0px";
	s.style.width  = "1px";
	s.style.height  = "1px";
	s.style.visibility = "hidden";
	document.body.appendChild ( s );

	var w, h;
	w = os3_get_offset_left ( s ) + s.clientWidth;
	h = os3_get_offset_top ( s ) + s.clientHeight;

	document.body.removeChild ( s );

	return { "width": w, "height": h };
};

// PUBLIC: create_element
liwe.dom.create_element = function ( tag, name, parent )
{
	if ( ! parent ) parent = document.body;

	// if ( document.ActiveXObject ) tag = '<' + tag + ' name="' + name + '">';
	if ( document.all ) tag = '<' + tag + ' name="' + name + '">';

	var e = document.createElement ( tag );
	e.style.position = 'absolute';
	e.style.top = "0px";
	e.style.right = "0px";
	e.id = name;
	e.name = name;
	parent.appendChild ( e );
	
	return e;
};

liwe.dom.remove_element = function ( e, parent )
{
	if ( ! parent ) parent = document.body;

	parent.removeChild ( e );
};

liwe.dom.get_event_pos = function ( e )
{
	var posx = 0, posy = 0;

	if ( e == null ) e = window.event;
	if ( e.pageX || e.pageY )
	{
		posx = e.pageX; 
		posy = e.pageY;
	} else if ( e.clientX || e.clientY ) {
	 	if ( document.documentElement.scrollTop )
		{
	 		posx = e.clientX + document.documentElement.scrollLeft;
	 		posy = e.clientY + document.documentElement.scrollTop;
	 	} else {
	 		posx = e.clientX + document.body.scrollLeft;
	 		posy = e.clientY + document.body.scrollTop;
	 	}
	 }

	return [ posx, posy ];
};

liwe.dom.has_class = function ( el, class_name )
{
	var pattern = new RegExp ( "(^| )" + class_name + "( |$)" );

	if ( pattern.test ( el.className ) ) return true;

	return false;
};

liwe.dom.add_class = function ( target, class_name )
{
	if ( liwe.dom.has_class ( target, class_name ) ) return;

	if ( target.className == "" ) 
		target.className = class_name;
	else
		target.className += " " + class_name;
};

liwe.dom.del_class = function ( target, class_name )
{
	var pattern = new RegExp ( "(^| )" + class_name + "( |$)" );

	target.className = target.className.replace ( pattern, "$1" ).replace ( / $/, "" );
};

Object.prototype.hide = function ()
{
	if ( ! this.style || this.style.display == 'none' ) return;

	this._old_display = this.style.display;
	this.style.display = 'none';
};

Object.prototype.show = function ()
{
	if ( ! this.style ) return;

	if ( this._old_display )
		this.style.display = this._old_display;
	else
		this.style.display = 'block';

	this._old_display = null;
};

liwe.dom.tableize = function ()
{
	if ( ( ! liwe.browser.ie ) && ( ! liwe.browser.version < 8 ) ) return;
	
	function _replace ( table_start, table )
	{
		var parent = table_start.parentNode;
		var next_sibling = table_start.nextSibling;
		parent.removeChild ( table_start );
		parent.insertBefore ( table, next_sibling );
	}

	function _add_cell ( row, div )
	{
		var c;
		cell = document.createElement ( "td" );
		cell.setAttribute ( "vAlign", "top" );
		cell.className = div.className;

		c = cell.appendChild ( div.firstChild.cloneNode ( true ) );
		c.style.display = "block";

		row.appendChild ( cell );
	}

	var divs = document.getElementsByTagName ( "div" );
	var t, l = divs.length, div;
	var table = null, tbody = null;
	var row = null, cell = null;
	var table_start = null;

	for ( t = 0; t < l; t ++ )
	{
		div = divs [ t ];
		if ( ! div.className ) continue;

		if ( div.className.indexOf ( 'table' ) != -1 )
		{
			if ( table_start )
			{
				_replace ( table_start, table );
				table = null;
			}

			table_start = div;
			table = document.createElement ( "table" );
			tbody = document.createElement ( "tbody" );
			table.appendChild ( tbody );
			table.className = div.className;
			table.style.border = "1px dotted black";
		} else if ( div.className.indexOf ( "cell-first" ) != -1 ) {
			row = document.createElement ( "tr" );
			tbody.appendChild ( row );
			_add_cell ( row, div );
		} else if ( div.className.indexOf ( "cell" ) != -1 ) {
			_add_cell ( row, div );
		}
	}

	if ( table )
		_replace ( table_start, table );
};

function $c ( element, class_name, base )
{
	if ( ! base ) base = document;
	var elements = base.getElementsByTagName ( element );
	var t, l = elements.length;
	var res = [], el;

	for ( t = 0; t < l; t ++ )
	{
		el = elements [ t ];
		if ( el.className.indexOf ( class_name ) == -1 ) continue;

		res.push ( el );
	}

	return res;
}
/*
 * 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-05-04:	ADD: new static function AJAXManager.handle_easy
 *
 *       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;

				AJAXManager.handle_easy ( req.responseText, callback, err_handler );
			}
		}
	};
	// }}}

	

	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;
	};
}

AJAXManager.handle_easy = function ( responseText, callback, err_handler )
{
	var resp_txt = 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: %s - (except: %o)", responseText, e );
			return;
		}

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

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;
	}
};
/*
 * utils.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: max
liwe.utils.max = function ()
{
	if ( ! arguments.length ) return 0;

	var m = 0;
	var t;

	for ( t = 0; t < arguments.length; t ++ )
		if ( m < arguments [ t ] ) m = arguments [ t ];

	return m;
};

// PUBLIC: min
liwe.utils.min = function ()
{
	if ( ! arguments.length ) return 0;

	var m = arguments [ 0 ];
	var t;

	for ( t = 1; t < arguments.length; t ++ )
		if ( m > arguments [ t ] ) m = arguments [ t ];

	return m;
};

// PUBLIC: date2str
// Mode:
//
//	0 - YYYY MM DD	( default )
//	1 - DD MM YYYY
// 	2 - MM DD YYYY
liwe.utils.date2str = function ( date, mode )
{
	var s = new String ( date );
	var v = s.match ( new RegExp ( "([0-9]{4}).([0-9]{1,2}).([0-9]{1,2})" ) );

	if ( ! mode ) mode = 0;

	switch ( mode )
	{
		case 1:
			s = v [ 3 ] + "-" + v [ 2 ] + "-" + v [ 1 ];
			break;
		case 2:
			s = v [ 2 ] + "-" + v [ 3 ] + "-" + v [ 1 ];
			break;

		default:
			s = v [ 1 ] + "-" + v [ 2 ] + "-" + v [ 3 ];
	}

	return s;
};

// PUBLIC: call
// Chiama una funzione passando un array di parametri
liwe.utils.call = function ( func_name, this_arg, arg_array )
{
	var i, l = arg_array.length;
	var s = "this_arg." + func_name + " ( ";
	
	for ( i = 0; i < l; i++ )
	{
		if ( i > 0 ) s += ", ";
		s += "arg_array[" + i + "]";
	}

	s += " );";

	return eval ( s );
};

// Formats a result list iterating on the list ``lst`` and using String.formatDict with
// the three templates str_row [mandatory], str_start [optional] and str_end [optional]
// Returns the formatted string
liwe.utils.format_list = function ( lst, str_row, str_start, str_end )
{
	var s = new String.buffer ();
	var t, l = lst.length;

	if ( ! l ) return '';

	if ( str_start ) s.add ( str_start );
	for ( t = 0; t < l; t ++ )
		s.add ( String.formatDict ( str_row, lst [ t ] ) );

	if ( str_end ) s.add ( str_end );

	return s.toString ();
};

liwe.utils._ents = null;

liwe.utils.map_entities = function ( txt )
{
	if ( ! liwe.utils_ents )
	{
		liwe.utils._ents = {
			 "&#8217;": "'",
			 "&#224;": "&agrave;",
			 "&#232;": "&egrave;",
			 "&#233;": "&eacute;",
			 "&#242;": "&ograve;",
			 "&#249;": "&ugrave;",
			 "&#8220;": '"',
			 "&#8221;": '"',
			 "&#8211;": "-",
			 "%u2013" : "-",
			 "%u2019" : "'",
		         "%u201C" : '"',
		         "%u201D" : '"'
		};

		var reg_exp = "";
		var ents = [];

		liwe.utils._ents.iterate ( function ( v, k ) { ents.push ( k ); } );
		reg_exp = "(" + "|".join ( ents ) + ")";

		liwe.utils._ents_re = RegExp ( reg_exp, "g" );
	}

	txt = txt.replace ( /&#37;/g, "%" );

	return txt.replace ( liwe.utils._ents_re, function ( k ) { return liwe.utils._ents [ k ]; } );
};
/*
 * 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-07-09: Fix htmlEntities now skips ";" "="
 *  2009-06-16: Fix htmlEntities now works again and skips "<" ">", '"', "'", "\r", "\n"
 *  2009-04-16: Fix htmlEntities RegExp to skip "-", "(" and ")"
 *  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 ()
	{
		var t, l = arguments.length;

		for ( t = 0; t < l; t ++ )
			this._buf.push ( arguments [ t ] );

		return this;
	};

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

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

	this.length = function () { return this._buf.length; };

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

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

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

String._re_entities_decl = /&#([^;]*);/g;
String.prototype.entities2char = function ()
{
	function _ch ( m, p1 )
	{
		return String.fromCharCode ( parseInt ( p1, 10 ) );
	}

	return this.replace ( String._re_entities_decl, _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: %o", 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;
}

/*
 * 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;
};

Object.fromForm = function ( form_id, max_depth )
{
	var arr = {};
	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;
	};
}

/*
 * object_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: iterate
Object.prototype.iterate = function ( cback )
{
	var k;

	for ( k in this )
	{
		if ( typeof ( this [ k ] ) == 'function' ) continue;
		cback ( this [ k ], k );
	}
};

Object.prototype.keys = function ()
{
	var res = [];

	this.iterate ( function ( v, k ) { res.push ( k ); } );

	return res;
};

Object.prototype.values = function ()
{
	var res = [];

	this.iterate ( function ( v ) { res.push ( v ); } );

	return res;
};

// PUBLIC: debugDump
Object.prototype.debugDump = function ( dump_funcs, lvl )
{
	var s = '';
	var k;

	if ( ! lvl ) lvl = '';

	for ( k in this )
	{
		if ( typeof ( this [ k ] ) == 'function' ) 
		{
			if ( dump_funcs ) s += lvl + 'function ' + k + ' ()\n';
		} else {
			if ( typeof ( this [ k ] ) == 'object' )
			{
				s += lvl + k + ":\n" + this [ k ].debugDump ( dump_funcs, lvl + "-----  " );
			} else {
				s += lvl + k + ": " + this [ k ] + "\n";
			}
		}
	}

	return s;
};

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

	return res;
};

// PUBLIC: get
Object.prototype.get = function ( name, def_val )
{
	var res = this [ name ];

	if ( typeof ( res ) == 'undefined' ) return def_val;

	return res;
};

// PUBLIC: getName
Object.prototype.getName = function ()
{
	if ( this.name ) return this.name;

	var s = "" + this;
	var v = s.match ( /^function  *([_a-zA-Z$][_a-zA-Z0-9$]*)  *.*/ ); //new RegExp ( "^function  *(.*) *\(" ) )

	if ( ! v ) return '';

	return v [ 1 ];
};

// PUBLIC: inherits
Object.prototype.inherits = function ( p )
{
	var name;

	this.parent = p;
	for ( name in p )
	{
		if ( typeof this [ name ] == 'undefined' ) this [ name ] = p [ name ];
	}
};


// PUBLIC: clone
Object.prototype.clone = function ()
{
        var res ={};
        var name;

        for ( name in this ) res [ name ] = this [ name ];

        return res;
};


/*
 * form.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-05-18:	ADD:	form.select_set_values ()
 *
 * 	2009-05-04:	ADD:	form.events: 'start', 'before-complete', 'complete'
 *			ADD:	form.easy
 *
 *			DEL:	form.onsubmit
 *			DEL:	form.form_callback
 *
 *	2009-03-06:	form.descr () now also accepts both a string and an object as param
 */

/*
	liwe.events [ 'submit' ] = callback con parametri ( campi_form, azione, func_di_cback );
*/

liwe.form = {};

liwe.form._instances = [];
liwe.form.cbacks = {};		// Internal callbacks
liwe.form.utils  = {};		// Global functions (forms only)

// liwe.form Callbacks
liwe.form.cbacks.ip_change = function ( v )
{
	console.debug ( v );
};

/*
liwe.form.cbacks.calendar = function ( cal, year, month, day )
{
	document.getElementById ( cal.id + "@cal_year" ).value = year;
	document.getElementById ( cal.id + "@cal_month" ).value = month +1;
	document.getElementById ( cal.id + "@cal_day" ).value = day;

	liwe.form.utils.cal_set_hidden ( cal.id );
};

liwe.form.cbacks.calendar_change = function ( i )
{
	var base = i.id.split ( "@" ) [ 0 ];
	var two = "";
	var cal;

	if ( i.id.split ( "@" ) [ 1 ] )
		two  = '@' + i.id.split ( "@" ) [ 1 ];
	if ( two )
		cal = _os3_cals [ base + two ];
	else
		cal = _os3_cals [ base ];
	var year = document.getElementById ( base + two + '@cal_year' ).value;
	var month = document.getElementById ( base + two + '@cal_month' ).value;
	var day = document.getElementById ( base + two + '@cal_day' ).value;

	cal.set_date ( year, month - 1, day );

	liwe.form.utils.cal_set_hidden ( base + two );
	
	return true;
};

liwe.form.utils.cal_set_hidden = function ( id )
{
	var old = document.getElementById ( id );

	var year = document.getElementById ( id + '@cal_year' ).value;
	var month = document.getElementById ( id + "@cal_month" ).value;
	var day = document.getElementById ( id + "@cal_day" ).value;
	var s = '';

	if ( ! month ) month = "0";
	if ( ! day ) day = "0";
	if ( ! year ) year = "0000";

	day = new String ( day );
	month = new String ( month );
	year = new String ( year );

	s += year + "-" + ( month.length < 2 ? "0" + month : month ) + "-" + ( day.length < 2 ? "0" + day : day );

	if ( old.value != "" && old.value != s ) console.debug ( "Calendar: cambiato %s", s );

	document.getElementById ( id ).value = s;
};
*/


liwe.form.get = function ( name )
{
	return liwe.form._instances [ name ];
};

liwe.form.check = function ( id )
{
	var s, t;
	var el, hint;
	var icon;
	var vals;
	var arr;

	var f = liwe.form.get ( id );

	// f.fetch_htmled_contents ();

	vals = f._mandatory;
	for ( t = 0; t < vals.length; t ++ )
	{
		el = document.getElementById ( vals [ t ] );
		hint = document.getElementById ( vals [ t ] + "@hint" );
		icon = document.getElementById ( vals [ t ] + "_mandatory" );

		if ( ! el ) continue;

		hint.innerHTML = "&nbsp;";

		if ( el.value.length == 0 ) 
		{
			hint.innerHTML = _ ( "os3_form", "Mandatory&nbsp;field" );

			icon.src = liwe._libbase + "/gfx/form/error.gif";
			el.focus ();
			return false;
		}
		icon.src = liwe._libbase + "/gfx/form/ok.gif";
	}

	vals = f._validates;
	for ( t = 0; t < vals.length; t ++ )
	{
		el = document.getElementById ( vals [ t ] [ 0 ] );
		icon = document.getElementById ( vals [ t ] [ 0 ] + "_valid" );
		hint = document.getElementById ( vals [ t ] [ 0 ] + "@hint" );
		if ( ! el ) continue;

		hint.innerHTML = "&nbsp;";
		if ( el.value.length == 0 ) continue;

		if ( vals [ t ] [ 1 ] ( el.value ) == false )
		{
			hint.innerHTML = _ ( "os3_form", "Validation&nbsp;failed" );	
			icon.src = liwe._libbase + "/gfx/form/error.gif";
			icon.alt = _ ( "os3_form", "Validation failed" );
			icon.title = _ ( "os3_form", "Validation failed" );
			el.focus ();
			return false;
		}
		icon.src = liwe._libbase + "/gfx/form/ok.gif";
		icon.alt = _ ( "os3_form", "Validation OK" );
		icon.title = _ ( "os3_form", "Validation OK" );
	}

	return true;
};

liwe.form.cbacks.ajax_submit = function ( id )
{
	var frm = liwe.form._instances [ id ];

	if ( ! frm.check () ) return;

	if ( frm.events [ 'start' ] )  
	{
		var r = frm.events [ 'start' ] ( frm );
		if ( ! r ) return;
	}

	var a = frm.get_values ();
	var action = frm._resolve_action ();
	
	// Resolve function pointer from function name in frm.events [ 'complete' ]
	eval ( "var _func = " + frm.events [ 'complete' ] );

	if ( ! frm.events [ 'submit' ] )
	{
		// AJAX Request
		liwe.AJAX.request ( action, a, _func, true );
	} else {
		frm.events [ 'submit' ] ( a, action, _func );
	}
};

// SPECIAL:
//	multi, bicolor, columns, width, height
function form_sel ( vars )
{
	if ( typeof OS3Sel == 'undefined' ) 
	{
		alert ( _ ( "os3_form", "You *MUST* include OS3Sel!" ) );
		return null;
	}

	this._start_field ( vars );

	vars [ 'id' ] = this.name + "@" + this._get_name ( vars );

	this.html += '<div id="' + vars [ 'id' ] + '"></div>';

	this._newline ( vars );

	var g = new OS3Sel ( 
		{ 	div_id: vars [ 'id' ], 
			multi: vars.get ( 'multi', 0 ), 
			bicolor: vars.get ( 'bicolor', true ),
			num_columns: vars.get ( 'columns', 1 ),
			width: vars.get ( 'width', '100%' ),
			height: vars.get ( 'height', '100%' )
		} );

	if ( vars [ 'headers' ] ) g.set_headers ( vars [ 'headers' ] );

	return g;
}

/*
function Form ( name, action, no_table )
{
	console.warn ( "Do not use the Form() function, use liwe.form.instance() instead" );
	return new liwe.form.instance ( name, action, no_table );
}
*/

// PUBLIC:
//		Form
liwe.form.instance = function ( name, action, no_table )
{
	this.name	= name;
	this.action	= action;
	this.easy	= true;

	this.events	= { 'start' : null, 'before-complete' : null, 'complete': null, 'submit' : null };

	this.no_table	= no_table;
	// this.auto_id	= true;

	this.multipart 	= false;
	// this.form_callback = '';

	this.html	= '';

	this.ajax_mode	= null;

	this.debug	= false;

	this._first_field = null;

	// PUBLIC METHODS
	// {{{ upload ( vars )
	this.upload = function ( vars )
	{
		this.multipart = true;

		this._start_field ( vars );
		this._add_field ( 'file', vars );
	};
	// }}}
	// {{{ text ( vars )
	this.text = function ( vars )
	{
		this._start_field ( vars );
		this._add_field ( 'text', vars );
	};
	// }}}
	// {{{ email ( vars )
	this.email = function ( vars )
	{
		vars [ 'filter' ] = "0123456789abcdefghijklmnopqrstuvwxyz._@";
		vars [ 'os3_def_validator' ] = liwe.validators.is_email;

		this._start_field ( vars );
		this._add_field ( 'text', vars );
	};
	// }}}
	// {{{ number ( vars )
	this.number = function ( vars )
	{
		vars [ 'filter' ] = "-0123456789";
		vars [ 'class'  ] = "number";
		vars [ 'os3_def_validator' ] = liwe.validators.is_integer;

		this._start_field ( vars );
		this._add_field ( 'text', vars );
	};
	// }}}
	// {{{ money ( vars )
	this.money = function ( vars )
	{
		if ( typeof Money == 'undefined' ) liwe.utils.append_js ( liwe._libbase + '/money.js' );
		
		vars [ 'filter' ] = "0123456789,.";
		vars [ 'class'  ] = "number";
		if ( ! vars [ 'onblur' ] )
			vars [ 'onblur' ]  = 'this.value = money_format ( this.value )';
		else
			 vars [ 'onblur' ]  = 'this.value = money_format ( this.value  );' + vars [ 'onblur' ] ;

		// vars [ 'os3_def_validator' ] = check_money;

		if ( vars [ 'defval' ] ) vars [ 'defval' ] = Money.fromLongInt ( vars [ 'defval' ] );
		if ( vars [ 'value' ] ) vars [ 'value' ] = Money.fromLongInt ( vars [ 'value' ] );

		this._start_field ( vars );
		this._add_field ( 'text', vars );
	};
	// }}}
	// {{{ submit ( vars )
	this.submit = function ( vars )
	{
		if ( typeof ( vars ) == 'string' ) vars = { value: vars };

		this._start_field ( vars );

		if ( this.multipart )
			this._add_field ( 'submit', vars );
		else
		{
			vars [ 'onclick' ] = "liwe.form.cbacks.ajax_submit('" + this.name + "');";
			this._add_button ( vars );
		}
	};
	// }}}
	// {{{ label ( vars )
	this.label = function ( vars )
	{
		this._start_field ( vars );
		this.html += vars [ 'value' ];
		this._newline ( vars );
	};
	// }}}

	// {{{ password ( vars )
	this.password = function ( vars )
	{
		this._start_field ( vars );
		this._add_field ( 'password', vars );
	};
	// }}}
	// {{{ checkbox ( vars ) 
	this.checkbox	= function ( vars )
	{
		this._start_field ( vars );
		this._add_field ( 'checkbox', vars );
	};
	// }}}
	// {{{ hidden ( vars, val )
	this.hidden = function ( vars, val )
	{
		/*
		NOTA: il metodo f.hidden() puo' essere usato in due modi:

			1 - La sintassi standard a "dizionario", cosi': f.hidden ( { name: 'nome_campo', value: 'valore' } );
			2 - Passando due parametri al posto del dizionario: f.hidden ( "module", "shop" );
			    che corrispondono a "name" e "value". 

			Nel secondo caso, il campo "id" viene valorizzato di default.
		*/
		if ( typeof ( val ) != 'undefined' )
		{
			var id = this.name + "@" + vars;

			this._fields.push ( vars );

			this.html += '<input type="hidden" name="' + vars + '" id="' + id + '" value="' + val + '" ';
			this.html += ' />';
		} else {
			this._fields.push ( vars [ 'name' ] );

			this.html += '<input type="hidden" name="' + vars [ 'name' ] + '" value="' + vars [ 'value' ] + '" ';
			if ( vars [ 'id' ] ) this.html += ' id="' + vars [ 'id' ] + '" ';
			if ( vars [ 'onchange' ] ) this.html += ' onchange="' + vars [ 'onchange' ] + '" ';
			this.html += ' />';
		}
	};
	// }}}
	// {{{ select ( vars ) 
	this.select = function ( vars )
	{
		this._start_field ( vars );

		var s = '<select ';
		var k;
		var skips = "{label}{mandatory}{hint}{options}{force_select}{nonl}{os3_full}{defval}";  
		var sel_val = -1;

		vars [ 'id' ] = this.name + "@" + this._get_name ( vars );
		if ( ( vars [ 'defval' ] != undefined ) && ( vars [ 'value' ] == undefined ) ) vars [ 'value' ] = vars [ 'defval' ];
		
		for ( k in vars )
		{
			if ( typeof vars [ k ] == 'function' ) continue;	// Skip functions
			if ( skips.indexOf ( '{' + k.toLowerCase () + '}' ) != -1 ) continue;
			s += k + '="' + vars [ k ] + '" ';
		}

		s += '>';

		this.html += s;

		if ( vars [ 'value' ] != undefined ) sel_val = vars [ 'value' ];

		s = '';
		if ( vars [ 'force_select' ] ) s += '<option value="">' + _ ( "os3_form", "(Selezionare)" ) + '</option>';

		if ( vars [ 'options' ] )
		{
			var opts = Array.fromObject ( vars [ 'options' ] );	
			var l = opts.length;
			var t, opt;

			for ( t = 0; t < l; t ++ )
			{
				opt = opts [ t ];
				s += '<option value="' + opt [ 'value' ] + '" ';
				if ( opt [ 'class' ] ) s += ' class="' + opt [ 'class' ] + '" ';
				if ( ( opt [ 'selected' ] || ( sel_val == opt [ 'value' ] ) ) ) s += ' selected="selected" ';
				s += '>' + opt [ 'label' ] + '</option>';
			}
		}
		
		s += '</select>';
		this.html += s;

		if ( vars [ 'mandatory' ] )	this._mandatory.push ( vars [ 'id' ] );

		this._create_hint ( vars );
		this._newline ( vars );
	};
	// }}}
	// {{{ select_set_values ( field_name, values )
	this.select_set_values = function ( field_name, values )
	{
		var t, l = values.length, e;
		var select = this.get_element ( field_name );

		for ( t = 0; t < l; t ++ )
			select.options [ 0 ] = null;

		for ( t = 0; t < l; t ++ )
		{
			e = new Option ( values [ t ] [ 'label' ], values [ t ] [ 'value' ], false, false );
			select.options [ select.options.length ] = e;
		}
	};
	// }}}
	// {{{ sep ( vars )
	this.sep = function ( vars )
	{
		this._newline ( {} );

		if ( ! this.no_table ) this.html += '<tr><td colspan="200">';
		this.html += '<hr />';
		this._newline ( {} );
	};
	// }}}
	// {{{ calendar ( vars ) 
	/*
	this.calendar_old = function ( vars )
	{
		var split = {};

		if ( typeof OS3Calendar == 'undefined' ) 
		{
			alert ( _ ( "os3_form", "You *MUST* include OS3Calendar" ) );
			return null;
		}

		this._start_field ( vars );
		vars [ 'id' ] = this.name + "@" + this._get_name ( vars );

		if ( ( vars [ 'defval' ] != undefined ) && ( vars [ 'value' ] == undefined ) ) vars [ 'value' ] = vars [ 'defval' ];

		if ( ! vars [ 'value' ] ) 
		{
			var Today = new Date ();
			vars [ 'value' ] = Today.getFullYear () + "-" + ( Today.getMonth() +1 ) + "-" + Today.getDate ();
		}

		if ( vars [ 'value' ] ) split = vars [ 'value' ].match ( new RegExp ( "([0-9]{4}).([0-9]{1,2}).([0-9]{1,2})" ) );

		if ( ! vars [ 'onchange' ] )
			this.hidden ( vars [ 'name' ], vars [ 'value' ] );
		else
			this.hidden ( vars );
		

		if ( ! vars [ 'onchange' ] )
			vars [ 'onchange' ] = "liwe.form.cbacks.calendar_change ( this )";
		else
			vars [ 'onchange' ] = "liwe.form.cbacks.calendar_change ( this );" + vars [ 'onchange' ];

		this.html += '<table border="0" cellpadding="0" cellspacing="0"><tr><td>';

		var v = Array ();

		v [ 'filter' ] = "0123456789";
		v [ 'class'  ] = "number";
		v [ 'os3_def_validator' ] = liwe.validators.is_integer;
		v [ 'nonl' ] = 1;
		if ( ! vars [ 'onchange' ] )
			v [ 'onchange' ] = "liwe.form.cbacks.calendar_change ( this )";
		else
			v [ 'onchange' ] = "liwe.form.cbacks.calendar_change ( this );" + vars [ 'onchange' ];

		v [ 'name' ] = vars [ 'name' ] + "@cal_year";
		v [ 'id'   ] = vars [ 'name' ] + "@cal_year";
		v [ 'size' ] = 4;
		v [ 'maxlength' ] = 4;
		v [ 'title' ] = "Year";
		v [ 'value' ] = split [ 1 ];
		
		this._add_field ( 'text', v  );
		this.html += '</td><td>';

		v [ 'name' ] = vars [ 'name' ] + "@cal_month";
		v [ 'id'   ] = vars [ 'name' ] + "@cal_month";
		v [ 'size' ] = 2;
		v [ 'maxlength' ] = 2;
		v [ 'title' ] = "Month";
		v [ 'value' ] = split [ 2 ];


		this._add_field ( 'text', v  );
		this.html += '</td><td>';

		v [ 'name' ] = vars [ 'name' ] + "@cal_day";
		v [ 'id'   ] = vars [ 'name' ] + "@cal_day";
		v [ 'title' ] = "Day";
		v [ 'value' ] = split [ 3 ];
		this._add_field ( 'text', v  );

		this.html += '</td><td><a href="javascript:os3cal_show(\'' + vars [ 'id' ] + '\',this)"><img src="' + liwe._libbase + '/gfx/icons/calendar.png" value="Calendar" border="0" /></a>';

		this._create_hint ( vars );

		this.html += '</td><td><div id="' + vars [ 'id' ] + '"></div>';
		this.html += '</td></tr></table>';

		this._newline ( vars );

		var cal = new OS3Calendar (); 
		cal.id = vars [ 'id' ];
		cal.show_days_labels = true; 
		cal.is_popup = true; 
		cal.cb_date_changed = liwe.form.cbacks.calendar;
		os3cal_register ( vars [ 'id' ], cal);

		return cal;
	};
	*/
	// }}}
	// {{{ textarea ( vars ) 
	this.textarea = function ( vars )
	{
		this._start_field ( vars );

		var s = '<textarea ';
		var k;
		var skips = "{label}{mandatory}{akey}{hint}{text}{nonl}{os3_full}{defval}{value}{show_entity}{code}";  

		vars [ 'id' ] = this.name + "@" + this._get_name ( vars );
		if ( ( vars [ 'value' ] ) && ( ! vars [ 'text' ] ) ) vars [ 'text' ] = vars [ 'value' ];
		if ( ( vars [ 'defval' ] != undefined ) && ( vars [ 'text' ] == undefined ) ) vars [ 'text' ] = vars [ 'defval' ];
		
		for ( k in vars )
		{
			if ( skips.indexOf ( '{' + k.toLowerCase () + '}' ) != -1 ) continue;
			if ( typeof vars [ k ] == 'function' ) continue;	// Skip functions
			s += k + '="' + vars [ k ] + '" ';
		}

		if ( vars [ 'akey' ] ) s += ' accesskey="' + vars [ 'akey' ] + '" ';
		if ( vars [ 'code' ] ) s += ' style="font-family: Courier, monospace; font-size: 80%;" ';

		s += '>';

		if ( vars [ 'text' ] ) 
		{
			if ( vars [ 'show_entity' ] )
				s += vars [ 'text' ].replace ( new RegExp ( "&([a-zA-Z][a-z]+);", "g" ), "&amp;$1;" ).replace ( new RegExp ( "<br[^>]*>", "g" ), "\n" );
			else
				s += vars [ 'text' ];
		}

		s += '</textarea>';

		this.html += s;

		if ( vars [ 'mandatory' ] ) this._mandatory.push ( vars [ 'id' ] );

		this._create_hint ( vars );
		this._newline ( vars );
	};
	// }}}
	// {{{ grid ( vars )
	this.grid = function ( vars )
	{
		if ( typeof OS3Grid == 'undefined' ) 
		{
			alert ( _ ( "os3_form", "You *MUST* include OS3Grid" ) );		
			return null;
		}

		var name = vars [ 'name' ];

		this._start_field ( vars );

		vars [ 'id' ] = this.name + "@" + this._get_name ( vars );

		this.html += '<div id="' + vars [ 'id' ] + '"></div>';

		this._newline ( vars );

		var g = new OS3Grid ( vars [ 'name' ] );

		g.width = "100%";
		g.height = "100%";
		g.highlight = true;
		g.div_id    = vars [ 'id' ];

		if ( vars [ 'headers' ] ) g.set_headers ( vars [ 'headers' ] );

		return g;
	};
	// }}}
	// {{{ button ( vars )
	this.button = function ( vars )
	{
		this._start_field ( vars );

		vars [ 'id' ] = this.name + "@" + this._get_name ( vars );
		this._add_button ( vars );

		this._newline ( vars );
	};
	// }}}
	// {{{ descr ( vars ) 
	this.descr = function ( vars )
	{
		if ( typeof ( vars ) == "string" ) vars = { "text" : vars };
		this._newline ( {} );
		if ( ! this.no_table ) this.html += '<tr><td colspan="200" class="text_descr">';
		this.html += vars [ 'text' ];
		this._newline ( {} );
	};
	// }}}
	// {{{ error_msg ( txt )
	this.error_msg	= function ( txt )
	{
		var e = $( this.name + "_err_box" );

		if ( ! e ) console.error ( "No error box for form: " + this.name );

		if ( txt )
		{
			e.innerHTML = txt;
			e.style.visibility = 'visible';
		} else
			e.style.visibility = 'hidden';
	};
	// }}}
	// {{{ get ()
	this.get = function ()
	{
		var start = '';
		var end   = '';
		var cback = '';
		var action = this._resolve_action ();

		if ( ! this.name ) this.name = "no_name";

		start += '<form method="post" name="' + this.name + '" id="' + this.name + '" ' + 
			 ' action="' + action + '" ' + 
			 ' onsubmit="return liwe.form._aim.submit(this,{onStart: liwe.form._event_on_start, onComplete: liwe.form._event_on_complete})">';

		if ( this.no_table  )
		{
			start += '<div class="frm" id="' + this.name + '_frm" >';
			end   += '</div>';
		} else {
			start += '<table border="0" class="frm" id="' + this.name + '_frm" cellpadding="0" cellspacing="0" >';
			end   += '</table>';
		}

		return start + this.html + end + '</form>';
	};
	// }}}
	// {{{ set ( id_dest )
	this.set = function ( id_dest )
	{
		document.getElementById ( id_dest ).innerHTML = this.get ();
		this._render_all ();

		if ( this._first_field )
			this.set_focus ( this._first_field );
	};
	// }}}
	// {{{ _resolve_action ()
	this._resolve_action = function ()
	{
		if ( this.action ) return this.action;
		if ( this.ajax_mode ) return this.ajax_mode;
		if ( liwe.AJAX && liwe.AJAX.url ) return liwe.AJAX.url;

		console.error ( "Form: %s does not have an 'action' value set", this.name );
		return '';
	};
	// }}}

	// NOT DOCUMENTED
	// {{{ add_wiget ( vars ) 
	this.add_widget		= function ( vars )
	{
		this._start_field ( vars );
		this.html += vars [ 'widget' ];

		this._newline ( vars );
	};
	// }}}
	
	// {{{ flat_calendar ( vars )
	/*
	this.flat_calendar = function ( vars )
	{
		var split = {};

		if ( typeof OS3Calendar == 'undefined' ) 
		{
			alert ( _ ( "os3_form", "You *MUST* include OS3Calendar" ) );
			return null;
		}

		this._start_field ( vars );

		vars [ 'id' ] = this.name + "@" + this._get_name ( vars );

		if ( ( vars [ 'defval' ] != undefined ) && ( vars [ 'value' ] == undefined ) ) vars [ 'value' ] = vars [ 'defval' ];

		if ( ! vars [ 'value' ] ) 
		{
			var Today = new Date ();
			vars [ 'value' ] = Today.getFullYear () + "-" + ( Today.getMonth() +1 ) + "-" + Today.getDate ();
		}


		split = vars [ 'value' ].match ( new RegExp ( "([0-9]{4}).([0-9]{1,2}).([0-9]{1,2})" ) );

		this.html += '<div id="' + vars [ 'name' ] + '">CIAO</div>';
		this._create_hint ( vars );
		this._newline ( vars );

		var cal = new OS3Calendar (); 
		cal.id = vars [ 'name' ];
		cal.show_days_labels = true; 
		cal.is_popup = false; 
		cal.cb_date_changed = liwe.form.cbacks.calendar;
		os3cal_register ( vars [ 'name' ], cal);

		return cal;
	};
	*/
	// }}}
	// {{{ error_box ( vars ) 
	this.error_box = function ()
	{
		var s;
		var vars = Array ();

		vars [ 'os3_full' ] = 1;

		this._start_field ( vars );

		// vars [ 'id' ] = this.name + "@" + this._get_name ( vars );
		s = 'border: 1px solid red; padding: 4px; background-color: #FFE87F; color: black; visibility: ' + ( vars [ 'show' ] ? 'visible' : 'hidden' );

		// this.html += '<div id="' + vars [ 'id' ] + '" style="' + s + '"></div>';
		this.html += '<div id="' + this.name + '_err_box" style="' + s + '"></div>';
		this._newline ( vars );
	};
	// }}}
	// {{{ workspace ( vars )
	this.workspace		= function ( vars )
	{
		this._newline ( {} );
		if ( ! this.no_table ) this.html += '<tr><td colspan="200">';
		this.html += '<div id="' + vars [ 'name' ] + '"></div>';
		this._newline ( {} );
	};
	// }}}
	// {{{ check ()
	this.check = function () { return liwe.form.check ( this.name ); };
	// }}}
	// {{{ get_value ( widget_name )
	this.get_value	= function ( widget_name )
	{
		if ( this._widgets [ widget_name ] )
		{
			var w = this._widgets [ widget_name ];
			return w.get_value ();
		}

		var e = document.getElementById ( this.name + "@" + widget_name );
		if ( ! e ) return null;

		if ( ( e.type == 'checkbox' ) && ( ! e.checked ) ) return false;
		return e.value;
	};
	// }}}
	// {{{ set_value ( widget_name, value )
	this.set_value	= function ( widget_name, value )
	{
		/*
		if ( this._htmled_names [ widget_name ] )
		{
			var h = HTMLEdManager.get ( this.name + "@" + widget_name );
			if ( h ) 
				h.set_html ( value );
			else
				console.warn ( "Form: could not find HTML Area '%s'", widget_name );

			return;
		} 
		*/

		if ( this._widgets [ widget_name ] )
		{
			this._widgets [ widget_name ].set_value ( value );
			return;
		}

		var e = document.getElementById ( this.name + "@" + widget_name );
		if ( ! e ) 
		{
			console.warn ( "Form: could not find input '%s'", this.name + "@" + widget_name );
			return;
		}

		switch ( e.type )
		{
			case "checkbox":
				e.checked = value;
				break;

			default:
				e.value = value;
		}
	};
	// }}}
	// {{{ set_focus ( widget_name )
	this.set_focus = function ( widget_name )
	{
		if ( this._widgets [ widget_name ] )
		{
			var w = this._widgets [ widget_name ];
			w.set_focus ();
			return;
		}

		var e = document.getElementById ( this.name + "@" + widget_name );
		if ( ! e ) return;

		e.focus ();
		e.select ();
	};
	// }}}
	// {{{ get_element ( widget_name )
	this.get_element = function ( widget_name ) { return document.getElementById ( this.name + "@" + widget_name ); };
	// }}}
	// {{{ get_values ()
	this.get_values	= function ()
	{
		var res = {};
		var _obj = this;

		this._fields.iterate ( function ( v )
			{
				res [ v ] = _obj.get_value ( v );
			} );
		// var a = Array.fromForm ( this.name + "_frm" );
		return res;
	};
	// }}}
	// {{{ clear ()
	this.clear = function ()
	{
		function _clear_input ( lst )
		{
			var l = lst.length;
			var t;

			for ( t = 0; t < l; t ++ ) lst [ t ].value = null;
		}

		var frm = $( this.name + "_frm" );

		_clear_input ( frm.getElementsByTagName ( 'input' ) );
		_clear_input ( frm.getElementsByTagName ( 'select' ) );
		_clear_input ( frm.getElementsByTagName ( 'textarea' ) );
	};
	// }}}

	// UNSTABLE
	// {{{ fetch_htmled_contents ()
	// FIXME: THIS FUNCTION DOES NOT WORK ANYMORE!
	this.fetch_htmled_contents = function ()
	{
		console.error ( "form.fetch_htmled_contents() has been REMOVED" );
		/*
		var i = this._htmled.length;
		var t, n;

		if ( ! i ) return;

		for ( t = 0; t < i; t ++ )
		{
			// Field name
			n = this._htmled [ t ];

			document.getElementById ( this.name + "@" + n + ":htmled" ).value = htmled_getText ( this.name + "@" + n );
		}
		*/
	};
	// }}}
	// {{{ _render_all ()
	this._render_all = function ()
	{
		this._widgets.iterate ( function ( v, k )
		{
			if ( v [ "render" ] )
				v.render ();

			if ( v [ "_refresh" ] )
				v._refresh ();
		} );

		/*
		// I have to use lists and not dicts because
		// the iterate function skips functions
		var t, l = this._suggests.length;
		for ( t = 0; t < l; t ++ )
			this._suggests [ t ] [ 1 ] ( this._suggests [ t ] [ 0 ] );
		*/
	};
	// }}}
	// NOT DOCUMENTED
	// {{{ ipaddr ( vars )
	this.ipaddr = function ( vars )
	{
		var split = {};

		this._start_field ( vars );
		// vars [ 'id' ] = this.name + "@" + this._get_name ( vars );

		if ( ( vars [ 'defval' ] != undefined ) && ( vars [ 'value' ] == undefined ) ) vars [ 'value' ] = vars [ 'defval' ];

		if ( vars [ 'value' ] ) split = vars [ 'value' ].match ( new RegExp ( "([1-9][0-9]{0,2})\.([1-9][0-9]{0,2})\.([1-9][0-9]{0,2})\.([1-9][0-9]{0,2})" ) );

		if ( ! vars [ 'onchange' ] )
			vars [ 'onchange' ] = "liwe.form.cbacks.ip_change ( this )";
		else
			vars [ 'onchange' ] = "liwe.form.cbacks.ip_change ( this );" + vars [ 'onchange' ];

		this.html += '<table border="0" cellpadding="0" cellspacing="0"><tr><td>';

		var v = Array ();

		v [ 'filter' ] = "0123456789";
		v [ 'class'  ] = "number";
		v [ 'os3_def_validator' ] = liwe.validators.is_integer;
		v [ 'nonl' ] = 1;
		v [ 'onchange' ] = vars [ 'onchange' ];

		v [ 'name' ] = vars [ 'name' ] + "@ip1";
		v [ 'id'   ] = vars [ 'name' ] + "@ip1";
		v [ 'size' ] = 3;
		v [ 'maxlength' ] = 3;
		v [ 'title' ] = "IP 1";
		v [ 'value' ] = split [ 1 ];
		
		this._add_field ( 'text', v  );
		this.html += '.</td><td>';

		v [ 'name' ] = vars [ 'name' ] + "@ip2";
		v [ 'id'   ] = vars [ 'name' ] + "@ip2";
		v [ 'size' ] = 3;
		v [ 'maxlength' ] = 3;
		v [ 'title' ] = "IP 2";
		v [ 'value' ] = split [ 2 ];


		this._add_field ( 'text', v  );
		this.html += '.</td><td>';

		v [ 'name' ] = vars [ 'name' ] + "@ip3";
		v [ 'id'   ] = vars [ 'name' ] + "@ip3";
		v [ 'title' ] = "IP 3";
		v [ 'value' ] = split [ 3 ];

		this._add_field ( 'text', v  );
		this.html += '.</td><td>';

		v [ 'name' ] = vars [ 'name' ] + "@ip4";
		v [ 'id'   ] = vars [ 'name' ] + "@ip4";
		v [ 'title' ] = "IP 4";
		v [ 'value' ] = split [ 4 ];
		this._add_field ( 'text', v  );
		this.html += '</td>';

		this._create_hint ( vars );

		if ( vars [ 'id' ] ) this.html += '</td><td><div id="' + vars [ 'id' ] + '"></div>';
		this.html += '</td></tr></table>';

		this._newline ( vars );
	};
	// }}}
	// NOT DOCUMENTED
	// {{{ cod_fisc ( vars )
	this.cod_fisc = function ( vars )
	{
		vars [ 'size' ] = 16;
		vars [ 'maxlength' ] = 16;
		vars [ 'filter' ] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
		vars [ 'os3_def_validator' ] = liwe.validators.is_codice_fiscale;

		this._start_field ( vars );
		this._add_field ( 'text', vars );
	};
	// }}}
	// NOT DOCUMENTED
	// {{{ p_iva ( vars )
	this.p_iva = function ( vars )
	{
		vars [ 'size' ] = 11;
		vars [ 'maxlength' ] = 11;
		vars [ 'filter' ] = "0123456789";
		vars [ 'os3_def_validator' ] = liwe.validators.is_partita_iva;

		this._start_field ( vars );
		this._add_field ( 'text', vars );
	};
	// }}}
	// {{{ radio ( vars )
	this.radio = function ( vars )
	{
		this._start_field ( vars );
		this._add_field ( 'radio', vars );
	};
	// }}}
	
	// this.sel		= form_sel;

	// ===========================================================
	// INTERNAL METHODS
	// ===========================================================
	// {{{ _start_field ( vars )
	this._start_field 	= function ( vars, kind )
	{
		var sty = '';
		var descr = vars.get ( "os3_class_descr", "descr" );
		var value = vars.get ( "os3_class_value", "value" );

		this._fields.push ( vars [ 'name' ] );

		if ( vars [ 'style' ] ) sty = 'style="' + vars [ 'style' ] + '"';	

		if ( ( ! this.no_table ) && ( ! this._row_open ) ) 
		{
			if ( vars [ 'os3_full' ] )
			{
				this._row_open = true;
				this.html += '<tr><td colspan="100" align="center" width="100%" class="' + descr + '" ' + sty + '>';
				return;
			} else
				this.html += '<tr><td class="' + descr +'" ' + sty + '>';
		}

		this._row_open = true;

		if ( vars [ 'label' ] ) 
		{
			if ( vars [ 'akey' ] )
			{
				var re = new RegExp ( "(" + vars [ 'akey' ] + ")", "i" );
				if ( ! re.test ( vars [ 'label' ] ) ) vars [ 'label' ] += " (" + vars [ 'akey' ] + ")";

				this.html  += '<label>' + vars [ 'label' ].replace ( re, '<span class="akey">$1</span>' ) + ": </label>";
			} else 
				this.html  += '<label>' + vars [ 'label' ] + ": </label>";
		}

		if ( ! this.no_table ) this.html += '</td><td class="' + value + '">';
	};
	// }}}
	// {{{ _add_field ( kind, vars )
	this._add_field	= function ( kind, vars )
	{
		var s = '<input type="' + kind + '" ';
		var k;
		var skips = "{label}{hint}{filter}{akey}{mandatory}{validator}{os3_def_validator}{nonl}{os3_full}{defval}{checked}{id}{suggest}";

		vars [ 'id' ] = this.name + "@" + this._get_name ( vars );

		if ( ( vars [ 'defval' ] != undefined ) && ( vars [ 'value' ] == undefined ) ) vars [ 'value' ] = vars [ 'defval' ];

		/*
		if ( vars [ 'suggest' ] ) 
		{
			if ( typeof AutoSuggest != "undefined" )
				this._suggests.push ( [ vars [ 'id' ], vars [ 'suggest' ] ] );
			else
				console.warn ( "AutoSuggest requested for %s but not included", vars [ 'id' ] );
		}
		*/

		if ( vars [ 'value' ] ) 
		{
			vars [ 'value' ] = ( vars [ 'value' ] + '' ).replace ( /"/g, '&quot;' );
			// console.debug ( "VALUE: %s", vars [ 'value' ] );
		}
		
		for ( k in vars )
		{
			if ( typeof vars [ k ] == 'function' ) continue;	// Skip functions
			if ( skips.indexOf ( '{' + k.toLowerCase () + '}' ) != -1 ) continue;
			if ( vars [ k ] == undefined ) continue;
			s += k + '="' + vars [ k ] + '" ';
		}

		if ( vars [ 'filter' ] ) s += ' onkeypress="return filter_valid_chars ( event, \'' + vars [ 'filter' ] + '\', false )" ';

		if ( ( kind == 'checkbox' ) && vars [ 'checked' ] ) s += ' checked="checked" ';
		if ( vars [ 'akey' ] )   	s += ' accesskey="' + vars [ 'akey' ] + '" ';
		if ( vars [ 'mandatory' ] )	this._mandatory.push ( vars [ 'id' ] );
		if ( vars [ 'validator' ] )
		{

			if ( vars [ 'validator' ] == true )
			{
				if ( vars [ 'os3_def_validator' ] ) this._validates.push ( [ vars [ 'id' ], vars [ 'os3_def_validator' ] ] );
			} else {
				this._validates.push ( [ vars [ 'id' ], vars [ 'validator' ] ] );
			}
		}

		s += ' id="' + vars [ 'id' ] + '"';

		s += ' />';

		this.html += s;
		this._create_hint ( vars );

		if ( ( ! this._first_field ) && ( vars [ 'name' ] ) ) 
			this._first_field = this._get_name ( vars );

		this._newline ( vars );
	};
	// }}}
	// {{{ _add_button ( vars )
	this._add_button = function ( vars )
	{
		var s = '<button ';
		var k;
		var skips = "{hint}{akey}{nonl}{os3_full}";  

		vars [ 'id' ] = this.name + "@" + this._get_name ( vars );
		
		for ( k in vars )
		{
			if ( typeof vars [ k ] == 'function' ) continue;	// Skip functions
			if ( skips.indexOf ( '{' + k.toLowerCase () + '}' ) != -1 ) continue;
			s += k + '="' + vars [ k ] + '" ';
		}

		if ( vars [ 'akey' ] ) s += ' accesskey="' + vars [ 'akey' ] + '" ';

		s += ' type="button">';
		s += vars [ 'value' ];
		s += '</button>';

		this.html += s;
		this._create_hint ( vars );

		this._newline ( vars );
	};
	// }}}
	// {{{ _newline ( vars ) 
	this._newline = function ( vars )
	{
		if ( ( vars [ 'nonl' ] ) || ( ! this._row_open ) ) 
		{
			this.html += '</td><td valign="top" nowrap="nowrap" class="descr">';
			return;
		}

		this._row_open = false;

		if ( this.no_table ) 
			this.html += '<br />';
		else
			this.html += '</td></tr>';
	};
	// }}}
	// {{{ _create_hint ( vars ) 
	this._create_hint = function ( vars )
	{
		var s;
		var l;

		if ( vars [ 'hint' ] )
		{
			l = _ ( "os3_form", "hint" );
			s = '<img alt="' + l + '" src="' + liwe._libbase + '/gfx/bubble/hint.png" onclick="bubble_show ( this.previousSibling, \'' + vars [ 'hint' ] + '\', true )" />';
			this.html += s;

			if ( typeof bubble_show == "undefined" ) liwe.utils.append_js ( liwe._libbase + "/bubble.js" );
		}

		if ( vars [ 'mandatory' ] )
		{
			l = _ ( "os3_form", "Mandatory field" );
			s = '&nbsp;<img alt="' + l + '" title="' + l + '" src="' + liwe._libbase + '/gfx/form/mandatory.gif" id="' + vars [ 'id' ] + '_mandatory" />';
			this.html += s;
		}

		if ( vars [ 'validator' ] )
		{
			l = _ ( "os3_form", "Field needs Validation" );

			s = '&nbsp;<img alt="' + l + '" title="' + l + '" src="' + liwe._libbase + '/gfx/form/okb.gif" id="' + vars [ 'id' ] + '_valid" />';
			this.html += s;
		}

		if ( vars [ 'id' ] ) this.html += '&nbsp;<span id="' + vars [ 'id' ] + "@hint" + '">&nbsp;</span>';
	};
	// }}}
	// {{{ _get_name ( vars )
	this._get_name = function ( vars )
	{
		this._widget_count ++;
		if ( ! vars [ 'name' ] ) vars [ 'name' ] = "W" + this._widget_count;
		return vars [ 'name' ];
	};
	// }}}

	// ===========================================================
	// INTERNAL ATTRS
	// ===========================================================
	this._row_open		= false;  // Flag T/F to tell if the row has been started

	this._widget_count	= 0;	  // Internal Widget Counter (used to create unique IDs)

	// this._htmled = Array ();
	// this._htmled_names = {};

	// this._htmled_manager = null;

	this._mandatory = Array ();
	this._validates = Array ();
	this._fields = [];
	this._widgets = {};
	// this._suggests = [];

	liwe.form._instances  [ name ] = this;
};
// {{{ _aim 
liwe.form._aim = {
	frame : function ( f, c, frm ) 
	{
		var i = document.getElementById ( '__ajax_form' );

		if ( ! i )
		{
			var d = document.createElement ( 'DIV' );
			d.innerHTML = '<iframe style="display:none" src="about:blank" id="__ajax_form" name="__ajax_form" onload="liwe.form._aim.loaded()"></iframe>';
			document.body.appendChild(d);
 
			i = document.getElementById ( '__ajax_form' );
		}

		if ( c && typeof ( c.onComplete ) == 'function') i.onComplete = c.onComplete;
		i._form = frm;
	},
 
	form : function ( f ) {
		f.setAttribute ( 'target', '__ajax_form' );
		f.setAttribute ( 'enctype', 'multipart/form-data' );
	},
 
	submit : function ( f, c ) 
	{
		var frm = liwe.form.get ( f.getAttribute ( "name" ) );

		if ( ! frm.check () ) return false;

		liwe.form._aim.form ( f, liwe.form._aim.frame ( f, c, frm ) );

		if ( c && typeof ( c.onStart ) == 'function' ) 
			return c.onStart ( frm );

		return true;
	},
 
	loaded : function () 
	{
		var i = document.getElementById( '__ajax_form' );
		var d;

		if ( i.contentDocument ) 
		{
			d = i.contentDocument;
		} else if (i.contentWindow) {
			d = i.contentWindow.document;
		} else {
			d = window.frames [ '__ajax_form' ].document;
		}

		if ( d.location.href == "about:blank" ) return;
 
		if ( typeof ( i.onComplete ) == 'function' ) i.onComplete ( i._form, d.body.innerHTML );
	}
 
};
// }}}
// {{{ _event_on_start ( frm )
liwe.form._event_on_start = function ( frm )
{
	if ( frm.events [ 'start' ] ) 
		if ( ! frm.events [ 'start' ] ( frm ) ) return false;

	return true;
};
// }}}
// {{{ _event_on_complete ( frm, vals )
liwe.form._event_on_complete = function ( frm, vals )
{
	if ( frm.easy )
	{
		AJAXManager.handle_easy ( vals, frm.events [ 'complete' ] );
	} else {
		if ( frm.events [ 'complete' ] ) frm.events [ 'complete' ] ( vals );
	}
}; 
// }}}
liwe.events = {};

if ( document.addEventListener )
{
	// W3C DOM 2 Events model
	liwe.events.add 	= function ( target, type, listener ) { target.addEventListener ( type, listener, false ); };
	liwe.events.del 	= function ( target, type, listener ) { target.removeEventListener ( type, listener, false ); };
	liwe.events.prevent 	= function ( e ) { e.preventDefault (); };
	liwe.events.stop 	= function ( e ) { e.stopPropagation(); };

	liwe.events.source  	= function ( e ) { return e.target; };
	liwe.events.keycode 	= function ( e ) { return e.which; };
} else if ( document.attachEvent ) {
	// Internet Explorer Events model

	liwe.events.add		= function ( target, type, listener )
	{
		// prevent adding the same listener twice, since DOM 2 Events ignores
		// duplicates like this
		if ( liwe.events._find ( target, type, listener) != -1 ) return;

		// _cback calls listener as a method of target in one of two ways,
		// depending on what this version of IE supports, and passes it the global
		// event object as an argument
		var _cback = function ()
		{
			var e = window.event;

			if ( Function.prototype.call )
				listener.call ( target, e );
			else {
				target._curr_listener = listener;
				target._curr_listener ( e )
				target._curr_listener = null;
			}
		};

    		// add _cback using IE's attachEvent method
    		target.attachEvent ( "on" + type, _cback );

    		// create an object describing this listener so we can clean it up later
    		var rec =
    		{
      			target: target,
      			type: type,
      			listener: listener,
      			_cback: _cback
    		};

    		// get a reference to the window object containing target
    		var targetDocument = target.document || target;
    		var targetWindow = targetDocument.parentWindow;

    		// create a unique ID for this listener
    		var listenerId = "l" + liwe.events._list_counter++;

    		// store a record of this listener in the window object
    		if ( !targetWindow._all ) targetWindow._all = {};
    		targetWindow._all [ listenerId ] = rec;

    		// store this listener's ID in target
    		if ( ! target._listeners ) target._listeners = [];
    		target._listeners [ target._listeners.length ] = listenerId;

    		if ( ! targetWindow._unload_added )
    		{
      			targetWindow._unload_added = true;
      			targetWindow.attachEvent ( "onunload", liwe.events._del_all );
    		}
  	};

  
	liwe.events.del = function ( target, type, listener )
	{
		// find out if the listener was actually added to target
		var listenerIndex = liwe.events._find ( target, type, listener );
		if ( listenerIndex == -1 ) return;

		// get a reference to the window object containing target
		var targetDocument = target.document || target;
		var targetWindow   = targetDocument.parentWindow;

		// obtain the record of the listener from the window object
		var listenerId = target._listeners [ listenerIndex ];
		var rec = targetWindow._all [ listenerId ];

		// remove the listener, and remove its ID from target
		target.detachEvent ( "on" + type, rec._cback );
		target._listeners.splice ( listenerIndex, 1 );

		// remove the record of the listener from the window object
		delete targetWindow._all [ listenerId ];
	};

	liwe.events.prevent = function ( e ) { e.returnValue = false; };
	liwe.events.stop = function ( e ) { e.cancelBubble = true; };
	liwe.events.source   = function ( e ) { return event.srcElement; };
	liwe.events.keycode  = function ( e ) { return event.keyCode; };

	liwe.events._find = function ( target, type, listener )
	{
		// get the array of listener IDs added to target
		var listeners = target._listeners;
		if ( !listeners ) return -1;

		// get a reference to the window object containing target
		var targetDocument = target.document || target;
		var targetWindow   = targetDocument.parentWindow;

		// searching backward ( to speed up onunload processing ), find the listener
		for ( var i = listeners.length - 1; i >= 0; i-- )
		{
			// get the listener's ID from target
			var listenerId = listeners [ i ];

			// get the record of the listener from the window object
			var rec = targetWindow._all [ listenerId ];

			// compare type and listener with the retrieved record
			if (rec.type == type && rec.listener == listener) return i;
		}

		return -1;
	};

	liwe.events._del_all = function()
	{
		var targetWindow = this;

		for ( id in targetWindow._all )
		{
			var rec = targetWindow._all [ id ];
			if ( typeof ( rec ) == "function" ) continue;

			rec.target.detachEvent ( "on" + rec.type, rec._cback );
			delete targetWindow._all[id];
		}
	};

  	liwe.events._list_counter = 0;
}


liwe.events.add_by_id = function ( id, event_name, func )
{
	liwe.events.add ( document.getElementById ( id ), event_name, func );
};

/*
EXAMPLES

liwe.events.add ( window, 'load', on_load, false );
*/
/*
 * locale.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.
 */
// Used by the L10n module
liwe.locale = {};
liwe.locale.words = {};

liwe.locale.set = function ( module_name, words ) 
{
	liwe.locale.words [ module_name ] = words;
};

/*
	PUBLIC: _

	This function is used by the L10n module.
	USAGE:

		_ ( mod_name, str )

	mod_name - Module name.
	str	 - String to be localized
*/
function _ ( mod_name, str )
{
	var mod = liwe.locale.words.get ( mod_name, Array () );
	return mod.get ( str, str );
}
// DataSet 2.0
//
// 2009-01-10: 	- Dataset row now contain also:
//
// 			- ``_ds_row_num`` : the current row num
// 			- ``_ds_bg``:	a 0 / 1 value to distinguish odd / even rows
function DataSet ( name, ajax_cgi )
{
	DataSet._instances [ name ] = this;

	this.name = name;

	this.ajax = ajax_cgi;
	this.ajax_req = DataSet.ajax;
	this.num_rows = 0;	// Rows in totale dalla query
	this.rows = {};	// Rows in memoria
	this.len  = 0;		// Numero di rows in memoria
	this.page = 0;		// Pagina corrente
	this.lines_per_page = 10; // Linee per pagina
	this.from_row = 0;
	this.to_row   = 0;
	this.curr_doc = 0;	// Valore ordinale del documento corrente in FulShow
	this.paginator_links = 10;

	this.templates = {
				'table_start'  : '<table border="1" width="100%">',
				'table_end'    : '</table>',
				'table_header' : '',
				'table_footer' : '',
				'table_row'    : '',
				'prev_page'    : '',
				'next_page'    : '',
				'dash'         : ' - ',
				'next_doc'  : '',
				'prev_doc'  : ''
			 };

	
	this.cbacks = { 
		// Funzione ridefinibile da parte dell'utente per manipolare i dati
		// nel momento che vengono inseriti nell'array del DataSet
		'fill_manip' : null, 
		'prefetch_start' : null,
		'prefetch_end'   : null,
		'fill_start'   : null,
		'fill_end'   : null,
		'show_results' : null,
		'row_manip': null
	};

	// PRIVATE ATTRS
	this._attrs = {};
	this._form_fields = null;	// Campi della ricerca
	this._dest_div = null;
	this._fill_cback = null;

	// ========================================================================================
	// METHODS
	// ========================================================================================

	this._init_paginator = function ()
	{
		if ( ! window [ "Paginator" ] ) return null;

		var p = new Paginator ();

		p.templates [ 'pag-first' ] = "&lt;&lt;&lt;";
		p.templates [ 'pag-first-lnk' ] = "javascript:DataSet.page('" + this.name + "',0)";
		p.templates [ 'pag-last' ] = "&gt;&gt;&gt;";
		p.templates [ 'pag-last-lnk' ] = "javascript:DataSet.page('" + this.name + "',%(_TOT_PAGES)s)";
		p.templates [ 'pag-prev' ] = "&lt;";
		p.templates [ 'pag-prev-lnk' ] = "javascript:DataSet.page('" + this.name + "',%(_PREV)s)";
		p.templates [ 'pag-next' ] = '&gt;';
		p.templates [ 'pag-next-lnk' ] = "javascript:DataSet.page('" + this.name + "',%(_CURR_PAGE)s+1)";
		p.templates [ 'pag-pos' ] = '%(_PAGE)s';
		p.templates [ 'pag-pos-lnk' ] = "javascript:DataSet.page('" + this.name + "',%(_NUM)s)";
		p.templates [ 'pag-sep' ] = '|';
		p.templates [ 'pag-link-space' ] = '';

		return p;
	};

	this.paginator = this._init_paginator ();

	// This function sets the fields for the DataSet search
	this.set_fields = function ( fields )
	{
		this._form_fields = fields.clone ();
		this.clear ();
	};

	this.get_fields = function () { return this._form_fields; }

	this.del_field = function ( name ) { delete this._form_fields [ name ]; };

	this.rename_field = function ( old_field_name, new_field_name )
	{
		this._form_fields [ new_field_name ] = this._form_fields [ old_field_name ];
		delete this._form_fields [ old_field_name ];
	};

	this.clear = function ()
	{
		this.page = 0;
		this.num_rows = 0;
		this.from_row = 0;
		this.to_row   = this.lines_per_page;
		this.rows = {};
		this.len = 0;

		if ( this._form_fields )
		{
			this._form_fields [ "_X_START_POINT" ] = 0;
			this._form_fields [ "_X_PAGE" ] = 0;
		}

		this._attrs = {};
	};

	this.fill = function ( fill_callback, replace )
	{
		var _obj = this;

		if ( fill_callback ) this._fill_cback = fill_callback;

		if ( ! this._form_fields ) 
		{
			this._fill_cback ( this );
			return;
		}

		if ( this.cbacks [ 'fill_start' ] ) this.cbacks [ 'fill_start' ] ( this );

		this._form_fields [ '_X_LINES' ] = this.lines_per_page; 

		this.ajax_req ( this.ajax, this._form_fields, function ( vars ) { _obj._fill_done ( vars, _obj._fill_cback, replace ); } );
	};

	this._fill_done = function ( vars, cback, replace )
	{
		var t, len = parseInt ( vars [ 'lines' ] );

		if ( vars [ '_X_START_POINT' ] )		
			this.from_row = vars [ '_X_START_POINT' ];
		else 
			this.from_row = vars [ 'from_row' ];

		if ( ! this.from_row ) this.from_row = 0;

		for ( t = 0; t < len; t ++ )
		{
			if ( ! vars [ 'row' + t ] ) break;

			vars [ "row" + t ] [ 'ds_name' ] = this.name;

			var row = vars [ 'row' + t ];
			var row_index = row [ '_pos' ]; // this.from_row + t;

			if ( this.cbacks [ 'fill_manip' ] )
				this.rows [ row_index ] = this.cbacks [ 'fill_manip' ].call ( this, row );
			else
				this.rows [ row_index ] = row;
		}

		// FABIO: aggiunto 2009-07-13
		// FIXME: forse non serve
		this.to_row = this.from_row + len;

		this.num_rows = vars [ 'rows' ];

		if ( this.cbacks [ 'fill_end' ] ) this.cbacks [ 'fill_end' ] ( this, vars );

		if ( cback ) cback ( this );
	};

	this.needs_prefetch = function ( row_num )
	{
		if ( row_num >= this.num_rows ) row_num = this.num_rows -1;
		if ( this.rows [ row_num ] ) return false;

		var start = Math.floor ( row_num / this.lines_per_page ) * this.lines_per_page;
		var end   = start + this.lines_per_page -1;

		if ( end >= this.num_rows ) end = this.num_rows -1;

		if ( ! this.rows [ start ] ) return true;
		if ( ! this.rows [ end ] ) return true;

		return false;
	};

	this.prefetch = function ( num, cback )
	{
		if ( ! this.needs_prefetch ( num ) ) return cback ( this );

		var start = Math.floor ( num / this.lines_per_page ) * this.lines_per_page;

		this._form_fields [ '_X_START_POINT' ] = start;

		if ( this.cbacks [ 'prefetch_start' ] ) this.cbacks [ 'prefetch_start' ] ( this );

		this.fill ( cback );

		return true;
	};


	this.get_row = function ( num )
	{
		var row;

		if ( num >= this.num_rows ) return null;

		row = this.rows [ num ];

		return row;
	};

	this.filter_date = function ( s )
	{
		var g = parseInt ( s.replace ( /[^0-9]*([0-9][0-9]*)-([0-9][0-9]*)-([0-9][0-9][0-9][0-9]).*/, "$1" ), 10 );
		var m = parseInt ( s.replace ( /[^0-9]*([0-9][0-9]*)-([0-9][0-9]*)-([0-9][0-9][0-9][0-9]).*/, "$2" ), 10 );
		var a = s.replace ( /.*([0-9][0-9]*)-([0-9][0-9]*)-([0-9][0-9][0-9][0-9]).*/, "$3" );
		var pre = s.replace ( /([^0-9]*)[0-9][0-9]*-[0-9][0-9]*-[0-9][0-9][0-9][0-9].*/, "$1" );
		var post = s.replace ( /.*[0-9][0-9]*-[0-9][0-9]*-[0-9][0-9][0-9][0-9](.*)/, "$1" );

		if ( g < 10 ) g = "0" + g;
		if ( m < 10 ) m = "0" + m;

		return pre + g + "/" + m + "/" + a + post;
	};

	this.render = function ( dest_div, render_cback )
	{
		var _obj = this;

		if ( ! dest_div ) dest_div = this._dest_div;
		this._dest_div = dest_div;

		this.prefetch ( this.from_row, function ( ds ) { _obj._render_done ( dest_div, render_cback ); } );
	};

	this._render_done = function ( dest_div, render_cback )
	{
		var s = '';

		this._prepare_pagination ();

		s = this.to_string ();

		$( dest_div ).innerHTML = s;

		if ( ! render_cback ) render_cback = this.cbacks [ 'show_results' ];
		if ( render_cback ) render_cback ( this );
	};

	this.refresh = function ( cback )
	{
		this._form_fields [ '_X_START_POINT' ] = this.from_row;
		this.fill ( cback, true );
	};

	this.to_string = function ()
	{
		var s = '';
		var t, row;

		s += String.formatDict ( this.templates [ 'table_start' ], this._attrs );
		s += String.formatDict ( this.templates [ 'table_header' ], this._attrs );

		// Ho messo <= in 'to_row' perche' altrimenti salta la prima riga
		// for ( t = 0; t < this.len; t ++ )
		for ( t = this.from_row; t < this.to_row ; t ++ )
		{
			row = this.get_row ( t ); 
			//console.debug ( "ROW: %s" + row );

			if ( ! row ) continue;

			if ( t > this.num_rows ) break;

			row [ 'ds_name' ] = this.name;
			row [ '_ds_row_num' ] = t;
			row [ '_ds_bg' ] = t % 2;

			if ( this.cbacks [ "row_manip" ] ) this.cbacks [ "row_manip" ] ( this, row );

			s += String.formatDict ( this.templates [ 'table_row' ], row );
		}

		s += String.formatDict ( this.templates [ 'table_footer' ], this._attrs );
		s += String.formatDict ( this.templates [ 'table_end' ], this._attrs );

		return s;
	};

	this._prepare_pagination = function ()
	{
		var delta    = this.to_row - this.from_row;
		var res, to_row, num_rows;

		res = this.from_row + 1;
		to_row = this.to_row;
		num_rows = this.num_rows;

		if ( to_row > num_rows ) to_row = num_rows;

		if ( num_rows <= this.lines_per_page )
			this._attrs [ 'docs_shown' ] = to_row;
		else
			this._attrs [ 'docs_shown' ] = res + " - " + to_row + " di " + num_rows;

		this._attrs [ 'from_row' ] = res;
		this._attrs [ 'to_row' ] = to_row;
		this._attrs [ 'num_rows' ] = num_rows;

		if ( this.page ) 
			this._attrs [ '_prev_page' ] = "javascript:DataSet.page('" + this.name + "'," + ( this.page -1 ) +")";
		else
			this._attrs [ '_prev_page' ] = null;

		if ( this.to_row < this.num_rows )
			this._attrs [ '_next_page' ] = "javascript:DataSet.page('" + this.name + "'," + ( this.page +1 ) + ")";
		else
			this._attrs [ '_next_page' ] = null;

		if ( this._attrs [ '_prev_page' ] )
			this._attrs [ 'prev_page' ] = String.formatDict ( this.templates [ 'prev_page' ], this._attrs );
		else
			this._attrs [ 'prev_page' ] = "&nbsp;";

		if ( this._attrs [ '_next_page' ] )
			this._attrs [ 'next_page' ] = String.formatDict ( this.templates [ 'next_page' ], this._attrs );
		else
			this._attrs [ 'next_page' ] = "&nbsp;";

		if ( this.page && ( this.to_row < this.num_rows ) )
			this._attrs [ 'dash' ] = this.templates [ "dash" ];
		else
			this._attrs [ 'dash' ] = "";

		if ( this.paginator )
		{
			this.paginator.init ( this.num_rows, this.lines_per_page, this.paginator_links );
			this.paginator.set_page ( this.page );
			this._attrs [ "paginator" ] = this.paginator.mk_str ();
		}
		else
			this._attrs [ "paginator" ] = "Include paginator.js";
	};

	this.show_page = function ( page )
	{
		this.page = page;

		this.from_row = this.lines_per_page * page;
		this.to_row = this.lines_per_page * ( page +1 );

		this.render ();
	};

	this.format_str = function ( template )
	{
		return String.formatDict ( template, this._attrs );
	};

	this.set_curr_doc   = function ( pos ) { 
		if ( pos === undefined ) pos = -1;
		this.curr_doc = pos; 
	};

	this.prepare_result_navi = function ( cback )
	{
		var _obj = this;

		if ( this.curr_doc == -1 ) return;

		this.prefetch ( this.curr_doc + 2, function ( ds ) { _obj.result_navi ( ds, cback ); } );
	};

	this.result_navi = function ( ds, cback )
	{
		if ( this._form_fields && this.needs_prefetch ( this.curr_doc +2 ) ) 
		{
			var _obj = this;
			this.prefetch ( this.curr_doc +2, function ( ds ) { _obj.result_navi ( ds, cback ); } );
			return;
		}

		var s = '';
		var row;
		
		if ( this.curr_doc > 0 )
		{
			// Posso tornare indiretro
			row = this.rows [ this.curr_doc -1 ];
			this._attrs [ 'prev_doc' ] = String.formatDict ( this.templates [ 'prev_doc' ], row );

			// 'javascript:DataSet.doc(\'' + this.name + '\',\'' + row.get ( 'id' ) + '\',{pos: ' + ( this.curr_doc -1 ) + '})';
		} else
			this._attrs [ 'prev_doc' ] = null;

		if ( this.curr_doc < this.num_rows -1 )
		{
			// Posso andare avanti
			row = this.rows [ this.curr_doc +1 ];
			this._attrs [ 'next_doc' ] = String.formatDict ( this.templates [ 'next_doc' ], row );
			// this._attrs [ 'next_doc' ] = 'javascript:DataSet.doc(\'' + this.name + '\',\'' + row.get ( 'id' ) + '\',{pos: ' + ( this.curr_doc +1 ) + '})';
		} else
			this._attrs [ 'next_doc' ] = null;

		if ( cback ) cback ( ds );
	}

}

DataSet._instances = {};

DataSet.get = function ( instance_name )
{
	return DataSet._instances [ instance_name ];
};

DataSet.page = function ( name, page_no )
{
	var ds = DataSet._instances [ name ];

	ds.show_page ( page_no );
};

DataSet.ajax = function ( ajax, fields, cback ) { liwe.AJAX.request ( ajax, fields, cback, true ); };
var Paginator = function ()
{
	var self = this;

	self._tot_rows = 0;		// Total number of rows
	self._rows_per_page = 0;	// Rows for each page
	self._page = 0;			// Current Page
	self._tot_links = 10;		// Number of links to show
	self._tot_pages = 0;		// Total number of pages

	self._dest_id = null;

	self.templates = {};
	self.templates [ 'pag-first' ] = "&lt;&lt;&lt;";
	self.templates [ 'pag-first-lnk' ] = 'javascript:self._go(0)';
	self.templates [ 'pag-last' ] = "&gt;&gt;&gt;";
	self.templates [ 'pag-last-lnk' ] = 'javascript:self._go(%(_TOT_PAGES)s)';
	self.templates [ 'pag-prev' ] = "&lt;";
	self.templates [ 'pag-prev-lnk' ] = 'javascript:self._go(%(_PREV)s)';
	self.templates [ 'pag-next' ] = '&gt;';
	self.templates [ 'pag-next-lnk' ] = 'javascript:self._go(%(_CURR_PAGE)s+1)';
	self.templates [ 'pag-pos' ] = '%(_PAGE)s';
	self.templates [ 'pag-pos-lnk' ] = 'javascript:self._go(%(_NUM)s)';
	self.templates [ 'pag-sep' ] = '|';
	self.templates [ 'pag-link-space' ] = '';
	self.templates [ 'pag-left-info' ] = '';
	self.templates [ 'pag-right-info' ] = '';

	self.cbacks =  { "mk_str" : null };

	// _TOT_PAGES 
	// _CURR_PAGE
	// _NUM
	// _PAGE

	self.init = function ( tot_rows, rows_per_page, tot_links )
	{
		self._tot_pages = Math.ceil ( tot_rows / rows_per_page );
		self._tot_rows = tot_rows;
		self._rows_per_page = rows_per_page;
		self._tot_links = ( tot_links ? tot_links : 10 );

		self.templates [ '_TOT_PAGES' ] = self._tot_pages;
		self.set_page ( 0 );
	};

	self.set_page = function ( page )
	{
		if ( page > self._tot_pages ) page = self._tot_pages;

		self._page = page;

		self.templates [ '_CURR_PAGE' ] = self._page;

		return self.mk_str ();
	};

	self.mk_str = function ()
	{
		if ( self.cbacks [ 'mk_str' ] ) 
			return self.cbacks [ 'mk_str' ] ( self );

		return self._mk_str ( self );
	}

	self._mk_str = function ( self )
	{
		var s = '';
		var t, p;
		var start_page = 0;

		self.templates [ '_NUM' ] = self._page;
		self.templates [ '_PAGE' ] = self._page + 1;
		s += String.formatDict ( self.templates [ "pag-left-info" ], self.templates );

		if ( self._page > 0 )
		{
			s += String.formatDict ( '<a href="%(pag-first-lnk)s">%(pag-first)s</a>', self.templates ); 
			s += self.templates [ 'pag-link-space' ];

			self.templates [ '_PREV' ] = self._page - 1;
			self.templates [ '_PREV-LNK' ] = String.formatDict ( self.templates [ 'pag-prev-lnk' ], self.templates );
			s += String.formatDict ( '<a href="%(_PREV-LNK)s">%(pag-prev)s</a>', self.templates );
		} else {
			s += String.formatDict ( '%(pag-first)s', self.templates ); 
			s += self.templates [ 'pag-link-space' ];
			s += String.formatDict ( '%(pag-prev)s', self.templates );
		}

		//s += self.templates [ 'pag-sep' ];

		if ( self._page > ( self._tot_links / 2 ) )
		{
			start_page = self._page - ( Math.floor ( self._tot_links / 2 ) );
			if ( ( self._tot_pages - start_page ) < self._tot_links )
				start_page = self._tot_pages - self._tot_links;
		}

		for ( t = 0; t < self._tot_links; t ++ )
		{
			p = start_page + t;

			if ( ( p + 1 ) > self._tot_pages ) break;

			s += self.templates [ 'pag-link-space' ];

			if ( t > 0 )
			{
				s += self.templates [ 'pag-sep' ];
				s += self.templates [ 'pag-link-space' ];
			}

			self.templates [ '_NUM' ] = p;
			self.templates [ '_PAGE' ] = p + 1;
			self.templates [ '_POS' ] = String.formatDict ( self.templates [ 'pag-pos' ], self.templates );

			if ( p == self._page )
				s += String.formatDict ( '%(_POS)s', self.templates );
			else {
				self.templates [ '_POS-LNK' ] = String.formatDict ( self.templates [ 'pag-pos-lnk' ], self.templates );
				s += String.formatDict ( '<a href="%(_POS-LNK)s">%(_POS)s</a>', self.templates );
			}
		}

		if ( ( self._page +1 ) >= self._tot_pages ) 
		{
			s += self.templates [ 'pag-link-space' ];
			s += String.formatDict ( '%(pag-next)s', self.templates );
			s += self.templates [ 'pag-link-space' ];
			s += String.formatDict ( '%(pag-last)s', self.templates );
		} else {
			s += self.templates [ 'pag-link-space' ];

			self.templates [ '_NEXT-LNK' ] = String.formatDict ( self.templates [ 'pag-next-lnk' ], self.templates );
			s += String.formatDict ( '<a href="%(_NEXT-LNK)s">%(pag-next)s</a>', self.templates );

			s += self.templates [ 'pag-link-space' ];
			self.templates [ '_LAST-LNK' ] = String.formatDict ( self.templates [ 'pag-last-lnk' ], self.templates );
			s += String.formatDict ( '<a href="%(_LAST-LNK)s">%(pag-last)s</a>', self.templates );
		}

		self.templates [ '_NUM' ] = self._page;
		self.templates [ '_PAGE' ] = self._page + 1;
		s += String.formatDict ( self.templates [ "pag-right-info" ], self.templates );

		return s;
	};

	self._go = function ( page_no )
	{
		self.set_page ( page_no );
		self.render ();
	};

	self.render = function ( dest_id )
	{
		var s;

		if ( ! dest_id ) dest_id = self._dest_id;
		self._dest_id = dest_id;

		s = self.mk_str ();

		$( dest_id ).innerHTML = s;
	};
};

liwe.lightbox = {};

liwe.lightbox.opacity = 70;
liwe.lightbox.fade = true;
liwe.lightbox._is_show = false;

liwe.lightbox._back_div  = null;
liwe.lightbox._front_div = [];

liwe.lightbox.events = {
	"click" : null
};

liwe.lightbox.create = function ( id, w, h, x, y )
{
	if ( liwe.lightbox._front_div.length == 0 )
	{
		var ua = navigator.userAgent.toLowerCase ();
		var an = navigator.appName.toLowerCase ();
		if ( ua.indexOf ( "msie 6" ) >= 0 )
			liwe.lightbox._save_windowed_status ();
		else if ( an.indexOf ( "netscape" ) >= 0 )
			liwe.lightbox._save_overflow_status ();
	}

	var back = liwe.lightbox._add_back_div ();
	var div  = liwe.lightbox._add_front_div ( id, w, h, x, y );

	return div;
};

liwe.lightbox.created = function ()
{
	return liwe.lightbox._back_div != null;
};

liwe.lightbox.close = function ()
{
	var d;

	d = liwe.lightbox._front_div.pop ();
	liwe.dom.remove_element ( d );

	if ( ! liwe.lightbox._front_div.length )
	{
		var ua = navigator.userAgent.toLowerCase ();
		var an = navigator.appName.toLowerCase ();
		if ( ua.indexOf ( "msie 6" ) >= 0 )
			liwe.lightbox._restore_windowed_status ();
		else if ( an.indexOf ( "netscape" ) >= 0 )
			liwe.lightbox._restore_overflow_status ();

		liwe.lightbox._back_div.style.display = "none";
	}

	liwe.dom.remove_element ( liwe.lightbox._back_div );
	liwe.lightbox._back_div = null;
};

liwe.lightbox.show = function ()
{
	var div = liwe.lightbox._front_div [ liwe.lightbox._front_div.length -1 ];

	liwe.fx.set_opacity ( liwe.lightbox._back_div, liwe.lightbox.opacity );
	liwe.lightbox._back_div.style.display = "block";

	if ( liwe.lightbox.fade )
	{
		liwe.fx.set_opacity ( div, 0 );
		div.style.display = "block";

		liwe.fx.fade_in ( div );
	} else 
		liwe.fx.set_opacity ( div, 100 );
};

liwe.lightbox.easy = function ( id, title, w, h, x, y )
{
	var div = liwe.lightbox.create ( id + "_win", w, h, x, y );
	var s;

	div.className = "lightbox_easy";

	s  = '<div class="title">' + title;
	s += '<div class="close" onclick="liwe.lightbox.close()"></div></div><div id="' + id + '"></div>';

	div.innerHTML = s;

	// TODO: fare il "pallino"

	liwe.lightbox.show ();
};

liwe.lightbox._add_back_div = function ()
{
	var d = liwe.lightbox._back_div;
	var h;
	
	if ( ! d ) 
	{
		d = liwe.dom.create_element ( "div", "liwe_lightbox" );

		d.style.display = 'none';
		d.style.backgroundColor = "black";

		liwe.lightbox._back_div = d;
	}

	var ua = navigator.userAgent;
	if ( ua.indexOf ( "MSIE" ) >= 0 )
		h = document.documentElement.clientHeight;
	else
		h = window.innerHeight;

	if ( document.body.parentNode.scrollHeight > h )
		h = document.body.parentNode.scrollHeight;

	d.style.zIndex = 10;
	d.style.width  = "100%";
	d.style.height = h + "px";

	liwe.events.add ( d, "click", liwe.lightbox._back_click );

	return d;
};

liwe.lightbox._back_click = function ()
{
	if ( liwe.lightbox.events [ 'click' ] ) liwe.lightbox.events [ 'click' ] ();
};

liwe.lightbox._add_front_div = function ( id, w, h, x, y )
{
	var d = liwe.lightbox._back_div;
	var div = liwe.dom.create_element ( "div", id );
	var bw, bh;

	var ua = navigator.userAgent;
	if ( ua.indexOf ( "MSIE" ) >= 0 )
	{
		bw = document.documentElement.clientWidth;
		bh = document.documentElement.clientHeight;
	}
	else
	{
		bw = window.innerWidth;
		bh = window.innerHeight;
	}

	if ( ( x == undefined ) || ( x == -1 ) ) x = Math.abs ( bw - w ) / 2;
	if ( ( y == undefined ) || ( y == -1 ) ) 
		y = Math.abs ( bh - h ) / 2;
	else
		if ( window.pageYOffset ) y += window.pageYOffset;

	x += document.body.parentNode.scrollLeft;
	y += document.body.parentNode.scrollTop;
	
	div.style.zIndex = document.body.childNodes.length + 10;
	div.style.width  = w + "px";
	div.style.height = h + "px";
	div.style.left = x + "px";
	div.style.top  = y + "px";

	liwe.lightbox._front_div.push ( div ); // = div;

	return div;
};

liwe.lightbox._save_overflow_status = function ()
{
	liwe.lightbox._overflow_status = [];

	liwe.lightbox._iterate_tree ( document.body, function ( item ) {

		if ( item.style )
		{
			liwe.lightbox._overflow_status.push ( [ item, item.style.overflow, item.style.overflowX, item.style.overflowY ] );
			item.style.overflow = "hidden";
		}

	} );
};

liwe.lightbox._restore_overflow_status = function ()
{
	var t, l = liwe.lightbox._overflow_status.length;

	for ( t = 0; t < l; t ++ )
	{
		var ost = liwe.lightbox._overflow_status [ t ];
		var item = ost [ 0 ];
		item.style.overflow = ost [ 1 ];
		item.style.overflowX = ost [ 2 ];
		item.style.overflowY = ost [ 3 ];
	}
};

liwe.lightbox._iterate_tree = function ( parent, cback )
{
	var children = parent.childNodes;
	if ( ! children || children.length == 0 ) return;

	var t, l = children.length;
	for ( t = 0; t < l; t ++ )
	{
		var child = children [ t ];
		cback ( child );

		liwe.lightbox._iterate_tree ( child, cback );
	}
};

liwe.lightbox._save_windowed_status = function ()
{
	liwe.lightbox._windowed_status = [];

	var windowed = [ "select", "object", "iframe", "applet", "plugin", "embed" ];
	var k, len = windowed.length;
	for ( k = 0; k < len; k++ )
	{
		var els = document.getElementsByTagName ( windowed [ k ] );

		var t, l = els.length;
		for ( t = 0; t < l; t++ )
		{
			var el = els [ t ];
			var vis = el.style.visibility;
			liwe.lightbox._windowed_status.push ( [ el, vis ] );
			el.style.visibility = "hidden";
		}
	}
};

liwe.lightbox._restore_windowed_status = function ()
{
	var t, l = liwe.lightbox._windowed_status.length;
	for ( t = 0; t < l; t ++ )
	{
		var item = liwe.lightbox._windowed_status [ t ];
		var el = item [ 0 ];
		var vis = item [ 1 ];
		el.style.visibility = vis;
	}
};

liwe.utils.notifier = {};

liwe.utils.notifier.fx = false; 	// Flag T/F. If T fx are used (if present)
liwe.utils.notifier.fade_in = 50; 	// Flag T/F. If T fx are used (if present)
liwe.utils.notifier.fade_out = 50; 	// Flag T/F. If T fx are used (if present)


liwe.utils.notifier.show = function ( text, mode )
{
	if ( ! mode ) mode = liwe.utils.notifier.mode.MESSAGE;

	liwe.utils.notifier._show ( text, mode );
};

liwe.utils.notifier.hide = function ()
{
	if ( ! liwe.utils.notifier._el || liwe.utils.notifier._el.style.display != 'block' ) return;

	if ( liwe.utils.notifier.fx && liwe.fx && liwe.fx.fade_in )
	{
		liwe.fx.fade_out ( liwe.utils.notifier._el, 10, liwe.utils.notifier.fade_out, function () { liwe.utils.notifier._el.style.display = "none"; } ); 
	} else 
		liwe.utils.notifier._el.style.display = "none";
};

liwe.utils.notifier.mode = { ALERT : "alert",
			     WARN  : "warn",
			     NOTICE : "notice",
			     MESSAGE : "message",
			     INFO : "info" 
			};

liwe.utils.notifier._el = null;

liwe.utils.notifier._show = function ( txt, mode )
{
	if ( ! liwe.utils.notifier._el )
	{
		liwe.utils.notifier._el = document.createElement ( "div" );
		document.body.insertBefore ( liwe.utils.notifier._el, document.body.firstChild );
	}

	liwe.utils.notifier._el.innerHTML = txt;

	liwe.utils.notifier._el.style.display = "none";
	liwe.utils.notifier._el.className = "liwe_notifier_" + mode;

	window.scrollTo ( 0, 0 );

	if ( liwe.utils.notifier.fx && liwe.fx && liwe.fx.fade_in )
	{
		liwe.fx.set_opacity ( liwe.utils.notifier._el, 0 ); 
		liwe.utils.notifier._el.style.display = "block";
		liwe.fx.fade_in ( liwe.utils.notifier._el, 10, liwe.utils.notifier.fade_in ); 
	} else 
		liwe.utils.notifier._el.style.display = "block";
};

/*
 * fx.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.
 */

// liwe.fx = {};	// Defined in liwe.js

liwe.fx.priv = {};	// Private methods

// PUBLIC: liwe.fx.set_opacity
//
// Setta la trasparenza dell'oggetto ``e``
// con il valore di alpha ``val``.
// ``val`` deve essere compreso tra 0 e 100
//
// Restituisce il valore di ``val`` assegnato all'oggetto
liwe.fx.set_opacity = function ( e, val )
{
        if ( val > 100 ) val = 100;
        if ( val < 0 ) val = 0;

        if ( e.filters )
        {
                if ( ! e.filters.alpha ) e.style.filter = "alpha(opacity=" + val + ")";
                e.filters.alpha.opacity = val;
        } else {
		e.style.MozOpacity = val / 100;
		e.style.opacity = val / 100;
	}

	return val;
};

liwe.fx.fade = {};

liwe.fx.fade._do_fade_in = function ( e )
{
	e.fade_val = liwe.fx.set_opacity ( e, e.fade_val + e.fade_amount );
	
	if ( e.fade_val < 100 ) setTimeout ( function () { liwe.fx.fade._do_fade_in ( e ); }, e.fade_millis );
	else if ( e.fade_cback ) e.fade_cback ( e );
};

liwe.fx.fade._do_fade_out = function ( e )
{
	e.fade_val = liwe.fx.set_opacity ( e, e.fade_val - e.fade_amount );

	if ( e.fade_val > 0 ) setTimeout ( function () { liwe.fx.fade._do_fade_out ( e ); }, e.fade_millis );
	else if ( e.fade_cback ) e.fade_cback ( e );
};

/* =======================================================================
	PUBLIC FUNCTIONS
======================================================================= */
liwe.fx.fade_in = function ( el, amount, millis, cback )
{
	el.fade_cback = cback;

	if ( ! amount ) amount = 10;
	if ( ! millis ) millis = 100;

	el.fade_amount = amount;
	el.fade_millis = millis;

	el.fade_val = liwe.fx.set_opacity ( el, 0 );
	// el.style.visibility = 'inherit';

	liwe.fx.fade._do_fade_in ( el );
};

liwe.fx.fade_out = function ( el, amount, millis, cback )
{
	el.fade_cback = cback;

	if ( ! amount ) amount = 10;
	if ( ! millis ) millis = 100;

	el.fade_amount = amount;
	el.fade_millis = millis;

	el.fade_val = liwe.fx.set_opacity ( el, 100 );
	el.style.visibility = 'inherit';

	liwe.fx.fade._do_fade_out ( el );
};
liwe.fx.resize = {};

liwe.fx.resize.start = function ( el, dest_w, dest_h, cback, step, millis )
{
	if ( el.fx_resize_interval ) return;

	if ( ! millis ) millis = 10;

	liwe.fx.resize._prepare ( el, dest_w, dest_h, cback, step );

	el.fx_resize_interval = setInterval ( function () { liwe.fx.resize._resize ( el ); }, millis );
};

liwe.fx.resize._prepare = function ( el, dest_w, dest_h, cback, step )
{
	if ( ! step ) step = 100;

	var w = el.clientWidth;
	var h = el.clientHeight;

	el.fx_resize_x = ( dest_w - w ) / step;
	el.fx_resize_y = ( dest_h - h ) / step;

	if ( el.fx_resize_x > 0 ) 
		el.fx_resize_x = Math.ceil ( el.fx_resize_x );
	else
		el.fx_resize_x = Math.floor ( el.fx_resize_x );

	if ( el.fx_resize_y > 0 ) 
		el.fx_resize_y = Math.ceil ( el.fx_resize_y );
	else
		el.fx_resize_y = Math.floor ( el.fx_resize_y );

	el.fx_resize_dest_w = dest_w;
	el.fx_resize_dest_h = dest_h;
	el.fx_resize_cback = cback;
};

liwe.fx.resize._resize = function ( el )
{
	if ( liwe.fx.resize._step ( el ) )
	{
		clearInterval ( el.fx_resize_interval );
		el.fx_resize_interval = 0;
		if ( el.fx_resize_cback ) el.fx_resize_cback ();
	}
};

liwe.fx.resize._step = function ( el )
{
	var w = el.clientWidth;
	var h = el.clientHeight;
	var x_stop = false, y_stop = false;
	var new_val;

	if ( el.fx_resize_x == 0 || el.fx_resize_dest_w == w )
	{
		x_stop = true;
	} else {
		if ( el.fx_resize_x > 0 ) {
			if ( w >= el.fx_resize_dest_w )
			{
				x_stop = true;
			} else {
				new_val = w + el.fx_resize_x;
				if ( new_val > el.fx_resize_dest_w ) new_val = el.fx_resize_dest_w;
				el.style.width = new_val + "px";
			}
		} else {
			if ( w <= 0 )
			{
				x_stop = true;
			} else {
				new_val = w + el.fx_resize_x;
				if ( new_val < el.fx_resize_dest_w ) new_val = el.fx_resize_dest_w;
				el.style.width = new_val + "px";
			}
		}
	}

	if ( el.fx_resize_y == 0 || el.fx_resize_dest_h == h )
	{
		y_stop = true;
	} else {
		if ( el.fx_resize_y > 0 ) {
			if ( h >= el.fx_resize_dest_h )
			{
				y_stop = true;
			} else {
				new_val = h + el.fx_resize_y;
				if ( new_val > el.fx_resize_dest_h ) new_val = el.fx_resize_dest_h;
				el.style.height = new_val + "px";
			}
		} else {
			if ( h <= el.fx_resize_dest_h )
			{
				y_stop = true;
			} else {
				new_val = h + el.fx_resize_y;
				if ( new_val < el.fx_resize_dest_h ) new_val = el.fx_resize_dest_h;
				el.style.height = new_val + "px";
			}
		}
	}

	return ( x_stop == true && y_stop == true );
};
/*
 * money.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: money_format
function money_format ( v )
{
	var m = new Money ( v );

	return m.value;
}

// PUBLIC:
//		Money
//		value
//		set
//		add
function Money ( v )
{
	this.value = '';

	this.set  = money_meth_set;
	this.add  = money_meth_add;

	this._format   = money_int_format;
	this._to_money = money_int_float_to_money;

	if ( v ) this.set ( v );
}

// PUBLIC: fromLongInt
Money.fromLongInt = function ( v )
{ 
        var s = new String ( v );

        if ( s.indexOf ( "," ) == -1 ) 
	{
		if ( s.length > 2 ) 
        	{
                	var e = s.substr ( s.length-2, 2 );
                	s = s.substr ( 0, s.length -2 );

                	s += "," + e;
		} else 
			s = "0," + s;
        }

	var m = new Money ( s );

        return m.value;
};

Money.toFloat = function ( amount )
{
	var sep;
	var str;
	var start;

	amount = new String ( amount );

	if ( amount == "" ) return 0.0;

	amount = amount.replace ( /\./g, '' );

	sep = amount.indexOf ( ',' );

	if ( sep == -1 ) 
		amount += ".00";
	else 
	{
        	start = amount.substring ( 0, sep );
            	str = amount.substring ( sep + 1 );

		amount = start + "." + str;
	}

	return parseFloat ( amount );
};

Money.toMoney = function ( amount )
{
	var m = new Money ( amount );

	return m.value;
};


function money_meth_set ( v )
{
	this.value = this._format ( v );
	
	return this.value;
}

function money_meth_add ( v )
{
	var f1 = Money.toFloat ( this.value );
	var f2 = Money.toFloat ( v );

	return this._to_money ( f1 + f2 );
}

function money_int_format ( amount ) 
{
	var out;
  	var cent;
  	var sign = "";
	var i;

	if ( typeof amount == 'number' ) 
	{
		this._to_money ( amount );
		return this.value;
	} 

	// console.debug ( "Money: amt1: "+ amount );
	amount = new String ( amount );

	// console.debug ( "Money: amt2: "+ amount );

	amount = amount.Strip ();
	if ( ! amount.length ) return '';

	// remove the "-" (or "+") sign
	amount = amount.replace ( /[+-]/g, "" );

	if ( amount.indexOf ( ',' ) == -1 ) amount += ",";
	amount += "00";

	cent   = amount.replace ( new RegExp ( ".*,(..).*" ),"$1" );
	amount = amount.replace ( new RegExp ( "(.*),.*" ),"$1" );
	amount = amount.replace ( new RegExp ( "\\.", "g" ), '' );

	// console.debug ( "Money: amt4: "+ amount );

    	for ( i = 0; i < Math.floor ( ( amount.length - ( 1 + i ) ) / 3 ); i++ ) 
      		amount = amount.substring(0,amount.length-(4*i+3))+'.'+amount.substring(amount.length-(4*i+3));

    	if ( amount == "" ) amount = "0";
	if ( cent.length == 1 ) cent = "0" + cent;

    	out = ( sign + amount + ',' + cent );

	return out;
}

function money_int_float_to_money ( amount )
{
        var s = new String ( amount );

        // Replace the "." with ","
	s = s.replace ( /\./g, "," );

	this.value = this._format ( s );

	return this.value;
}
/*
 * validators.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.
 */
liwe.validators = {};

liwe.validators.is_integer  = function ( n ) { return RegExp ( "^[-+]?[0-9]+$" ).test ( n ); };
liwe.validators.is_alpha    = function ( s ) { return RegExp ( "^[a-zA-Z]+$" ).test ( s ); };
liwe.validators.is_alphanum = function ( s ) { return RegExp ( "^[a-zA-Z0-9]+$" ).test ( s ); };
liwe.validators.is_date     = function ( s ) { return RegExp ( "^[0-9]{4,4}.[0-9]{2,2}.[0-9]{2,2}$" ).test ( s ); };
liwe.validators.is_time     = function ( s ) { return RegExp ( "^[012][0-9]:[0-5][0-9]$" ).test ( s ); };
liwe.validators.is_email    = function ( s ) { return RegExp ( "^[a-zA-Z0-9-_.]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$" ).test ( s ); };
liwe.validators.is_float    = function ( n ) { return RegExp ( "^[-+]?[0-9]*.[0-9]*$" ).test ( n ); };

// PUBLIC: filter_valid_chars
function filter_valid_chars ( evt, valids, case_ins )
{
        evt = (evt) ? evt : event;

	if ( evt.charCode < 32 ) return true;

	var ccode = ( evt.charCode ) ? evt.charCode : ( ( evt.which ) ? evt.which : evt.keyCode );
        var ch = String.fromCharCode ( ccode );

        if ( case_ins )
        {
                ch = ch.toLowerCase ();
                valids = valids.toLowerCase ();
        }
                                                                                                                                                            
        if ( valids.indexOf ( ch ) == -1 ) return false;
                                                                                                                                                            
        return true;
}

liwe.validators.is_codice_fiscale = function ( value )
{
	var caratteri = new Array ("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z" );
	var pari      = new Array ( 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25 );
   	var dispari   =new Array ( 1,0,5,7,9,13,15,17,19,21,1,0,5,7,9,13,15,17,19,21,2,4,18,20,11,3,6,8,12,14,16,10,22,25,24,23 );
   	var cod = value;//.toLowerCase();
   	var check = true;
	var numeri = '';
	var lettere = '';
	var i, test, somma = 0;
	var lettera, carattere, resto, k;
	
   	if ( cod.length != 16 ) return false;

	cod = cod.toLowerCase();

	lettere = cod.substr ( 0, 6 ) + cod.substr ( 8, 1 ) + cod.substr ( 11, 1) + cod.substr ( 15 );
	numeri  = cod.substr ( 6, 2 ) + cod.substr ( 9, 2 ) + cod.substr ( 12, 3 );

	for  ( i = 0; i < 10; i++ )
		if ( lettere.charCodeAt ( i ) < 97 || lettere.charCodeAt ( i ) > 122 ) return false;


	for  ( i = 0; i < 8; i++ )
		if ( numeri.charCodeAt ( i ) < 48 || numeri.charCodeAt ( i ) > 57 ) return false;

   	//checksum del codice fiscale
   	test = cod.substr ( 15,1 );
   	somma = 0;
   	for ( i = 0; i < 16; i = i + 2 )
	{ //dispari
       		carattere = cod.substr ( i, 1 );
       		for ( k = 0; k < 36; k++ )
		{
             		if ( carattere == caratteri [ k ] )
			{
                		somma += dispari [ k ];
             			break;
          		}
       		}
    	}

    	for ( i = 1; i < 15; i= i + 2 )
	{ //pari
       		carattere = cod.substr ( i, 1 );
       		for ( k = 0; k < 36; k++ )
		{
            		if ( carattere == caratteri [ k ] )
			{
             			somma += pari [ k ]; 
             			break;
          		}
       		}
    	}

   	resto = somma % 26;
   	lettera = String.fromCharCode ( 97 + resto );            

   	if ( test != lettera ) return false;

   	return true;
};

liwe.validators.is_partita_iva = function ( pi )
{
	var i, validi, s, c;

	if ( pi == '' ) return false;

	if( pi.length != 11 )
	{
		console.warn ( "PIVA: %s - length invalid: %d", pi, pi.length );
		return false;
	}

	validi = "0123456789";

	for ( i = 0; i < 11; i++ )
	{
		if ( validi.indexOf ( pi.charAt ( i ) ) == -1 )
		{
			console.warn ( "PIVA: %s - invalid char: %s at pos: %d", pi, pi.charAt ( i ), i );
			return false;
		}
	}

	s = 0;
	for ( i = 0; i <= 9; i += 2 ) s += pi.charCodeAt ( i ) - '0'.charCodeAt ( 0 );

	for( i = 1; i <= 9; i += 2 )
	{
		c = 2 * ( pi.charCodeAt ( i ) - '0'.charCodeAt ( 0 ) );
		if ( c > 9 ) c = c - 9;
		s += c;
	}

	if( ( 10 - s % 10  ) % 10 != pi.charCodeAt ( 10 ) - '0'.charCodeAt ( 0 ) )
	{
		console.warn ( "PIVA: %s - invalid checksum" );
		return false;
	}

	return true;
};

/*
 *
 * 	2009-04-05:	NEW: get_current_obj() - returns an object of the current history hash
 *
 */
liwe.history = {};

liwe.history.listener_callback = {};

liwe.history.cbacks = {
	"before-add" : null,
	"before-module" : null
};

liwe.history._load = function ()
{
	liwe.history._is_ie = ( document.all && navigator.userAgent.toLowerCase().indexOf ( 'msie' ) != -1 );

	liwe.history._blank_page = liwe._libbase + "/data/history_blank.html";

	liwe.history._data_storage = [];
	
	if ( liwe.history._is_ie )
		liwe.history._int_create_iframe ();

	document.write ( '<form style="display: none;"><input id="historyDataText" type="text" value="" \/><\/form>' );
};

liwe.history.init = function ()
{
	liwe.history._saved_location = liwe.history.get_current_location();

	setInterval ( liwe.history._int_check_location, 100 );

	setTimeout ( liwe.history._init_done, 200 );
};


liwe.history._init_done = function ()
{
	var hdt = document.getElementById ( "historyDataText" );
	
	if ( hdt.value )
		liwe.history._data_storage  = hdt.value.parseJSON();

	liwe.history._int_call_listener();
};


liwe.history._int_create_iframe = function ()
{
	var loc = liwe.history.get_current_location();
	
	liwe.history._adding = true;
	
	document.write ( "<iframe style='border: 2px; width: 1px; "
                               + "height: 1px; position: absolute; bottom: 0px; "
                               + "right: 0px; display: none;' "
                               + "name='liwe.historyFrame' id='liwe.historyFrame' src='" + liwe.history._blank_page + "?" + loc + "'>"
                               + "<\/iframe>" );

	liwe.history._iframe = document.getElementById ( "liwe.historyFrame" );

	window._os3_history_cb = liwe.history._int_iframe_location_changed;
};


liwe.history.get_current_location = function ()
{
	var loc = window.location.hash;
	if ( loc.length > 0 && loc.charAt ( 0 ) == '#' )
		loc = loc.slice ( 1 );
	return loc;
};

liwe.history.get_current_obj = function ()
{
	var loc = liwe.history.get_current_location ().split ( "," );
	var t, l = loc.length;
	var res = {}, p;

	for ( t = 0; t < l; t ++ )
	{
		p = loc [ t ].split ( "=" );
		res [ p [ 0 ] ] = p [ 1 ];
	}

	return res;
};


liwe.history._int_call_listener = function ()
{
	if ( ! liwe.history.listener_callback ) return;

	var id = liwe.history.get_current_location ();
	var dict = liwe.history._str2dict ( id );
	var data, module;

	if ( typeof dict [ "__dk" ] != "undefined" )
	{
		var key = parseInt ( dict [ "__dk" ] );
		data = liwe.history._data_storage [ key ];
		delete dict [ "__dk" ];
	}

	if ( typeof dict [ "__m" ] != "undefined" )
		module = dict [ "__m" ];
	else
		module = "__DEFAULT__";

	if ( ! liwe.history.listener_callback [ module ] ) return;

	liwe.history._listener_call = true;
	try
	{
		liwe.history.listener_callback [ module ] ( dict, data );
	}
	finally
	{
		liwe.history._listener_call = false;
	}
};


liwe.history.set_listener = function ( listener, module )
{
	if ( ! module ) module = "__DEFAULT__";
	liwe.history.listener_callback [ module ] = listener;
};


liwe.history.add = function ( dict, data )
{
	return liwe.history.add_module ( null, dict, data );
};


liwe.history.add_module = function ( module, dict, data )
{
	if ( ! dict ) dict = {};

	if ( liwe.history._listener_call ) return;
	if ( dict.get ( "__nh" ) == 1 ) return;

	if ( liwe.history.cbacks [ 'before-add' ] )
	{
		// NOTE: function should return TRUE to block event propagation
		var block = liwe.history.cbacks [ 'before-add' ] ( module, dict, data );

		if ( block ) return;
	}

	if ( data )
	{
		var key = liwe.history._data_storage.length.toString();
		liwe.history._data_storage.push ( data );
		dict [ "__dk" ] = key;

		var s = liwe.history._data_storage.toJSONString();
		var is = document.getElementById ( "historyDataText" );
		is.value = s;
	}

	if ( module ) dict [ "__m" ] = module;

	var id = liwe.history._dict2str ( dict );
	window.location.hash = id;
	liwe.history._saved_location = id;

	if ( liwe.history._is_ie )
	{
		liwe.history._adding = true;
		liwe.history._iframe.src = liwe.history._blank_page + "?" + id;
	}
};


liwe.history.replace = function ( module, dict, data )
{
	if ( liwe.history._listener_call ) return;

	if ( dict.get ( "__nh" ) == 1 ) return;

	var key = (liwe.history._data_storage.length - 1).toString();
	liwe.history._data_storage [ liwe.history._data_storage.length - 1 ] = data;
	dict [ "__dk" ] = key;

	var s = liwe.history._data_storage.toJSONString();
	var is = document.getElementById ( "historyDataText" );
	is.value = s;

	if ( module ) dict [ "__m" ] = module;

	var loc = String ( location ).split ( '#' ) [ 0 ];
	var id = liwe.history._dict2str ( dict );
	window.location.replace ( loc + "#" + id );
	liwe.history._saved_location = id;

	if ( liwe.history._is_ie )
	{
		liwe.history._adding = true;
		liwe.history._iframe.src = liwe.history._blank_page + "?" + id;
	}
};


liwe.history._dict2str = function ( dict )
{
	var str = "";
	var is_first = true;
	
	var k, v;
	for ( k in dict )
	{
		v = dict [ k ];
		if ( typeof ( v ) == 'function' ) continue;

		if ( is_first ) is_first = false;
		else str += ",";
		
		str += k;
		if ( v != null && v != undefined )
		{
			v = v.toString();
			str += "=" + liwe.history._escape_value ( v );
		}

	}

	return str;
};


liwe.history._str2dict = function ( str )
{
	var tok;

	var dict = {};

	str = liwe.history._lstrip ( str );

	while ( str.length > 0 )
	{
		// cerco la virgola divisoria
		var cpos = str.indexOf ( "," );
		while ( cpos < str.length - 1 && str.charAt ( cpos + 1 ) == ',' )
			cpos = str.indexOf ( ",", cpos + 2 );

		if ( cpos == -1 )
		{
			tok = str;

			str = "";
		} else {
			tok = str.slice ( 0, cpos );

			str = str.slice ( cpos + 1 );
			str = liwe.history._lstrip ( str );
		}

		// splittiamo sull'uguale
		var splt = tok.split ( "=" );
		var k = splt [ 0 ];
		var v = liwe.history._join ( "=", splt.slice ( 1 ) );
		v = v.replace ( ",,", "," );

		dict [ k ] = unescape(v);
	}

	return dict;
};


liwe.history._escape_value = function ( v )
{
	return v.replace ( ",", ",," );
};


liwe.history._lstrip = function ( s )
{
	while ( s.length > 0 && s.charAt ( 0 ) == ' ' )
		s = s.slice ( 1 );

	return s;
};


liwe.history._join = function ( sep, arr )
{
	var l = arr.length;
	if ( l == 0 ) return "";
	
	var s = arr [ 0 ];
	for ( var i = 1; i < l ; i++ )
		s += sep + arr [ i ];

	return s;
};


liwe.history._int_iframe_location_changed = function ( id )
{
	if ( liwe.history._adding )
	{
		liwe.history._adding = false;
		return;
	}

	if ( id.length > 0 && id.charAt ( 0 ) == '?' )
		id = id.slice ( 1 );

	window.location.hash = id;
	liwe.history._saved_location = id;

	liwe.history._int_call_listener ();
};


liwe.history._int_check_location = function ()
{
	var loc = liwe.history.get_current_location();
	if ( loc == liwe.history._saved_location )
		return;

	liwe.history._saved_location = loc;

	if ( liwe.history._is_ie )
		liwe.history._iframe.src = liwe.history._blank_page + "?" + loc;
	else
		liwe.history._int_call_listener();
};

liwe.history._load();
liwe.module = function ( name, history_cbacks )
{
	function _module ( name, history_cbacks )
	{
		var self = this;

		this.module_name = name;
		this._events = {};

		this.cbacks = {};	// Custom module callbacks

		this.history_cbacks = history_cbacks;

		this.event_dispatch = function ( dict, data )
		{
			console.debug ( this );
			console.debug ( this._events );

			var page = dict.get ( "_page" );
			var evt = this._events.get ( page );

			if ( liwe.history.cbacks [ 'before-module' ] ) 
				liwe.history.cbacks [ 'before-module' ] ( this.module_name, dict, data );

			if ( ! evt ) 
			{
				if ( this.history_cbacks && ( evt = this.history_cbacks [ page ] ) )
				{
					evt = this [ evt ];
				} else {
					console.warn ( "Module: %s - Event: %s not handled", this.module_name, page );
					return;
				}
			}

			evt ( dict, data );
		};

		this.set_history = function ( page_name, cback, dict )
		{
			if ( typeof ( cback ) == "string" ) cback = this [ cback ];

			console.debug ( "SET: %s", page_name );
			this._events [ page_name ] = cback;

			if ( ! dict ) dict = {};
			dict [ "_page" ] = page_name;
			liwe.history.add_module ( this.module_name, dict );
		};

		this.ajax = function ( dct, cback, url, easy )
		{
			var _obj = this;

			if ( typeof easy == "undefined" ) 
				easy = true;
			else
				easy = false;

			if ( typeof url == "undefined" )  url = null;
			if ( typeof cback == "undefined" )  cback = function ( v ) { console.debug ( "Module: %s - Result: %o", _obj.module_name, v ); };

			liwe.AJAX.request ( url, dct, cback, easy );
		};

		self.templates = null;

		this.load_templates = function ( cback )
		{
			if ( ! self.templates )
				self.ajax ( { action: self.module_name + ".ajax.get_templates" }, 
					function ( v ) 
					{ 
						self.templates = v [ 'templates' ]; 
						if ( cback ) cback ();
					} 
				);
		};
	}

	var mod = new _module ( name, history_cbacks );

	liwe.history.set_listener ( function ( dict, data ) { mod.event_dispatch ( dict, data ); }, name );

	return mod;
};

function WWL ( type, instance_name )
{
	this.class_name = "";

	/* REFINE WHEN NEEDED */
	this.to_string = function ()
	{
		var s = '', id;

		s = '<div class="wwl_' + this.type + '"><div id="' + this.id + '" ';

		s += this.mk_events ();

                s += ' class="' + WWL.mk_class_str ( this, ( this._is_disabled ? "disabled" : null ) ) + '">';
		s += this.name;
                s += '</div></div>';

		return s;
	};

	/* DO NOT TOUCH !! */
	this.type = type;
	this.name = instance_name;
	this.id	  = type + ":" + instance_name;

	this._events = {};
	this._is_disabled = false;
	this._dest_id = null;
	this._blocked_events = {};

	this._event_names = [ 'over', 'out', 'btn_up', 'btn_down', 'click', 'dblclick', 'blur' ];

	this.set_event 	  = function ( name, cback ) { this._events [ name ] = cback; };
	this.block_event  = function ( name, mode )  { this._blocked_events [ name ] = mode; };

	this.send_event = function ( evt_name )
	{
		WWL.evt ( null, document.getElementById ( this.id ), evt_name, this );
	};

	this.mk_events = function ()
	{
		var s = '';
		var t, l = this._event_names.length;
		var evt_name, map_name;

		for ( t = 0; t < l; t ++ )
		{
			evt_name = this._event_names [ t ];
			map_name = WWL._event_remap [ evt_name ];
			if ( ! map_name ) map_name = evt_name;

			s += ' on' + map_name + '="return WWL.evt(event,this,\'' + evt_name + '\')" ';
		}

		return s;
	};

	this.disable = function ( is_disabled )
	{
		this._is_disabled = is_disabled;
		this.render ();
	};

	this.render = function ( html_id )
	{
		var s = '', id;
		var el;

		// debugger

		if ( ! html_id ) html_id = this._dest_id;

		if ( html_id )
		{
			// Ho l'id giusto
			this._dest_id = html_id;
			el = document.getElementById ( this._dest_id );

			if ( ! el )
			{
				console.error ( "ERROR: element with id: '" + this._dest_id + "' does not exists" );
				return;
			}
		} else {
			// No HTML ID e no dest_id
			if ( ! this.id )
			{
				console.error ( "ERROR: element %s does not have dest_id or this.id", this.name );
				return;
			}
			el = document.getElementById ( this.id );

			if ( ! el ) return;

			el = el.parentNode;
		}

		el.innerHTML = this.to_string ();
	};

	this.value = function ( new_val )
	{
		var el = document.getElementById ( this.id );
		var old_val = el.value;

		if ( new_val !== undefined )
		{
			if ( new_val != old_val )
			{
				el.value = new_val;
				// WWL.evt ( null, el, 'change', this );
				this.send_event ( 'change' );
			}
		}

		return old_val;
	};

	WWL._instances [ type + ":" + instance_name ] = this;
}

WWL._instances = {};
WWL._int_events = {};
WWL._event_remap = {
			"over"  : "mouseover",
			"out"   : "mouseout",
			"btn_up" : "mouseup",
			"btn_down" : "mousedown"
		   };

WWL.get_instance = function ( type, instance_name )
{
	return WWL._instances [ type + ":" + instance_name ];
};

WWL.evt = function ( evt, div, event_name, widget )
{
	var event_result = null;

	if ( ! widget ) widget = WWL._resolve_widget ( div.id ); // WWL._instances [ div.id ];

	if ( widget._is_disabled ) return false;
	if ( widget._blocked_events [ event_name ] ) return false;

	// widget.className = widget.className ( /evt_[a-zA-Z0-9]*/, "" );
	// div.className = "wwl " + widget.type + " " + widget.class_name;

	// if ( WWL [ widget.type ]._int_events && WWL [ widget.type ]._int_events [ event_name ] ) WWL [ widget.type ]._int_events [ event_name ] ( widget, div, evt );
	if ( widget._events [ "before-" + event_name ] ) event_result = widget._events [ "before-" + event_name ] ( widget, event_name, div, evt );
	if ( widget._int_events && widget._int_events [ event_name ] ) widget._int_events [ event_name ] ( widget, div, evt );
	if ( widget._events [ event_name ] ) event_result = widget._events [ event_name ] ( widget, event_name, div, evt );

	if ( event_result === null ) event_result = true;

	return event_result === null ? true : event_result;
};

WWL._resolve_widget = function ( id_name )
{
	var w = WWL._instances [ id_name ];
	if ( w ) return w;

	var lst = id_name.split ( ":" );
	var name;
	lst.pop ();

	while ( lst.length )
	{
		name = lst.join ( ":" );
		w = WWL._instances [ name ];
		if ( w ) return w;
	}

	return null;
};

WWL.get_char_code = function ( evt )
{
        evt = ( evt ) ? evt : event;

        // if ( evt.charCode < 32 ) return true;
                
        return ( evt.charCode ) ? evt.charCode : ( ( evt.which ) ? evt.which : evt.keyCode );
};

WWL.get_char = function ( evt )
{
	var ccode = WWL.get_char_code ( evt );

	if ( ccode < 32 ) return null;

        return String.fromCharCode ( ccode );
};

// Automagically includes dependencies
// example: WWL.include ( 'button' );
//
// This function requires liwe.js module
WWL.include = function ( module_name )
{
	var wait_str = "WWL." + module_name;

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

	liwe.utils.append_js ( module_name + ".js" );
};

WWL.mk_class_str = function ( widget, class_name )
{
	var s = ( widget.class_name ? 
			( widget.class_name  + ( class_name ? "_" + class_name : "" ) ) :
			( class_name ? class_name : "" ) );

	return s;
};

WWL._libbase = "";

WWL.set_libbase = function ( libbase_url )
{
	if ( libbase_url )
	{
		WWL._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 ( /wwl.js/ ) )
		{
			pos = s.lastIndexOf ( "/" );
			if ( pos != -1 ) path = s.slice ( 0, pos + 1 );
		}
	}

	if ( path ) WWL._libbase = path;
	else WWL._libbase = "/os3wwl";
};

WWL.set_libbase ();
var HTMLEdManager = {};

HTMLEdManager._instances = {};
HTMLEdManager._plugins = {};

HTMLEdManager.create = function ( name, txtarea_id, plugins )
{
	var htmled = new HTMLEd ( name, plugins );

	if ( txtarea_id ) htmled.replace ( txtarea_id );

	HTMLEdManager._instances [ name ] = htmled;

	return htmled;
};

HTMLEdManager.get = function ( name )
{
	return HTMLEdManager._instances [ name ];
};

HTMLEdManager.register_plugin = function ( name, plugin_data )
{
	HTMLEdManager._plugins [ name ] = plugin_data;
};

HTMLEdManager.execute = function ( ed_name, plugin_name, action )
{
	var editor = HTMLEdManager._instances [ ed_name ];
	var plugin = HTMLEdManager._plugins [ plugin_name ];
	var act    = plugin [ 'actions' ] [ action ];

	act [ 1 ] ( editor.iframe.contentWindow.document, editor );

	// console.debug ( act );
};

/*
	This is the generic HTMLEd class, the real interface
	for both Mozilla and IE version of the editor
*/
function HTMLEd ( name, plugins )
{
	this.name	= name;		// Name of the HTMLEditor
	this.plugins	= plugins;

	this.iframe	= null;		// IFrame
	this.doc 	= null;		// ContentWindow.document

	this._div_toolbar = null;
	this._toolbar = null;
	
	this.toolbar_elements = 10;

	this.create_toolbar = function ()
	{
		var plugins = HTMLEdManager._plugins;
		var s = '';
		var cont = 0;
		var _obj = this;

		this._toolbar = new WWL.toolbar ( this.name + ":tbar" );
		
		plugins.iterate ( function ( v, k ) { 
			var pname = k;

			if ( _obj.plugins && _obj.plugins.indexOf ( pname ) < 0 ) return;

			v [ 'actions' ].iterate ( function ( v, k ) {
				_obj._toolbar.add_item ( { style: "htmled-" + pname + "-" + v [ 2 ], tooltip: v [ 2 ], cback: function () { HTMLEdManager.execute ( _obj.name, pname, k ); } } );
				}  );

				if ( cont > _obj.toolbar_elements )
				{
					cont = 0;
					_obj._toolbar.add_item ( { type: "newline" } );
				}
			}
		);

		this._div_toolbar.innerHTML = this._toolbar.to_string ();
	};

	this.replace = function ( textarea_id, w, h, html_text )
	{
		var txt_area = $( textarea_id );
		var main_div;
		var _obj = this;

		main_div = document.createElement ( "div" );
		main_div.id = this.name + ":main";

		this._div_toolbar = document.createElement ( "div" );
		this._div_toolbar.id = this.name + ":toolbar";
		this._div_toolbar.className = "wwl_htmled";

		this.iframe = document.createElement ( "iframe" );
		this.iframe.htmled = this;	// Save HTMLEd reference into the iframe
		if ( w ) this.iframe.style.width = w + "px";
		if ( h ) this.iframe.style.height = h + "px";

		this.textarea = document.createElement ( 'textarea' );
		this.textarea.htmled = this;	// Save HTMLEd reference into the iframe
		this.textarea.style.display = "none";

		main_div.appendChild ( this._div_toolbar );
		main_div.appendChild ( this.iframe );
		main_div.appendChild ( this.textarea );

		txt_area.parentNode.appendChild ( main_div );
		txt_area.style.display = 'none';

		function _set_design_mode ()
		{
			console.debug ( "Set Design Mode ... ");
			if ( _obj.iframe && _obj.iframe.contentWindow && _obj.iframe.contentWindow.document )
			{
				_obj.doc = _obj.iframe.contentWindow.document;
				_obj.doc.designMode = "on";
				_obj.set_html ( html_text );
			} else
				setTimeout ( _set_design_mode, 400 );
		}
		
		setTimeout ( _set_design_mode, 500 );

		this.create_toolbar ();
	};

	this.remove = function ()
	{
		var div = $( this.name + ":main" );
		if ( ! div ) return;

		div.parentNode.removeChild ( div );
	};

	this.perform = function ( btn )
	{
		var split = btn.split ( "/" );
		this.plugins [ split [ 0 ] ] [ split [ 1 ] ] ();
	};

	this.get_html = function ()
	{
		var s = this.doc.body.innerHTML;

		return s;
	};

	this.set_html = function ( html )
	{
		if ( this.doc )
			this.doc.body.innerHTML = html;
		else {
			console.debug ( "Waiting ... " );
			var _obj = this;
			setTimeout ( function () { _obj.set_html ( html ); }, 300 );
		}
	};


	this.show_html = function ( show )
	{
		var shown = ( this.textarea.style.display == "block" );
		var s;

		if ( typeof show == "undefined" ) show = ! shown;

		if ( show )
		{
			s = this.get_html ();
			this.textarea.value = s;

			this.textarea.style.width = this.iframe.clientWidth + "px";
			this.textarea.style.height = this.iframe.clientHeight + "px";

			this.iframe.style.display = "none";
			this.textarea.style.display = "block";
		}
		else
		{
			s = this.textarea.value;
			this.set_html ( s );

			this.iframe.style.display = "block";
			this.textarea.style.display = "none";
		}
	};
}

function _init_iframe () 
{
	_os3_htmled.set ( _os3_htmled.frame_id );

	var doc = _os3_htmled.doc;

	if (! doc )
	{
		// Try again..
		if ( _os3_htmled.is_gecko) {
			setTimeout ( _init_iframe, 100 );
			return;
		} else {
			alert("ERROR: IFRAME can't be initialized.");
		}
	} else {
		doc.designMode = "on";
		alert ( doc.designMode );
	}
}
/*
	Edit Plugin
*/
HTMLEdManager.register_plugin ( "edit", 
{
	actions: [
			[ "cut", 	function ( doc ) { doc.execCommand ( "cut", false, null ); }, "cut" ],
			[ "copy", 	function ( doc ) { doc.execCommand ( "copy", false, null ); }, "copy" ],
			[ "paste", 	function ( doc ) { doc.execCommand ( "paste", false, null ); }, "paste" ],
			[ "undo",	function ( doc ) { doc.execCommand ( "undo", false, null ); }, "undo" ],
			[ "redo", 	function ( doc ) { doc.execCommand ( "redo", false, null ); }, "redo" ]
		]
} );
/*
	Text Styles Plugin
*/
HTMLEdManager.register_plugin ( "text_styles", 
{
	actions: [
			[ "bold",      function ( doc ) { doc.execCommand ( "bold", false, null ); }, "bold" ],
			[ "italic",    function ( doc ) { doc.execCommand ( "italic", false, null ); }, "italic" ],
			[ "underline", function ( doc ) { doc.execCommand ( "underline", false, null ); }, "underline" ],
			[ "superscript", function ( doc ) { doc.execCommand ( "superscript", false, null ); }, "sup" ],
			[ "subscript", function ( doc ) { doc.execCommand ( "subscript", false, null ); }, "sub" ],
			[ "striket", function ( doc ) { doc.execCommand ( "strikethrough", false, null ); }, "striket" ]
		]
} );
/*
	Text Align Plugin
*/
HTMLEdManager.register_plugin ( "text_align", 
{
	actions: [
			[ "left", function ( doc ) { doc.execCommand ( "justifyleft", false, null ); }, "left" ],
			[ "right", function ( doc ) { doc.execCommand ( "justifyright", false, null ); }, "right" ],
			[ "center", function ( doc ) { doc.execCommand ( "justifycenter", false, null ); }, "center" ],
			[ "full", function ( doc ) { doc.execCommand ( "justifyfull", false, null ); }, "full" ]
	]
} );

/*
	HTML Plugin
*/
HTMLEdManager.TablePlugin = {};

HTMLEdManager.TablePlugin.create_table = function ( doc, editor )
{
	HTMLEdManager.TablePlugin.create_table._cur_doc = doc;

	liwe.lightbox.fade = false;
	liwe.lightbox.easy ( "htmled_table", "Inserimento tabella", 500, 160 );

	$ ( "htmled_table" ).innerHTML = '<table border="0" width="100%">' +
				'<tr>' +
				'	<td>Righe:</td>' +
				'	<td><input type="text" id="htmled_table_rows" value="3" /></td>' +
				'	<td>Colonne:</td>' +
				'	<td><input type="text" id="htmled_table_cols" value="2" /></td>' +
				'</tr>' +
				'<tr>' +
				'	<td>Larghezza:</td>' +
				'	<td><input type="text" id="htmled_table_width" value="200" /></td>' +
				'	<td>Altezza:</td>' +
				'	<td><input type="text" id="htmled_table_height" value="" /></td>' +
				'</tr>' +
				'<tr>' +
				'	<td>Spaziatura celle:</td>' +
				'	<td><input type="text" id="htmled_table_cellsp" value="1" /></td>' +
				'	<td>Padding celle:</td>' +
				'	<td><input type="text" id="htmled_table_cellpad" value="1" /></td>' +
				'</tr>' +
				'<tr>' +
				'	<td>Bordo:</td>' +
				'	<td><input type="text" id="htmled_table_border" value="1" /></td>' +
				'	<td>Allineamento:</td>' +
				'	<td>' +
				'		<select id="htmled_table_align">' +
				'			<option value="left" selected="selected">Sinistra</option>' +
				'			<option value="center">Centrato</option>' +
				'			<option value="right">Destra</option>' +
				'		</select>' +
				'	</td>' +
				'</tr>' +
				'<tr>' +
				'	<td align="center" colspan="4">' +
				'		<button type="button" onclick="HTMLEdManager.TablePlugin.create_table_done()">Ok</button>' +
				'		<button type="button" onclick="liwe.lightbox.close()">Annulla</button>' +
				'	</td>' +
				'</tr>' +
				'</table>';
};


HTMLEdManager.TablePlugin.create_table_done = function ()
{
	var rows = $v ( "htmled_table_rows" );
	var cols = $v ( "htmled_table_cols" );
	var width = $v ( "htmled_table_width" );
	var height = $v ( "htmled_table_height" );
	var cellsp = $v ( "htmled_table_cellsp" );
	var cellpad = $v ( "htmled_table_cellpad" );
	var border = $v ( "htmled_table_border" );
	var align = $v ( "htmled_table_align" );

	liwe.lightbox.close ();

	var doc = HTMLEdManager.TablePlugin.create_table._cur_doc;

	var t = doc.createElement ( "TABLE" );
	
	t.setAttribute ( "border", border );
	t.setAttribute ( "width", width );
	t.setAttribute ( "height", height );
	t.setAttribute ( "align", align );
	t.setAttribute ( "cellPadding", cellpad );
	t.setAttribute ( "cellSpacing", cellsp );

	if ( ! rows ) rows = 0;
	else rows = parseInt ( rows, 10 );

	if ( ! cols ) cols = 0;
	else cols = parseInt ( cols, 10 );

	var tbody = doc.createElement ( "TBODY" );
	t.appendChild ( tbody );

	var r;
	for ( r = 0; r < rows; r ++ )
	{
		var tr = doc.createElement ( "TR" );
		tbody.appendChild ( tr );
		
		var c;
		for ( c = 0; c < cols; c ++ )
		{
			var td = doc.createElement ( "TD" );
			tr.appendChild ( td );

			if ( navigator.userAgent.indexOf ( "Gecko" ) >= 0 )
			{
				var br = doc.createElement ( "BR" );
				br.setAttribute ( "type", "_moz" );
				td.appendChild ( br );
			}
		}
	}

	doc.body.appendChild ( t );
};


HTMLEdManager.register_plugin ( "table", 
{
	actions : [
			[ "create_table", HTMLEdManager.TablePlugin.create_table, "create_table" ]
	]
} );

/*
	List Plugin
*/
HTMLEdManager.register_plugin ( "list", 
{
	actions : [
			[ "unordered", function ( doc ) { doc.execCommand ( "insertunorderedlist", false, null ); }, "unordered" ],
			[ "ordered", function ( doc ) { doc.execCommand ( "insertorderedlist", false, null ); }, "ordered" ]
	]
} );
/*
	HTML Plugin
*/
HTMLEdManager.register_plugin ( "html", 
{
	actions : [
			[ "show_html", function ( doc, editor ) { editor.show_html (); }, "show_html" ]
	]
} );

WWL.uploader = function ( name )
{
	var uploader = new WWL ( 'uploader', name );

	var orig_name = name;

	uploader.type = 0;		// valid: mini, small, full

	uploader.cbacks = {
		"complete" : null,
		"error" : null,
		"cancel" : null
	};

	uploader.to_string = function ()
	{
		var name = "swf:" + uploader.id;
		var w, h;

		switch ( uploader.type )
		{
			case 0:
				w = 340;
				h = 30;
				break;
			case 1:
				w = 350;
				h = 80;
				break;

			case 2:
				w = 350;
				h = 320;
		}

		w = 400;
		h = 275;

		var s = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="' + name + '" width="' + w + '" height="' + h + '" ' +
                        'codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab"> ' + 
                        '<param name="movie" value="' + WWL._libbase + '/uploader/gfx/uploader.swf" /> ' + 
                        '<param name="quality" value="high" /> ' + 
                        '<param name="bgcolor" value="#ffffff" /> ' + 
                        '<param name="allowNetworking" value="all" /> ' + 
                        '<param name="allowScriptAccess" value="always" /> ' +
			'<param name="flashVars" value="upl_id=' + orig_name + '&" />' + 
                        '<embed src="' + WWL._libbase + '/uploader/gfx/uploader.swf" quality="high" bgcolor="#ffffff" width="' + w + '" height="' + h + '" name="' + name + '" align="middle" ' +
                        'play="true" loop="false" quality="high" flashVars="upl_id=' + orig_name + '" allowNetworking="all" ' + 
			' allowScriptAccess="always" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer"> ' +
                        '</embed> </object>';

		return s;
	};

	return uploader;
};

WWL.uploader.event = function ( upl_id, mode )
{
	var upl = WWL.get_instance ( "uploader", upl_id );

	if ( upl.cbacks [ mode ] ) upl.cbacks [ mode ] ();
};

WWL.uploader.TYPE_MINI  = 0;
WWL.uploader.TYPE_SMALL = 1;
WWL.uploader.TYPE_FULL  = 2;
liwe.form.instance.prototype.uploader = function ( vars )
{
	vars [ 'os3_class_value' ] = '';

	this._start_field ( vars );

	var upl = new WWL.uploader ( vars [ 'name' ] );

	upl.type = vars.get ( "type", 0 );

	this.html += upl.to_string ();

	this._widgets [ vars [ 'name' ] ] = upl;

	this._newline ( vars );

	this.events [ 'submit' ] = function ( form_fields, action, cback )
	{
		upl.cbacks [ 'complete' ] = cback;

		console.debug ( "CUSTOM SUBMIT: %s", action );
		var p = upl._get_player ();

		form_fields.iterate ( function ( v, k ) { if ( k ) p.setArg ( k, v ); } );
		p.setURL ( action );
		p.send ();
	};

	upl.get_value = function ()
	{
		return "uploader";
	};

	upl._get_player = function ()
	{
        	if ( navigator.appName.indexOf ( "Microsoft" ) != -1) 
             		return window [ "swf:" + upl.id ];

        	return document [ "swf:" + upl.id ];
	};
};
var media_manager = liwe.module ( "media_manager" );

function MediaManagerItem ( data, templ_preview, templ_full )
{
	this.data = data;
	this._t_preview = templ_preview;
	this._t_full    = templ_full;

	this.preview = function ( mode )
	{
		if ( ! mode ) mode = "icon";

		this.data [ '_mode' ] = mode;
		// var s = String.formatDict ( MediaManagerItem.templates [ this.data [ 'kind' ] + "-preview" ], data );
		return String.formatDict ( this._t_preview, this.data );
	}

	this.toString = function ()
	{
		// return String.formatDict ( MediaManagerItem.templates [ this.data [ 'kind' ] + "-render" ], data );
		return String.formatDict ( this._t_full, this.data );
	}
}

MediaManagerItem.templates = 
	{
		"image-preview"  : '<img src="/site/media_manager/image/%(_mode)s/%(id_media)s.jpg" alt="%(descr)s" title="%(descr)s" border="0" />',
		"image-render"  : '<img src="/site/media_manager/image/full/%(id_media)s.jpg" alt="%(descr)s" title="%(descr)s" border="0" />',

		"youtube-preview"  : '<img src="/site/media_manager/youtube/%(_mode)s/%(id_media)s.jpg" alt="%(descr)s" title="%(descr)s" border="0" />',
		"youtube-render" : '<object width="618" height="500"><param name="movie" value="http://www.youtube.com/v/%(data)s&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/%(data)s&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" wmode="transparent" width="618" height="500"></embed></object>',

		"start-view" : '<a href="javascript:media_manager.show(\'%(module)s\',\'%(id_obj)s\',%(_pos)d)">%(_img)s</a>',
		"flash-preview" : '<object width="200" height="200"><param name="movie" value="/site/media_manager/flash/orig/%(id_media)s.swf"></param><param name="wmode" value="transparent"></param><embed src="/site/media_manager/flash/orig/%(id_media)s.swf" type="application/x-shockwave-flash" wmode="transparent" width="200" height="200"></embed></object>',
		"flash-render" : '<object width="200" height="200"><param name="movie" value="/site/media_manager/flash/orig/%(id_media)s.swf"></param><param name="wmode" value="transparent"></param><embed src="/site/media_manager/flash/orig/%(id_media)s.swf" type="application/x-shockwave-flash" wmode="transparent" width="200" height="200"></embed></object>'
	};

media_manager.instances = {};

media_manager.get_items = function ( module, id_obj, cback, templates, force )
{
	if ( media_manager.instances [ module + ":" + id_obj ] && ! force )
	{
		if ( cback ) cback ( media_manager.instances [ module + ":" + id_obj ] );
		return;
	}

	media_manager.ajax ( { action: "media_manager.ajax.get_items", module: module, id_obj: id_obj }, 
		function ( v )
		{
			media_manager._set_items ( v, module, id_obj, templates, cback );
		} );
};

media_manager.get_items_list = function ( module, id_obj )
{
	if ( media_manager.instances [ module + ":" + id_obj ] )
		return media_manager.instances [ module + ":" + id_obj ];

	return [];
};

media_manager._set_items = function ( v, module, id_obj, templates, cback )
{
	// console.debug ( "SET ITEMS: module: %s - id_obj: %s - items: %o", module, id_obj, v [ 'media_items' ] );

	if ( ! templates ) templates = MediaManagerItem.templates;

	var items = v [ 'media_items' ];
	if ( ! items ) items = [];

	var t, l = items.length;
	var lst = [], data;

	for ( t = 0; t < l; t ++ )
	{
		data = v [ 'media_items' ] [ t ];
		lst.push ( media_manager._create ( data, templates ) );
	}

	media_manager.instances [ module + ":" + id_obj ] = lst;
	if ( cback ) return cback ( lst );

	return lst;
};

media_manager._create = function ( data, templates )
{
	var preview, full;
	var mmi;

	preview = templates [ data [ 'kind' ] + "-preview" ];
	full    = templates [ data [ 'kind' ] + "-render" ];

	mmi = new MediaManagerItem ( data, preview, full );

	return mmi;
};

media_manager.set_items = function ( items, templates )
{
	if ( ! items ) return;

	var it = items;

	if ( typeof it [ 'media_items' ] != "undefined" ) it = items [ 'media_items' ];
	console.debug ( "---- IT: %o", it );
	if ( ! it || it.length == 0 ) return;

	return media_manager._set_items ( { "media_items" : it }, it [ 0 ] [ 'module' ], it [ 0 ] [ 'id_obj' ], templates );
};

media_manager.panel = function ( items, mode, items_per_row )
{
	if ( ! mode ) mode = "icon";
	if ( ! items_per_row ) items_per_row = 8;

	return media_manager._render_icons ( items, mode, MediaManagerItem.templates [ 'start-view' ],  items_per_row);
};
	
media_manager.show = function ( module, id_obj, pos, width, force )
{
	// console.debug ( "SHOW: module: %s - id_obj: %s", module, id_obj );

	var items = media_manager.instances [ module + ":" + id_obj ];

	if ( ! items || ! items.length ) 
	{
		$( "mm-object", "" );
		$( "mm-panel", "" );
		return;
	}

	var mi = items [ pos ];
	var div;
	var lb_created = liwe.lightbox.created ();

	if ( ! width ) width = 800;

	if ( ! lb_created || force )
	{
		liwe.lightbox.events [ 'click' ] = function () { liwe.lightbox.close (); };

		if ( ! lb_created ) 
		{
			div = liwe.lightbox.create ( "mm-show-div", width, 700 );
			div.innerHTML = '<div id="mm-container" align="center"><div id="mm-tbar"><div id="mm-tbar-close" onclick="liwe.lightbox.close()"></div></div><div id="mm-object"></div><div id="mm-panel" class="panel"></div></div>';
		}

		$( "mm-panel", media_manager._render_icons ( items, "icon", MediaManagerItem.templates [ 'start-view' ], 8 ) );

		if ( ! lb_created ) liwe.lightbox.show ();
	}


	$( "mm-object", mi.toString () );
};

media_manager._render_icons = function ( items, mode, template, items_per_row )
{
	var t, l = items.length;
	var res = new String.buffer ();
	var mi, dct;
	var count = 0;

	res.add ( '<table border="0" class="media_manager_icons">' );
	
	for ( t = 0; t < l; t ++ )
	{
		if ( ! count ) res.add ( "<tr>" );
		count ++;

		mi = items [ t ];
		dct = { "id_obj" : mi.data [ 'id_obj' ], "module" : mi.data [ 'module' ], _pos: t, _img: mi.preview ( mode ) };

		res.add ( '<td>' );
		res.add ( String.formatDict ( template, dct ) );
		res.add ( '</td>' );

		if ( count == items_per_row ) 
		{
			res.add ( '</tr>' );
			count = 0;
		}
	}
	if ( count ) res.add ( '</td></tr>' );
	res.add ( '</table>' );

	return res.toString ();
};
var home = liwe.module ( "home", { "show_page": "_show_page", "gallery": "_show_gallery" } );

home._pages = {};

home.init = function ()
{
	var page = dict.get ( 'page', 5 );

	switch ( page )
	{
		case "news":
			home.show_news ();
			break;

		case "gallery":
			home.show_gallery ( dict );
			break;

		default:
			home.show_page ( page );
			break;
	}
};

home._show_page = function ( dict )
{
	home.show_page ( dict.get ( "page", "home" ) );
};


home.show_page = function ( page )
{
	if ( home [ 'show_' + page ] )
	{
		home.set_history ( "show_page", function ( data ) { home.show_page ( data [ 'page' ] ); }, { page: page } );
		home.set_menu ( page );
		home [ 'show_' + page ] ();
	}

	/*
	home.set_history ( "show_page_" + page, function ( data ) { home.show_page ( data [ 'page' ] ); }, { page: page } );

	home.set_menu ( page );

	if ( home [ 'show_' + page ] ) home [ 'show_' + page ] ();
	*/
};

home.set_menu = function ( page )
{
	var lnks = $ ( 'topbar' ).getElementsByTagName ( 'span' );
	var t, l = lnks.length;
	var lnk;
	var a;

	for ( t = 0; t < l; t ++ )
	{
		lnk = lnks [ t ];
		a = lnk.getElementsByTagName ( 'a' );
		if ( lnk.id == 'menu_' + page )
		{
			a [ 0 ].style.color = '#D1161F';
		}
		else a [ 0 ].style.color = 'white';
	}
};

home.create_cnt_page = function ( dct )
{
	return String.formatDict ( home.templates [ 'cnt_page' ], dct );
};

home.show_cartina = function ()
{
	liwe.lightbox.fade = false;
	liwe.lightbox.easy ( "cnt_cartina_big", "Percorso", 620, 620 );
	$( "cnt_cartina_big", '<img src="/gfx/cartina_big.jpg" alt="" title="" />' );

};

home.show_cont = function ()
{
	var f = home._create_contact_frm ();

	$ ( 'block_main' ).innerHTML = home.create_cnt_page ( { title: 'Contatti', txt: '', id_cnt: 'cnt_frm' } );

	f.set ( 'cnt_frm' );
};

home._create_contact_frm = function ()
{
	var f = new liwe.form.instance ( 'home-cont' );

	f.hidden ( "action", "home.ajax.contact_send" );
	f.email ( { label: "Tua Email", name: "sender", size: 40, mandatory: true } );
	f.text ( { label: "Oggetto", name: "obj", size: 40 } );
	f.textarea ( { label: "Messaggio", name: "msg", rows: 8, cols: 60, mandatory: true } );
	f.button ( { value: "Invia", name: "btn", onclick: 'home.contact_send()' } );

	return f;
};

home.contact_send = function ()
{
	var f = liwe.form.get ( 'home-cont' );
	var dct = f.get_values ();
	var obj = dct.get ( 'obj' );

	if ( ! f.check () ) return;

	if ( ! obj ) dct [ 'obj' ] = 'Family Bike - Contatti ';

	home.ajax ( dct, function ( v )
	{
		console.debug ( v );
	} );
};

home.get_html_page = function ( dct, page, cback )
{
	function _set_html ()
	{
		$ ( 'block_main' ).innerHTML = home._pages [ page ];
	}

	if ( ! home._pages [ page ] )
	{
		home.ajax ( { action: 'home.ajax.get_html_page', page: page }, function ( v ) {
			cback && cback ( v )
			dct [ 'txt' ] = String.formatDict ( v [ 'html' ], dct );

			home._pages [ page ] = home.create_cnt_page ( dct );

			_set_html ()
		} );
	}
	else _set_html ();
};

home.show_chisiamo = function ()
{
	var dct = { title: 'Chi Siamo', txt: '', id_cnt: 'cnt_chisiamo' };
	home.get_html_page ( dct, 'chisiamo' );
};

home.show_percorso = function ()
{
	var dct = { title: 'Percorso', txt: '', id_cnt: 'cnt_percorso', img: 'cartina.jpg' };
	home.get_html_page ( dct, 'percorso' );
};

home.show_info = function ()
{
	var dct = { title: 'Informazioni', txt: '', id_cnt: 'cnt_info', img: 'info_img.jpg' };
	home.get_html_page ( dct, 'info' );
};

home.show_home = function ()
{
	$ ( 'block_main' ).innerHTML = //'<img src="/gfx/hp_img.jpg" alt="FAMILY BIKE " title="FAMILY BIKE" />';
				'<div id="home_img" >' +
				'	<div class="cnt_imgs" >' +
				//'	<a href="http://www.inforete.it/index.html?videoid=1874&newsid=" target="_blank" >' +
				//'		<img src="/gfx/video_little.jpg" alt="VIDEO FAMILY BIKE " title="VIDEO FAMILY BIKE" />' +
				//'	</a>' +
				'	<a href="javascript:home.show_page(\'gallery\')" >' +
				'		<img class="foto_img" src="/gfx/foto_click.jpg" alt="FOTO FAMILY BIKE " title="FOTO FAMILY BIKE" />' +
				'	</a>' +
				'	</div>' +
				'</div>';
};

home.show_news = function ( id_news )
{
	if ( ! id_news ) id_news = site.get_param ( 'id_news', 8, -1 );


	if ( id_news < 0 ) return;

	home.set_menu ( "" );

	home.set_history ( "show_news_" + id_news, function ( data ) {
		home._cur_nid = data [ 'id_news' ];
		home.show_news ( data [ 'id_news' ] ); 
	}, { id_news: id_news, page: 'news' } );

	news.get ( id_news, home._show_news );
};

home._show_news = function ( v )
{
	var n = v [ 'news' ];
	var m = n [ 'media' ];
	var img = "";

	if ( m )
		img = String.formatDict ( m [ 0 ] [ 'html' ], { _size: 'small', _ext: m [ 0 ] [ 'ext' ] } );

	home._pages [ 'news' ] = null;

	var txt_n = String.formatDict ( '<div class="abs">%(abstract)s</div><div class="descr">%(descr)s</div>', n );

	var dct = { title: n [ 'title' ], txt: txt_n, id_cnt: 'cnt_info', img: img };
	home.get_html_page ( dct, 'news' );
};

/*
home.show_gallery = function ()
{
	home.set_history ( "gallery", function ( data ) { home.show_gallery (); } );

	home.set_menu ( "gallery" );

	var flash =
		'<div style="height: 500px">' +
		'<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"' +
		' codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0"' +
		' width="100%" height="100%" align="middle">' +
		'	<param name="allowScriptAccess" value="sameDomain" />' +
		'	<param name="allowFullScreen" value="false" />' +
		'	<param name="movie" value="/modules/gallery/flash/xmlGalleryThumbs.swf" />' +
		'	<param name="quality" value="high" />' +
		'	<param name="scale" value="noscale" />' +
		'	<param name="bgcolor" value="#333333" />' +
		'	<embed src="modules/gallery/flash/xmlGalleryThumbs.swf" quality="high" scale="noscale" bgcolor="#333333" ' +
		'		width="100%" height="100%" name="/gallery/xmlGalleryThumbs" align="middle" ' +
		'		allowScriptAccess="sameDomain" allowFullScreen="false" type="application/x-shockwave-flash" ' +
		'		pluginspage="http://www.macromedia.com/go/getflashplayer" />' +
		'</object>' +
		'</div>';

	flash =
		'<div style="height: 500px">' +
		'<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"' +
		' codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0"' +
		' width="100%" height="100%" align="middle">' +
		'	<param name="allowScriptAccess" value="sameDomain" />' +
		'	<param name="allowFullScreen" value="false" />' +
		'	<param name="movie" value="/modules/gallery/flash2/viewer.swf" />' +
		'	<param name="quality" value="high" />' +
		'	<param name="scale" value="noscale" />' +
		'	<param name="bgcolor" value="#ffffff" />' +
		'	<param name="xmlDataPath" value="/modules/gallery/gallery2.pyhp" />' +
		'	<param name="flashvars" value="xmlDataPath=/modules/gallery/gallery2.pyhp" />' +
		'	<embed src="/modules/gallery/flash2/viewer.swf" quality="high" scale="noscale" bgcolor="#ffffff" ' +
		'		width="100%" height="100%" name="viewer" align="middle" ' +
		'		flashvars="xmlDataPath=/modules/gallery/gallery2.pyhp" ' +
		'		xmlDataPath="/modules/gallery/gallery2.pyhp" ' + 
		'		allowScriptAccess="sameDomain" allowFullScreen="false" type="application/x-shockwave-flash" ' +
		'		pluginspage="http://www.macromedia.com/go/getflashplayer" />' +
		'</object>' +
		'</div>';

	// var flash2 = '<div id="gallery_flash_cnt" style="height: 500px"></div>';
	
	$ ( "block_main", String.formatDict ( home.templates [ "cnt_page" ],
		{ title: 'Galleria immagini <a href="javascript:home.gallery_upload()">' +
			'',
			// '<img border="0" style="vertical-align: top" height="27" src="/gfx/upload.png" alt="Upload" title="Upload" /></a>',
			txt: flash, id_cnt: 'gallery_cnt' } ) );
};
*/

home.show_gallery = function ( dict )
{
	if ( ! dict ) dict = {};
	var year = dict.get ( 'year' );

	home.set_history ( "gallery", function ( data ) { home.show_gallery ( dict ); }, { 'year': year } );

	home.set_menu ( "gallery" );

	/*
	var flash =
		'<div style="height: 500px">' +
		'<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"' +
		' codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0"' +
		' width="100%" height="100%" align="middle">' +
		'	<param name="allowScriptAccess" value="sameDomain" />' +
		'	<param name="allowFullScreen" value="false" />' +
		'	<param name="movie" value="/modules/gallery/flash/xmlGalleryThumbs.swf" />' +
		'	<param name="quality" value="high" />' +
		'	<param name="scale" value="noscale" />' +
		'	<param name="bgcolor" value="#333333" />' +
		'	<embed src="modules/gallery/flash/xmlGalleryThumbs.swf" quality="high" scale="noscale" bgcolor="#333333" ' +
		'		width="100%" height="100%" name="/gallery/xmlGalleryThumbs" align="middle" ' +
		'		allowScriptAccess="sameDomain" allowFullScreen="false" type="application/x-shockwave-flash" ' +
		'		pluginspage="http://www.macromedia.com/go/getflashplayer" />' +
		'</object>' +
		'</div>';
	*/

	function _render_gallery ( year )
	{
		var flash =
			'<div style="height: 500px">' +
			'<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"' +
			' codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0"' +
			' width="100%" height="100%" align="middle">' +
			'	<param name="allowScriptAccess" value="sameDomain" />' +
			'	<param name="allowFullScreen" value="false" />' +
			'	<param name="movie" value="/modules/gallery/flash2/viewer.swf" />' +
			'	<param name="quality" value="high" />' +
			'	<param name="scale" value="noscale" />' +
			'	<param name="bgcolor" value="#ffffff" />' +
			'	<param name="xmlDataPath" value="/modules/gallery/gallery2.pyhp?year=' + year + '" />' +
			'	<param name="flashvars" value="xmlDataPath=/modules/gallery/gallery2.pyhp?year=' + year + '" />' +
			'	<embed src="/modules/gallery/flash2/viewer.swf" quality="high" scale="noscale" bgcolor="#ffffff" ' +
			'		width="100%" height="100%" name="viewer" align="middle" ' +
			'		flashvars="xmlDataPath=/modules/gallery/gallery2.pyhp?year=' + year + '" ' +
			'		xmlDataPath="/modules/gallery/gallery2.pyhp?year=' + year + '" ' + 
			'		allowScriptAccess="sameDomain" allowFullScreen="false" type="application/x-shockwave-flash" ' +
			'		pluginspage="http://www.macromedia.com/go/getflashplayer" />' +
			'</object>' +
			'</div>';

		// var flash2 = '<div id="gallery_flash_cnt" style="height: 500px"></div>';
		
		$ ( "block_main", String.formatDict ( home.templates [ "cnt_page" ],
			{ title: 'Galleria immagini' +
				'',
				// '<img border="0" style="vertical-align: top" height="27" src="/gfx/upload.png" alt="Upload" title="Upload" /></a>',
				txt: flash, id_cnt: 'gallery_cnt' } ) );

		/*
		var fo = new SWFObject ( "/modules/gallery/flash2/viewer.swf", "viewer", "100%", "100%", "8", "#FFFFFF" );
		fo.addVariable ( "xmlDataPath", "/modules/gallery/gallery2.pyhp" );
		fo.write ( "gallery_flash_cnt" );
		*/
	}


	if ( ! year )
	{
		home._get_gallery_years ( function () {
			var t, l = home._gallery_years.length;
			var s = '';
			if ( l && l == 1 ) _render_gallery ( home._gallery_years [ 0 ] );
			else
			{
				for ( t = 0; t < l; t ++ )
				{
					s += String.formatDict ( home.templates [ "event_gallery_row" ], { 'year': home._gallery_years [ t ]} );
				}

				s = String.formatDict ( home.templates [ 'gallery_years' ], { txt: s, img: 'info_img3.jpg' });

				$ ( "block_main", String.formatDict ( home.templates [ "cnt_page" ], { title: 'Galleria immagini', txt: s, id_cnt: 'gallery_cnt' } ) );
			}
		} );
	}
	else _render_gallery ( year );
	
};

home._show_gallery = function ()
{
	home.show_gallery ();
};

home._get_gallery_years = function ( cback )
{
	//if ( ! home._gallery_years )
	//{
		liwe.AJAX.easy ( { 'action': "gallery.ajax.get_years"}, function ( v ) {
			home._gallery_years = v [ 'years' ];
			cback ();
		});
	//}
	//else cback ();
};


home.gallery_upload = function ()
{
	$ ( "block_main", String.formatDict ( home.templates [ "cnt_page" ],
		{ title: 'Galleria upload', txt: '', id_cnt: 'upload_cnt' } ) );

	var f = new liwe.form.instance ( "upload" );

	f.hidden ( "action", "gallery.ajax.upload" );

	f.text ( { label: "Descrizione", name: "descr", mandatory: true } );
	f.uploader ( { label: "Files", name: "files" } );

	f.submit ( { value: "Invia" } );

	f.set ( "upload_cnt" );
};

home.templates = {};
var self = home.templates;

self [ 'cnt_page' ] = 	'<div class="page_cnt">' +
			'	<div class="border_in">' +
			' 		<div class="page_top">' +
			'			<div class="border_in">%(title)s</div>' +
			'		</div>' +
			'		<div id="%(id_cnt)s" class="text" >%(txt)s</div>' +
			'	</div>' +
			'</div>';


self [ 'gallery_years' ] =
	'<table border="0" cellpadding="0" cellspacing="0" width="100%"><tr>' +
	'<td valign="top" width="250"><div class="img_left"><img src="/gfx/%(img)s" alt="" title="" /></div></td>' +
	'<td valign="top"><div class="text_right">%(txt)s</div></td>' +
	'</tr></table>';


self [ 'event_gallery_row'] =
	'<div class="event_gallery_row">Anno: <a href="javascript:home.show_gallery({year:\'%(year)s\'})">%(year)s</a></div>';
var news = liwe.module ( "news", { "news_show": "_show", "news_categ_search": "_categ_search" } );

news.templates = null;

news.cbacks = {
	'show': null,
	'before_show': null,
	'search': null,
	'before_search': null
};

news.cnts_navi = [];

news.init = function ( cback )
{
	news.cnts_navi = [];

	if ( ! news.templates )
	{
		liwe.AJAX.easy ( { action: "news.ajax.get_templates" }, function ( v ) {
			news.templates = v [ 'templates' ];
			cback && cback ();
		} );
	}
};

news.list = function ( dct, cback )
{
	if ( ! dct ) dct = {};

	dct [ 'action' ] = "news.ajax.list";

	liwe.AJAX.easy ( dct, function ( v )
		{
			console.debug ( v );	
			cback && cback ( v );
		} );
};

news.get = function ( id_news, permalink, cback )
{
	liwe.AJAX.easy ( { action: "news.ajax.get", 'id_news': id_news, 'permalink' : permalink }, function ( v ) {
		cback && cback ( v );
	} );
};

news._show = function ( data )
{
	if ( news.cbacks.get ( 'before_show' ) )  news.cbacks.get ( 'before_show' ) ();
	news.show ( data [ 'id_news' ], data [ 'dest' ], data [ 'permalink' ] );
};

news.show = function ( id_news, dest, permalink, pos )
{
	news.set_history ( "news_show", news._show, { "id_news" : id_news, "dest" : dest, "permalink" : permalink } );

	news.get ( id_news, permalink, function ( v ) {
		var n = v.get ( 'news' );
		var html = '';

		if ( n ) html = n [ '_html' ];

		if ( news.cbacks.get ( 'show' ) ) news.cbacks [ 'show' ] ( v [ 'news' ], id_news, dest, permalink, pos );
		else
		{
			$( dest, html );
			news.navi_render ( id_news, dest, permalink, pos );
		}
	} );
};

news.navi_render = function ( id_news, dest, permalink, pos )
{
	var t, l = news.cnts_navi.length
	if ( l <= 0 ) return;

	var in_navi = ( news.ds && pos != null );

	var num_rows = news.ds ? news.ds.num_rows : 0;
	var prev = null;
	var next = null;

	var id_prev_row = null;
	var id_next_row = null;

	if ( in_navi )
	{
		pos = parseInt ( pos, 10 );

		prev = (pos > 0) ? (pos - 1) : null;
		next = (pos < num_rows - 1) ? (pos + 1) : null;

		news.ds.prefetch ( ( prev ? prev : 0 ), function ()
		{
			news.ds.prefetch ( ( next ? next : 0 ), function ()
			{
				if ( prev != null ) id_prev_row = news.ds.get_row ( prev ) [ "id" ];
				if ( next != null ) id_next_row = news.ds.get_row ( next ) [ "id" ];

				var s = '';
				if ( id_prev_row ) s += String.formatDict ( news.templates [ 'NEWS_SHOW_NAVI_PREV' ],
					{ id: id_prev_row, dest: dest, permalink: permalink, pos: prev } );
				if ( id_next_row ) s += String.formatDict ( news.templates [ 'NEWS_SHOW_NAVI_NEXT' ],
					{ id: id_next_row, dest: dest, permalink: permalink, pos: next } );

				for ( t = 0; t < l; t ++ )
				{
					var cnt_nav = news.cnts_navi [ t ];
					if ( ! $ ( cnt_nav ) ) continue;

					$ ( cnt_nav ).innerHTML = s;
				}
			} );
		} );
	}
};

news.categ_search = function ( id_categ, dest, name, lines )
{
	news.set_history ( "news_categ_search", null, { 'id_categ': id_categ, dest: dest, lbl_categ: name, 'lines': lines } );

	var dct = {};
	dct [ 'id_categs' ] = id_categ;

	news.init_ds_search ( 'Correlati: ' + name, lines );

	news._search_start ( dct, dest );
};

news._check_templates = function ( cback )
{
	if ( ! news [ 'templates' ] ) setTimeout ( function () { news._check_templates ( cback ); }, 300 );
	else cback ();
};

news._categ_search = function ( data )
{
	news._check_templates ( function () {
		news.categ_search ( data [ 'id_categ' ], data [ 'dest' ], data [ 'lbl_categ' ], data [ 'lines' ] );
	} );
};


news.search = function ( txt, dest, name, lines )
{
	if ( !txt ) return;

	news.set_history ( "news_search", function ( data ) 
		{
			news.search ( data [ 'txt' ], data [ 'dest' ] ); 
		},
		{ 'testo': txt, dest: dest } 
	);

	var dct = {};
	dct [ 'testo' ] = txt;

	news.init_ds_search ( 'Correlati: ' + name, lines );

	news._search_start ( dct, dest );
};

news.tag_search = function ( tag, dest, lines, exclude_tags )
{
	news.set_history ( "news_tag_search", function ( data ) {
		news.tag_search ( data [ 'tag' ], data [ 'dest' ], data [ 'lines' ], data [ 'exclude_tags' ] ); 
		}, { tag: tag, dest: dest, lines: lines, exclude_tags: exclude_tags } 
	);

	var dct = {};

	dct [ 'tags' ] = tag;
	dct [ 'exclude_tags' ] = exclude_tags;

	//news.list ( dct, function ( v ) {
		//
	//} );

	news.init_ds_search ( 'Correlati: ' + tag, lines );
	//news.ds.lines_per_page = 1;

	
	news._search_start ( dct, dest );
};

news.init_ds_search = function ( titolo, lines )
{
	news.ds = new DataSet ( "ds_news", "/ajax.pyhp" );
	if ( ! titolo ) titolo = 'News';

	news._titolo = titolo;

	news.ds.templates [ 'table_start' ] = String.formatDict ( news.templates [ 'ds_news_start' ], { 'titolo_box': titolo } );
	news.ds.templates [ 'table_end' ]   = news.templates [ 'ds_news_end' ];
	news.ds.templates [ 'table_header' ] = news.templates [ 'ds_news_header' ];
	news.ds.templates [ 'table_footer' ] = news.templates [ 'ds_news_footer' ];
	
	news.ds.templates [ 'table_row' ] = news.templates [ 'ds_news_row' ];
	news.ds.templates [ 'prev_page' ] = news.templates [ 'ds_prev_page' ];
	news.ds.templates [ 'next_page' ] = news.templates [ 'ds_next_page' ];

	news.ds.paginator.templates [ "pag-link-space" ] = "&nbsp;&nbsp;";
	news.ds.paginator.templates [ "pag-sep" ] = "-";
	news.ds.paginator.templates [ "pag-first" ] = "&lt;&lt;";
	news.ds.paginator.templates [ "pag-last" ] = "&gt;&gt;";
	news.ds.paginator.templates [ "pag-right-info" ] = ' | <span class="pagi_res">Pag. <b>%(_PAGE)s</b> di <b>%(_TOT_PAGES)s</b></span>';

	news.ds.lines_per_page = lines ? lines : 10;

	news.ds.cbacks [ 'row_manip' ] = news._row_manip;

	if ( news.cbacks.get ( 'show_results' ) ) news.ds.cbacks [ 'show_results' ] = news.cbacks.get ( 'show_results' );
};

news._search_start = function ( dict, dest )
{
	if ( ! dict ) dict = {};

	if ( ! dest ) dest = "block_main";

	news._dest = dest;

	dict [ 'action' ] = "news.ajax.search";

	if ( news.cbacks.get ( 'search' ) ) news.cbacks [ 'search' ] ();

	news.ds.set_fields ( dict );
	news.ds.fill ( news._show_results );
};

news._show_results = function  ()
{
	if ( news.cbacks.get ( 'before_search' ) )  news.cbacks.get ( 'before_search' ) ();

	if ( news.ds.num_rows <= 0 ) $ ( news._dest ).innerHTML = String.formatDict ( news.templates [ 'no_result' ], { titolo_box: news._titolo } );
	else news.ds.render ( news._dest );
};

news._row_manip = function ( ds, row )
{
	if ( row [ '_img' ] == '-1' )
		row [ '_img' ] = news.templates [ 'NO_FOTO' ];
};

var tags = liwe.module ( "tags" );

tags._cache = {};
tags.limit = 0;

tags.init = function()
{

};

tags.list = function ( module_name, cback, reload )
{
	if ( ! reload && tags._cache [ module_name ] )
	{
		if ( cback ) cback ( tags._cache [ module_name ] );
	} else {
		tags.ajax ( { action: "tags.ajax.tags_list_all", module: module_name, limit: tags.limit }, 
			function ( v )
			{
				var res = {};
				var tgs = v [ 'tags' ], t, l = tgs.length;

				for ( t = 0; t < l; t ++ ) 
					res [ tgs [ t ] [ 'name' ] ] = tgs [ t ] [ 'id' ];

				tags._cache [ module_name ] = res;
				// console.debug ( "RES: %o", res );
				if ( cback ) cback ( tags._cache [ module_name ] );
			} );
	}
};

tags.convert = function ( tag_list )
{
	if ( ! tag_list ) return "";

	var t, l = tag_list.length;
	var s = new String.buffer ();

	for ( t = 0; t < l; t ++ )
		s.add ( tag_list [ t ] [ 'name' ] );

	return s.get ( "|" );
};
liwe.AJAX.url = "/ajax.pyhp";

var site = {};
site._cur_shown = null;

site.init = function ()
{
	news.init ();
	news.cnts_navi = [ "navi_news_top", "navi_news_bottom" ];
	news.cbacks [ 'before_show' ] = news.cbacks [ 'before_search' ] = function () { home.set_menu ( "news" ); };
	news.cbacks [ "show" ] = site.render_news;

	/*
	var page = site.get_param ( 'page', 5 );

	switch ( page )
	{
		case "news":
			home.show_news ();
			break;

		case "gallery":
			home.show_gallery ();
			break;

		default:
			home.show_page ( page );
			break;

	}
	*/

	liwe.history.set_listener ( function () { home.show_home (); } );
	liwe.history.init ();
};

site._init_admin = function ()
{
	//tags.admin.create_tags_menu ();
	banner.admin.init ();
	user.admin.init ();
	news.admin.init ( 'block_main' );
	//staticpage.admin.init ( 'block_main' );
};

site.logout = function ()
{
	user.events [ 'logout' ] = function(){ location.reload (); };
	user.logout();
};


site.render_news = function ( v, id_news, dest, permalink, pos  )
{
	var media_items = v [ 'media' ] && v [ 'media' ].length > 0 ? media_manager.set_items ( v [ 'media' ] ) : null;
	var str_imgs = '';
	v [ '_media_panel' ] = '';

	if ( media_items )
	{
		v [ '_media_panel' ] = media_manager.panel ( media_items, "icon", 2 );
		str_imgs = '<div class="mm_images_title">Galleria</div><div class="cnt_mm_images">' + v [ '_media_panel' ] + '</div>';
	}

	$ ( 'block_main' ).innerHTML = String.formatDict ( v [ '_html' ], { "_gallery": str_imgs } );

	var youtube = null;
	var media = v.get ( 'media', [] );
	var t, l = media.length;
	var s = '';

	for ( t = 0; t < l; t ++ )
	{
		var m = media [ t ];

		if ( m.kind == "youtube" )
		{
			youtube = m;
			break;
		}
	}

	news.navi_render ( id_news, dest, permalink, pos );
};


site.get_param = function ( p, l, def_val )
{
	var loc = document.location.hash;
	var url = '';
	var pos = loc.indexOf ( p + '=' );
	var param = def_val || 'home';

	if ( pos >= 0 ) 
	{
		pos += l;
		var p2 = loc.indexOf ( ",", pos );
		param = loc.substr ( pos, p2 - pos );
	}

	return param;
};

site.show_hide = function ( el_name )
{
	if ( site._cur_shown )
		site._cur_shown.style.display = 'none';

	var dst = $ ( el_name );
	var d = dst.style.display;

	site._cur_shown = dst;

	dst.style.display = 'block';
	/*
	if ( !d ) dst.style.display = 'none';
	else if ( d == "none" ) dst.style.display = 'block';
	else dst.style.display = 'none';
	*/
};

liwe.history.init ();
/**
 * SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/
 *
 * SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 *
 */
if(typeof deconcept=="undefined"){var deconcept=new Object();}if(typeof deconcept.util=="undefined"){deconcept.util=new Object();}if(typeof deconcept.SWFObjectUtil=="undefined"){deconcept.SWFObjectUtil=new Object();}deconcept.SWFObject=function(_1,id,w,h,_5,c,_7,_8,_9,_a){if(!document.getElementById){return;}this.DETECT_KEY=_a?_a:"detectflash";this.skipDetect=deconcept.util.getRequestParameter(this.DETECT_KEY);this.params=new Object();this.variables=new Object();this.attributes=new Array();if(_1){this.setAttribute("swf",_1);}if(id){this.setAttribute("id",id);}if(w){this.setAttribute("width",w);}if(h){this.setAttribute("height",h);}if(_5){this.setAttribute("version",new deconcept.PlayerVersion(_5.toString().split(".")));}this.installedVer=deconcept.SWFObjectUtil.getPlayerVersion();if(!window.opera&&document.all&&this.installedVer.major>7){deconcept.SWFObject.doPrepUnload=true;}if(c){this.addParam("bgcolor",c);}var q=_7?_7:"high";this.addParam("quality",q);this.setAttribute("useExpressInstall",false);this.setAttribute("doExpressInstall",false);var _c=(_8)?_8:window.location;this.setAttribute("xiRedirectUrl",_c);this.setAttribute("redirectUrl","");if(_9){this.setAttribute("redirectUrl",_9);}};deconcept.SWFObject.prototype={useExpressInstall:function(_d){this.xiSWFPath=!_d?"expressinstall.swf":_d;this.setAttribute("useExpressInstall",true);},setAttribute:function(_e,_f){this.attributes[_e]=_f;},getAttribute:function(_10){return this.attributes[_10];},addParam:function(_11,_12){this.params[_11]=_12;},getParams:function(){return this.params;},addVariable:function(_13,_14){this.variables[_13]=_14;},getVariable:function(_15){return this.variables[_15];},getVariables:function(){return this.variables;},getVariablePairs:function(){var _16=new Array();var key;var _18=this.getVariables();for(key in _18){_16[_16.length]=key+"="+_18[key];}return _16;},getSWFHTML:function(){var _19="";if(navigator.plugins&&navigator.mimeTypes&&navigator.mimeTypes.length){if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","PlugIn");this.setAttribute("swf",this.xiSWFPath);}_19="<embed type=\"application/x-shockwave-flash\" src=\""+this.getAttribute("swf")+"\" width=\""+this.getAttribute("width")+"\" height=\""+this.getAttribute("height")+"\" style=\""+this.getAttribute("style")+"\"";_19+=" id=\""+this.getAttribute("id")+"\" name=\""+this.getAttribute("id")+"\" ";var _1a=this.getParams();for(var key in _1a){_19+=[key]+"=\""+_1a[key]+"\" ";}var _1c=this.getVariablePairs().join("&");if(_1c.length>0){_19+="flashvars=\""+_1c+"\"";}_19+="/>";}else{if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","ActiveX");this.setAttribute("swf",this.xiSWFPath);}_19="<object id=\""+this.getAttribute("id")+"\" classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" width=\""+this.getAttribute("width")+"\" height=\""+this.getAttribute("height")+"\" style=\""+this.getAttribute("style")+"\">";_19+="<param name=\"movie\" value=\""+this.getAttribute("swf")+"\" />";var _1d=this.getParams();for(var key in _1d){_19+="<param name=\""+key+"\" value=\""+_1d[key]+"\" />";}var _1f=this.getVariablePairs().join("&");if(_1f.length>0){_19+="<param name=\"flashvars\" value=\""+_1f+"\" />";}_19+="</object>";}return _19;},write:function(_20){if(this.getAttribute("useExpressInstall")){var _21=new deconcept.PlayerVersion([6,0,65]);if(this.installedVer.versionIsValid(_21)&&!this.installedVer.versionIsValid(this.getAttribute("version"))){this.setAttribute("doExpressInstall",true);this.addVariable("MMredirectURL",escape(this.getAttribute("xiRedirectUrl")));document.title=document.title.slice(0,47)+" - Flash Player Installation";this.addVariable("MMdoctitle",document.title);}}if(this.skipDetect||this.getAttribute("doExpressInstall")||this.installedVer.versionIsValid(this.getAttribute("version"))){var n=(typeof _20=="string")?document.getElementById(_20):_20;n.innerHTML=this.getSWFHTML();return true;}else{if(this.getAttribute("redirectUrl")!=""){document.location.replace(this.getAttribute("redirectUrl"));}}return false;}};deconcept.SWFObjectUtil.getPlayerVersion=function(){var _23=new deconcept.PlayerVersion([0,0,0]);if(navigator.plugins&&navigator.mimeTypes.length){var x=navigator.plugins["Shockwave Flash"];if(x&&x.description){_23=new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/,"").replace(/(\s+r|\s+b[0-9]+)/,".").split("."));}}else{if(navigator.userAgent&&navigator.userAgent.indexOf("Windows CE")>=0){var axo=1;var _26=3;while(axo){try{_26++;axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+_26);_23=new deconcept.PlayerVersion([_26,0,0]);}catch(e){axo=null;}}}else{try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");}catch(e){try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");_23=new deconcept.PlayerVersion([6,0,21]);axo.AllowScriptAccess="always";}catch(e){if(_23.major==6){return _23;}}try{axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");}catch(e){}}if(axo!=null){_23=new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));}}}return _23;};deconcept.PlayerVersion=function(_29){this.major=_29[0]!=null?parseInt(_29[0]):0;this.minor=_29[1]!=null?parseInt(_29[1]):0;this.rev=_29[2]!=null?parseInt(_29[2]):0;};deconcept.PlayerVersion.prototype.versionIsValid=function(fv){if(this.major<fv.major){return false;}if(this.major>fv.major){return true;}if(this.minor<fv.minor){return false;}if(this.minor>fv.minor){return true;}if(this.rev<fv.rev){return false;}return true;};deconcept.util={getRequestParameter:function(_2b){var q=document.location.search||document.location.hash;if(_2b==null){return q;}if(q){var _2d=q.substring(1).split("&");for(var i=0;i<_2d.length;i++){if(_2d[i].substring(0,_2d[i].indexOf("="))==_2b){return _2d[i].substring((_2d[i].indexOf("=")+1));}}}return "";}};deconcept.SWFObjectUtil.cleanupSWFs=function(){var _2f=document.getElementsByTagName("OBJECT");for(var i=_2f.length-1;i>=0;i--){_2f[i].style.display="none";for(var x in _2f[i]){if(typeof _2f[i][x]=="function"){_2f[i][x]=function(){};}}}};if(deconcept.SWFObject.doPrepUnload){if(!deconcept.unloadSet){deconcept.SWFObjectUtil.prepUnload=function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){};window.attachEvent("onunload",deconcept.SWFObjectUtil.cleanupSWFs);};window.attachEvent("onbeforeunload",deconcept.SWFObjectUtil.prepUnload);deconcept.unloadSet=true;}}if(!document.getElementById&&document.all){document.getElementById=function(id){return document.all[id];};}var getQueryParamValue=deconcept.util.getRequestParameter;var FlashObject=deconcept.SWFObject;var SWFObject=deconcept.SWFObject;