/* ===== VESSEL/TYPIC.JS ===== */

function $(elem_id)
{
	return document.getElementById(elem_id);
}

if (!window.console) // Define dummy for IE
{
	var console = new Object();
	console.debug = function() {}
	console.error = function() {}
	console.log = function() {}
}

String.prototype.trim = String.prototype.trim || function() {
    return this.replace(/^\s+/,'').replace(/\s+$/,'');
}

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

Array.prototype.push = Array.prototype.push || function() {
    for (var i = 0; i < arguments.length; i++) {
        this[this.length] = arguments[i];
    }
    return this.length;
}


Array.prototype.splice = Array.prototype.splice || function(start, deleteCount) {
    var beg = this.slice(0, start);
    var del = this.slice(start, start + deleteCount);
    var end = this.slice(start + deleteCount);

    var ins = [];
    for (var i = 2; i < arguments.length; i++) {
    	ins[i-2] = arguments[i];
    }
    
    this.length = 0;
    var tmp = this.concat(beg, ins, end);
    for (var i = 0; i < tmp.length; i++) {
    	this[i] = tmp[i];
    }

    return del;
}

// typic.get_element - protypic - actyvic


/* .... TYPIC OBJECT ... */

var Typic = new Object();

function typic_get_elem(elem)
// Deprecated
{
	return Typic._elem(elem);
}

function typic_add_item(elem, vars)
// Takes the item prototype (elem) and makes a copy with the provided parameters (vars)
{
	return Typic.insert(elem, vars);
}
	
function typic_clone_item(elem1, elem2, vars)
// Like add_item, but inserts the new item into a different list
{
	var elem1 = typic_get_elem(elem1);
	var elem2 = typic_get_elem(elem2);
	if (typeof(vars) == "array")
	{
		var vars = cynic_compose_query_string(vars);
	}
	var new_elem = elem1.cloneNode(true);
	new_elem.style.display = "";
	new_elem = elem2.parentNode.appendChild(new_elem);
	
	prototype_id = elem2.getAttribute("id");
	var new_elem_id = prototype_id + ":" + typic_extract_var("id", vars);
	new_elem.setAttribute("id", new_elem_id);
	new_elem.setAttribute("typic_vars", vars);
	typic_set_elem(new_elem, vars);
	return new_elem;
}

Typic._elem = function(elem)
// Takes an element id or element and returns the element
{
	if (typeof(elem) == "string")
	{
		var x = $(elem);
		if (x)
			return x;
		else
			return null;
	}
	else if (typeof(elem) == "object")
		return elem;
	else
		return null;
}

Typic.insert = function(elem, vars)
// Insert a new element with the given parameters (vars)
{
	var elem = typic_get_elem(elem);
	if (typeof(vars) == "array")
	{
		var vars = cynic_compose_query_string(vars);
	}
	var new_elem = elem.cloneNode(true);
	new_elem.style.display = "";
	new_elem = elem.parentNode.appendChild(new_elem);
	
	prototype_id = elem.getAttribute("id");
	var new_elem_id = prototype_id + ":" + typic_extract_var("id", vars);
	new_elem.setAttribute("id", new_elem_id);
	new_elem.setAttribute("typic_vars", vars);
	typic_set_elem(new_elem, vars);
	Typic.removeClass(new_elem, "typic_proto");
	return new_elem;
}

Typic.copy = function(source_elem, proto_elem)
// Copies the data of a list element and inserts it into another list
{
	typic_add_item(proto_elem, typic_get_item_vars(source_elem));
}

Typic.move = function(source_elem, proto_elem)
{
	Typic.copy(source_elem, proto_elem);
	Typic.remove(source_elem);	
}

Typic.remove = function(elem)
{
	if (elem = Typic._elem(elem))
		elem.parentNode.removeChild(elem);
}

function typic_set_elem(elem, vars)
{
	var elem = typic_get_elem(elem);
	if (!elem)
		return;
	
	if (elem.nodeType == "1") // Normal element (HTML tag)
	{
		for (var i = 0; i < elem.attributes.length; i++)
		{
			var value = elem.attributes[i].value;
			var name = elem.attributes[i].name;
			if (name.match(/typic_.+/i))
			{
				name = name.replace(/typic_(.+)/i, "$1");
				new_value = typic_replace_vars(value, vars);
				elem.setAttribute(name, new_value);
				if (name.match(/on.+/i)) // IE bug - events wont be set by setting attributes
					elem[name] = new Function(new_value);
				if (name.match("class")) // IE bug - class wont be set by setting attributes
					elem.className = new_value;
			}
		}
		for (var i = 0; i < elem.childNodes.length; i++)
		{
			typic_set_elem(elem.childNodes[i], vars);
		}
	}
	else if (elem.nodeType == "3") // Text element (not HTML tag)
	{
		var text = typic_replace_vars(elem.nodeValue, vars);
		elem.nodeValue = text;
	}	
}

