var s = null;

window.addEvent('domready', function() {
	init();
	window.fireEvent('siteready');
});

window.addEvent('domready', function() {
	$$('.js').setStyle('visibility', 'visible');
});

window.addEvent('unload', function() {
	uninit();
} );

function init()
{
	// initialize map engine
	s = new siteEngine();
	s.init();
	s.initBlock( s.body );
	
	document.addEvent('updateblock', function(obj) {
		s.initBlock( obj );
	} );
	
	document.addEvent('removeblock', function(obj) {
		//s.removeBlock( obj );
	} );
}

function uninit()
{
	s = null;
}

function siteEngine()
{
	
	this.init = function()
	{
		this.plugins = [];
		
		this.body = document.getElement('body');
		window.fireEvent('resize');
		
		document.addEvent('mousemove', function(e) {
			this.mouse = { 'x': e.page.x, 'y': e.page.y };
		}.bind(this) );
	},
	
	this.initBlock = function( obj )
	{
		var objs = obj.getElements('.exec');
		objs[objs.length] = obj;
		for (var i=0; i<objs.length; i++)
		{
			objs[i].importProps();
			if (objs[i].hasClass('search'))			this.addSearch(objs[i]);
			if (objs[i].hasClass('save'))			this.addSave(objs[i]);
			if (objs[i].hasClass('update'))			this.addUpdate(objs[i]);
			if (objs[i].hasClass('ratings'))		this.addRating(objs[i]);
			if (objs[i].hasClass('rating-star'))	this.addRatingValue(objs[i]);
			if (objs[i].hasClass('scroller'))		this.addScroller(objs[i]);
			if (objs[i].hasClass('popup'))			this.addPopup(objs[i]);
			if (objs[i].hasClass('onfly'))			this.addOnFly(objs[i]);
			
			if (objs[i].hasClass('delayed'))		this.addDelayed(objs[i]);
			if (objs[i].hasClass('relabel'))		this.addRelabel(objs[i]);
			
			if (objs[i].hasClass('put-input'))		this.addPutInput(objs[i]);
			if (objs[i].hasClass('range'))			this.addRangeSlider(objs[i]);
			if (objs[i].hasClass('sortable'))		this.addSortable(objs[i]);
			if (objs[i].hasClass('change-input'))	this.addChangeInput(objs[i]);
			//if (objs[i].hasClass('thumbslide'))		this.addThumbSlide(objs[i]);
			if (objs[i].hasClass('tip'))			this.addTip(objs[i]);
			if (objs[i].hasClass('gallery'))		this.addGallery(objs[i]);
			
			// SHOW/HIDE
			if (objs[i].hasClass('tab'))			this.addTab(objs[i]);
			if (objs[i].hasClass('expand'))			this.addExpand(objs[i]);
			if (objs[i].hasClass('accordion'))		this.addAccordion(objs[i]);
			if (objs[i].hasClass('slider'))			this.addSlider(objs[i]);
			
			// FX
			if (objs[i].hasClass('changefontsize'))	this.addChangeFontSize(objs[i]);
			if (objs[i].hasClass('highlight'))		this.highlight(objs[i]);
			if (objs[i].hasClass('eyefish'))		this.addEyeFish(objs[i]);
			
			// last
			if (objs[i].hasClass('question'))		this.addConfirm(objs[i]);
		}
	},
	
	this.addSearch = function( obj )
	{
		obj.form = obj.getElement('form');
		obj.search = obj.getElement('.inp-search');
		//obj.button = obj.getElement('.go-search');
		if (obj.suggest)
		{
			obj.search.addEvent('keyup', function(search) {
				if (this.timerPreSearch) $clear(this.timerPreSearch);
				this.timerPreSearch = this.preSearch.delay(500, this, search);
			}.pass(obj.search, this) );
			obj.search.addEvent('focus', function(search) {
				this.openPreSearch(search);
			}.pass(obj.search, this) );
			obj.search.addEvent('blur', function(search) {
				this.closePreSearch(search);
			}.pass(obj.search, this) );
		}
		var fn = function(obj) {
			/***/
		}.pass(obj, this);
		/*if (obj.form)
		{
			obj.form.addEvent('submit',  fn );
			obj.form.addEvent('submit',  function(event) { new Event(event).stop(); } );
		}
		obj.button.addEvent('click',  fn );
		obj.button.addEvent('click',  function(event) { new Event(event).stop(); } );
		*/
	},
	
	this.preSearch = function( search )
	{
		if (search.get('value').length >= 3)
		{
			if (search.preSearchXHR)
				search.preSearchXHR.cancel();
			search.preSearchXHR = new Request( {
				url: 'ajax.php',
				data: "scope=module&load=presearch&q=" + search.get('value'),
				method: "get"
			} ).send();
			search.preSearchXHR.addEvent('onComplete', this.parsePreSearch.pass(search, this) );
		}
		else
			this.closePreSearch( search )
	},
	
	this.parsePreSearch = function( search )
	{
		/*var pts = search.preSearchXHR.response.text.split('|');
		if (pts.length > 0)
		{
			for (var i=0; i<pts.length; i++)
			{
				var ppts = pts[i].split('=>');
				if (ppts[0].length > 0)
					$(ppts[0]).innerHTML = ppts[1];
				//$(ppts[0]).setHTML( ppts[1] );
			}
		}*/
		search.results.set('html', search.preSearchXHR.response.text);
		this.openPreSearch(search);
	},
	
	this.createPreSearch = function( search )
	{
		var searchPos = search.getCoordinates();
		search.results = new Element('div', {'class': 'search-results'} )
			.setStyles({'position': 'absolute', 'zIndex': 2000, 'left': searchPos.left + searchPos.width, 'top': (searchPos.top + searchPos.height)/*, 'width': searchPos.width*/ })
			.inject(document.body);
		search.results.fx = new Fx.Tween(search.results, { 'duration': 200, 'property': 'opacity' });
		search.results.bounce = new Fx.Tween(search.results, { 'duration': 1000, 'property': 'padding-top', 'transition': Fx.Transitions.Bounce.easeOut });
	},
	
	this.openPreSearch = function( search )
	{
		if (!search.results)
			this.createPreSearch( search );
		if (search.get('value').length >= 3)
		{
			search.results.bounce.set(0);
			search.results.fx.start(1).chain( function(search) {
				search.results.bounce.start(5);
			}.pass(search) );
		}
	},
	
	this.closePreSearch = function( search )
	{
		search.results.fx.start(0);
	},
	
	this.addConfirm = function( obj )
	{
		obj.addEvent('click', function(obj) {
			if (!obj.continueClick()) return false;
		}.pass(obj, this) );
	},
	
	this.login = function( post )
	{
		this.popupMng.addEvent('onUpdate', function() { document.fireEvent('updateblock', this.popupMng.content); }.bind(this) );
		this.popupMng.fromElement( $('enter'), { 'url': $('enter').getURL() } );
	},
	
	this.initPopup = function( )
	{
		SqueezeBox.initialize({
			ajaxOptions: {
				method: 'get'
			}
		});
		this.popupMng = SqueezeBox;
	},
	
	this.initMouseTip = function( )
	{
		this.mouseTip = new Element('div', {'class': 'mousetip'}).setStyles({'position':'absolute', 'z-index': 100000}).inject(this.body);
		this.mouseTip.fx = new Fx.Tween(this.mouseTip, { 'property': 'opacity', 'link': 'cancel' } ).set(0);
		this.plugins['mousetip'] = true;
	},
	
	this.execBlock = function( obj )
	{
		this.addMouseTip( obj.loadmsg || 'Caricamento...', 0 );
		var url = obj.getURL();
		obj.xhr = new Request( {
			url: url
		} ).send();
		obj.xhr.addEvent('onComplete', function(obj) {
			var response = obj.xhr.response.text
			if (this.parseResponse(response))
				obj.setContent( response );
			this.closeMouseTip( );
		}.pass(obj, this) );
	},
	
	this.execForm = function( obj )
	{
		this.addMouseTip( obj.loadmsg || 'Caricamento...', 0 );
		var url = obj.getURL();
		if (obj.xhr)
			obj.xhr.cancel();
		obj.xhr = new Request( {
			'url': url,
			'data': obj.getQueryString(),
			'method': "post"
		} ).send();
		obj.xhr.addEvent('onComplete', this.parseSave.pass(obj, this) );
		return false;
	},
	
	this.addSave = function( obj )
	{
		if (obj.unload)	
			window.addEvent('beforeunload', function(obj) { if (!confirm(obj.unload)) return true; }.pass(obj, this) );
		obj.addEvent('submit', this.execForm.pass(obj, this) );
		//obj.addEvent('submit', function(e) { new Event(e).stop(); return false; } );
	},
	
	this.parseSave = function( obj )
	{
		var response = obj.xhr.response.text;
		if (this.parseResponse(response))
		{
			if (obj.targetEl == 'popup')
				this.popupMng.setContent( 'string', response );
			else if (obj.targetEl == 'none') { }
			else
				$(obj.targetEl).setContent(response);
		}
		this.closeMouseTip( );
	},
	
	this.parseResponse = function( text )
	{
		var trigger = '[goto:';
		if (text.indexOf(trigger) !== -1)
		{
			self.location.href = text.substr( trigger.length, text.length - trigger.length - 1 );
			return false;
		}
		if (text == '[login]')
		{
			this.login();
			return false;
		}
		return true;
	},
	
	this.addUpdate = function( obj )
	{
		if (obj.get('tag') == 'form')
			this.updateFormDelay(obj);
		if (obj.get('tag') == 'select')
		{
			obj.addEvent('change', function(event) {
				new Event(event).stop();
				this.feedSelect(obj);
				return false;
			}.pass(obj, this) );
		}
	},
	
	this.updateFormDelay = function( obj )
	{
		var inputs = obj.getElements('input,select,textarea');
		var autosave = obj.getElement('.autosave');
		var func = function(obj)
		{
			if (obj.autosave)
				if (!obj.autosave.get('checked'))
					return true;
			
			if (obj.updateTimer)
				$clear( obj.updateTimer );
			obj.updateTimer = this.execForm.delay(obj.delay, this, obj);
			//return false;
		}.pass(obj, this);
		for (var i=0; i<inputs.length; i++)
		{
			if ( (!inputs[i].hasClass('no-update')) && (inputs[i].get('type') != 'file') )
			{		
				inputs[i].addEvent('change', func);
				inputs[i].addEvent('keypress', func);
			}
		}
	},
	
	this.addWidget = function( obj )
	{
		obj.widget = new Widget( obj, obj.name, obj.get, obj.functions );
		obj.widget.addEvent('login', function( obj ) {
			this.login();
		}.pass(obj, this) );
		obj.widget.addEvent('added', function( obj ) {
			this.addMouseTip('Questo modulo è stato aggiunto al tuo pannello!', 1);
		}.pass(obj, this) );
		obj.widget.addEvent('removed', function( obj ) {
			this.addMouseTip('Questo modulo è stato rimosso dal tuo pannello!', 1);
		}.pass(obj, this) );
		this.widgets[ this.widgets.length ] = obj.widget;
	},
	
	this.addRating = function( obj )
	{
		if (!this.plugins['ratings'])
		{
			this.plugins['ratings'] = new Asset.javascript("includes/libraries/ratings.js");
			this.plugins['ratings'].addEvent('load', this.addRatingBlock.pass(obj, this) );
		}
		else
			this.addRatingBlock( obj );
	},
	
	this.addRatingBlock = function( obj )
	{
		obj.ratings = new Ratings( obj );
	},
	
	this.addRatingValue = function( obj )
	{
		obj.thisHTML = obj.get('html');
		obj.empty();
		obj.container = new Element('div', {'class': 'rating-container'}).set('title', obj.thisHTML).inject( obj );
		obj.size = obj.container.getSize();
		obj.stars = new Element('div', {'class': 'rating-stars'}).setStyles({'width': obj.size.x * obj.value / obj.base}).set('html', '&nbsp').inject( obj.container );
	},
	
	this.addScroller = function( obj )
	{
		obj.scroll = $(obj.scrollEl);
		obj.target = $(obj.targetEl);
		if (!obj.scroll.fx)
		{
			obj.scroll.fx = new Fx.Scroll(obj.scroll, {
										wait: false,
										duration: 500,
										offset: {'x': 0, 'y':0},
										transition: Fx.Transitions.Quad.easeInOut
									});
		}
		obj.addEvent('click', function(obj) {
			obj.scroll.fx.toElement(obj.targetEl);
		}.pass(obj, this) );
		obj.addEvent('click', function(event) {
			event = new Event(event).stop();
		} );
	},
	
	this.addPopup = function( obj )
	{
		if (obj.blank == 'true')
		{
			obj.addEvent('click', function(obj) {
				window.open( obj.getURL(), 'new', 'menubar=no,width='+obj.pwidth+',height='+obj.pheight+',location=no,resizable=no,scrollbars=yes,status=no' );
			}.pass(obj, this) );
		}
		else
		{
			if (!this.popupMng)
				this.initPopup();
			obj.addEvent('click', function(obj) {
				obj.options = {
					url: obj.getURL(),
					size: { x: (obj.pwidth || 550),
							y: (obj.pheight || 500) }
				}
				if (!obj.continueClick()) return false;
				this.popupMng.addEvent('onUpdate', function() { document.fireEvent('updateblock', this.popupMng.content); }.bind(this) );
				this.popupMng.fromElement(obj, obj.options);
			}.pass(obj, this) );
		}
		obj.addEvent('click', function(e) { new Event(e).stop(); } );
	},
	
	this.addMouseTip = function( content, closeAfter )
	{
		if (!this.plugins['mousetip'])
			this.initMouseTip();
		
		this.mouseTip.fn = function(e) {
			this.mouseTip.setStyles({'left': this.mouse.x, 'top': this.mouse.y});
		}.bind(this)
		
		if (this.mouseTip.status)
			document.removeEvent('mousemove', this.mouseTip.fn);
		document.addEvent('mousemove', this.mouseTip.fn );
		this.mouseTip.status = true;
		this.mouseTip.setStyles({'left': this.mouse.x, 'top': this.mouse.y});
		this.mouseTip.set('html', content);
		this.mouseTip.fx.start(1);
		$clear(this.mouseTip.delayTimer);
		if (closeAfter)
			this.mouseTip.delayTimer = this.closeMouseTip.delay(2000, this);
	},
	
	this.closeMouseTip = function()
	{
		this.mouseTip.fx.start(0).chain( function() {
			document.removeEvent('mousemove', this.mouseTip.fn);
			this.mouseTip.status = false;
		}.bind(this) );
	},
	
	this.addExpand = function( obj )
	{
		obj.status = false;
		obj.toggler = obj.getElement('.expand-toggler');
		obj.block = obj.getElement('.expand-block').setStyle('overflow', 'hidden');
		obj.block.fx = new Fx.Tween( obj.block, { 'property': 'height', 'link': 'cancel'} ).set(0);
		if (obj.show == 'true') this.openExpand(obj); else this.closeExpand(obj);
		obj.toggler.addEvent('click', function(obj) {
			if (!obj.continueClick()) return false;
			if (obj.status)
				this.closeExpand( obj );
			else
				this.openExpand( obj );
		}.pass(obj, this) );
		if (obj.toggler.get('tag') == 'a')
			obj.toggler.addEvent('click', function(e) { new Event(e).stop(); } );
	},
	
	this.openExpand = function( obj )
	{
		obj.block.fx.start( obj.block['scrollHeight'] ).chain( function(block) { block.setStyle('height', 'auto'); }.pass(obj.block) );
		obj.toggler.addClass('expand-open');
		obj.status = true;
	},
	
	this.closeExpand = function( obj )
	{
		obj.block.fx.set(obj.block['scrollHeight']).start( 1 );
		obj.toggler.removeClass('expand-open');
		obj.status = false;
	},
	
	this.addTab = function( obj )
	{
		obj.tabs = obj.getElements('.'+obj.tabCSS);
		obj.pages = obj.getElements('.'+obj.pageCSS);
		
		obj.pages.setStyle('display', 'none');
		if (obj.tabSelected)
		{
			obj.defaultTab = obj.tabSelected;
			this.openTab( obj, obj.tabSelected );
		}
		else
			this.openTab( obj, 0 );
		for (var i=0; i<obj.tabs.length; i++)
		{
			switch (obj.onevent)
			{
				case 'over':
					obj.tabs[i].addEvent('mouseenter', this.openTabDelayed.pass([obj, i], this) );
					obj.tabs[i].addEvent('mouseenter', function(obj) { $clear(obj.periodical); }.pass(obj, this) );
					obj.tabs[i].addEvent('mouseleave', function(obj) { $clear(obj.delay); }.pass(obj, this) );
					if (obj.backToDefault == 'true') obj.tabs[i].addEvent('mouseleave', function(obj) { this.openTabDelayed(obj, obj.defaultTab); }.pass(obj, this) );
				break;
				default:
					obj.tabs[i].addEvent('click', this.openTab.pass([obj, i], this) );
					obj.tabs[i].addEvent('click', function(e) { $clear(obj.periodical); new Event(e).stop(); } );
				break;
			}
		}
		
		if (obj.loop == 'true')
		{
			obj.position = 0;
			obj.periodical = this.loopTab.periodical( parseInt(obj.timer), this, obj );
		}
	},
	
	this.loopTab = function( obj )
	{
		//document.title = new Date();
		obj.position++;
		if (obj.position > (obj.tabs.length-1)) obj.position = 0;
		
		this.openTab( obj, obj.position );
	},
	
	this.openTabDelayed = function( obj, selected )
	{
		if (obj.delay)
			$clear(obj.delay);
		obj.delay = this.openTab.delay( (obj.changedelay || 300), this, [obj, selected] );
	},
	
	this.openTab = function( obj, selected )
	{
		if (!obj.continueClick()) return false;
		
		for (var i=0; i<obj.tabs.length; i++)
		{
			if (i == selected)
			{
				obj.tabs[i].addClass('tab-selected');
				obj.pages[i].setStyle('display', 'block');
			}
			else
			{
				obj.tabs[i].removeClass('tab-selected');
				obj.pages[i].setStyle('display', 'none');
			}
		}
	},
	
	this.addPager = function( obj )
	{
		obj.pager = new Pager( obj, {
			target: obj.targetEl,
			urlproto: obj.urlproto,
			current: obj.current,
			pages: obj.pages,
			total: obj.total
		} );
	},
	
	this.addOnFly = function( obj )
	{
		obj.addEvent('click', function(obj) {
			if (!obj.continueClick()) return false;
			this.addMouseTip( obj.loadmsg || '<img src="templates/images/icons/loading.gif" />', 0 );
			var url = obj.getURL();
			var options = { url: url, method: 'post' }
			if (obj.post)
			{
				options.data = $(obj.post).toQueryString();
			}
			obj.xhr = new Request( options ).send();
			obj.xhr.addEvent('onComplete', function(obj) {
				var response = obj.xhr.response.text;
				if (obj.targetEl == 'popup')
					this.popupMng.setContent( 'string', response );
				else
				{
					if (obj.targetEl == '[same]')
						var target = obj;
					else
						var target = $(obj.targetEl);
					if (obj.transition)
						target.transition = obj.transition;
					target.setContent( response );
				}
				this.closeMouseTip( );
				obj.fireEvent('success');
			}.pass(obj, this) );
		}.pass(obj, this) );
		obj.addEvent('click', function(e) { new Event(e).stop(); } );
	},
	
	this.addDelayed = function( obj )
	{
		if (!obj.loadedDelay)
		{
			var url = obj.getURL();
			obj.xhr = new Request( {
				url: url
			} ).send();
			obj.xhr.addEvent('onComplete', function(obj) {
				obj.loadedDelay = true;
				obj.setContent( obj.xhr.response.text );
			}.pass(obj, this) );
		}
	},
	
	/// TABS ///
	this.addRelabel = function( obj )
	{
		obj.set('value', obj.label);
		
		obj.addEvent('focus', function() {
			if (obj.get('value') == obj.label)
				obj.set('value', '');
		}.pass(obj, this) );
		
		obj.addEvent('blur', function() {
			if (obj.get('value') == '')
				obj.set('value', obj.label);
		}.pass(obj, this) );
	},
	
	this.addRadioGroup = function( obj )
	{
		var radios = obj.getElements('.'+obj.childs);
		var labels = obj.getElements('label');
		for (var i=0; i<radios.length; i++)
		{
			radios[i].importProps();
			if (!radios[i].css)
				radios[i].css = 'radio';
			// found label
			for (var j=0; j<labels.length; j++)
			{
				if ( radios[i].get('id') == labels[j].get('for') )
					radios[i].label = labels[j];
			}
			
			radios[i].setStyles( { 'display': 'none' } );
			radios[i].replace = new Element('a', {'href': 'javascript:;', 'class': radios[i].css }).set('html', '<span>&nbsp;</span>').inject(radios[i], 'after');
			this.switchRadio( radios[i], radios[i].get('checked') );
			if (radios[i].get('disabled'))
				radios[i].replace.addClass(radios[i].css + '-disabled');
			radios[i].replace.addEvent('click', function(obj) {
				if (!obj.disabled)
				{
					obj.click();
					//obj.fireEvent('change');
				}
			}.pass(radios[i], this ) );
			if (obj.selection == 'multiple')
			{
				radios[i].addEvent('change', function(obj) {
					this.switchRadio( obj, obj.get('checked') );
				}.pass(radios[i], this ) );
			}
			else
			{
				radios[i].addEvent('change', function(obj, index) {
					for (var i=0; i<radios.length; i++)
					{
						this.switchRadio( radios[i], (i == index) && (radios[i].get('checked')) );
           			}
				}.pass([radios, i], this ) );
			}
			if (radios[i].label)
			{
				radios[i].label.addEvents( {
					'mouseenter': function(obj) { obj.replace.addClass(obj.css + '-over'); }.pass(radios[i], this),
					'mouseleave': function(obj) { obj.replace.removeClass(obj.css + '-over'); }.pass(radios[i], this)
				} );
			}
		}
	},
	
	this.switchRadio = function( obj, status )
	{
		if (status)
		{
			obj.replace.addClass(obj.css + '-selected');
			if (obj.label)
				obj.label.addClass(obj.css + '-selected');
		}
		else
		{
			obj.replace.removeClass(obj.css + '-selected');
			if (obj.label)
				obj.label.removeClass(obj.css + '-selected');
		}
	},
	
	this.addChangeInput = function( obj )
	{
		obj.addEvent('click', function(obj) {
			obj.input = $(obj.input);
			obj.input.set('value', obj.set);
			if (obj.forcesubmit == 'true')
			{
				obj.getParent('form').removeEvents('submit');
				obj.getParent('form').submit();
			}
			else
				obj.input.fireEvent('change');
		}.pass(obj,this) );
	},
	
	this.addPutInput = function( obj )
	{
		this.parseInput(obj);
		obj.addEvent('click', this.parseInput.pass(obj, this) );
	},
	
	this.parseInput = function( obj )
	{
		var url = obj.get('href');
		var trigger = '[input:';
		var indstart	= url.indexOf(trigger);
		var indend		= url.indexOf(']', indstart);
		if (indstart !== -1)
		{
			var inputname = url.substring(indstart + trigger.length, indend);
			var url = url.replace(url.substring(indstart, indend+1), $(inputname).get('value') );
			obj.set('href', url);
		}
	},
	
	this.highlight = function( obj )
	{
		obj.hlFx = new Fx.Tween(obj, { 'property': 'opacity', 'wait': false, 'duration': 400, 'fps': 100}).set(.6);
		obj.addEvents( {
			'mouseenter': function(obj) {
				obj.hlFx.start(1);
			}.pass(obj,this),
			'mouseleave': function(obj) {
				obj.hlFx.start(.6);
			}.pass(obj,this)
		} );
	},
	
	this.addEyeFish = function( obj )
	{
		obj.fx = new Fx.Tween(obj, {'property': 'font-size', 'link': 'cancel', 'duration': 300});
		obj.addEvent('mouseenter', function(obj) {
			obj.fx.start(parseInt(obj.to));
		}.pass(obj, this) );
		obj.addEvent('mouseleave', function(obj) {
			obj.fx.start(parseInt(obj.from));
		}.pass(obj, this) );
	},
	
	this.addRangeSlider = function( obj )
	{
		if (!this.plugins['rangeslider'])
		{
			this.plugins['rangeslider'] = new Asset.javascript("includes/libraries/range.js");
			this.plugins['rangeslider'].addEvent('load', this.addRangeSlider.pass(obj, this) );
			return false;
		}
		// saving inputs
		obj.inputFrom = obj.getElement('.from');
		obj.inputTo = obj.getElement('.to');
		var fromValue = parseInt(obj.inputFrom.get('value'));
		var toValue = parseInt(obj.inputTo.get('value'));
		obj.slider = new Element('div', {'class': 'range-slider'} ).inject(obj);
		obj.knobLeft = new Element('div', {'class': 'range-knob knob-left'} ).inject(obj.slider);
		obj.knobRight = new Element('div', {'class': 'range-knob knob-right'} ).inject(obj.slider);
		obj.rangeSlider = new RangeSlider(obj.slider, obj.knobLeft, obj.knobRight, {
			steps: parseInt(obj.steps),
			minValue: parseInt(obj.min),
			maxValue: parseInt(obj.max)
		}).set( { from: fromValue, to: toValue } );
		obj.rangeSlider.addEvent('onChange', function(step) {
			this.inputFrom.set('value', step.from);
			this.inputTo.set('value', step.to);
			if (!this.disabled)
			{
				this.inputFrom.fireEvent('change', '');
				this.inputTo.fireEvent('change', '');
			}
		}.bind(obj) );
		// actions...
		obj.inputFrom.addEvent('change', function()
		{
			obj.rangeSlider.setFrom( parseInt(this.getProperty('value')) );
		} );
		obj.inputTo.addEvent('change', function()
		{
			obj.rangeSlider.setTo( parseInt(this.getProperty('value')) );
		} );
	}
	
	this.addSortable = function( obj )
	{
		if (obj.sortable)
			obj.sortable = null;
		obj.sortable = new Sortables( obj.getElements('.' + obj.list), {
			handle: '.' + obj.handle,
			constrain: false,
			//clone: true,
    		revert: { duration: 500, transition: 'bounce:out' },
			onComplete: this.parseOrder.pass(obj,this)
		});
	}
	
	this.parseOrder = function( obj )
	{
		var inputs = obj.getElements('.' + obj.input);
		for (var i=0; i<inputs.length; i++)
		{
			inputs[i].set('value', i);
			inputs[i].fireEvent('change');
		}
	}
	
	this.addThumbSlide = function( obj )
	{
		if (obj.total > 1)
		{
			var params = { total: obj.total }
			if (obj.id)
			{
				var proto = '';
				var pt = obj.getProperty('src').split("/");
				for (var i=0; i<pt.length-1; i++)
				{
					proto += pt[i] + '/';
				}
				proto += obj.id + '_[num].jpg';
				params.proto = proto;
			}
			if (obj.files)
			{
				params.files = obj.files.split(',');
				for (var i=0; i<params.files.length; i++)
					params.files[i] = params.files[i].replace('[http]', 'http://');
			}
			obj.thumbslide = new Thumbchange( obj, params );
			obj.addEvent('mouseenter', function(event) {
				new Event(event).stop();
				this.thumbslide.start();
				return false;
			} );
			obj.addEvent('mouseleave', function(event) {
				new Event(event).stop();
				this.thumbslide.stop();
				return false;
			} );
		}
	},
	
	this.addAccordion = function( obj )
	{
		var togglers = obj.getElements('.toggler');
		var blocks = obj.getElements('.block');
		obj.accordion = new Accordion(togglers, blocks, {
			opacity: true
		} );
		obj.accordion.addEvents( {
			'onActive': function(toggler,block) {
				toggler.addClass('toggler-selected');
			},
			'onBackground': function(toggler,block) {
				toggler.removeClass('toggler-selected');
			}
		} )
		if (togglers.length > 0)
		{
			var found = 0;
			for (var i=0; i<togglers.length; i++)
				if (togglers[i].hasClass('selected'))
					var found = i;
			togglers[found].addClass('toggler-selected');
			obj.accordion.display( found );
		}
	},
	
	this.addSlider = function( obj )
	{
		var totalwidth = 0;
		var maxheight = 0;
		obj.items = obj.getElements('.slider-item');
		obj.items.removeClass('slider-item-ghost');
		for (var i=0; i<obj.items.length; i++)
			if (obj.items[i].getSize().y > maxheight)
				maxheight = obj.items[i].getSize().y;
		
		obj.slider = new Element('div').setStyles({'position': 'relative', 'overflow': 'hidden', 'width': obj.getSize().x, 'height': maxheight } ).inject( obj );
		obj.container = new Element('div').setStyles( { 'height': obj.getSize().y } ).inject( obj.slider );
		obj.container.fx = new Fx.Tween( obj.container, {'property': 'margin-left', 'link': 'cancel', 'duration': 500, 'fps': 200, 'transition': Fx.Transitions.Back.easeOut } ).set(0);
		
		for (var i=0; i<obj.items.length; i++)
		{
			obj.width = obj.items[i].getSize().x;
			totalwidth += obj.width;
			obj.items[i].setStyles( { 'float': 'left', 'width': obj.width, 'height': maxheight } );
			obj.items[i].inject( obj.container );
		}
		obj.container.setStyles( { 'width': totalwidth } );
		if (obj.noprevnext == 'true') {} else
		{
			obj.prev = new Element('a', {'class': 'slide-prev_' + obj.get('id'), 'html': '<span>indietro</span>', 'href': 'javascript:;' }).inject( obj, 'before' );
			obj.next = new Element('a', {'class': 'slide-next_' + obj.get('id'), 'html': '<span>avanti</span>', 'href': 'javascript:;' }).inject( obj, 'before' );
			obj.prev.addEvent('click', this.slidePrevNext.pass([obj, 'prev'], this) );
			obj.next.addEvent('click', this.slidePrevNext.pass([obj, 'next'], this) );
			obj.prev.addEvent('click', function(obj) { $clear(obj.periodical); }.pass(obj) );
			obj.next.addEvent('click', function(obj) { $clear(obj.periodical); }.pass(obj) );
		}
		obj.exposition = 0;
		obj.position = 0;
		
		if (obj.bullet == 'true')
		{
			obj.bullets = [];
			obj.bulletsContainer = new Element('div', {'class': 'slide-bullets'}).inject(obj);
			for (var i=0; i<obj.items.length; i++)
			{
				obj.bullets[i] = new Element('a', {'href': 'javascript:;', 'html': '<span>'+(i+1)+'</span>' } ).inject( obj.bulletsContainer );
				obj.bullets[i].addEvent('click', function(obj, i) {
					$clear(obj.periodical);
					this.slidePrevNext( obj, i );
				}.pass([obj, i], this) );
			}
			obj.bullets[0].addClass('slide-bullet-selected');
		}
		
		if (obj.loop == 'true')
		{
			obj.periodical = this.slidePrevNext.periodical( parseInt(obj.timer), this, [obj, 'next'] );
		}
	},
	
	this.slidePrevNext = function( obj, move )
	{
		obj.exposition = obj.position;
		switch (move)
		{
			case 'prev':
				obj.position--;
				if (obj.position < 0) obj.position = (obj.items.length-1);
			break;
			case 'next':
				obj.position++;
				if (obj.position > (obj.items.length-1)) obj.position = 0;
			break;
			default:
				obj.position = move;
			break;
		}
		obj.container.fx.start( -(obj.width * obj.position) );
		
		if (obj.bullets)
		{
			obj.bullets[obj.exposition].removeClass('slide-bullet-selected');
			obj.bullets[obj.position].addClass('slide-bullet-selected');
		}
	},
	
	this.addTip = function( obj )
	{
		obj.addEvent('click', function(obj) {
			this.addMouseTip( obj.get('title'), obj.delay || 2000 )
		}.pass(obj, this) );
	},
	
	this.addChangeFontSize = function( obj )
	{
		obj.addEvent('click', function( obj ) {
			obj.size = parseInt($( obj.targetEl ).getStyle('font-size'));
			if (obj.action == 'up')
				obj.size++;
			else
				obj.size--;
			$( obj.targetEl ).setStyle('font-size', obj.size );
		}.pass(obj, this) );
		obj.addEvent('click', function( e ) { new Event(e).stop(); } );
	},
	
	this.addGallery = function( obj )
	{
		var thumbs = obj.getElements('.photo-thumb');
		for (var i=0; i<thumbs.length; i++)
		{
			thumbs[i].mode = obj.gallerymode;
			this.parseThumbGallery( thumbs[i] );
		}
	},
	
	this.parseThumbGallery = function( obj )
	{
		obj.importProps();
		obj.link = obj.getElement('a');
		obj.thumb = obj.getElement('img');
		obj.link.addEvent('click', this.showImageGallery.pass([obj, true], this) );
		obj.link.addEvent('click', function(e) { new Event(e).stop(); } );
		
		obj.addEvent('selected', this.showImageGallery.pass([obj, false], this) );
	},
	
	this.showImageGallery = function( obj, selectpoi )
	{
		switch (obj.mode)
		{
			default:
			case 'normal':
				this.galleryImg = $( obj.targetEl );
				this.galleryImg.set('src', obj.link.get('href') );
			break;
			
			case 'marker':
			case 'bottom':
				if (obj.mode == 'bottom')
				{			
					var size = obj.getSize();
					var pos = obj.getPosition();
				}
				if (obj.mode == 'marker')
				{
					var size = obj.poi.getMain()._el.getSize();
					var pos = obj.poi.getMain()._el.getPosition();
					pos.y -= (size.y / 2) - (obj.poi.marker._img.getSize().y / 2);
				}
				
				if (!this.galleryDiv)
				{
					this.fxOptions = { 'link': 'cancel', 'duration': 'long', 'transition': Fx.Transitions.Sine.easeOut }
					this.galleryDiv = new Element('div', {'class': 'gallery-image'}).setStyles({'z-index': 10000, 'position':'absolute','left': pos.x + (size.x / 2) - (obj.width / 2), 'top': pos.y - obj.height - 100}).inject(this.body, 'top');
					this.galleryDiv.fx = new Fx.Morph(this.galleryDiv, this.fxOptions ).start({'opacity': 0});
					this.galleryImg = new Element('img').inject( this.galleryDiv );
					this.galleryImg.fx = new Fx.Morph(this.galleryImg, this.fxOptions );
					this.galleryImg.addEvent('load', function() {
						this.galleryImg.setStyle('display', 'block');
					}.bind(this) );
					this.galleryCaption = new Element('div', {'class': 'gallery-caption'}).setStyles({'z-index': 100, 'position':'absolute', 'left': 0, 'bottom': 0}).inject(this.galleryDiv);
					this.galleryCaption.span = new Element('span').inject( this.galleryCaption );
					this.galleryCaption.fx = new Fx.Morph(this.galleryCaption, this.fxOptions );
					this.galleryClose = new Element('a', {'href': 'javascript:;', 'class': 'gallery-close'}).setStyles({'float': 'right'}).set('html', '<span>x</span>').inject( this.galleryCaption, 'top');
					this.galleryClose.addEvent('click', function() {
						this.galleryDiv.fx.start({ 'opacity': 0 });
					}.bind(this) );
				}
				
				this.galleryImg.setStyle('display', 'none');
				this.galleryImg.set('src', obj.link.get('href') );
				this.galleryCaption.span.set('html', obj.link.get('title') );
				this.galleryDiv.fx.start({
					'width': obj.width, 
		   			'height': obj.height,
					'left': pos.x + (size.x / 2) - (obj.width / 2),
					//'top': pos.y - obj.height,
					'top': pos.y + size.y,
					'opacity': 1
				});
				this.galleryImg.fx.start({
					'width': obj.width, 
		   			'height': obj.height
				});
				this.galleryCaption.fx.start({
					'width': obj.width
				});
				
				if (obj.poi && selectpoi)
					obj.poi.select( );
			break;
		}
	}
}

