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

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


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

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

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

	s += "}";

	return s;
};

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

	return res;
};

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

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

		arr [ k ] = a [ k ];
	}

	return arr;
};

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

	_form_add_elems ( f, arr, max_depth, 0 );

	return arr;
};

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

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

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

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

	return -1;
};

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

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

	return res;
};

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

	var to_del = Array();

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

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

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

		to_del.push ( k );
	}

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

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


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


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

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

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

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


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

		return this.length;
	};
}

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

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

		this.load_templates = function ()
		{
		};
	}

	var mod = new _module ( name, history_cbacks );

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

	return mod;
};

/*
 * 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 );
}
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 );
*/
/*
 * 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 );
	};
	// }}}
	// {{{ htmlarea ( vars ) 
	this.htmlarea = function ( vars )
	{
		console.error ( "form.htmlarea is deprecated. Use form.rte" );
		/*
		if ( typeof HTMLEdManager == 'undefined' ) 
		{
			alert ( _ ( "os3_form", "You *MUST* include HTMLEd" ) );
			return;
		}

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

		this.textarea ( vars );
		this.html += '<input type="hidden" name="' + vars [ 'name' ] + '" id="' + vars [ 'id' ] + ':htmled" />';

		// Register the HTMLEd 
		this._htmled.push ( vars [ 'name' ] );
		this._htmled_names [ vars [ 'name' ] ] = 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 ] );
		*/
	};
	// }}}
	// {{{ 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 );
	};
	// }}}
	// {{{ 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 );
	};
	// }}}
	// {{{ 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 );
	}
}; 
// }}}
/*
 * 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 ]; } );
};
/*
 * 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;
};

/*
 * 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;
}
/*
 * 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;
}
var drag = {};

drag.is_ie = document.all;
drag.enabled = false;
drag.obj = null;
drag.x = 0;
drag.y = 0;
drag.move_func = null;
drag.release_func = null;
drag.start_func = null;
drag.x_start = 0;
drag.y_start = 0;
drag.container_class = "drag_box";
drag.handle_class = "drag_handle";
drag.exclude_class = "drag_exclude";

drag.lock_x = false;
drag.lock_y = false;

drag.move = function ( e ) 
{
	if ( ! drag.enabled ) return;

	var xpos, ypos;
	var evt = drag.is_ie ? event : e;

	// document.title = "XSTART: " + drag.x_start + " - CX: " + evt.clientX + " - DX: " + drag.x;

	xpos = evt.clientX;
	ypos = evt.clientY;

	if ( ! drag.lock_y ) drag.obj.style.top = ( ypos - drag.y_start ) + "px";
	if ( ! drag.lock_x ) drag.obj.style.left = ( xpos - drag.x_start ) + "px";

	/*if ( ! drag.obj._dragged )
	{
		drag.obj._dragged = true;
		if ( drag.start_func ) drag.start_func ( drag.obj );
	}*/

	if ( drag.move_func ) drag.move_func ( drag.obj, xpos, ypos );
};

drag.start = function ( e ) 
{
	var evt = drag.is_ie ? event : e;

	var firedobj   = drag.is_ie ? evt.srcElement : evt.target;
	var topelement = drag.is_ie ? "BODY" : "HTML";

	if ( ! firedobj || firedobj == null || firedobj == "" || firedobj.tagName && firedobj.tagName == 'HTML' ) return;

	while ( firedobj.tagName != topelement &&
		( firedobj.className.indexOf ( drag.handle_class ) == -1 ) &&
		( firedobj.className.indexOf ( drag.exclude_class ) == -1 ) )
			firedobj = drag.is_ie ? firedobj.parentElement : firedobj.parentNode;

	if ( firedobj.className.indexOf ( drag.handle_class ) != -1 )
	{
		while ( firedobj.tagName != topelement && ( firedobj.className.indexOf ( drag.container_class ) == -1 ) )
			firedobj = drag.is_ie ? firedobj.parentElement : firedobj.parentNode;

		drag.enabled = true;
		drag.obj = firedobj;
		drag.x = evt.clientX;
		drag.y = evt.clientY;
		//drag.obj._dragged = false;
		document.onmousemove = drag.move;

		var start_x = 0;
		var start_y = 0;
		var obj = drag.obj;
		while ( obj && obj.tagName != topelement )
		{
			start_x += obj.offsetLeft;
			start_y += obj.offsetTop;
			obj = obj.offsetParent;
		}

		drag.x_start = drag.x - start_x;
		drag.y_start = drag.y - start_y;

		if ( drag.start_func ) drag.start_func ( drag.obj );

		drag.obj.parentNode.removeChild ( drag.obj );
		document.body.appendChild ( drag.obj );

		drag.obj.style.position = "absolute";
		drag.obj.style.top = ( drag.y - drag.y_start ) + "px";
		drag.obj.style.left = ( drag.x - drag.x_start ) + "px";
	}
}

drag.stop = function ()
{
	if ( ! drag.obj ) return;

	drag.enabled = false;

	if ( drag.release_func ) drag.release_func ( drag.obj );

	//drag.obj._dragged = false;

	drag.obj = false;
};

document.onmousedown = drag.start;
document.onmouseup = drag.stop;

var user = liwe.module ( "user" );

user.load_templates ();

user._popbox = null;

user.events = {
	"login"  : null,
	"logout" : null
};

user._evt_login = function ()
{
	var res = false;

	if ( user.events [ 'login' ] ) 
		res = user.events [ 'login' ] ();

	return false;
};

user.login_box = function ()
{
	user._popbox_init ();

	var frm = new liwe.form.instance ( "user-login-form" );
	frm.text ( { label: "Login", name: "login", size: 30, maxlength: 50, mandatory: true } );
	frm.password ( { label: "Password", name: "pwd", size: 30, maxlength: 30, mandatory: true } );
	frm.button ( { value: "Accedi", onclick: "user._login()" } );
	frm.sep ();
	frm.descr ( "Hai dimenticato la password?" );
	frm.text ( { label: "Tua e-mail", name: "email", size: 30, maxlength: 50 } );
	frm.button ( { value: "Richiedi", onclick: "user._lost_password()" } );

	frm.set ( user._popbox.get ().id );

	if ( user._popbox.is_hidden () )
		user._popbox.show ();
	else
		user._popbox.hide ();
};

user.change_password = function ()
{
	user._popbox_init ();

	var frm = new liwe.form.instance ( "user-change-pwd-form" );
	frm.password ( { label: "Password", name: "pwd", size: 30, maxlength: 30, mandatory: true } );
	frm.password ( { label: "Password (verifica)", name: "pwd2", size: 30, maxlength: 30, mandatory: true } );
	frm.button ( { value: "Accedi", onclick: "user._change_pwd()" } );

	frm.set ( user._popbox.get ().id );

	if ( user._popbox.is_hidden () )
		user._popbox.show ();
	else
		user._popbox.hide ();
};

user._change_pwd = function ()
{
	var f = liwe.form.get ( "user-change-pwd-form" );
	var a;

	if ( ! f.check () ) return;

	a = f.get_values ();

	if ( a [ 'pwd' ] != a [ 'pwd2' ] ) 
	{
		alert ( "Le due password inserite non coincidono" );
		return;
	}

	liwe.AJAX.easy ( { action: "user.ajax.change_password", pwd: a [ 'pwd' ] }, function ( v )
		{
			alert ( "Password aggiornata!" );
			user._popbox.hide ();
		} );

};

user._popbox_init = function ()
{
	if ( ! user._popbox )
	{
		user._popbox = WWL.popbox ( 'login-box' );
		user._popbox.set_parent ( $( "user-login-box" ), "D" );
		user._popbox.set_size ( 300, 150 );
		user._popbox.init ();
	}
};