function typic_replace_vars(txt, vars)
{
	var vars = vars.split("&");
	for (var i = 0; i < vars.length; i++)
	{
		var z = vars[i].split("=");
		var name = z[0];
		var value = unescape(z[1]);
		var match = "{" + name + "}";
		txt = txt.replace(match, value);
		match = "^" + name + "^";
		txt = txt.replace(match, value);
	}
	return txt;
}

function typic_set_var(name, value, vars)
	{
	vars = vars.split("&");
	for (var i=0; i<vars.length; i++)
		{
		var z = vars[i].split("=");
		if (name == z[0])
			z[1] = value;
		vars[i] = z.join("=");
		}
	vars = vars.join("&");
	return vars;
	}

function typic_remove_item(elem)
{
	elem = typic_get_elem(elem);
	elem.parentNode.removeChild(elem);
}

function typic_get_item_vars(elem)
	{
	elem = typic_get_elem(elem);
	if (!elem)
		return "";
	vars = elem.getAttribute("typic_vars");
	return vars;
	}
	
function typic_extract_var(name, vars)
	{
	vars = vars.split("&");
	for (var i=0; i<vars.length; i++)
		{
		var z = vars[i].split("=");
		if (z[0] == name)
			return z[1];
		}
	}

function typic_get_parameters(elem)
{
	var vars = typic_get_item_vars(elem);
	return cynic_parse_query_string(vars);
}

function typic_swap_items(elem1,elem2)
	{
	elem1 = typic_get_elem(elem1);
	elem2 = typic_get_elem(elem2);
	elem1.parentNode.insertBefore(elem2, elem1);
	}

function typic_flash_item(item_id, c)
	{
	return;
	elem = typic_get_elem(item_id);
	vars = "color="+color[c];
	typic_set_elem(elem, vars);
	c++;
	if (c < color.length)
		setTimeout('typic_flash_item("'+item_id+'",'+c+')', 25);
	else
		{
		vars = typic_get_item_vars(elem);
		typic_set_elem(elem, vars);
		}
	}
	
//var color = new Array("#505050","#a0a020","#ffff00","#c0a000","#a05000");
var color = new Array("#a0a020", "#ffff00");

var last_push_time = new Date();

function typic_push_item(prototype_id, vars)
	{
	// The time procedures are for when more items are pushed at the same time.
	// Then they will be scheduled for pushing with an interval.
	push_time = new Date();	
	time_dif = push_time.getTime() - last_push_time.getTime();
	last_push_time.setTime(push_time.getTime());
	time_dif_min = 25;
	time_wait = time_dif_min - time_dif;
	if (time_wait < 0) time_wait = 0;
	last_push_time.setTime(push_time.getTime() + time_wait);
	setTimeout("typic_push_item_now('"+prototype_id+"', '"+vars+"')", time_wait);
	}
	
function typic_push_item_now(prototype_id, vars)
	{
	elem_id = typic_extract_var('id', vars);
	item_id = prototype_id + "_" + elem_id;
	if (elem = document.getElementById(item_id))
		{
		vars_old = typic_get_item_vars(elem);
		count_old = typic_extract_var("count", vars_old);
		count = parseInt(count_old) + parseInt(typic_extract_var("count", vars));
		vars = typic_set_var("count",count, vars);
		typic_set_item(elem, vars);
		}
	else
		{
		typic_add_item(prototype_id, vars);
		}
	typic_flash_item(prototype_id + "_" + elem_id, 0);
	setTimeout("typic_sort_item_list('"+prototype_id+"', 'count')", 200);
	}

function typic_sort_item_list(elem_id, order_by)
	{
	elem = typic_get_elem(elem_id);
	item_list = elem.parentNode.childNodes;
	for (i = 0; i < item_list.length - 1; i++)
		{
		elem1 = item_list[i];
		elem2 = item_list[i+1];
		if (elem1.nodeType == "1")
			{
			vars1 = typic_get_item_vars(elem1);
			if (vars1)
					{
				vars2 = typic_get_item_vars(elem2);
				count1 = typic_extract_var(order_by, vars1);
				count2 = typic_extract_var(order_by, vars2);
				if (parseInt(count2) > parseInt(count1))
					{
					typic_swap_items(elem1, elem2);
					id = elem2.getAttribute("id");
					typic_flash_item(id, 0);
					setTimeout("typic_sort_item_list('"+elem_id+"', '"+order_by+"')", 200);
					return;
					}
				}
			}
		}
	}
	
function typic_flush_list(elem, n) // Truncates list (optional: to n elements)
{
	if (!n) n = 0;
	var elem = typic_get_elem(elem);
	var elem_id = elem.getAttribute("id");
	var item_list = elem.parentNode.childNodes;
	for (i = 0; i < item_list.length; i++)
	{
		elem = item_list[i];
		if (elem.nodeType == "1")
		{
			id = elem.getAttribute("id");
			if ((id) && (id.match(elem_id + ".+")))
			{
				if (n == 0)
				{					
					typic_remove_item(elem);
					i--;
				}
				else
					n--;
			}
		}
	}
}