/******* OBJECTS *****************/
var DragDrop = new Class({
	Implements: Events,
	
	initialize: function(el, target, options){
		this._el = $(el);
		this._target = target;
		this._options = options;
		this.launch();
	},
	
	launch: function( )
	{
		this._el.addEvent('mousedown', function(e) {
			e = new Event(e).stop();
			this.dragTimer = this.build.delay(200, this, e);
		}.bindWithEvent(this) );
		this._el.addEvent('mouseup', function() {
			$clear(this.dragTimer);
		}.bind(this) );
		this._el.addEvent('selectstart', function() { return false; } );
	},
	
	build: function( e )
	{
		//e = new Event(e).stop();
		this.fireEvent('start');
		this.cloned = this._el.clone().setStyles( this._el.getCoordinates() ).setStyles({'opacity': 0.7, 'position': 'absolute', 'z-index': 100000}).inject(document.body, 'top');
		//this._target.addEvent('drop', function () { this.reset(); this.fireEvent('drop'); }.bind(this) ); // REMOVE
		this.drag = this.cloned.makeDraggable({droppables: [this._target]});
		this.drag.addEvent('drop', function () { this.reset(); this.fireEvent('drop'); }.bind(this) );
		this.cloned.addEvent('emptydrop', this.reset.bind(this) )
		this.drag.start(e);
	},
	
	reset: function( )
	{
		this._target.removeEvents('drop');
		this.fxRemove = new Fx.Tween( this.cloned, { 'property': 'opacity', 'fps': 100, 'duration': 500 } ).start( 0 );
		this.fxRemove.addEvent('onComplete', function() {
			this.cloned.dispose();
		}.bind(this) );
	},
	
	getMouse: function( )
	{
		return this.drag.mouse.now;
	}
});