user.logout = function ()
{
	liwe.AJAX.easy ( { action: "user.ajax.logout" }, user.events.logout );
};

user._login = function ()
{
	var f = liwe.form.get ( "user-login-form" );
	var a = f.get_values ();

	a [ 'action' ] = "user.ajax.login";

	liwe.AJAX.easy ( a, function ( v ) { 
		user._popbox.hide ();

		if ( user.events.login ) user.events.login ( v );
	} );
};

user._lost_password = function ()
{
	var f = liwe.form.get ( "user-login-form" );
	var email = f.get_value ( "email" );

	liwe.AJAX.easy ( { action: "user.ajax.lost_password", email: email }, function ( v )
		{
			alert ( "Una nuova password e' stata inviata all'indirizzo di email: " + email );
		} );
};
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 OS3Tabs = {};
// OS3Tabs._events = {};
OS3Tabs._int_events = {};
OS3Tabs._instances = {};

OS3Tabs._int_events [ 'hover' ] = function ( tabs, div )
{
	if ( tabs._curr_tab ) tabs._curr_tab.className = ( tabs._curr_tab == tabs._curr_tab_sel ? "sel" : "tab" );
	div.className = "tab_hover";
	tabs._curr_tab = div;
};

OS3Tabs._int_events [ 'out' ] = function ( tabs, div )
{
 	div.className = ( div == tabs._curr_tab_sel ? "sel" : "tab" );
};

OS3Tabs._int_events [ 'btn_down' ] = function ( tabs, div )
{
 	div.className = "btn_down";
};

OS3Tabs._int_events [ 'btn_up' ] = function ( tabs, div )
{
 	div.className = "btn_up";
};

OS3Tabs._int_events [ 'click' ] = function ( tabs, div )
{
	var d = tabs._tabs_ref [ div.id ];

	if ( ! d )
	{
		d = document.getElementById ( tabs._tabs_names_ref [ div.id ] );
		if ( d ) 
			tabs._tabs_ref [ div.id ] = d;
		else
		{
			console.warn ( "OS3Tabs: div: %s does not exist.", tabs._tabs_names_ref [ div.id ] );
			return;
		}
	}

	if ( ( tabs._curr_tab_sel ) && ( tabs._curr_tab_sel == tabs._curr_tab ) ) return;

	if ( tabs._curr_tab_sel ) tabs._curr_tab_sel.className = 'tab';

	tabs._curr_tab_sel = tabs._curr_tab;
	if ( tabs._curr_div_shown ) tabs._curr_div_shown.style.display = 'none';

	d.style.display = 'block';

	tabs._curr_div_shown = d;
	tabs._curr_tab.className = 'sel';
};

/*
This function is the event dispatcher
It takes:
	
	- event_name:	- Name of the event
	- instance	- Name of the instance
	- group_name	- Name of the group which is firing the event
	- pos		- Tab position which is firing the event
*/
OS3Tabs.evt = function ( div, event_name, instance, group_name, pos )
{
	if ( div._disabled ) return;

	var tabs = OS3Tabs._instances [ instance ];

	if ( tabs._blocked_events [ event_name ] ) return;
	if ( OS3Tabs._int_events [ event_name ] ) OS3Tabs._int_events [ event_name ] ( tabs, div );
	if ( tabs._events [ event_name ] ) tabs._events [ event_name ] ( tabs, event_name, div, tabs._curr_div_shown, pos );

	// console.debug ( "Event: %s - instance: %s - group: %s, pos: %d", event_name, instance, group_name, pos );
};

OS3Tabs.instance = function ( prefix )
{
	this._prefix  = prefix;
	this._events  = {}; 
	this._blocked_events = {};		// Events that should not be called
	this._tabs    = { 'default' : [] };
	this._tabs_ref = {};
	this._tabs_names_ref = {};
	this._divs_ref = {};
	this._group_names = [ 'default' ];	// Group names (in order)

	this._curr_group = this._tabs [ 'default' ];
	this._curr_group_name = 'default';

	this.tab_width = 0;
	this.tab_height = 0;

	this.render = function ()
	{
		var t, l = this._group_names.length;
		var grp;
		var s = '', ss;
		var header;
		var style = '';
		var rows = 0;

		for ( t = 0; t < l; t ++ )
		{
			grp = this._tabs [ this._group_names [ t ] ];
			if ( ! grp.length ) continue;
			rows ++;
			s += this._render_grp ( grp, this._group_names [ t ] );
		}

		header = document.getElementById ( this._prefix + '_header' );

		if ( ! header )
		{		
			console.warn ( "OS3Tabs: ERROR: Could not find: %s div for headers", this._prefix + "_header" );
			return;
		}
		if ( this.tab_height ) header.style.height = this._calc_header_height ( rows );

		header.innerHTML = s;
	};

	this._calc_header_height = function ( rows )
	{
		var split = this.tab_height.split ( /(mm|px|pt|ex|em|%)/i );
		if ( split.length < 2 ) return "";

		var v = parseInt ( split [ 0 ] );
		var mis = split [ 1 ];
		var res = ( v * rows ) + mis;

		return res;
	};

	this.set_tab_title = function ( title, group_name, pos )
	{
		var id = this._mk_tab_id ( this._prefix, group_name, pos );
		var d = document.getElementById ( id );

		d.innerHTML = title;
	};

	this.block_event = function ( event_name, mode )
	{
		if ( mode === undefined ) mode = true;
		this._blocked_events [ event_name ] = mode;
	};

	this._render_grp = function ( grp, grp_name )
	{
		var t, l, s = '', events, events_meta, id, style = '';
		var gname;

		l = grp.length;

		s += '<div id="' + this._mk_tab_row_id ( this._prefix, grp_name ) + '" class="row" >';

		if ( this.tab_width ) style += 'width: ' + this.tab_width;

		if ( style ) style = ' style="' + style + '" ';

		events_meta = "'" + this._prefix + "','" + grp_name + "'";
		for ( t = 0; t < l; t ++ )
		{
			events  = "onmouseover=\"OS3Tabs.evt(this,'hover'," + events_meta + "," + t + ")\" ";
			events += "onmouseout=\"OS3Tabs.evt(this,'out'," + events_meta + "," + t + ")\" ";
			events += "onmousedown=\"OS3Tabs.evt(this,'btn_down'," + events_meta + "," + t + ")\" ";
			events += "onmouseup=\"OS3Tabs.evt(this,'btn_up'," + events_meta + "," + t + ")\" ";
			events += "onclick=\"OS3Tabs.evt(this,'click'," + events_meta + "," + t + ")\" ";
			events += "ondblclick=\"OS3Tabs.evt(this,'dblclick'," + events_meta + "," + t + ")\" ";
			id=' id="' + this._mk_tab_id ( this._prefix, grp_name, t ) + '" ';
			s += '<div class="tab" ' + id + events + style + '>' + grp [ t ] + '<\/div>';
		}
		s += '<\/div>';

		return s;
	}

	this._mk_tab_row_id = function ( prefix, grp_name )
	{
		return prefix + ":" + grp_name + ":tab_row";
	};

	this._mk_tab_id = function ( prefix, grp_name, pos )
	{
		return prefix + ":" + grp_name + ":" + pos;
	};

	this.set_event = function ( evt_name, cback )
	{
		this._events [ evt_name ] = cback;
	};

	this.clear = function ()
	{
		this._tabs    = { 'default' : [] };
		this._tabs_ref = {};
		this._tabs_names_ref = {};
		this._divs_ref = {};
		this._group_names = [ 'default' ];	// Group names (in order)
		this._curr_group = this._tabs [ 'default' ];
		this._curr_group_name = 'default';
	};

	// {{{ set_group ( group_name )
	this.set_group = function ( group_name )
	{
		if ( ! this._tabs [ group_name ] )
		{
			this._group_names.push ( group_name );
			this._tabs [ group_name ] = [];
		}

		this._curr_group = this._tabs [ group_name ];
		this._curr_group_name = group_name;
	};
	// }}}
	// {{{ add ( title, div_name )
	this.add = function ( title, div_name )
	{
		var pos = this._curr_group.length;
		var id = this._mk_tab_id ( this._prefix, this._curr_group_name, pos );

		this._curr_group.push ( title );
		this._tabs_ref [ id ] = null; // document.getElementById ( div_name );
		this._tabs_names_ref [ id ] = div_name;

		this._divs_ref [ div_name ] = id;
	};
	// }}}

	this.send_event = function ( div_name, evt )
	{
		var id = this._divs_ref [ div_name ];
		var div = document.getElementById ( id );

		this._curr_tab = div;
		OS3Tabs.evt ( div, evt, this._prefix );
	};

	this.enable_tab = function ( div_name, enable )
	{
		var id = this._divs_ref [ div_name ];
		var div = document.getElementById ( id );

		if ( ! div [ "_disabled" ] && enable ) return;
		if ( div [ "_disabled" ] && ! enable ) return;

		if ( enable )
		{
			div._disabled = false;
			div.className = "tab";
		}
		else
		{
			div._disabled = true;
			div.className = "disabled";
		}
	};


	OS3Tabs._instances [ this._prefix ] = this;
};


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