function typic_expand_collapse(elem, img)
	{
	elem = typic_get_elem(elem);
	//elem = elem.parentNode;
	if (elem.getAttribute("typic_display") == "collapsed")
		{
		typic_expand(elem, img);
		}
	else
		{
		typic_collapse(elem, img);
		}
	}

function show_html(elem)
{
	alert(elem.parentElement.innerHTML);
}

var typic_flowbox = new Array();

function typic_flowbox_add_item(flowbox, elem, vars)
{
	// works with an element like this: <div typic_max_height="300" style="_height: 0px">
	elem = typic_get_elem(elem);
	new_elem = typic_add_item(elem, vars);

	if (typic_flowbox_overflowed(flowbox))
	{
		typic_remove_item(new_elem);
		return 0;
	}
	else
		return 1;
}

function typic_flowbox_overflowed(flowbox)
{
	flowbox = typic_get_elem(flowbox);
	if ((document.all) && (!flowbox.style.height))
		flowbox.style.height = 0;
	if (flowbox.clientHeight > flowbox.getAttribute("typic_max_height"))
		return 1
	else
		return 0
}

function typic_expand(elem)
{
	y = $(elem + ":collapsed");
	x = $(elem + ":expanded");
	if (!x)
		x = $(elem);
	
	x.style.visibility = "hidden";
	x.style.position = "absolute";
	x.style.display = "";
	max = x.clientHeight;
	
	x.style.overflow = "hidden";
	x.style.height = "20px";
	x.style.position = "relative";
	x.style.visibility = "visible";
	
	if (y)
		y.style.display = "none";
	
	typic_smooth_expand(elem, 20, max);
}

function typic_collapse(elem)
{
	x = document.getElementById(elem + ":expanded");
	x.style.display = "none";
	x = document.getElementById(elem + ":collapsed");
	x.style.display = "";
}

function typic_smooth_expand(elem, h, max)
{
	h = parseInt(h);
	max = parseInt(max);
	var x = $(elem + ":expanded");
	if (!x)
		x = $(elem);
	x.style.height = h + "px";
	x.style.opacity = h / max;
	x.style.filter = "alpha(opacity=" + (h / max) * 100 + ")";
	if (h == max)
		return;
	h = h + 1 + (max - h) / 10;
	if (h > max)
		h = max;
	setTimeout("typic_smooth_expand('" + elem + "', " + h + ", " + max + ")", 20);
}

Typic.smooth_expand = function(elem)
{
	elem = Typic._elem(elem);
	var h = elem.h ? elem.h : 20;
	var max = elem.max ? elem.max : elem.clientHeight; //parseInt(Typic.get_style(elem, "height").replace(/[^\d]/, ""));
	
	elem.style.height = h + "px";
	elem.style.opacity = h / max;
	elem.style.filter = "alpha(opacity=" + (h / max) * 100 + ")";
	
	if (h == max)
	{
		elem.h = null;
		return;
	}
	h = h + 1 + (max - h) / 5;
	if (h > max)
		h = max;
	elem.h = h;
	elem.max = max;
	setTimeout("Typic.smooth_expand('" + Typic.get_id(elem) + "')", 40);
}

function typic_alertbox(cla, message, callback, url)
{
	if (!url)
		url = "http://www.campitello-matese.it/images/body_background.gif";
	typic_flush_list("typic:alertbox");
	typic_add_item("typic:alertbox", "id=1&message=" + message + "&class=" + cla + "&callback=" + callback + "&url=" + url);
	if ((cla == "ok") || (cla == "error"))
	{
		setTimeout("typic_flush_list('typic:alertbox')", 1000);
		if (callback)
			setTimeout(callback + "()", 1100);
	}
}


Typic.confirm = function(message, callback)
{
	if (typeof(callback) == "function")
	{
		Typic.callback = callback;
		callback = "Typic.callback";
	}
	typic_alertbox("confirm", message, callback);
}

Typic.wait = function(message)
{
	typic_alertbox("wait", message);
}

Typic.ok = function(message)
{
	typic_alertbox("ok", message);
}

// ............... TYPIC_CLUE .................. //

function typic_clue_init(init_elem)
{
	var li = Typic.getElementsByClass("typic_clue_field");
	for (var i = 0; i < li.length; i++)
	{
		var elem = li[i];
		elem.onkeydown = function(event)
		{
			return typic_clue_keydown(event, this.name);
		}
		elem.onfocus = function()
		{
			return typic_clue_show_list(this.name);
		}
		elem.onclick = elem.onfocus;
		elem.onblur = function()
		{
			return typic_clue_hide_list(this.name);
		}
	}
	
	var li = Typic.getElementsByClass("typic_clue");
	for (var i = 0; i < li.length; i++)
	{
		var elem = li[i];
		elem.onmouseover = function()
		{
			return typic_clue_mouse_over(this);
		}
		elem.onmousedown = function()
		{
			return typic_clue_select(this.getAttribute("name"));
		}
	}
	
	var li = Typic.getElementsByClass("typic_clue_list");
	for (var i = 0; i < li.length; i++)
	{
		li[i].style.display = "none";
		li[i].style.position = "absolute";
	}
	
	
	return typic_clue_show_list(init_elem.name);
}

