// Version 0.5 
var undefined;

function Xar(item){
	if(arguments.length === 0) { this.item = []; }
	
	this.item = item;
}

Xar.prototype = {
	find: function(value){
		var length = this.item.length;
		
		for(var i = 0; i < length; ++i){
			if(this.item[i] == value) { return i; }
		}
		
		return null;
	},
	
	remove: function(value){
		var length = this.item.length;
		
		var newArray = [];
		
		for(var i = 0; i < length; ++i){
			if(this.item[i] != value) { newArray.push(this.item[i]); }
		}
		
		return newArray;
	},
	
	removeByValue: function(value){
		return this.remove(value);
	},
	
	removeByKey: function(value){
		var newArray = [];
		
		for(var key in this.item){
			if(key != value) { newArray[key] = this.item[key]; }
		}
		
		return newArray;
	},
	
	keys: function(){
		var newArray = [];
		
		for(var key in this.item) { newArray.push(key); }
		
		return newArray;
	},
	
	values: function(){
		var newArray = [];
		
		for(var key in this.item) { newArray.push(this.item[key]); }
		
		return newArray;
	}
};

function Xu(item, create, textString){
	var createStructure = true;
	if(create) {
		if(item == 'text') { item = document.createTextNode(textString); }
		else{ item = document.createElement(item); }
	}
	else{
		if(arguments.length === 0) { item = document; }
		else if(typeof item === 'string') { item = document.getElementById(item); }
		else if(typeof item === 'object' && item.isXu){
			item = item.get();
			createStructure = false;
		}
	}
	
	this.item = item;
	this.isXu = true;
	
	if(createStructure && this.item != undefined && this.item.nodeType != 3 && this.item.Xu_data == undefined){
		this.item.Xu_data      = [];
		this.item.Xu_events    = [];
		this.item.Xu_listeners = [];
	}
	
	this.addTagSpecificFunctions();
	delete this.addTagSpecificFunctions;
}