WWL.popbox = function ( name )
{
	var pop = new WWL ( 'popbox', name );

	pop._parent_div = null;
	pop._direction = "D";	// "U"P, "D"own, "L"eft and "R"ight
	pop._width = 0;
	pop._height = 0;
	pop._delta_x = 0;
	pop._delta_y = 0;
	pop._element = null;
	
	pop.set_parent = function ( div, direction )
	{
		if ( direction ) this._direction = direction;

		this._parent_div = div;
	};

	pop.set_delta = function ( x, y )
	{
		this._delta_x = x;
		this._delta_y = y;
	};

	pop.set_size = function ( width, height )
	{
		this._width = width;
		this._height = height;
	};
	
	pop.init = function ()
	{
		if ( ! this._element ) 
		{
			this._element = liwe.dom.create_element ( "div", this.id, document.body );
			this._element.style.display = "none";
		}

		return this._element;
	};

	pop.get = function ()
	{
		return this._element;
	};

	pop.show = function ( cback )
	{
		var pos = this._calc_pos ();
		var e;

		e = this.init ();

		e.style.top  = pos [ 'y' ] + "px";
		e.style.left = pos [ 'x' ] + "px";
		if ( this._width ) e.style.width = this._width + "px";
		if ( this._height ) e.style.height = this._height + "px";
		e.className = "wwl_popbox";

		e.style.display = 'block';

		this._element = e;

		return e;
	};

	pop.hide = function ( cback )
	{
		if ( ! this._element ) return;
	
		this._element.style.display = "none";
	};

	pop.is_hidden = function ()
	{ 
		if ( ! this._element ) return true;
		return ( this._element.style.display == "none" );
	};

	pop.destroy = function ()
	{
		if ( ! this._element ) return;

		document.body.removeChild ( this._element );
		this._element = null;
	};

	pop._calc_pos = function ()
	{
		var x = 0, y = 0;
		var size;

		if ( ! this._parent_div ) return { x: x, y: y };

		y = liwe.dom.get_offset_top ( this._parent_div );
		x = liwe.dom.get_offset_left ( this._parent_div );
		//size = liwe.dom.get_size ( this._parent_div );
		size = [ this._parent_div.offsetWidth, this._parent_div.offsetHeight ];

		switch ( this._direction )
		{
			case "D":
				y += size [ 1 ];
				break;

			case "U":
				y -= this._height;
				break;

			case "L":
				x -= this._width;
				break;

			case "R":
				x += size [ 0 ];
				break;
		}

		return { x: x + this._delta_x, y: y + this._delta_y };
	};

	return pop;
};

WWL.popbox.get_instance = function ( instance_name )
{
	return WWL.get_instance ( "popbox", instance_name );
};

// This is an internal function for popbox class only
WWL.popbox._set_class = function ( widget, div, class_name ) 
{ 
	div.className = WWL.mk_class_str ( widget, class_name );
};

WWL.popbox._int_events = {};

WWL.popbox._int_events [ 'over' ]     = function ( widget, div ) { WWL.popbox._set_class ( widget, div, "hover" ); };
WWL.popbox._int_events [ 'btn_down' ] = function ( widget, div ) { WWL.popbox._set_class ( widget, div, "click" ); };
WWL.popbox._int_events [ 'btn_up' ]   = function ( widget, div ) { WWL.popbox._set_class ( widget, div, "hover" ); }; 
WWL.popbox._int_events [ 'click' ]    = function ( widget, div ) { WWL.popbox._set_class ( widget, div, "hover" ); };
WWL.popbox._int_events [ 'out' ]      = function ( widget, div ) { WWL.popbox._set_class ( widget, div ); };

function AutoSuggest ( field_id )
{
	this.field = document.getElementById ( field_id );

	this.name = field_id;

	var self = this;

	this._old_val = "";

	this.min_chars = 1;

	this._selected = 0;	// Selected element (from 0)
	this._list = null;	// Current list of elements

	this.cbacks = {
		"request" : AutoSuggest.fake_request,
		"row-render" : AutoSuggest._row_render,
		"row-get-val" : AutoSuggest._row_get_val
	};

	this._cache = {};

	this.use_cache = true;

	this._evt_keypress = function ( evt )
	{
		var key = window.event ? window.event.keyCode : evt.keyCode;

		var bubble = 1;

		switch ( key )
		{
			case 9: // TAB
			case 13: // RETURN
				if ( ! self.pop.is_hidden () )
				{
					self._set_value ();
					bubble = 0;
				}
				break;

			case 27: // ESC
				self._clear_suggestions ();
				break;
		}

		return bubble;
	};

	this._evt_keyup = function ( evt )
	{

		var key = window.event ? window.event.keyCode : evt.keyCode;
		
		// set responses to keydown events in the field
		// this allows the user to use the arrow keys to scroll through the results
		// ESCAPE clears the list
		// TAB sets the current highlighted value
		//

		var bubble = 1;

		switch ( key )
		{
			case 38:  // ARROW UP
				if ( self.pop.is_hidden () ) return bubble;
				self._selected -= 1;
				if ( self._selected < 0 ) self._selected = 0;
				self._render ();
				bubble = 0;
				break;


			case 40:  // ARROW DOWN
				if ( self.pop.is_hidden () ) return bubble;
				self._selected += 1;
				if ( self._selected >= self._list.length ) self._selected = self._list.length -1;
				self._render ();
				bubble = 0;
				break;

			case 13:
				break;
			
			default:
				self._get_suggestions ( self.field.value );
		}

		return bubble;
	};

	// Disable browser autocomplete feature
	this.field.setAttribute ( "autocomplete", "off" );

	this.field.onkeypress 	= this._evt_keypress;
	this.field.onkeyup 	= this._evt_keyup;

	this.pop = new WWL.popbox ( this.field.id + "-pop" );
	this.pop.set_parent ( this.field, "D" );
	this.pop.show ();
	this.pop.hide ();

	AutoSuggest._instances [ this.name ] = this;
}