function typic_clue_show_list(name)
{
	var elem = typic_clue_get_list_elem(name);
	elem.style.display = "block";
	
	if (!typic_clue_get_selected(name))
	{
		typic_clue_focus(typic_clue_get_clue_elems(name)[0]);
	}
}

function typic_clue_hide_list(name, now)
{
	var elem = typic_clue_get_list_elem(name);
	if ((!now) && (elem.style.display == "block"))
	{
		setTimeout("typic_clue_hide_list('"+name+"', true)", 100);
		return;
	}
	var elem = typic_clue_get_list_elem(name);
	elem.style.display = "none";
}

function typic_clue_focus(elem)
{
	elem.className = elem.className.replace("typic_clue", "typic_clue_focus");
}

function typic_clue_unfocus(elem)
{
	elem.className = elem.className.replace("typic_clue_focus", "typic_clue");
}

function typic_clue_get_list_elem(name)
{
	var li = Typic.getElementsByClass("typic_clue_list");
	for (var i = 0; i < li.length; i++)
	{
		if (li[i].getAttribute("name") == name)
			return li[i];
	}
}

function typic_clue_get_field_elem(name)
{
	var li = Typic.getElementsByClass("typic_clue_field");
	for (var i = 0; i < li.length; i++)
	{
		if (li[i].getAttribute("name") == name)
			return li[i];
	}
}

function typic_clue_get_clue_elems(name)
{
	var a = new Array();
	var li = document.getElementsByTagName("*");
	for (var i = 0; i < li.length; i++)
	{
		if (li[i].getAttribute("name") == name)
			if (li[i].className.match(new RegExp("(^|\\s)typic_clue(_focus)?(\\s|$)")))
				a.push(li[i]);;
	}
	return a;
}

function typic_clue_get_selected(name)
{
	var li = Typic.getElementsByClass("typic_clue_focus");
	for (var i = 0; i < li.length; i++)
	{
		if (li[i].getAttribute("name") == name)
			return li[i];
	}
}

function typic_clue_mouse_over(elem)
{
	var name = elem.getAttribute("name");
	var selected = typic_clue_get_selected(name);
	if (selected)
		typic_clue_unfocus(selected);
	typic_clue_focus(elem);
}

function typic_clue_select(name)
{
	var selected = typic_clue_get_selected(name);
	var value = selected.innerHTML.trim();
	var fieldelem = typic_clue_get_field_elem(name);
	fieldelem.value = value;
	fieldelem.focus();
	return false;
}

function typic_clue_keydown(event, name)
{
	if (event.which == "40")
	{	
		var li = typic_clue_get_clue_elems(name);
		for (var i = 0; i < li.length; i++)
		{
			if (li[i].className.match(new RegExp("(^|\\s)typic_clue_focus(\\s|$)")))
			{
				if (i + 1 < li.length)
				{
					typic_clue_unfocus(li[i]);
					typic_clue_focus(li[i+1]);
					i = li.length;
				}
			}
		}		
		return false;
	}
	if (event.which == "38")
	{
		var li = typic_clue_get_clue_elems(name);
		for (var i = 0; i < li.length; i++)
		{
			if (li[i].className.match(new RegExp("(^|\\s)typic_clue_focus(\\s|$)")))
			{
				if (i > 0)
				{
					typic_clue_unfocus(li[i]);
					typic_clue_focus(li[i-1]);
					i = li.length;
				}
			}
		}		
		return false;
	}
	if (event.which == "13")
	{
		typic_clue_select(name);
		return false;
	}
	
}

Typic.elementExistsInStringList = function(element, stringList, separator)
{
	// separator might need regexp escaping first...
	return stringList.match(new RegExp("(^|"+separator+")" + element + "("+separator+"|$)", "i"));
}

Typic.mouseover_init = function(elem_id)
{
	if (typeof(elem_id) == "object")
	{
		Typic.mouseover_init_element(elem_id);
		return;
	}
	var li = Typic.getElementsByClass("typic_mouseover", elem_id);
	for (var i = 0; i < li.length; i++)
	{
		var elem = li[i];
		elem.onmouseover = function()
		{
			if (this.mouseout_delay_timer)
				clearTimeout(this.mouseout_delay_timer);
			Typic.addClass(this, "mouseover");
		}
		elem.onmouseout = function()
		{
			elem_id = Typic.get_id(this);
			this.mouseout_delay_timer = setTimeout("Typic.removeClass(document.getElementById('" + elem_id + "'), 'mouseover'", 1000);
		}
		Typic.removeClass(elem, "typic_mouseover");
	}
	
	var li = Typic.getElementsByClass("typic_click");
	for (var i = 0; i < li.length; i++)
	{
		var elem = li[i];
		var att_old = elem.getAttribute("onclick");
		var att_new = "Typic.toggleClassName(this, 'click'); Typic.removeClass(this, 'mouseover')";
		if (att_old != "")
			att_new = att_old + "; " + att_new;
		elem.setAttribute("onclick", att_new);
		Typic.removeClass(elem, "typic_click");
	}
}