Xu.prototype = {
	getById: function(id){
		return document.getElementById(id);
	},
	
	getByTag: function(tag, num){
		var tmp = this.item.getElementsByTagName(tag);
		
		var results = [];
		for(var i = 0; i < tmp.length; ++i) { results.push(tmp[i]); }
		
		if(arguments.length == 2) { return (results.length > num ? results[num] : null); }
		
		return results;
	},
	
	getByClass: function(tag, className, num){
		var tmp = this.getByTag(tag);
		
		var results = [];
		for(var i = 0; i < tmp.length; ++i){
			if(tmp[i].className == className) { results.push(tmp[i]); }
		}
		
		if(arguments.length == 3) { return (results.length > num ? results[num] : null); }
		
		return results;
	},
	
	contains: function(item){
		return this.item == item;
	},
	
	get: function(){
		return this.item;
	},
	
	isNull: function(){
		return this.item === null;
	},
	
	setVar: function(label, value){
		if(arguments.length == 1){
			if(this.item[label] != undefined) { delete this.item[label]; }
		}
		else { this.item[label] = value; }
		
		return this;
	},
	
	getVar: function(label){
		if(this.item[label] == undefined) { return undefined; }
		
		return this.item[label];
	},
	
	setData: function(label, value){
		if(arguments.length == 1){
			if(this.item.Xu_data[label] != undefined) { delete this.item.Xu_data[label]; }
		}
		else { this.item.Xu_data[label] = value; }
		
		return this;
	},
	
	getData: function(label){
		if(this.item.Xu_data[label] == undefined) { return undefined; }
		
		return this.item.Xu_data[label];
	},
	
	addListener: function(listener, event, funcName){
		if(!funcName) { funcName = event + 'Handler'; }
		if(!this.item.Xu_listeners[event]) { this.item.Xu_listeners[event] = []; }
		
		this.item.Xu_listeners[event].push([listener, funcName]);
		
		if(!this.item.Xu_events[event]){
			var emptyFunc = function(){ return true; };
			this.addEvent(event, emptyFunc);
		}
		
		return this;
	},
	
	removeListener: function(listener, event){
		if(!event){
			for(event in this.item.Xu_listener){
				this.item.Xu_listener[event] = new Xar(this.item.Xu_listener[event]).remove(listener);
			}
		}
		
		this.item.Xu_listener[event] = new Xar(this.item.Xu_listener[event]).remove(listener);
		
		return this;
	},
	
	purgeListeners: function(event){
		if(!event) { this.item.Xu_listeners = []; }
		else { this.item.Xu_listeners = new Xar(this.item.Xu_listeners).removeByKey(event); }
	},
	
	getListeners: function(){
		return this.item.Xu_listeners;
	},
	
	addEvent: function(event, func){
		if(!this.item.Xu_events[event]){
			this.item.Xu_events[event] = [];
			
			this.item[event] = function(e){
				if (!e) { e = window.event; }
				
				var type = 'on' + e.type;
				
				var source = this;
				
				if(this.Xu_listeners[type]){
					var listenersLength = this.Xu_listeners[type].length;
					
					for(var i = 0; i < listenersLength; ++i) {
						this.Xu_listeners[type][i][0][this.Xu_listeners[type][i][1]](e, source, type);
					}
				}
				
				var eventsLength = this.Xu_events[type].length;
				
				var propagate = true;
				
				for(var x = 0; x < eventsLength; ++x) { propagate = this.Xu_events[type][x](e, source, type); }
				
				if(propagate === false) { return false; }
			};
		}
		
		this.item.Xu_events[event].push(func);
		
		return this;
	},
	
	removeEvent: function(event, func){
		if(!event){
			for(event in this.item.Xu_events){
				this.item.Xu_events[event] = new Xar(this.item.Xu_events[event]).remove(func);
			}
		}
		
		this.item.Xu_events[event] = new Xar(this.item.Xu_events[event]).remove(func);
		
		return this;
	},
	
	purgeEvents: function(event){
		if(!event) { this.item.Xu_events = []; }
		else { this.item.Xu_events = new Xar(this.item.Xu_events).removeByKey(event); }
	},
	
	getEvents: function(){
		return this.item.Xu_events;
	},
	
	fireEvent: function(event){
		var e = {
			type: event.substring(2),
			srcElement: this.item,
			target: this.item
		};
		
		this.item[event](e);
	},
	
	getComputedStyle: function(property){
		if(this.item.currentStyle) { return this.item.currentStyle[property]; }
		
		if(document.defaultView.getComputedStyle) { return document.defaultView.getComputedStyle(this.item, '')[property]; }
		
		return null;
	},
	
	getJSStyle: function(property){
		return this.item.style[property];
	},
	
	getStyle: function(property){
		//TODO: migliorare come setstyle
		var res = this.getJSStyle(property);
		
		if(res !== null) { return res; }
		
		return this.getComputedStyle(property);
	},
	
	setStyles: function(styleObj){
		for(var property in styleObj) { this.setStyle(property, styleObj[property]); }
		
		return this;
	},
	
	setStyle: function(property, value){
		switch(property){
			case 'float':
			if(!document.all || window.Opera) { this.item.style.cssFloat   = value; }
			else                              { this.item.style.styleFloat = value; }
			break;
			
			case 'opacity':
			this.item.style.opacity = (value / 100);
			this.item.style.filter  = 'alpha(opacity=' + value + ')';
			break;
			
			default:
			this.item.style[property] = value;
			break;
		}
		
		return this;
	},
	
	getAbsolutePosition: function(){
		var x = 0;
		var y = 0;
		var obj = this.item;
		if (obj.offsetParent) {
			x = obj.offsetLeft;
			y = obj.offsetTop;
			while (obj = obj.offsetParent) {
				x += obj.offsetLeft;
				y += obj.offsetTop;
			}
		}
		return [x, y];
	},
	
	appendTo: function(item){
		new Xu(item).get().appendChild(this.item);
		
		return this;
	},
	
	append: function(item){
		this.item.appendChild(new Xu(item).get());
		
		return this;
	},
	
	insertBeforeItem: function(item){
		item = new Xu(item).get();
		
		item.parentNode.insertBefore(this.item, item);
		
		return this;
	},
	
	insertAfterItem: function(item){
		item = new Xu(item).get();
		
		var next = item.nextSibling;
		
		if(next) { item.parentNode.insertBefore(this.item, next); }
		else     { item.parentNode.appendChild(this.item); }
		
		return this;
	},
	
	parentItem: function(level){
		if(level == undefined) { level = 0; }
		
		var tmp = this.item.parentNode;
		for(var i = level; i > 0; --i){
			if(tmp.parentNode == null) { return null; }
			tmp = tmp.parentNode;
		}
		
		return tmp;
	},
	
	childItem: function(pos){
		if(!this.item.hasChildNodes) { return null; }
		
		if(pos == undefined){
			var tmp = [];
			for(var i = 0; i < this.item.childNodes.length; ++i) { tmp.push(this.item.childNodes[i]); }
			return tmp;
		}
		else if(pos == 0) { return this.item.firstChild; }
		else if(pos == -1) { return this.item.lastChild; }
		else{
			var tmp = [];
			for(var i = 0; i < this.item.childNodes.length; ++i) { tmp.push(this.item.childNodes[i]); }
			
			if(pos > 0) { return (pos < tmp.length ? tmp[pos] : null); }
			else        { return (tmp.length + pos >= 0 ? tmp[tmp.length + pos] : null); }
		}
	},
	
	removeItem: function(item){
		this.item.removeChild(new Xu(item).get());
	},
	
	removeAll: function(){
		while(this.item.hasChildNodes()) { this.item.removeChild(this.item.lastChild); }
		
		return this;
	},
	
	removeSelf: function(){
		return this.item.parentNode.removeChild(this.item);
	},
	
	swapVarWithItem: function(item, property){
		//TODO: un po' di controllo di errore
		item = new Xu(item);
		tmp  = item.getVar(property);
		item.setVar(property, this.item[property]);
		this.item[property] = tmp;
	},
	
	//tag specific functions
	addTagSpecificFunctions: function(){
		if(this.item == null) { return; }
		
		switch(this.item.nodeType){
			case 1:
			switch(this.item.tagName.toLowerCase()){
				case 'select':
				this.setComboOptions = function(options, selected){
					for(var i = 0; i < options.length; i++) { this.item.options[i] = new Option(options[i].text, options[i].value); }
					this.item.options.length = options.length;
					this.item.selectedIndex = (selected == undefined || selected < 0 || selected > options.length ? 0 : selected);
					return this;
				}
				
				this.getComboValue = function(what){
					if(what == undefined) { return this.item.selectedIndex; }
					switch(what){
						case 'text': return this.item.options[this.item.selectedIndex].text;
						case 'value': return this.item.options[this.item.selectedIndex].value;
						case 'object':
						case 'option':
						case 'both': return this.item.options[this.item.selectedIndex];
						default: return null;
					}
				}
				break;
			}
			break;
		}
	}
}