AutoSuggest._instances = {};

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

AutoSuggest.set = function ( field_id )
{
	return new AutoSuggest ( field_id );
};

AutoSuggest.evt = function ( div, event_name, instance_name, pos )
{
	var ac = AutoSuggest.get ( instance_name );
	var s;

	switch ( event_name )
	{
		case "over":
			s = ac.cbacks [ 'row-render' ] ( ac._list [ ac._selected ], false );
			$( ac.name + ":" + ac._selected, s );
			$( ac.name + ":" + ac._selected ).className = "row";

			ac._selected = pos;
			s = ac.cbacks [ 'row-render' ] ( ac._list [ pos ], true );
			div.innerHTML = s;
			div.className = 'row_hover';
			break;

		case "click":
			ac._set_value ();
			break;
	}
};

AutoSuggest._row_render = function ( row, is_selected )
{
	
	var s = row [ 'label' ] + ( is_selected ? " - SELECTED" : "" );

	return s;
};

AutoSuggest._row_get_val = function ( row )
{
	return row [ 'value' ];
};

AutoSuggest.prototype._get_suggestions = function ( val )
{
	var self = this;

	var my_val = val.toLowerCase ();

	// if input stays the same, do nothing
	if ( my_val == this._old_val ) return;

	this._old_val = my_val;

	// input length is less than the min required to trigger a request
	// do nothing
	if ( val.length < this.min_chars ) 
	{
		this._clear_suggestions ();
		return;
	}

	if ( this.use_cache && typeof this._cache [ my_val ] != "undefined" )
	{
		console.debug ( "CACHE HIT FOR: %s", my_val );

		self._set_suggestions ( this._cache [ my_val ], val );
	} else {
		// new request
		this.cbacks [ 'request' ] ( val, function ( lst ) { self._set_suggestions ( lst, val ); } );
	}
};

AutoSuggest.prototype._clear_suggestions = function ()
{
	this.pop.get ().innerHTML = '';
	this.pop.hide ();
};

AutoSuggest.prototype._set_value = function ()
{
	var val = this.cbacks [ 'row-get-val' ] ( this._list [ this._selected ] );
	var orig = this.field.value;
	var pos;

	pos = orig.lastIndexOf ( " " );
	orig = orig.substr ( 0, pos ) + " " + val;

	this.field.value = orig.replace ( /^ */, "" ) + ", ";
	this._clear_suggestions ();

	var self = this;
	setTimeout ( function () { self.field.focus (); }, 50 );
};


AutoSuggest.prototype._set_suggestions = function ( lst, orig_txt )
{
	if ( this.use_cache )
	{
		var my_val = orig_txt.toLowerCase ();
		this._cache [ my_val ] = lst;
	}

	// if field input no longer matches what was passed to the request
	// don't show the suggestions
	//
	if ( orig_txt != this.field.value )
		return false;

	this._selected = 0;
	this._list = lst;

	this._render ();

	this.pop.show ();
};

AutoSuggest.prototype._render = function ()
{
	if ( ! this._list || ! this._list.length ) 
	{
		this._clear_suggestions ();
		return;
	}

	var lst = this._list;
	var t, l = lst.length;
	var s = '<div class="suggest-box">';
	var args;
	var class_name;

	for ( t = 0; t < l; t ++ )
	{
		class_name = ( t == this._selected ? "row_hover" : "row" );
		args = "'" + this.name + "'," + t;
		s += '<div class="' + class_name + '" ';
		s += ' id="' + this.name + ':' + t + '" ';
		s += ' onclick="AutoSuggest.evt(this,\'click\',\'' + this.name + '\',' + t + ')" ';
		s += ' onmouseover="AutoSuggest.evt(this,\'over\',\'' + this.name + '\',' + t + ')" ';
		s += '>';
		s += this.cbacks [ 'row-render' ] ( lst [ t ], ( t == this._selected ? true : false ) );
		s += '</div>';

	}

	s += '</div>';

	this.pop.get ().innerHTML = s;
};

AutoSuggest.fake_request = function ( txt, cback )
{
	var t, l = [];

	for ( t = 0; t < 10; t ++ )
		l.push ( { label: txt + "-" + t, value: "v-" + txt + "-" + t } );

	if ( cback ) return cback ( l );
};

var tags = liwe.module ( "tags" );

tags._cache = {};

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 }, 
			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 ( "|" );
};
WWL.tags = function ( name, vars )
{
	var tags = new WWL ( 'tags', name );

	if ( ! vars ) vars = {};

	tags.events = {
		"update" : null,
		"list-tags" : null
	};

	tags.form = new liwe.form.instance ( tags.id );
	tags.form.text   ( { label: "", name: "_tags", value: "", size: vars.get ( "size", 30 ),
		maxlength: 250, onblur: "WWL.tags._add_tags('" + tags.name + "')",
		filter: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 0123456789_-,"
		// suggest: WWL.tags._suggest_init
		} );
	tags.form.workspace ( { name: tags.id + "@tags_added" } );
	tags.form.workspace ( { name: tags.id + "@tags_available" } );

	tags.form._data = {};
	tags._available_hidden = true;

	tags.to_string = function ()
	{
		return tags.form.get ();
	};

	tags.get_value = function ()
	{
		var k = tags.form._data.keys ();

		k.sort ();
		return '|'.join ( k );
	};

	tags.set_value = function ( v )
	{
		WWL.tags._parse_txt ( tags, v, "|" );
	};

	tags._refresh = function ()
	{
		var tag_widget = tags.form.get_element ( "_tags" );
		WWL.tags._suggest_init ( tag_widget.id, tags );
	};

	return tags;
};

WWL.tags._suggest_init = function ( dest_id, tags_obj )
{ 
	tags.list ( tags_obj.module_name, function ( v ) { tags_obj._curr_tags_list = v; }, true );

	function request ( txt, cback )
	{
		var names; 
		var lst = [], t, l, tag;

		txt = txt.split ( "," );
		txt = txt [ txt.length -1 ].Strip();

		if ( txt.length < 3 ) return;

 		names = WWL.tags._mk_name_list ( tags_obj, ( tags_obj._curr_tags_list ? tags_obj._curr_tags_list : {} ) );
		l = names.length;

		for ( t = 0; t < l; t ++ )
		{
			tag = names [ t ];
			if ( tag.startsWith ( txt ) ) lst.push ( [ tag, tag ] );
		}

		cback ( lst );
	}

	function row_render ( row, is_selected )
	{
		return '<div class="value">' + row [ 1 ] + '</div>';
	}

	function row_get_val ( row )
	{
		return row [ 0 ];
	}

	var as = new AutoSuggest ( dest_id );

	as.cbacks [ 'request' ] = request;
	as.cbacks [ 'row-render' ] = row_render;
	as.cbacks [ 'row-get-val' ] = row_get_val;
};

WWL.tags.templates = {
		"tag-item" : '<div id="tag-del-cnt-%(name)s" class="tag-del-cnt"><div class="tag-del" onmouseover="this.className=\'tag-del-hover\'" onmouseout="this.className=\'tag-del\'" onclick="WWL.tags._del_tag(\'%(tags_name)s\',\'%(name)s\')"></div>%(name)s</div>',
		"tag-available" : '<div class="tag-available"><div class="action"><a href="javascript:WWL.tags.available_toggle(\'%(tags_name)s\')">Tags disponibili</a></div>' +
				  '<div class="tag-available-list" id="%(tags_id)s-cnt"></div></div>',
		"wait-medium" : '<div class="liwe_progress" align="center"><div class="medium_white"></div></div>',
		"tag-add" : '<a class="tag-add" href="javascript:WWL.tags._add_tag(\'%(tags_name)s\',\'%(name)s\')">%(name)s</a> ',
		"tag-update" : '<div class="action"><a class="tag-add" href="javascript:WWL.tags._update(\'%(tags_name)s\')">Aggiorna lista tags</a></div>'
	};