Typic.mouseover_init_element = function(elem)
{
	if (elem.mouseout_delay_timer) // If mouseover shortly after mouseout... cancel the pending mouseout event and do nothing
		clearTimeout(elem.mouseout_delay_timer);
	else
	{
			
		if (!elem.onmouseout)
			elem.onmouseout = function()
			{
				elem_id = Typic.get_id(this);
				this.mouseout_delay_timer = setTimeout("Typic.removeClass(document.getElementById('" + elem_id + "'), 'mouseover'); document.getElementById('" + elem_id + "').mouseout_delay_timer = null", 20);
			}
		
		Typic.addClass(elem, "mouseover");
		
		// The following only applies to top level navigation elements
		if (Typic.hasClass(elem, "level1") && Typic.hasClass(elem, "smooth-expand-submenu"))
		{
			var sub = elem.getElementsByTagName("ul")[0];
			if (sub)
			{	
				Typic.smooth_expand(sub);
			}
		}
	}
}

// .................. TYPIC POPUP ................. //

Typic.popup_init = function(source_elem, target_elem)
// Associates a popup menu to an element and attaches event handlers to open and close it.
// Usage: <div id="elem_id" onclick="Typic.popup_init(this)">
// The popup element should have id="popup@elem_id", unless the target id is passed as second parameter
{
	source_elem = Typic._elem(source_elem);
	if (source_elem.typic_popup_target_elem) // Event already attached
	{
		Typic.popup_open(source_elem);
		return;
	}
	
	if (!target_elem)
		target_elem = "popup@" + Typic.get_id(source_elem);
	target_elem = Typic._elem(target_elem);

	// We need to create an element, that can recieve focus. This element should not be seen.
	var focus_elem = document.createElement("input");
	Typic.addClass(focus_elem, "blind");
	
	target_elem.appendChild(focus_elem);
	target_elem.typic_popup_focus_elem = focus_elem;
	focus_elem.onblur = function()
	{
		// Closing the popup menu needs to be delayed, or it might close before a click is received
		setTimeout("Typic.popup_close('" + Typic.get_id(this.parentNode) + "')", 100);
	}
	
	source_elem.typic_popup_target_elem = target_elem;
	Typic.popup_open(source_elem);
}

Typic.popup_open = function(elem)
{
	elem = Typic._elem(elem);
	var target_elem = elem.typic_popup_target_elem;
	Typic.removeClass(target_elem, "blind");
	target_elem.typic_popup_focus_elem.focus();
}

Typic.popup_close = function(elem)
{
	elem = Typic._elem(elem);
	if (elem)
		Typic.addClass(elem, "blind");
}

/* ------------------ */

Typic.get_id = function(elem)
// This function will return the elements unique id attribute
// If it doesn't have one already set, it will apply a unique one
// (The purpose is to be able to reference the element later)
{
	if (elem.id)
		return elem.id;
	var i = 1;
	while ($("typic" + i))
		i++;
	elem.id = "typic" + i;
	return elem.id;
}

Typic.onkeyup_delay = function(elem)
// This will execute the elements onchange event handler 
// half a second after the keyupevent, if no more keys are pressed
// assign to element's onkeyup event [onkeyup="Typic.onkeyup_delay(this)"]
{
	var id = Typic.get_id(elem);
	elem.value2 = elem.value;
	if (elem.timer)
		clearTimeout(elem.timer);
	elem.timer = setTimeout("$('"+id+"').onchange()", 500);
}

Typic.outline = function(elem)
{
	//var oe = document.createElement("div");
	
	elem.style.zoom = "1";
	oe = elem.cloneNode(false);
	
	oe = elem.offsetParent.appendChild(oe);
	
	oe.onmouseover = null;
	oe.style.position = "absolute";
	oe.style.top = parseInt(elem.offsetTop + 1) + "px";
	oe.style.left = parseInt(elem.offsetLeft + 1) + "px";
	oe.style.width = parseInt(elem.offsetWidth - 2) + "px";
	oe.style.height = parseInt(elem.offsetHeight - 2 ) + "px";
	oe.style.border = "1px dashed yellow";
	elem.style.zoom = "normal";
}

Typic.get_style = function (oElm, strCssRule)
{
	var strValue = "";
	if(document.defaultView && document.defaultView.getComputedStyle){
		strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
	}
	else if(oElm.currentStyle){
		strCssRule = strCssRule.replace(/-(w)/g, function (strMatch, p1){
			return p1.toUpperCase();
		});
		strValue = oElm.currentStyle[strCssRule];
	}
	return strValue;
}