var Pager = new Class({
	initialize: function(el, options){
		this._el = el;
		this._options = options;
		this._el.empty();
		this._el.size = this._el.getSize();
		this._el2 = new Element('div', {'class': 'pager-right'}).inject( this._el );
		var knobWidth = parseInt(this._el.size.x / this._options.pages);
		knobWidth = ( (knobWidth < 50) ? 50 : knobWidth );
		this._knob = new Element('div', {'class': 'pager-knob'}).setStyles({'width': knobWidth }).inject( this._el2 );
		this._prev = new Element('a', {'class': 'pager-knob-prev'}).addEvent('click', this.prevPage.bindWithEvent(this)).inject( this._knob );
		this._next = new Element('a', {'class': 'pager-knob-next'}).addEvent('click', this.nextPage.bindWithEvent(this)).inject( this._knob );
		this._knob_body = new Element('div', {'class': 'pages-knob-body'}).inject( this._knob );
		
		this._target = $(this._options.target);
		this._page = parseInt( (this._options.current || 1) );
		this._pages = parseInt( this._options.pages );
		this._slider = new Slider( this._el, this._knob, {
			snap: true,
			steps: this._pages - 1,
			wheel: true
		} );
		this._slider.set( this.page2Step(this._page) );
		this._slider.addEvent('onComplete', this.changePage.bind(this) );
	},
	
	changePage: function( step )
	{
		page = parseInt(step) + 1;
		var url = this._options.urlproto.replace( '(page)', parseInt(page) );
		this.xhr = new Request( { url: url, autoCancel: true } ).send();
		this.xhr.addEvent('onComplete', function(page) {
			this._page = page;
			this._target.setContent( this.xhr.response.text );
		}.pass(page, this) );
	},
	
	prevPage: function(e)
	{
		new Event(e).stop();
		if ( this._page > 1)
			this._slider.set(this.page2Step(this._page - 1));
	},
	
	nextPage: function(e)
	{
		new Event(e).stop();
		if ( this._page < this._pages)
			this._slider.set(this.page2Step(this._page + 1));
	},
	
	page2Step: function(page)
	{
		return page - 1;
	}
});