WWL.tags.get_instance = function ( instance_name )
{
	return WWL.get_instance ( "tags", instance_name );
};

WWL.tags._add_tags = function ( name )
{
	var tags = WWL.tags.get_instance ( name );
	var txt = tags.form.get_value ( "_tags" );

	WWL.tags._parse_txt ( tags, txt, "," );
};

WWL.tags.available_toggle = function ( name )
{
	var tags = WWL.tags.get_instance ( name );

	if ( tags._available_hidden == true )
	{
		var e = $( tags.id + "-cnt" );
		e.innerHTML = WWL.tags.templates [ 'wait-medium' ];

		e.style.display = "block";
		tags._available_hidden = false;

		if ( tags.events [ 'list-tags' ] )
		{
			tags.events [ 'list-tags' ] ( function ( v ) { WWL.tags._show_avail ( tags, v ); } );
		}
	} else {
		$( tags.id + "-cnt" ).style.display = "none";
		tags._available_hidden = true;
	}
};

WWL.tags._mk_name_list = function ( tags, all_tags_list )
{
	var names = all_tags_list.keys ();
	var t, l, name;
	var lst = [];

	names.sort ();
	l = names.length;

	for ( t = 0; t < l; t ++ )
	{
		name = names [ t ];
		if ( tags.form._data [ name ] ) continue;

		lst.push ( name );
	}

	return lst;
};

WWL.tags._show_avail = function ( tags, all_tags_list )
{
	if ( ! all_tags_list ) return;

	var names = WWL.tags._mk_name_list ( tags, all_tags_list );
	var t, l, name;
	var s = new String.buffer ();

	l = names.length;

	for ( t = 0; t < l; t ++ )
	{
		name = names [ t ];

		s.add ( String.formatDict ( WWL.tags.templates [ 'tag-add' ], { "tags_name" : tags.name, "name" : name } ) );
	}

	tags._curr_tags_list = all_tags_list;

	s = s.toString ();

	if ( ! s.length ) s = "Non ci sono altri tag disponibili";

	$( tags.id + "-cnt", s + String.formatDict ( WWL.tags.templates [ 'tag-update' ], { "tags_name" : tags.name } ) );
};


WWL.tags._parse_txt = function ( tags, txt, sep )
{
	if ( ! $( tags.id + "-cnt" ) )
		$( tags.id + "@tags_available", String.formatDict ( WWL.tags.templates [ 'tag-available' ], { "tags_id" : tags.id, "tags_name" : tags.name } ) );

	var tags_form = tags.form;
	var lst = txt.split ( sep );
	var t, l = lst.length;
	var k;

	for ( t = 0; t < l; t ++ )
	{
		k = lst [ t ].Strip ().toLowerCase ();
		if ( ! k.length ) continue;
		tags_form._data [ k ] = 1;
	}

	WWL.tags._show_tags ( tags, tags_form );
};

WWL.tags._show_tags = function ( tags, tags_form )
{
	var t, l;
	var k;

	k = tags_form._data.keys ();
	k.sort ();

	var res = new String.buffer ();

	l = k.length;
	for ( t = 0; t < l; t ++ )
		res.add ( String.formatDict ( WWL.tags.templates [ 'tag-item' ], { "name" : k [ t ], "tags_name" : tags.name } ) );

	$( tags.id + "@tags_added", res.toString () );
	tags_form.set_value ( "tags", "" );

	WWL.tags._show_avail ( tags, tags._curr_tags_list );

	if ( tags.events [ 'update' ] ) tags.events [ 'update' ] ( tags.get_value () );
};

WWL.tags._del_tag = function ( tags_name, name )
{
	var tags = WWL.tags.get_instance ( tags_name );
	var tags_form = tags.form;
	
	$( "tag-del-cnt-" + name ).style.display = "none";

	delete tags_form._data [ name ];
	WWL.tags._show_avail ( tags, tags._curr_tags_list );
	if ( tags.events [ 'update' ] ) tags.events [ 'update' ] ( tags.get_value () );
};

WWL.tags._add_tag = function ( tags_name, name )
{
	var tags = WWL.tags.get_instance ( tags_name );
	var tags_form = tags.form;
	
	tags_form._data [ name ] = 1;

	// WWL.tags._show_avail ( tags, tags._curr_tags_list );
	WWL.tags._show_tags ( tags, tags_form );
};

WWL.tags._update = function ( tags_name )
{
	var tags = WWL.tags.get_instance ( tags_name );
	
	if ( tags.events [ 'list-tags' ] )
	{
		var e = $( tags.id + "-cnt" );
		e.innerHTML = WWL.tags.templates [ 'wait-medium' ];
		tags.events [ 'list-tags' ] ( function ( v ) { WWL.tags._show_avail ( tags, v ); }, true );
	}
};
liwe.form.instance.prototype.tags = function ( vars )
{
	vars [ 'os3_class_value' ] = '';

	this._start_field ( vars );

	var value = vars.get ( "value", "" );

	var w_tags = new WWL.tags ( "tags@" + vars [ 'name' ], vars );

	w_tags.module_name = vars.get ( "module_name" );

	this.html += w_tags.to_string ();

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

	this.hidden ( vars [ 'name' ], value );

	this._newline ( vars );

	var name = vars [ 'name' ], _obj = this;
	w_tags.events [ 'update' ] = function ( v ) 
	{ 
		var e = _obj.get_element ( name );
		e.value = v;
	};

	w_tags.events [ 'list-tags' ] = function ( cback, reload )
	{
		tags.list ( w_tags.module_name, cback, reload );
	};

	w_tags.render = function ()
	{
		this.set_value ( value );
	};
};
var Links = liwe.module ( "links" );

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 = {};
var staticpage = liwe.module ( "staticpage" );

staticpage._static_page = {};


staticpage.init = function ()
{
	if ( ! staticpage.templates )
	{
		liwe.AJAX.easy ( { action: "staticpage.ajax.get_templates" }, function ( v ) {
			staticpage.templates = v [ 'templates' ];
		} );
	}
};

staticpage.get_page = function ( page, db, cback )
{
	var p = staticpage._static_page.get ( page );

	function _get_page ()
	{
		cback && cback ( staticpage._static_page [ page ] );
	}

	if ( p )
		_get_page ();
	else
	{
		var act = '';
		if ( db ) act = "staticpage.ajax.get_static_page_by_name";
		else act = "staticpage.ajax.get_html_page";

		liwe.AJAX.easy ( { action: "staticpage.ajax.get_static_page_by_name", 'page': page }, function ( v ) {
			staticpage._static_page [ page ] = v [ 'page' ];
			_get_page ();
		} );
	}
};

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 inforete = liwe.module ( "inforete" );

inforete._static_page = {};

inforete.set_static_page = function ( dest )
{

};

inforete.list_static_page = function ( dest )
{

};

inforete.show_page = function ( page )
{
	inforete.set_history ( page );

	var p = inforete._static_page.get ( page );
	if ( p ) $ ( 'block_main' ).innerHTML = p;
	else
	{
		liwe.AJAX.easy ( { action: "inforete.ajax.get_static_page", 'page': page }, function ( v ) {
			$ ( 'block_main' ).innerHTML = v [ 'page' ];
		} );
	}
};