Typic.get_absolute_offset = function (obj)
{
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		curleft = obj.offsetLeft
		curtop = obj.offsetTop
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft
			curtop += obj.offsetTop
		}
	}
	return [curleft,curtop];
}

Typic.activate_hasLayout = function(elem)
// Activates hasLayout for all block elements
{
	if (!elem)
	{
		var elems = document.getElementsByTagName("*");
		for (var i = 0; i < elems.length; i++)
			Typic.activate_hasLayout(elems[i]);
	}
	else
	{
		if (Typic.get_style(elem, "display") == "block")
			elem.style.zoom = "1";
	}
}

// ----------- STRING LISTS ------------- //


String.prototype.has = function(element)
{
	var separator = this._separator();
	
	// separator might need regexp escaping first...
	return this.match(new RegExp("(^|"+separator+")" + element + "("+separator+"|$)", "i"));
}

String.prototype.add = function(element)
{
	var separator = this._separator();
	if (!this.has(element))
	{
		if (this.length == 0)
			return element
		else
			return this.valueOf() + separator + element;
	}
}

String.prototype.remove = function(element)
{
	var separator = this._separator();
	var value = this.replace(new RegExp("(^|" + separator + ")(" + element + ")(" + separator + "|$)", "gi"), "$1$3");
	value = value.replace(new RegExp(separator + "+", "gi"), separator);
	return value.replace(new RegExp("(^" + separator + "|" + separator + "$)", "gi"), "");
}

String.prototype.toggle = function(element)
{
	if (this.has(element))
		this.remove(element);
	else
		this.add(element);
}

String.prototype._separator = function()
{
	if (!this.separator)
		this.separator = ",";
	if (this.separator == " ")
		this.separator = "\\s";
	return this.separator;
}

// -------------- NEW CLASS HANDLER ------------ //

Typic.getElementsByClass = function(searchClass,node,tag)
{
	var classElements = new Array();
	if ( node == null )
		node = document;
	if ( tag == null )
		tag = '*';
	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
	for (i = 0, j = 0; i < elsLen; i++) {
		if ( pattern.test(els[i].className) ) {
			classElements[j] = els[i];
			j++;
		}
	}
	return classElements;
}

Typic.getClasses = function(element)
{
    return (element && element.className) ? element.className.trim().split(/\s+/) : [];
}

Typic.addClass = function(element, c)
{
    var classes = Typic.getClasses(element);
    if (classes.indexOf(c) == -1)
    {
        classes.push(c);
        element.className = classes.join(' ');
    }
}

Typic.removeClass = function(element, c)
{
    var classes = Typic.getClasses(element);
    var idx = classes.indexOf(c);
    if (idx != -1)
    {
        classes.splice(idx, 1);
        element.className = classes.join(' ');
    }
}

Typic.hasClass = function(element, c)
{
    return Typic.getClasses(element).indexOf(c) != -1;
}

Typic.toggleClass = function(elem, className)
{
	if (Typic.hasClass(elem, className))
		Typic.removeClass(elem, className);
	else
		Typic.addClass(elem, className);
}




	/* ===== CYNIC.JS ===== */

var Cynic = new Object();

Cynic.maxTime = 10000;
Cynic.script = new Array();
Cynic.par = new Array();
Cynic.call = function(url, callback, updateElements)
// Calls a socket specified by url
// Pass a callback funtion name to return data
// Callback function has to take 2 parameters: xx (the dataobject) and script_id - in case you are using it for something
// Returns the script_id which can be used to track the call
{
	var script_element = document.createElement('script');
	var script_id = this.script.push(script_element) - 1;
	
	if (this.par.callback)
		callback = this.par.callback;
	this.par.callback = null;
	if (!callback)
		callback = "";
	
	this.script[script_id].callback = callback;
	var qs = "cynic[id]=" + script_id;
	if (url.indexOf("?") > 0)
		url = url + "&" + qs;
	else
		url = url + "?" + qs;
	
	if (!updateElements)
		updateElements = "";
	if (this.par.update)
		updateElements += this.par.update;
	this.par.update = null;
	
	if (updateElements)
	{
		var e = cynic_parse_query_string(updateElements);
		for (var i in e)
		{	
			if (!e[i])
				e[i] = "/pages/index.php/" + i;
			url = url + "&cynic_update["+i+"]=" + e[i];
		}
	}
	this.script[script_id].src = url;
	
	document.getElementsByTagName('head')[0].appendChild(this.script[script_id]);
	setTimeout("Cynic.timeout(" + script_id + ")", this.maxTime);
	return script_id;
}