var Thumbchange = new Class ({
	Implements: [Events, Options],
	
	options: {
		total: 1,
		delay: 1000,
		bullet: { 'width': 12, 'height': 12 }
	},
	
	initialize: function(element, options) {
		this.element  	= element;
		this.origsrc  	= element.src;
		this.running  	= false;
		this.runnable 	= true;
		this.images   	= new Array();
		this.srcs		= new Array();
		this.loaded		= new Array();
		this.setOptions(options);
		this.build();
	},
	
	build: function() {
		this.element.set('title', '');
		this.fx = new Fx.Tween( this.element, { 'property': 'opacity', 'link':'cancel'} );
		this.temp = new Element('img').inject( document.body, 'bottom' );
		this.temp.fx = new Fx.Tween(this.temp, { 'property': 'opacity', 'link':'cancel'}).set(0);
		this.counter = new Element('span', {'class': 'thumbslide-counter'}).setStyle('width', (this.options.bullet.width * this.options.total)).inject( this.element, 'after' );
		this.selection = new Element('strong').set('html', '<span>&nbsp;</span>').inject( this.counter );
		if (this.options.files)
		{
			for (var i=0; i<this.options.files.length; i++)
				this.srcs[i] = this.options.files[i];
		}
		else
		{
			for (var i=0; i<this.options.total; i++)
				this.srcs[i] = this.options.proto.replace('[num]', (i+1) );
		}
	},
	
	start: function () {
		this.element.addClass('highlight-on');
		if (this.runnable) {
			this.running = true;
			this.load.delay( this.options.delay, this, 1 );
		}
	},
	
	stop: function () {
		this.element.removeClass('highlight-on');
		if (this.runnable) {
			this.to( this.origsrc );
			this.selection.setStyle('background-position', '0px -'+this.options.bullet.height+'px');
			this.running = false;
		}
	},
	
	load: function (num) {
		if (this.timer) $clear(this.timer);
		if (this.running) {
			if (!this.loaded[num])
			{
				this.images[num] = new Element('img').set('src', this.srcs[num] );
				this.images[num].addEvent('load', this.animate.pass(num, this) );
			}
			else
				this.animate(num);
		}
	},
	
	animate: function (num) {
		if (this.running)
		{
			this.loaded[num] = true;
			this.selection.setStyle('background-position', (num * this.options.bullet.width) + 'px -'+this.options.bullet.height+'px');
			this.to( this.images[num].src );
			
			var next = (num == this.options.total-1) ? 0 : num + 1;
			this.timer = this.load.delay( this.options.delay, this, next );
		}
	},
	
	to: function( src )
	{
		var pos = this.element.getPosition();
		this.temp.set('src', src);
		this.temp.setStyles( { 'position': 'absolute', 'left': pos.x, 'top': pos.y } );
		this.fx.start(0);
		this.temp.fx.start(1).chain( function() {
			this.element.src = this.temp.src;
			this.destroy();
		}.bind(this) );
	},
	
	destroy: function( )
	{
		this.fx.set(1);
		this.temp.fx.set(0);
	}
});