inforete.show_contatti = function ()
{
	inforete.set_history ( "contatti" );

	$ ( 'block_main' ).innerHTML = String.formatDict ( inforete.templates [ 'cnt_box_show' ], { title: 'Contattaci' } );

	var f = new liwe.form.instance ( "contatti" );

	var dest_email = [
		{ 'label': 'Redazione', 'value': 10 },
		{ 'label': 'Amministrazione', 'value': 20 },
		{ 'label': 'Web Master', 'value': 30 }
	];


	f.hidden ( "action", "inforete.ajax.send_email" );
	
	f.text ( { label: 'Nome', name: 'nome', size: 30 } );
	f.text ( { label: 'Cognome', name: 'cognome', size: 30 } );
	f.email ( { label: 'Email', name: 'email', size: 30, mandatory: true } );
	f.select ( { label: 'Destinatario', name: 'dest', options: dest_email, mandatory: true } );
	f.text ( { label: 'Oggetto', name: 'oggetto', size: 30, mandatory: true } );
	f.textarea ( { label: 'Testo', name: 'testo', mandatory: true, rows: 15, cols: 40 } );

	f.button ( { value: 'Invia', name: 'btn_go', onclick: 'inforete.send_contatti()' } );

	f.set ( 'box_news_roll_body' );
};

inforete.send_contatti = function ()
{
	var f = liwe.form.get ( "contatti" );

	if ( ! f.check () )
	{
		alert ( "Valorizzare i campi: email, oggetto e testo" );
		return;
	}

	liwe.AJAX.easy ( f.get_values (), function ( v ) {
		alert ( "Email spedita con successo!" );
		site.show_page ( "home" );
	} );
};
var self = inforete.templates = {
'cnt_box_show' : '<div class="news_box">' +
				'	<div class="news_box_title" id="box_news_roll_title">' +
				'		<table cellspacing="0" cellpadding="0" border="0"><tbody><tr>' +
				'			<td><img title="" alt="" src="gfx/icon_plus.gif"/></td>' +
				'			<td>%(title)s</td>' +
				'		</tr></tbody></table>' +
				'	</div>' +
				'	<div class="news_box_body" id="box_news_roll_body">' +
				'	</div>' +
				'</div>'
};
// 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" ) );
		var m = parseInt ( s.replace ( /[^0-9]*([0-9][0-9]*)-([0-9][0-9]*)-([0-9][0-9][0-9][0-9]).*/, "$2" ) );
		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.show_results_table = function ( dest_div, render_cback )
	{
		console.warn ( "DataSet WARNING: show_results_table() has been deprecated. Use render()" );
		this.render ( dest_div, render_cback );
	};

	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' ] = '';

	// _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 ()
	{
		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 );
};
var news_roller = liwe.module ( "news_roller" );

news_roller._news = null;
news_roller._dest_div = null;
news_roller._curr_news = 0;
news_roller._max_news = 0;

news_roller.init = function ()
{
	news_roller.ajax ( { action: "news.ajax.list", tags: 'anteprima', quant: 5 }, 
		function ( v )
		{
			news_roller._news = v [ 'news' ];
			news_roller._max_news = news_roller._news.length;
			news_roller._curr_news = 0;
		} );
};

news_roller.render = function ( dest_div )
{
	if ( ! news_roller._max_news )
	{
		setTimeout ( function () { news_roller.render ( dest_div ) }, 400 );
		return;
	}

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

	if ( news_roller._curr_news > news_roller._max_news -1 ) news_roller._curr_news = 0;

	var s = String.formatDict ( news.templates [ 'NEWS_BOX' ], news_roller._news [ news_roller._curr_news ] );

	$( dest_div, s );

	if ( $ ( 'cnt_roller_links' ) )
	{
		var lnks = $ ( 'cnt_roller_links' ).getElementsByTagName ( 'a' );
		var t, l = lnks.length;

		for ( t = 0; t < l; t ++ )
		{
			var lnk = lnks [ t ];
			if ( lnk.className.startsWith ( "roller_lnk" ) ) lnk.className = "roller_lnk";
		}

		$ ( 'roller' + news_roller._curr_news ).className = "roller_lnk_sel";
	}


	news_roller._curr_news ++;

	if ( news_roller._timeout ) clearTimeout ( news_roller._timeout );
	news_roller._timeout = setTimeout ( function () { news_roller.render ( dest_div ) }, 6000 );
};

news_roller.evt = function ( name )
{
	// console.debug ( "EVT: %s", name );

	if ( name == 'over' )
	{
		if ( news_roller._timeout ) clearTimeout ( news_roller._timeout );
		news_roller._timeout = 0;
	} else {
		news_roller._curr_news --;
		news_roller.render ();
	}
};

news_roller.set = function ( pos )
{
	if ( ! news_roller._cursel ) news_roller._cursel = 0;

	$ ( 'roller' + news_roller._cursel ).className = "roller_lnk";
	news_roller._cursel = pos;
	$ ( 'roller' + news_roller._cursel ).className = "roller_lnk_sel";

	news_roller._curr_news = pos;
	news_roller.render ();
};
var cinema = liwe.module ( "cinema" );

cinema.templates = null;

cinema.init = function ( cback )
{
	if ( ! cinema.templates )
	{
		liwe.AJAX.easy ( { action: "cinema.ajax.get_templates" }, function ( v ) {
			cinema.templates = v [ 'templates' ];
			cback && cback ();
		} );
	}
};


cinema.show_last_program = function ( dest )
{
	cinema.set_history ( "cinema" );

	liwe.AJAX.easy ( { action: "cinema.ajax.get_last_program" }, function ( v )
	{
		$ ( dest ).innerHTML = v [ "html" ];
	} );
};

var annunci = liwe.module ( "annunci" );

annunci.templates = null;
annunci._categs = null;

annunci.init = function ( cback )
{
	annunci._get_template ();
};

annunci._get_template = function ( cback )
{
	if ( ! annunci.templates )
	{
		liwe.AJAX.easy ( { action: "annunci.ajax.get_templates" }, function ( v ) {
			annunci.templates = v [ 'templates' ];
			cback && cback ();
		} );
	}
	else cback && cback ();
};

annunci.list_categs = function ( cback )
{
	annunci._categs = null;
	liwe.AJAX.easy ( { action: "annunci.ajax.list_categs" }, function ( v )
	{
		annunci._categs = v [ 'categs'];

		cback && cback ();
	});
};

annunci.show_page = function ( dest, def_val, cback )
{
	$ ( dest ).innerHTML = annunci.templates [ 'full_page' ];

	if ( ! annunci._categs )
	{
		annunci.list_categs ( function () {
			annunci._create_filter ( def_val );
			cback && cback ();
		});
	}
	else
	{
		annunci._create_filter ( def_val );
		cback && cback ();
	}
};

annunci._create_filter = function (def_val)
{
	$ ( "annunci_filter" ).innerHTML = '<span class="categ">Categoria: </span>';
	var t, l = annunci._categs.length;
	var sel = '<select name="id_categ" onchange="annunci.categ_change(this.value)">' +
		  '	<option value="">(Selezionare)</option>';

	for ( t = 0; t < l; t ++ )
	{
		var cat = annunci._categs [ t ];

		var chk = '';
		if ( def_val == cat [ 'id_ann_categ' ]) chk = ' selected="selected" ';

		sel += '<option value="' + cat [ 'id_ann_categ' ] + '" ' + chk + '>' + cat [ 'nome' ] + '</option>';
	}

	sel += '</select>';

	$ ( "annunci_filter" ).innerHTML += sel;
};