function Xf(items){
	this.source = null;
	this.items  = null;
	
	if(items !== null && items !== undefined){
		if(items instanceof Array || (typeof NodeList != 'undefined' && items instanceof NodeList)){
			this.items  = [];
			this.source = [];
			var tmp = null;
			
			for(var i = 0; i < items.length; ++i){
				if(items[i].nodeType != 1) { continue; }
				tmp = new Xu(items[i]);
				this.items.push(tmp);
				this.source.push(tmp);
			}
		}
		else if(items.nodeType == 1){
			this.items  = [];
			this.source = [];
			items       = new Xu(items);
			
			this.items.push(items);
			this.source.push(items);
		}
	}
}

Xf.prototype = {
	reset: function(){
		if(this.source === null) { this.items = null; }
		else{
			this.items = [];
			for(var i = 0; i < this.source.length; ++i) { this.items.push(this.source[i]); }
		}
		
		return this;
	},
	
	consolidate: function(){
		if(this.items === null) { this.source = null; }
		else{
			this.source = [];
			for(var i = 0; i < this.items.length; ++i) this.source.push(this.items[i]);
		}
		
		return this;
	},
	
	getXu: function(pos){
		if(this.items === null) { return null; }
		
		if(pos === undefined) { return this.items; }
		else{
			if(pos >= 0) { return (pos < this.items.length ? this.items[pos] : null); }
			else         { return (this.items.length + pos >= 0 ? this.items[this.items.length + pos] : null); }
		}
	},
	
	get: function(pos){
		var items = this.getXu(pos);
		
		if(items === null) { return null; }
		else if(items instanceof Array) {
			for(var i = 0; i < items.length; ++i) { items[i] = items[i].get(); }
			return items;
		}
		else return new Xu(items);
	},
	
	filterByVar: function(varName, varValue){
		if(this.items === null) return;
		var tmp = [];
		for(var i = 0; i < this.items.length; ++i){
			if(this.items[i].getVar(varName) !== varValue) continue;
			tmp.push(this.items[i]);
		}
		this.items = tmp;
		
		return this;
	},
	
	filterByTag: function(tagName){
		if(this.items === null) return;
		
		tagName = tagName.toLowerCase();
		
		var tmp = [];
		for(var i = 0; i < this.items.length; ++i){
			if(this.items[i].getVar('tagName').toLowerCase() !== tagName) continue;
			tmp.push(this.items[i]);
		}
		this.items = tmp;
		
		return this;
	},
	
	filterByClass: function(className, multiclass){
		if(this.items === null) return;
		var tmp = [];
		if(!multiclass){
			for(var i = 0; i < this.items.length; ++i){
				if(this.items[i].getVar('className') !== tagName) continue;
				tmp.push(this.items[i]);
			}
		}
		else{
			var curClassName = null;
			var classes      = null;
			var found        = null;
			for(var i = 0; i < this.items.length; ++i){
				curClassName = this.items[i].getVar('className');
				if(curClassName.match(' ')){
					classes = curClassName.split(' ');
					found = false;
					for(var x = 0; x < classes.length; ++x){
						if(classes[x] !== className) continue;
						found = true;
						break;
					}
					if(!found) continue;
				}
				else if(curClassName !== tagName) continue;
				
				tmp.push(this.items[i]);
			}
		}
		this.items = tmp;
		
		return this;
	}
}