Cynic.callback = function(xx, script_id)
{
	if (this.script[script_id])
	{	
		document.getElementsByTagName('head')[0].removeChild(this.script[script_id]);
		if (xx && xx.html)
		{
			for (i in xx.html)
			{
				if (i.substr(i.length-1, 1) == ".")
				{	
					j = i.substring(0, i.length-1);
					if ($(j))
						$(j).innerHTML += xx.html[i];
					else
						console.error("No element with id = '" + j + "' found for cynic-update");
				}
				else
				{
					if ($(i))
						$(i).innerHTML = xx.html[i];
					else
						console.error("No element with id = '" + i + "' found for cynic-update");
				}
			}
		}
		var callback = this.script[script_id].callback;
		if (callback)
		{
			if (typeof(callback) == "string")
				eval(this.script[script_id].callback + "(xx, script_id)");
			else if (typeof(callback) == "function")
				callback(xx, script_id);
		}
		this.script[script_id] = null;
	}
}

Cynic.timeout = function(script_id)
{
	this.callback(false, script_id);
}

Cynic.parse_query_string = function(qs)
{
	if (!qs)
		qs = decodeURIComponent(document.location.hash.substr(1) + "&" + document.location.search.substr(1));
	var par = qs.split("&");
	var x = Array();
	var set;
	for (var i = 0; i < par.length; i++)
	{
		set = par[i].split("=");
		if (!set[1])
			set[1] = "";
		if (set[0].indexOf("[]") > -1)
		{
			set[0] = set[0].split("[]");
			set[0] = set[0][0];
			if (!x[set[0]])
				eval("x['" + set[0] + "'] = Array();");
			eval("x['" + set[0] + "'].push(unescape('" + escape(set[1]) + "'))");
		}
		else
		{
			eval("x['" + set[0] + "'] = unescape('" + escape(set[1]) + "');");
		}
	}
	
	return x;
}

Cynic.compose_query_string = function(x)
// Composes a one-dimensional query string of the (non-function) properties of object x
// ex: a=1&b=2&c=3
// Encodes values so that they are safe to send as a query string part of a url
{
	var qs = new Array();
	for (var key in x)
	{
		if ((key) && (typeof(x[key]) != "function"))
		{
			qs.push(key + "=" + encodeURIComponent(x[key]));
		}
	}
	
	return qs.join("&");
}

Cynic.form_to_query_string = function(form)
// Composes a query string of the form elements and their values
{
	var x = new Array();
	for (var i = 0; i < form.elements.length; i++)
	{
		x.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
	}
	return x.join("&");
}

Cynic.form_to_url = function(form)
{
	return form.action + "?" + Cynic.form_to_query_string(form);
}

Cynic.form_submit = function(form)
{
	Cynic.call(Cynic.form_to_url(form));
}

Cynic.bookmark_query_string = function(qs)
{
	location.href = location.pathname + location.search + "#" + qs;
}

Cynic.hyperlink_activate = function(elem, callback, update)
{
	Cynic.call(elem.href, callback, update);
}

/* --------------------- */


function cynic_call(url, callback)
// Deprecated
{
	return Cynic.call(url, callback);
} 



function cynic_parse_query_string(qs)
{
	return Cynic.parse_query_string(qs);
}

function cynic_compose_query_string(x)
{
	return Cynic.compose_query_string(x);
}

function cynic_compose_query_string_simple(x, key)
// Composes a querystring of the form "a=2&a=4&a=5"
{
	for (var i = 0; i < x.length; i++)
	{
		x[i] = key + "=" + encodeURIComponent(x[i]);
	}
	return x.join("&");
}

function cynic_bookmark_query_string(qs)
{
	Cynic.bookmark_query_string(qs);
}

var _cynic_watch_qs_interval_id;
function cynic_watch_query_string(callback)
// Call this function in the beginning of your script (on a page that uses ajax)
// to initiate a timer/interval that checks wheter the query string has changed
// If it has changed it will check if it is still changing (i.e. if you are typing in a keyword...)
// and then call the callback function once a new value seems permanent.
{
	// TODO: Rewrite this to use Timeout instead of Interval
	cynic_watch_query_string_reset();
	if (!_cynic_watch_qs_interval_id)
		_cynic_watch_qs_interval_id = setInterval("_cynic_watch_qs('"+callback+"')", 500);
}

var _cynic_qs = new Array();
_cynic_qs.current = "";
_cynic_qs.old = "";
function _cynic_watch_qs(callback)
{
	var changed = (_cynic_qs.old != _cynic_qs.current);
	_cynic_qs.old = _cynic_qs.current;
	_cynic_qs.current = document.location.hash.substr(1);
	if ((changed) && (_cynic_qs.current == _cynic_qs.old))
		eval(callback + "()");
}

function cynic_watch_query_string_reset()
{
	_cynic_qs.current = document.location.hash.substr(1);
	_cynic_qs.old = _cynic_qs.current;
}

function cynic_submit(form, callback, updateElements)
{
	var x = new Array();
	for (var i = 0; i < form.elements.length; i++)
	{
		x.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
	}
	x = x.join("&");
	Cynic.call(form.action + "?" + x, callback, updateElements);
}