annunci.categ_change = function ( val )
{
	if ( ! val )
	{
		alert ( "Selezionare una categoria" );
		return;
	}

	annunci.list ( val, '', 'block_main' );
};

annunci.list = function ( id_categ, txt, dest, lines )
{
	if ( ! dest ) dest = 'block_main';

	annunci.set_history ( "annuncio_search", function ( data ) 
		{
			annunci.list ( data [ 'id_categ' ], data [ 'testo'], data [ 'dest' ], data [ 'lines' ] ); 
		},
		{ 'id_categ': id_categ, 'testo': txt, dest: dest, 'lines': lines } 
	);

	annunci._get_template ( function () {

		if ( ! id_categ )
		{
			annunci.show_page ( dest );
			return;
		}

		annunci.show_page ( dest, id_categ, function () {
			annunci._list ( id_categ, txt, lines );
		} );

	});
};

annunci._list = function ( id_categ, txt, lines )
{
	var dct = {};
	dct [ 'testo' ] = txt;
	dct [ 'id_categ' ] = id_categ;

	annunci.init_ds_search ( 'Annunci', lines );

	annunci._search_start ( dct, 'annunci_cnt' );
};

annunci.init_ds_search = function ( titolo, lines )
{
	annunci.ds = new DataSet ( "ds_annuncio", "/ajax.pyhp" );

	annunci._titolo = titolo;

	annunci.ds.templates [ 'table_start' ] = annunci.templates [ 'ds_annunci_start' ];
	annunci.ds.templates [ 'table_end' ]   = annunci.templates [ 'ds_annunci_end' ];
	annunci.ds.templates [ 'table_header' ] = annunci.templates [ 'ds_annunci_header' ];
	annunci.ds.templates [ 'table_footer' ] = annunci.templates [ 'ds_annunci_footer' ];
	
	annunci.ds.templates [ 'table_row' ] = annunci.templates [ 'ds_annunci_row' ];
	//annunci.ds.templates [ 'prev_page' ] = annunci.templates [ 'ds_prev_page' ];
	//annunci.ds.templates [ 'next_page' ] = annunci.templates [ 'ds_next_page' ];

	annunci.ds.paginator.templates [ "pag-link-space" ] = "&nbsp;&nbsp;";
	annunci.ds.paginator.templates [ "pag-sep" ] = "-";
	annunci.ds.paginator.templates [ "pag-first" ] = "&lt;&lt;";
	annunci.ds.paginator.templates [ "pag-last" ] = "&gt;&gt;";
	annunci.ds.paginator.templates [ "pag-right-info" ] = ' | <span class="pagi_res">Pag. <b>%(_PAGE)s</b> di <b>%(_TOT_PAGES)s</b></span>';

	annunci.ds.cbacks [ 'row_manip' ] = annunci._row_manip;

	annunci.ds.lines_per_page = lines ? lines : 10;
};

annunci._row_manip = function ( ds, row )
{
	row [ '_num' ] = row [ '_pos' ] + 1;
};

annunci._search_start = function ( dict, dest )
{
	if ( ! dict ) dict = {};

	if ( ! dest ) dest = "block_main";

	annunci._dest = dest;

	dict [ 'action' ] = "annunci.ajax.list_annunci";

	annunci.ds.set_fields ( dict );
	annunci.ds.fill ( annunci._show_results );
};

annunci._show_results = function  ()
{
	if ( annunci.ds.num_rows <= 0 )
		$ ( annunci._dest ).innerHTML = String.formatDict ( annunci.templates [ 'no_result' ], { titolo_box: annunci._titolo } );
	else annunci.ds.render ( annunci._dest );
};
liwe.AJAX.url = "/ajax.pyhp";
var site = {};

site._id_site = 10;

site._init_admin = function ()
{
	tags.admin.create_tags_menu ();
	user.admin.init ();
	news.admin.init ( 'block_main' );
	banner.admin.init ( 'block_main' );
	Links.admin.init ( 'block_main' );
	staticpage.admin.init ( 'block_main' );
	cinema.admin.init ( 'block_main' );

	/*TODO: da eliminare PROVA DI ARTIST MODULE
	if ( artist && artist.admin )
	{
		artist.admin.init ('block_main');
		
		artist.init ();
	}
	*/
};

site.logout = function ()
{
	user.events [ 'logout' ] = function(){ location.reload (); };
	user.logout();
};

site.init = function ()
{
	news.init ();
	news_roller.init ();
	news_roller.render ( "news_roller" );

	news.cnts_navi = [ "navi_news_top", "navi_news_bottom" ];
	news.cbacks [ "show" ] = site.render_news;
	news.cbacks [ "search" ] = site._set_home_player;

	liwe.history.set_listener ( function () { site.show_page ( 'home' ); } );
	liwe.history.init ();
};


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

	if ( youtube ) site._set_home_player ( youtube [ 'data' ] );
	else site._set_home_player ();

	news.navi_render ( id_news, dest, permalink, pos );
};

site._set_home_player = function ( code )
{
	var s = '';

	if ( code )
	{
		s = 	'<div id="news_mm_youtube"><object width="386" height="315">' +
			'	<param value="http://www.youtube.com/v/%(_code)s&hl=en&fs=1" name="movie"></param>' +
			'	<param value="true" name="allowFullScreen"></param>' +
			'	<param value="always" name="allowscriptaccess"></param>' +
			'	<param value="transparent" name="wmode"></param>' +
			'	<embed width="386" height="315" wmode="transparent" allowfullscreen="true" allowscriptaccess="always" type="application/x-shockwave-flash" src="http://www.youtube.com/v/%(_code)s&hl=en&fs=1"/>' +
			'</object></div>';

		$ ( 'player_mio' ).innerHTML = String.formatDict ( s, { '_code': code } );
	}
	else
	{
		if ( $ ( "news_mm_youtube" ) )
		{
			s = 	'<object width="386" height="315" align="absmiddle">' +
				'	<param name="movie" value="http://www.youtube.com/p/F2585EFFB98C4E1D&autoplay=0"></param>' +
				'	<param name="wmode" value="transparent"></param>' +
				'	<embed src="http://www.youtube.com/p/F2585EFFB98C4E1D&autoplay=0" width="386" height="315" align="absmiddle" type="application/x-shockwave-flash" wmode="transparent"></embed>' +
				'</object>';

			$ ( 'player_mio' ).innerHTML = s;
		}
	}
};


site.show_news_tab = function ( n, el )
{
	var cnt = $ ( "box_news_list_body" );
	var chd = cnt.childNodes;
	var t, l = chd.length;

	for ( t = 0; t < l; t ++ )
	{
		var c = chd [ t ];
		if ( c.id && c.id.startsWith ( 'cnt_hp_news_list_' ) ) 
			c.style.display = 'none';
	}

	$ ( 'cnt_hp_news_list_' + n ).style.display = '';

	var lnks = $ ( "box_news_categ_list" ).getElementsByTagName ( "a" );
	l = lnks.length;

	for ( t = 0; t < l; t ++ )
		lnks [ t ].className = '';

	el.className = "sel";
};

site.create_lightbox = function ( name, title, w, h )
{
        liwe.lightbox.fade = false;
        liwe.lightbox.easy ( name , title, w, h );
	var d = $ ( name );
	var s = '';

	//d.style.border = "2px solid black";
	d.style.padding = "8px";
	d.style.backgroundColor = "white";

	d.innerHTML = s;
	liwe.lightbox.show ();

	return d;
};