function Xi(obj, method, func, interval, parameters){
	this.obj        = obj;
	this.method     = method;
	this.func       = func;
	this.parameters = (parameters ? parameters : []);
	this.interval   = interval;
	
	return this;
}

Xi.prototype = {
	start: function(){
		var selfObj = this;
		
		var vfunc = function(){ selfObj.proceed(); }
		
		if(this.method == 'interval') { this.timerID = setInterval(vfunc, this.interval); }
		else                          { this.timerID = setTimeout(vfunc, this.interval); }
		
		return this;
	},
	
	abort: function(){
		clearTimeout(this.timerID);
		this.timerID = null;
		
		return this;
	},
	
	reset: function(){
		this.abort();
		this.start();
		
		return this;
	},
	
	proceed: function(){
		this.func.apply(this.obj, this.parameters);
		
		return this;
	}
}

function Xt(startValue, endValue, duration, mode, func, timeStep){
	this.startValue = startValue;
	this.endValue   = endValue;
	this.duration   = duration;
	this.mode       = mode;
	this.func       = func;
	this.timeStep   = (timeStep ? timeStep : 100);
	
	this.path       = null;
	this.pos        = null;
	this.Xi         = null;
	
	this.prepare();
	
	return this;
}

Xt.prototype = {
	//TODO: in futuro mettere dei listener
	prepare: function(){
		switch(this.mode){
			//TODO: mettere altre modalità: logaritmica, doppia logaritmica ecc.
			default:
			case 'linear':
			var steps = Math.floor(this.duration / this.timeStep);
			var step  = Math.floor((this.endValue - this.startValue) / steps);
			
			this.path = [];
			for(var i = 1; i < steps; ++i) { this.path.push(this.startValue + step * i); }
			this.path.push(this.endValue);
			break;
		}
		
		return this;
	},
	
	start: function(){
		this.pos = 0;
		this.Xi = new Xi(this, 'interval', this.doTransition, this.timeStep);
		this.Xi.start();
		
		return this;
	},
	
	doTransition: function(){
		this.func(this.path[this.pos++]);
		if(this.pos == this.path.length) { this.Xi.abort(); }
	}
}