function clear_error_messages(name, form)
{
	for (var i = 0; i < form.elements.length; i++)
	{
		var match = new RegExp(name + "\\[(.*?)\\]", "i");
		var e = document.getElementById("error_" + name + "_" + form.elements[i].name.replace(match, "$1"));
		if (e)
			typic_flush_list(e);
	}
}	
	
function display_error_messages(name, errors)
{
	for (var i in errors)
	{	
		if (typeof(errors[i]) == "string")
		{
			var elem_id = "error_" + name + "_" + i;
			if ($(elem_id))
			{
				var message = text[elem_id + "_" + errors[i]];
				if (!message)
					message = errors[i];
				typic_clone_item("error", elem_id, "id="+i+"&message="+message);
			}
		}
	}
}

	function phantom_change_language(language)
{
	Cynic.call("socket.phantom.php?language=" + language, "phantom_change_language_callback");
}

function phantom_change_language_callback(language)
{
	location.reload();
}

	/* vessel.js */

function text_edit(id, lan_code)
{
	if (document.isKeyPressed(17))
	{
		typic_alertbox("window", "", "", escape("http://www.campitello-matese.it/admin/text_edit.php?id=" + id + "&lan_code=" + lan_code));
		return false;
	}
	else
		return true;
}

document.onkeydown = function(event)
{
	var keynum;
	
	if (window.event && window.event.keyCode) // IE
		keynum = window.event.keyCode
	else if (event.which)
		keynum = event.which
	else
		return;
		
	if (!this.keyPressed)
		this.keyPressed = new Array();
	this.keyPressed[keynum] = true;
}

document.onkeyup = function(event)
{
	var keynum;
	
	if (window.event && window.event.keyCode) // IE
		keynum = window.event.keyCode
	else if (event.which)
		keynum = event.which
	else
		return;
		
	if (!this.keyPressed)
		this.keyPressed = new Array();
	this.keyPressed[keynum] = false;
}

document.isKeyPressed = function(keynum)
{
	if (this.keyPressed && this.keyPressed[keynum])
		return true;
	else
		return false;
}

	
	window.onload = function()
	{
		// jsimagereplacement
	ipath = 'http://www.campitello-matese.it/images/titles/';
	replaceTitles("h1", "jsimagereplacement");

	// Flash object activate
	objectSwap();

	}
/* ===== COMPONENT.NAVIGATION.JS ===== */

var navigation = new Object();

navigation.onmouseover = function(elem)
{
	navigation.mouseover(elem);
	var sub = elem.getElementsByTagName("ul")[0];
	if (sub && sub.style.display != "block")
	{
		sub.style.display = "block";
		console.log("opening");
		
		/*
		sub.style.visibility = "hidden";
		sub.style.display = "block";
		max = sub.clientHeight;
		
		sub.style.overflow = "hidden";
		sub.style.height = "20px";
		sub.style.visibility = "visible";
		
		typic_smooth_expand(Typic.get_id(sub), 20, max);*/
	}
	if (!elem.onmouseout)
		elem.onmouseout = function()
		{
			navigation.onmouseout(this);
		}
}

navigation.onmouseout = function(elem)
{
	navigation.mouseout(elem);
	var sub = elem.getElementsByTagName("ul")[0];
	if (sub)
	{
		setTimeout("navigation.hide($('" + Typic.get_id(sub) + "'))", 1000);
	}
	
}

navigation.hide = function(elem)
{
	if (!elem.is_mouseover)
	{
		console.log("hiding");
		elem.style.display = "none";
	}
}

navigation.show = function(elem)
{
	Typic.addClass(elem, 'jshover');
	var sub = elem.getElementsByTagName("ul")[0];
	if (sub)
	{	
		Typic.smooth_expand(sub);
	}
}
		
navigation.mouseover = function(elem)
{
	elem.is_mouseover = true;
}

navigation.mouseout = function(elem)
{
	elem.is_mouseover = false;
}

function MenuHoverManager(id, timeout)
{

	var ul2List = Typic.getElementsByClass('level1', document.getElementById(id), "li");
	var timeout = 100;
	var offCounter = 0;
	var resetCounter = 0;
	var that = this;

	function menuClearHovers() {
		for (var i=0; i<ul2List.length; ++i) {
			ul2 = ul2List[i];
			Typic.removeClass(ul2, 'jshover');
		}
	}

	this.init = function () {
		for (var i=0; i<ul2List.length; ++i) {
			ul2 = ul2List[i];
		
			ul2.onmouseover = function () {
				//menuClearHovers();
				Typic.addClass(this, 'jshover');
				//setTimeout("navigation.show($('"+Typic.get_id(this)+"'))", 20);
			};
		
			ul2.onmouseout = function ()	{
				++offCounter;
				this.timeoutid = setTimeout(function () {
								++resetCounter;
								if (offCounter==resetCounter)	{
									menuClearHovers();
								}
							}, timeout);
			};
		}
	}
}