site._tabs_arrange = function ( page )
{
	var tabs = [ 'home', 'servizi', 'eventi' ];
	var t, l = tabs.length;

	for ( t = 0; t < l; t ++ )
	{
		$ ( tabs [ t ] + '_tab' ).className = 'tab_menu';
	}

	$ ( page + '_tab' ).className = "tab_menu_sel";
};

site.show_page = function ( page, dict )
{
	site._cur_page = page;

	switch ( page )
	{
		case "eventi":
			if ( news.templates )
			{
				$ ( 'servizi_sects' ).style.display = 'none';
				$ ( 'home_sects' ).style.display = 'none';

				$ ( 'eventi_sects' ).style.display = 'block';

				site._tabs_arrange ( page );

				news.tag_search ( "eventi" );

				site._set_home_player ();
			} else 
				setTimeout ( function () { site.show_page ( page, dict ) }, 500 );
			break;

		case "servizi":
			$ ( 'home_sects' ).style.display = 'none';
			$ ( 'eventi_sects' ).style.display = 'none';

			$ ( 'servizi_sects' ).style.display = 'block';

			site._tabs_arrange ( page );
			site._set_home_player ();
			inforete.show_page ( "servizi", false );
			break;

		case "contatti":
			$ ( 'home_sects' ).style.display = 'none';
			$ ( 'eventi_sects' ).style.display = 'none';

			$ ( 'servizi_sects' ).style.display = 'block';

			site._tabs_arrange ( 'servizi' );
			site._set_home_player ();

			inforete.show_contatti ( "contatti" );
			break;

		case "info":
			$ ( 'home_sects' ).style.display = 'none';
			$ ( 'eventi_sects' ).style.display = 'none';

			$ ( 'servizi_sects' ).style.display = 'block';

			site._tabs_arrange ( 'home' );
			site._set_home_player ();

			inforete.show_page ( "info", false );
			break;

		case "cinema":
			$ ( 'home_sects' ).style.display = 'none';
			$ ( 'eventi_sects' ).style.display = 'none';

			$ ( 'servizi_sects' ).style.display = 'block';

			site._tabs_arrange ( 'home' );
			site._set_home_player ();
			cinema.show_last_program ( "block_main" );
			break;

		case "news_categ_search":
			site._tabs_arrange ( 'home' );
			if ( news.templates )
			{
				$ ( 'home_sects' ).style.display = 'block';
				$ ( 'eventi_sects' ).style.display = 'none';
				$ ( 'servizi_sects' ).style.display = 'none';

				site._set_home_player ();
				news.categ_search ( dict [ "id_categ" ], dict [ "dest" ], dict [ "lbl_categ" ] );
			} else 
				setTimeout ( function () { site.show_page ( page, dict ) }, 500 );
			break;

		case "news_tag_search":
			site._tabs_arrange ( dict [ "tag" ] == "eventi" ? "eventi" : 'home' );
			if ( news.templates )
			{
				$ ( 'home_sects' ).style.display = 'block';
				$ ( 'eventi_sects' ).style.display = 'none';
				$ ( 'servizi_sects' ).style.display = 'none';

				site._set_home_player ();
				news.tag_search ( dict [ "tag" ], dict [ "dest" ], dict [ "lines" ], dict [ "exclude_tags" ] );
			} else 
				setTimeout ( function () { site.show_page ( page, dict ) }, 500 );
			break;

		case "news_search":
			site._tabs_arrange ( 'home' );
			if ( news.templates )
			{
				$ ( 'home_sects' ).style.display = 'block';
				$ ( 'eventi_sects' ).style.display = 'none';
				$ ( 'servizi_sects' ).style.display = 'none';

				site._set_home_player ();
				news.search ( dict [ "testo" ], dict [ "dest" ], "Ricerca generale" );
			} else 
				setTimeout ( function () { site.show_page ( page, dict ) }, 500 );
			break;

		case "home":
			liwe.AJAX.easy ( { action: "system.ajax.load_page", page_name: "home_page" }, function ( v )
			{
				$ ( 'home_sects' ).style.display = 'block';
				$ ( 'eventi_sects' ).style.display = 'none';
				$ ( 'servizi_sects' ).style.display = 'none';
				site._tabs_arrange ( 'home' );
				site._set_home_player ();

				$ ( "block_main" ).innerHTML = v [ "html" ];
			} );
			break;

		case "news_show":
			site._tabs_arrange ( dict [ "tag" ] == "eventi" ? "eventi" : 'home' );
			break;

		case "annuncio_search":
			$ ( 'home_sects' ).style.display = 'none';
			$ ( 'eventi_sects' ).style.display = 'none';

			$ ( 'servizi_sects' ).style.display = 'block';

			site._tabs_arrange ( 'servizi' );
			annunci.list ( dict [ 'id_categ'], dict [ "testo" ], dict [ "dest" ] );
			break;


		default:
			console.error ( "Pagina non gestita: %s", page );
			break;
	}

	//site.set_tabs ( page );
};

site.set_tabs = function ( page )
{
	var cnt = $ ( 'cnt_tabs' );
	var tabs = cnt.childNodes;
	var t, l = tabs.length;
	var tab;

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

		tab.className = 'tab_menu';
	}

	if ( ! page ) page = 'home';

	site.tab_over ( $ ( page + '_tab' ) );
};

site.tab_over = function ( el )
{
	return;
	if ( ! el ) return;

	el._old_class = el.className;

	el.className = el.className + '_hover';
};

site.tab_out = function ( el )
{
	return;
	if ( el._old_class ) el.className = el._old_class;
	else el.className = 'tab_menu';

	if ( el.id.indexOf ( site._cur_page ) >= 0 ) el.className = 'tab_menu_sel';
};

site.show_video = function ( id )
{
	window.scrollTo ( 0, 0 );
	$ ( 'player' ).innerHTML = '';
	var videos = [
		{ url: 'http://www.youtube.com/v/V_ZtNbX5NdI&hl=en&fs=1&border=1' },
		{ url: 'http://www.youtube.com/v/H8cTdG9qaDM&hl=en&fs=1&border=1' }
	];
	var vid = videos [ id ];
	vid.url = escape ( vid.url );

	$ ( 'player' ).innerHTML = String.formatDict ( site.templates [ 'home_flash' ], vid );
};

site.container_choose = function ( set_container_cback )
{
	site.create_lightbox ( "banner_container_choose", "Scelta contenitore banner", 500, 600 )

	var s = '<img src="/gfx/banner_container_choose.jpg" alt="" usemap="#banner_map" />' +
		'<map name="banner_map">' +
		'	<area shape="rect" coords="125,0,417,33" href="javascript:site.set_banner_cnt(1)" />' +
		'	<area shape="rect" coords="398,99,458,326" href="javascript:site.set_banner_cnt(2)" />' +
		'	<area shape="rect" coords="240,349,311,406" href="javascript:site.set_banner_cnt(3)" />' +
		'	<area shape="rect" coords="320,349,394,406" href="javascript:site.set_banner_cnt(4)" />' +
		'</map>';

	$ ( "banner_container_choose" ).innerHTML = s;

	site._set_container_cback = set_container_cback;
};

if ( banner && banner.admin ) banner.admin.cbacks [ "container_choose" ] = site.container_choose;

site.set_banner_cnt = function ( cnt )
{
	site._set_container_cback ( cnt );
	liwe.lightbox.close ();
};


liwe.history.cbacks [ "before-module" ] = function ( module, dict, data )
{
	site.show_page ( dict [ '_page' ], dict, data );
};

site.templates = { 
	"home_flash" : '<iframe style="margin-left: 18px;" frameBorder="no" scrolling="no" class="iframe_home" width="350px" height="320px" src="/swfpage.pyhp?url=%(url)s"></iframe>'
};