function applyFormErrorHighlighter(item){
	item = new Xu(item);
	if(item.isNull()) return;
	
	var labels = item.getByTag('label');
	if(labels.length === 0) return;
	
	var tmp = new Array();
	for(var i = 0; i < labels.length; ++i) tmp.push(new Xu(labels[i]));
	labels = tmp;
	
	var links    = null;
	var link     = null;
	var labelFor = null;
	var label    = null;
	var done     = false;
	
	links = new Xu('Errori').getByTag('a');
	if(links.length > 0){
		for(i = 0; i < links.length; ++i){
			link = new Xu(links[i]);
			if(link.getVar('className') === 'inlink') continue;
			
			labelFor = link.getVar('href').split('#')[1];
			
			done = false;
			for(var x = 0; x < labels.length; ++x) {
				label = labels[x];
				if(label.getVar('htmlFor') != labelFor) continue;
				
				label.setVar('className',
					label.getVar('className') ? label.getVar('className') + ' errore' : 'errore'
				);
				done = true;
				break;
			}
			
			if(!done){
				label = new Xu(labelFor);
				if(!label.isNull()){
					label.setVar('className',
						label.getVar('className') ? label.getVar('className') + ' errore' : 'errore'
					);
				}
			}
		}
	}
}

function applyBlankTargetLinks(){
	var links = new Xu().getByTag('a');
	if(!links) return;
	
	links = new Xf(links).filterByVar('rel', 'external').getXu();
	
	for(var i = 0; i < links.length; ++i) links[i].setVar('target', '_blank');
}

function ScreenManager(){
}

ScreenManager.prototype = {
	getSize: function(){
		var width  = 0;
		var height = 0;
		
		if(window.innerWidth){
			width = window.innerWidth;
			height = window.innerHeight;
		}
		else if(document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)){
			width  = document.documentElement.clientWidth;
			height = document.documentElement.clientHeight;
		}
		else if(document.body && (document.body.clientWidth || document.body.clientHeight)){
			width  = document.body.clientWidth;
			height = document.body.clientHeight;
		}
		
		return {
			width:  width,
			height: height
		}
	},
	
	getScroll: function(){
		var scrollX = 0;
		var scrollY = 0;
		
		if(window.pageYOffset){
			scrollX = window.pageXOffset;
			scrollY = window.pageYOffset;
		}
		else if(document.body && (document.body.scrollLeft || document.body.scrollTop)){
			scrollX = document.body.scrollLeft;
			scrollY = document.body.scrollTop;
		}
		else if(document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)){
			scrollX = document.documentElement.scrollLeft;
			scrollY = document.documentElement.scrollTop;
		}
		
		return {
			scrollX: scrollX,
			scrollY: scrollY
		}
	}
}

function ImagePopupManager(link, closeText, loadingText, displayText){
	link = new Xu(link);
	if(link.isNull()) return;
	
	this.link        = link;
	this.closeText   = (closeText ? closeText : 'Chiudi');
	this.loadingText = (loadingText ? loadingText : 'Loading...');
	this.displayText = (displayText ? displayText : null);
	this.imagePath   = null;
	this.description = null;
	this.image       = null;
	this.loaded      = false;
	this.display     = null;
	
	this.updateLink();
}