/******* IMPLEMENTATION ***********/
Array.prototype.sum = function(){
	for(var i=0,sum=0;i<this.length;sum+=this[i++]);
	return sum;
}
Array.prototype.max = function(){
	return Math.max.apply({},this)
}
Array.prototype.min = function(){
	return Math.min.apply({},this)
}

Element.implement({
	importProps: function()
	{
		this.saveProps( this, this );
	},
	
	copyProps: function( obj )
	{
		this.saveProps( obj, this );
	},
	
	saveProps: function( source, target )
	{
		var trigger = "logics@";
		if (source.className.indexOf(trigger) !== -1)
		{
			// import rel settings
			var logics = source.className.substring( source.className.indexOf(trigger) + trigger.length );
			var parts = logics.split('|');
			for (var j=0; j<parts.length; j++)
			{
				kv = parts[j].split(':');
				if (kv.length == 2)
				{
					eval("target."+kv[0]+" = '"+kv[1]+"'");
				}
			}
		}
	},
	
	getURL: function( )
	{
		var uri = (this.tagName == 'A' ? this.get('href') : this.get('action') );
		if (this.urlproto)
			var url = this.urlproto.replace( '[url]', uri + '&' );
		else
			var url = uri;
		return url;
	},
	
	getQueryString: function(){
		var queryString = [];
		this.getElements('input, select, textarea').each(function(el){
			if (!el.name || el.disabled) return;
			var value = (el.tagName.toLowerCase() == 'select') ? Element.getSelected(el).map(function(opt){
				return opt.value;
			}) : ((el.type == 'radio' || el.type == 'checkbox') && !el.checked) ? null : el.value;
			$splat(value).each(function(val){
				if (val) queryString.push(el.name + '=' + escape(val));
			});
		});
		return queryString.join('&');
	},
	
	getPosition: function(relative){
		if (Browser.Engine.trident)
			var offset = {'x': this.getBoundingClientRect().left, 'y': this.getBoundingClientRect().top }
		else
			var offset = this.getOffsets();
		var scroll = this.getScrolls();
		var position = {x: offset.x - scroll.x, y: offset.y - scroll.y};
		var relativePosition = (relative && (relative = $(relative))) ? relative.getPosition() : {x: 0, y: 0};
		return {x: position.x - relativePosition.x, y: position.y - relativePosition.y};
	},
	
	continueClick: function( )
	{
		if (this.hasClass('confirm'))
		{
			if (confirm(this.question))
				return true;
			else
				return false;
		}
		return true;
	},
	
	loading: function( mode )
	{
		if (!this.loadingDiv)
		{
			this.loadingDiv = new Element('div', {'class': 'loading-trip-panel'}).setStyles({'position':'absolute'}).set('html', '&nbsp;').inject( this, 'top' );
			this.loadingFx = new Fx.Tween(this.loadingDiv, {'link': 'chain', 'property': 'opacity'}).set(0);
		}
		var size = this.getSize();
		this.loadingDiv.setStyles( { 'width': size.x, 'height': size.y } );
		switch (mode)
		{
			case 1: this.loadingFx.start(.7); break;
			case 0: this.loadingFx.start(0); break;
		}
	},
	
	setContent: function( html )
	{
	  	switch (this.transition)
	  	{
		case 'slide':
		
			// cancel if
			if (this.settingContent)
			{
				this.nextHTML = html;
				return;
			}
				
			this.size = this.getCoordinates();
			
			// build
			this.view = new Element('div').setStyles( {'position': 'relative', 'overflow': 'hidden'} ).inject( this, 'before' );
				this.view.setStyles( {'width': this.size.width, 'height': this.size.height} );
			this.wrapper = new Element('div').inject( this.view );
				this.wrapper.setStyles( {'width': this.size.width * 2 + 10, 'height': this.size.height, 'margin-left': 0} );
			this.exitDiv = new Element('div').set('html', this.get('html')).setStyles( {'width': this.size.width, 'float': 'left'} ).inject( this.wrapper );
			this.enterDiv = this.exitDiv.clone( ).set('html', html).inject( this.wrapper );
			this.empty();
			
			// slide
			this.nextHeight = this.enterDiv.getSize().y
			this.fxAdjust = new Fx.Tween( this.view, { 'property': 'height' } );
			this.fxScroll = new Fx.Tween( this.wrapper, { 'property': 'margin-left', 'fps': 100, 'duration': 1000, 'transition': Fx.Transitions.Sine.easeOut} );
			// starting animation
			this.settingContent = true;
			this.fxAdjust.start( this.nextHeight );
			
			this.setStyles({'display': 'none'});
			document.fireEvent('removeblock', this.exitDiv);
			this.set('html', html);
			document.fireEvent('updateblock', this.enterDiv);
			
			this.fxAdjust.addEvent('onComplete', function() {
				this.fxScroll.start( -this.size.width );
			}.bind(this) );
			
			this.fxScroll.addEvent('onComplete', function() {
				this.setStyles({'display': 'block'});
				document.fireEvent('updateblock', this);
				this.fireEvent('updated');
				this.destroySettingContent();
				if (this.nextHTML)
				{
					this.setContent( this.nextHTML );
					this.nextHTML = null;
				}
			}.bind(this) );
			
		break;
			
		default:
			document.fireEvent('removeblock', this);
			this.set('html', html);
			document.fireEvent('updateblock', this);
		break;
		}
	},
	
	destroySettingContent: function( )
	{
		this.exitDiv.destroy();
		this.enterDiv.destroy();
		this.wrapper.destroy();
		this.view.destroy();
		this.fxAdjust = null;
		this.fxScroll = null;
		this.exitDiv = this.enterDiv = this.wrapper = this.view = null;
		this.settingContent = false;
	}
} );

function docFromXML( txt )
{
	if (Browser.Engine.trident)
	{
		xml = new ActiveXObject("Microsoft.XMLDOM");
		xml.async="false";
		xml.loadXML(txt);
		var xmlDoc = xml.documentElement;
	}
	else
	{
		parser = new DOMParser();
		xml = parser.parseFromString(txt, "text/xml");
		var xmlDoc = xml.documentElement;
	}
	return xmlDoc;
}

function getXMLdata( node )
{
	var data;
	
	if (node.nodeValue)
		data = node.nodeValue;
	else if (node.firstChild)
		data = node.firstChild.data;
	
	if (!data)
		return null;
	
	return decodeHTML( data );
}

function decodeHTML( html )
{
	// DECODE HTML entities...let's the browser do the job! ^_^
	var temp_div = new Element('div').set('html', html);
	return temp_div.get('html');
}

function controlAll( form )
{
	var check = true;
	var inputs = form.getElements('input,select,textarea');
	for (var i=0; i<inputs.length; i++)
		if (inputs[i].get('value').length > 0) {} else check = false;
	if (!check)
	{
		alert('Completare tutti i campi');
		return false;
	}
}