ImagePopupManager.prototype = {
	updateLink: function(){
		this.imagePath   = this.link.getVar('href');
		this.description = this.link.getVar('title');
		
		var func = function(e, source, type){
			new Xu(source).getData('main').loadImage();
			
			return false;
		}
		
		this.link.
		setData('main', this).
		addEvent('onclick', func);
	},
	
	loadImage: function(){
		if(!new Xu('ImagePopupManagerDiv').isNull()) new Xu('ImagePopupManagerDiv').removeSelf();
		if(this.image == null){
			this.displayLoading();
			
			var selfObj = this;
			
			var func = function(){
				selfObj.imageLoaded();
			}
			
			this.image = new Image();
			this.image.onload = func;
			this.image.src = this.imagePath;
		}
		else if(this.loaded) this.displayImage();
	},
	
	imageLoaded: function(){
		this.loaded = true;
		this.displayImage();
	},
	
	displayLoading: function(){
		this.removeDisplay();
		
		this.display =
		new Xu('div', true).
		setVar('id', 'ImagePopupManagerDiv').
		setStyle('position', 'absolute').
		append(
			new Xu('h1', true).
			append( new Xu('text', true, this.loadingText) ).
			get()
		).
		appendTo( new Xu().getByTag('body', 0) );
		
		this.centerDisplay();
	},
	
	displayImage: function(){
		this.removeDisplay();
		
		var image =
		new Xu('img', true).
		setVar('src', this.imagePath);
		
		var func = function(e, source, type){
			new Xu(source).getData('main').removeDisplay();
		}
		
		var closeLink =
		new Xu('a', true).
		setVar('href', 'javascript:;').
		setData('main', this).
		addEvent('onclick', func).
		append( new Xu('text', true, this.closeText) );
		
		this.display =
		new Xu('div', true).
		setVar('id', 'ImagePopupManagerDiv').
		setStyle('position', 'absolute').
		append( closeLink ).
		append(image).
		appendTo( new Xu().getByTag('body', 0) );
		
		if(this.description){
			this.display.
			append(
				new Xu('h1', true).
				append( new Xu('text', true, this.description) ).
				get()
			);
		}
		
		this.centerDisplay();
		if(location.href.indexOf('#') != -1){
			var newHref = location.href.split('#');
			newHref = newHref[0] + '#ImagePopupManagerDiv';
		}
		else var newHref = location.href + '#ImagePopupManagerDiv';
		location.href = newHref;
	},
	
	centerDisplay: function(){
		if(this.display == null) return;
		
		var SM        = new ScreenManager();
		var size      = SM.getSize();
		var scroll    = SM.getScroll();
		
		var divWidth  = parseInt(this.display.getStyle('width'));
		var divHeight = parseInt(this.display.getStyle('height'));
		
		
		if(!divWidth)  divWidth  = (this.image ? this.image.width : 0);
		if(!divHeight) divHeight = (this.image ? this.image.height + 20 : 0);
		
		if(divWidth) this.display.setStyle('width', (divWidth + 10) + 'px');
		
		var posX = Math.round((size.width + scroll.scrollX) / 2 - (divWidth / 2));
		if(posX < 0) posX = 0;
		var posY = Math.round((size.height + scroll.scrollY) / 2 - (divHeight / 2));
		if(posY < 0) posY = 0;
		
		this.display.
		setStyle('left', posX + 'px').
		setStyle('top',  posY + 'px');
	},
	
	removeDisplay: function(){
		if(this.display == null) return;
		
		new Xu( this.display.parentItem() ).removeItem(this.display.get());
		this.display = null;
	}
}

function applyPictureZoomByClass(className){
	var links = new Xu().getByClass('a', className);
	if(!links) return;
	
	for(var i = 0; i < links.length; ++i) new ImagePopupManager(new Xu(links[i]));
}

function pageEnancher(page, param1){
	applyBlankTargetLinks();
	
	switch(page){
		case 'contatti':
		applyFormErrorHighlighter('modulo');
		break;
		
		case 'foto_gallery':
		applyPictureZoomByClass('zoom');
		break;
		
		case 'eventi_speciali':
		applyPictureZoomByClass('zoom');
		break;
	}
}
