/****************************************************************************
**                                                                         **
**  slideshow.js                                                           **
**  ---------------------------------------------------------------------  **
**  rev. "1.5"                                                             **
**                                                                         **
**  REQUIRES: SWFObject.js                                                 **
**                                                                         **
**  Copyright(c) Kyknet SRL, 2008                                          **
**  http://www.kyknet.it                                                   **
**  Author: Simone Gabbiani                                                **
**                                                                         **
****************************************************************************/

var SLIDESHOW_DEBUG 	= true;
var SLIDESHOW_DEMO		= true;

var SL_FULL_SIZE			= 0;
var SL_SMALL_SIZE			= 1;

if (!window.top.sl_global) {
	window.top.sl_global = new Object()
	window.top.sl_global.list = new Array();
	window.top.sl_global.tabitems = new Array();
	window.top.sl_global.current = null;
}

var sl = (window.sl_local = new Object());
var slt = window.top.sl_global;

slt.lang = 'it';
sl.txt = new Object();
sl.txt.it = new Object();
sl.txt.en = new Object();
sl.colors = new Object();
sl.localConnId = 0;
sl.last_cmd = null;
sl.last_trace = null;
sl.debug_win = null;
sl.scroller = null;
sl.scrollInterval = 0;
sl.stages_scroll_mms = 25;
sl.stages_scroll_freq = 2;
sl.is_Microsoft = (document.all && navigator.userAgent.indexOf("MSIE") != -1);


sl.STAGES = "stage";
sl.TYPES = "type";
sl.TL_SUBTYPES = "subtype";

// ContentResourceFactory
sl.CT_CUSTOM = 0;
sl.CT_USER_PHOTO = 1;
sl.CT_USER_VIDEO = 3;
sl.CT_AUTHOR_PHOTO = 2;
sl.CT_AUTHOR_VIDEO = 4;
sl.CT_PLEASE_SELECT_STAGE_WELCOME = 101;
sl.CT_PLEASE_SELECT_STAGE_NEW = 102;
sl.CT_CRUISE_IS_EMPTY_VISITOR = 103;
sl.CT_NEW_TAB_CRUISE = 104;
sl.CT_STAGE_IS_EMPTY = 105;
sl.CT_WELCOME_NEW_TAB = 106;
sl.CT_NEW_TAB_KINDLY = 107;
sl.CT_SLIDE_IS_EMPTY = 108;
sl.CT_USER_VIDEO_INSERT = 9003;
sl.CT_USER_PHOTO_INSERT = 9001;
sl.CT_AUTHOR_PHOTO_INSERT = 9002;

// text resources
sl.txt.it.DEFAULT_FULL_DETAILS = "($NUMBER$ di $SIZE$)";
sl.txt.en.DEFAULT_FULL_DETAILS = "($NUMBER$ of $SIZE$)";

sl.txt.it.DEFAULT_SHORT_DETAILS = "($SIZE$)";
sl.txt.en.DEFAULT_SHORT_DETAILS = "($SIZE$)";

sl.txt.it.WELCOME = "Benvenuti";
sl.txt.en.WELCOME = "Welcome";

sl.txt.it.NEW = "NUOVO...";
sl.txt.en.NEW = "NEW...";

sl.txt.it.EMPTY_STAGE = "Tappa vuota";
sl.txt.en.EMPTY_STAGE = "Empty stage";

sl.txt.it.INSERT_AUTHOR_PHOTO = "Inserisci \"foto d'autore\""; 
sl.txt.en.INSERT_AUTHOR_PHOTO = "Insert \"author photo\"";

sl.txt.it.INSERT_USER_PHOTO = "Inserisci foto";
sl.txt.en.INSERT_USER_PHOTO = "Insert photo";

sl.txt.it.INSERT_USER_VIDEO = "Inserisci video";
sl.txt.en.INSERT_USER_VIDEO = "Insert movie";

sl.txt.it.WAIT = "attendere...";
sl.txt.en.WAIT = "please wait...";

sl.txt.it.PLEASE_SELECT_STAGE = "Per inserire video e fotografie devi prima selezionare una tappa";
sl.txt.en.PLEASE_SELECT_STAGE = "In order to insert movies and photos you must select a stage before";

sl.txt.it.CT_CRUISE_IS_EMPTY_VISITOR = "Siamo spiacenti, questa crociera non ha ancora alcun contenuto mutlimediale";
sl.txt.en.CT_CRUISE_IS_EMPTY_VISITOR = "We are sorry, this cruise does not have any multimedia content yet";

sl.txt.it.CT_NEW_TAB_SIMPLE = "Inserisci i tuoi video e le tue fotografie";
sl.txt.en.CT_NEW_TAB_SIMPLE = "Insert new videos and photos";

sl.txt.it.CT_NEW_TAB_CRUISE = "Inserisci video e fotografie per questa tappa";
sl.txt.en.CT_NEW_TAB_CRUISE = "Insert movie and photos for this stage";

sl.txt.it.CT_NEW_TAB_KINDLY = "Contribuisci a Uomo in Mare e condividi i tuoi video e le tue fotografie";
sl.txt.en.CT_NEW_TAB_KINDLY = "Join to Uomo in Mare and share your photos and videos";

sl.txt.it.CT_STAGE_IS_EMPTY = "Siamo spiacenti, questa tappa non ancora ha contenuti multimediali";
sl.txt.en.CT_STAGE_IS_EMPTY = "We are sorry, this stage does not have yet multimedia contents";

sl.txt.it.CT_WELCOME_NEW_TAB = "Non ci sono contenuti multimediali presenti. Inseriscili ora!";
sl.txt.en.CT_WELCOME_NEW_TAB = "There aren't multimedia video or images. Insert now!";

sl.txt.it.CT_SLIDE_IS_EMPTY = "Siamo spiacenti, non ci sono contenuti multimediali presenti";
sl.txt.en.CT_SLIDE_IS_EMPTY = "We are sorry, there aren't multimedia video or images";


sl.EXC_ITEM_INFO = 'I';
sl.EXC_ITEM_INDEX = 'T';
sl.EXC_DEFAULT_STAGE = 'c';
sl.EXC_DEFAULT_TYPE = 'p';
sl.EXC_TYPE_DATA = 't';
sl.EXC_TYPES_ORDER = 'o';
sl.EXC_END_OF_INITBLOCK = '!';
sl.EXC_END_OF_STAGEBLOCK = ';';
sl.EXC_VOTO = 'v';
sl.EXC_TRACE = 'y';
sl.EXC_WINDOW = 'w';
sl.EXC_FULL_LAYOUT = 'S';
sl.EXC_SMALL_LAYOUT = 's';
sl.EXC_CONFIRM_DATA = 'f';
sl.EXC_CROSS_INSERTION = '+';
sl.EXC_INS_FOTO_SUCCESS = 'F';

// default colors
sl.colors.user = new Object();
sl.colors.user.selectedBackgroundColor = "#DFE0B8";
sl.colors.user.selectedForegroundColor = "#000";

sl.colors.author = new Object();
sl.colors.author.selectedBackgroundColor = "#E1E7F3";
sl.colors.author.selectedForegroundColor = "#000";

sl.colors.generic = new Object();
sl.colors.generic.selectedBackgroundColor = "#999";
sl.colors.generic.selectedForegroundColor = "#000";

sl.msie6fix1 = ''; //(sl.is_Microsoft && parseInt(navigator.appVersion.charAt(navigator.appVersion.indexOf("MSIE") + 5)) < 7 ? 'margin-bottom:-6px;' : '');
sl.msie6fix2 = (sl.is_Microsoft && parseInt(navigator.appVersion.charAt(navigator.appVersion.indexOf("MSIE") + 5)) < 7 ? '3' : '');
sl.msiefix3 = 'margin-bottom:7px';

sl.findSlideshowById = function( id ) {
	for (var i in window.top.sl_global.list) {
		if (window.top.sl_global.list[i].core.ref.placeHolder.id == id)
			return window.top.sl_global.list[i];
	}
	return null;
}

sl.getColorSchemeByCType = function(ctype) {
	if (ctype == window.sl_local.CT_USER_PHOTO)
		return 'user';
	if (ctype == window.sl_local.CT_USER_VIDEO) 
		return 'user';
	if (ctype == window.sl_local.CT_AUTHOR_PHOTO)
		return 'author';
	if (ctype == window.sl_local.CT_AUTHOR_VIDEO)
		return 'author';
	if (ctype == window.sl_local.CT_USER_VIDEO_INSERT)
		return 'user';
	if (ctype == window.sl_local.CT_USER_PHOTO_INSERT)
		return 'user';
	if (ctype == window.sl_local.CT_AUTHOR_PHOTO_INSERT)
		return 'author';
	return 'generic';
}

sl.colorCode = function(color) {
	if (!color)
		return '';
	else
		return (color.charAt(0) == '#') ? color.substring(1) : color;
}

sl.inspect = function(elem, liv) {
	if (!liv)
		liv = "... ";
	var buff = '';
	for (var n in elem.childNodes) {
		try {
			if (elem.childNodes[n].nodeType == 1) { //ELEMENT_NODE
				buff += liv + elem.childNodes[n].tagName + "." + elem.childNodes[n].className+"\n" 
								+ this.inspect(elem.childNodes[n], liv + "... ");
			}
			else if (elem.childNodes[n].nodeType == 3) //TEXT NODE
				buff += liv + elem.childNodes[n].textContent+"\n";
		}
		catch (err) { // non un elemento
		}
	}
	return buff;
}

sl.border = function(elem, color) {
	elem.style.border="1px solid " + (color || "red");
}

sl.trace = function(msg, src) {
	if (SLIDESHOW_DEBUG && src == 1) {
		if (msg != this.last_trace) {
			try {
				if (this.debug_win == null) {
					if (top.trace_window == null)
						this.debug_win = window.open("about:blank", "debug_win", "width=500,height=800,scrollbars=yes");
					else
						this.debug_win = top.trace_window;
					this.debug_win.document.open();
				}
				this.debug_win.document.write(msg + "<br/>");
				this.debug_win.scroll(0, 1000000);
				this.last_trace = msg;
			}
			catch(e) {
			}
		}
	}
}

sl.array_remove = function(a, index) {
	for (var i=parseInt(index); i<a.length-1; i++)
		a[i] = a[i+1];
	a.pop();
}

sl.last_time = 0;
sl.reset = function() {
	this.last_time = (new Date().getTime());
}

sl.time = function( name ) {
	var new_time = (new Date().getTime());
	this.trace("<span style='color:green'>---- "+name+": " + (new_time - this.last_time) + " ----</span>" );
	this.last_time = new_time;
}

sl.onblur = function() {
	for (var i in window.top.sl_global.list)
		try { window.top.sl_global.list[i].sendBlurSignal(); } catch(e) {}
}

sl.onfocus = function() {
	for (var i in window.top.sl_global.list)
		try { window.top.sl_global.list[i].sendFocusSignal(); } catch(e) {}
}

sl.onunload = function() {
	for (var i in window.top.sl_global.list) {
		//try { window.top.sl_global.list[i].sendUnloadSignal(); } catch(e) {}
	}
}

sl.buildLocalProxyIfNotExists = function() {
	if (this.localConnId == 0) {
		this.localConnId = Math.round(Math.random()*0xFFFFFFFF);
		if (this.is_Microsoft) {
			//document.body.attachEvent( 'onblur', this.onblur );
			//document.body.attachEvent( 'onfocus', this.onfocus );
			
			//window.attachEvent( 'onunload', this.onunload );
		}
		else if (document.styleSheets) {
			//document.body.addEventListener('onblur', this.onblur, 1 );
			//document.body.addEventListener('onfocus', this.onfocus, 1 );
			
			//window.addEventListener('unload', this.onunload, 1 );
		}
		else {
			var e = document.body.getAttribute("onunload");
			//document.body.setAttribute( 'onblur', "this.onblur();" + e );
			//document.body.setAttribute( 'onfocus', "this.onfocus();" + e );
			
			//document.body.setAttribute( 'onunload', "this.onunload();" + e );
		}
	}
}

sl.insertCssRule = function( sheet, selector, styles ) {
	try {
		if (!this.is_Microsoft)
			sheet.insertRule( selector + "{" + styles + "}", sheet.cssRules.length - 1 );
		else
			sheet.addRule( selector, styles );
		// this.trace("CSS " + selector + " {" + styles + " }" );
	}
	catch (e) {
	}
}

sl.findMyStylesheet = function() {
	var tot=0, trovato=false, m=document.styleSheets.length-1;
  while(tot < document.styleSheets.length) {
   if (document.styleSheets[tot].title == "PlayerStyle")
    return document.styleSheets[tot];
   if (!document.styleSheets[tot].disabled && (document.styleSheets[tot].media == "all" || document.styleSheets[tot].media == "screen"))
   	m = tot;
   tot++;
  }
  return document.styleSheets[m];
}

sl.readCookie = function(name) { // quirksmode.org
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

sl.text = function() { //text("testo % %", a, b)
	if (arguments.length < 2) {
		throw new Error('this.text() wrong arguments count');
	}
	else {
		var buff = new String();
		var s = arguments[0].split("%");
		for (var i=0; i<s.length; i++) {
			if (i > 0)
				buff += arguments[i];
			buff += s[i];
		}
		return buff;
	}
}

sl.nobreak_text = function(s) {
	try {
		s = s.toString();
		while (s.indexOf(' ') != -1)
			s = s.replace(' ', '&nbsp;');
	}
	catch (err) {
		return '';
	}
	return s;
}

sl.openWindow = function(mode, url) {
	if (mode == 0) { // in the same window
		top.document.location = url;
	}
	else if (mode == 1) { // tabbed
		// TODO s.appendTab();
	}
	else if (mode == 2) { // new window
		window.open( url );
	}
}

sl.tabClick = function(uid) {
	var t = window.top.sl_global.tabitems[ uid ];
	try {
		if (t.parent.getSelected().uid == uid)
			return;
	}
	catch (err) {
	}
	var s = window.top.sl_global.list[ t.parent.slideshowIndex ];
	var fd = new ForwardDescriptor(s.core.fd);
	fd.selectTab(t.parent.id, t.id); // selezione del tab
	if (t.parent.id == this.STAGES) {
		s.loadStageContent(t.id);
		fd.content = null;
		// TODO controllare che fd.content sia NULL
	}
	else {
		fd.content = ContentResourceFactory(s, t.ctype, t.id, null, null, fd.layout);
	}
	s.forward(fd);
}

sl.tabOverEvent = function(uid) {
	var t = window.top.sl_global.tabitems[ uid ];
	t.parent.tabOverEvent(t.tIndex);
}

sl.tabOutEvent = function(uid) {
	var t = window.top.sl_global.tabitems[ uid ];
	t.parent.tabOutEvent(t.tIndex);
}

sl.scrollRight = function(s, tl) {
	sl.trace("window.top.sl_global.list" + window.top.sl_global.list + " s=" + s + " tl=" + tl );
	window.top.sl_global.list[s].core.tablist[tl].scroller.startToRight();
}

sl.scrollLeft = function(s, tl) {
	sl.trace("window.top.sl_global.list" + window.top.sl_global.list + " s=" + s + " tl=" + tl );
	window.top.sl_global.list[s].core.tablist[tl].scroller.startToLeft();
}

sl.stopScroll = function() {
	clearInterval( this.scrollInterval );
	this.scrollInterval = 0;
}

sl.executeScrollRight = function() {
	if ((this.scroller.step += 2) >= this.stages_scroll_freq && this.scroller.amount < 30) {
		this.scroller.amount *= 1.66;
		this.scroller.step = 0;
	}
	//sl.trace("pos=" + this.scroller.pos() + " amount=" + this.scroller.amount + " offset="+this.scroller.offset());
	var p = Math.max(this.scroller.pos() - this.scroller.amount, this.scroller.offset());
	/*if (p == this.scroller.offset())
		this.scroller.amount = 0;*/
	this.scroller.pos(p);
}

sl.executeScrollLeft = function() {
	if ((this.scroller.step += 2) >= this.stages_scroll_freq && this.scroller.amount < 30) {
		this.scroller.amount *= 1.66;
		this.scroller.step = 0;
	}
	var p = Math.min(0, this.scroller.pos() + this.scroller.amount);
	this.scroller.pos(p);
}

sl.hideAll = function() {
	for (var s in window.top.sl_global.list) {
		try {
			window.top.sl_global.list[s].hideContent();
		}
		catch (err) {
		}
		try {
			window.top.sl_global.list[s].core.hidden = true;
		}
		catch (err) {
		}
	}
}

sl.showAll = function() {
	for (var s in window.top.sl_global.list) {
		try {
			if (window.top.sl_global.list[s].core.hidden && (!window.top.sl_global.current || window.top.sl_global.current.index != s))
				try {
					window.top.sl_global.list[s].forward(window.top.sl_global.list[s].core.fd);
				}
				catch (err) {
				}
		}
		catch (err) {
		}
	}
}

sl._void = function() {
}

// Animazioni slideshow vere e proprie per UomoinMare.it
sl._SLIDESHOW = function(slideshow, cr, op, instanceId, swf_file) {
	// non usare 'this' gli handler chiamati con eval() hanno 'this' del client
	if (op == 'draw') {
		if ("" + cr.ref.id == '')
			throw new Error("_SLIDESHOW: l'elemento html contenitore deve avere un id");
		if (swf_file == undefined)
			throw new Error("_SLIDESHOW: swf_file assente");
		else if (swf_file instanceof Array)
			swf_file = swf_file[slideshow.core.fd.layout];
		//TODO: slideshow.showInsertForm = slideshow.showInsertForm || (parseInt(cr.ctype) > 100);
		//slideshow.swfEmptyCanvas.style.width = slideshow.layoutWidth + "px";
		var swf = new SWFObject( null, swf_file, instanceId, slideshow.core.contentWidth, slideshow.core.contentHeight, 8.0, cr.colors.selectedBackgroundColor );
		swf.addParam("allowScriptAccess", "sameDomain");
		swf.addVariable("sl_id", slideshow.id );
		swf.addVariable("sl_lang", window.top.sl_global.lang );
		swf.addVariable("sl_baseDataURL", escape(slideshow.conf.baseDataURL) );
		swf.addVariable("sl_lc_id", window.sl_local.localConnId + slideshow.core.ref.placeHolder.id);
		swf.addVariable("sl_index", slideshow.index );
		if (slideshow.core.tablist[window.sl_local.STAGES].items.length > 0)
			swf.addVariable("sl_stage_id", slideshow.core.tablist[window.sl_local.STAGES].currentId );
		else
			swf.addVariable("sl_stage_id", "0" );
		swf.addVariable("sl_type_id", cr.id /*slideshow.core.tablist[window.sl_local.TYPES].currentId*/ );
		swf.addVariable("sl_user_id", slideshow.conf.userID ); // potrebbe essere undefined
		swf.addVariable("sl_mmaid", slideshow.core.fd.mmaId );
		swf.addVariable("sl_stage", Math.max(slideshow.core.fd.tabid[window.sl_local.STAGES], 0));
		swf.addVariable("sl_conf_contentid", slideshow.conf.contentId );
		swf.addVariable("sl_hasInsertPriv", slideshow.conf.hasInsertPrivilege && slideshow.core.fd.tabid[window.sl_local.STAGES] != 0);
		swf.addVariable("sl_hasFullModPriv", slideshow.conf.hasFullModifyPrivileges );
		swf.addVariable("sl_hasFullDelPriv", slideshow.conf.hasFullDeletePrivileges );
		swf.addVariable("sl_autoPriv", slideshow.conf.automaticPrivileges );
		swf.addVariable("sl_hasAuthorPriv", slideshow.conf.hasAuthorPrivileges );
		swf.addVariable("sl_showInsForm", slideshow.core.fd.showInsertForm || cr.id > 9000);
		swf.addVariable("sl_showModForm", slideshow.core.fd.showModifyForm );
		swf.addVariable("sl_showDelForm", slideshow.core.fd.showDeleteForm );
		swf.addVariable("sl_showVotoForm", slideshow.core.fd.showVotoForm ); // (interna)
		swf.addVariable("sl_layout", slideshow.core.fd.layout == SL_FULL_SIZE ? "full" : "small" );
		swf.addVariable("sl_loginUrl", escape(slideshow.conf.loginURL) );
		swf.addVariable("sl_fmistoUrl", escape(slideshow.conf.frittomistoURL) );
		swf.addVariable("sl_uploadUrl", escape(slideshow.conf.uploadActionURL) );
		swf.addVariable("sl_uplInfoUrl", escape(slideshow.conf.uploadInfoURL) );
		//swf.addVariable("sl_jsessionid", '123456789ABCDEF');
		swf.addVariable("sl_jsessionid", window.sl_local.readCookie("JSESSIONID"));
		// TODO colori
		//swf.addVariable("sl_textForegroundColor", slideshow.textForegroundColor );
		//swf.addVariable("sl_mainBackgroundColor", slideshow.mainBackgroundColor );
		// opzioni specifiche dell'animazione VideoAuthorFull.swf che condivide parte
		// della logica con player predefinito di UomoInMare
		if (swf_file.lastIndexOf("VideoUserFull.swf") != -1) {
			swf.addVariable( "stopdelay", "8" );
			swf.addVariable( "stopdelaytitle", "false" );
			swf.addVariable( "defaultvolume", "30" );
		}
		swf.write( cr.ref );
		cr.flashInstanceRef = document.getElementById(instanceId);
		// deve azzerare le (altre) opzioni di ripristino di stato, 
		// altrimenti le riproporrebbe continuamente.
		slideshow.core.fd.clearForms();
		// debug
		var buff = "<pre style='color:orange'>-----------------------------------------\nswf:";
		for (var i in swf.variables)
			buff += "\n" + i + "=" + swf.variables[i];
		window.sl_local.trace(buff + "\n-----------------------------------------</pre>");	
	}
	else if (op == 'signal') {
		var signal = instanceId;
		try {
			/*
			if (signal == 'unload')
				cr.flashInstanceRef.signalUnload();
			else if (signal == 'pause')
				cr.flashInstanceRef.signalPause();
			else if (signal == 'wakeup')
				cr.flashInstanceRef.signalWakeup();
			else if (signal == 'blur')
				cr.flashInstanceRef.signalBlur();
			else if (signal == 'focus')
				cr.flashInstanceRef.signalFocus();
			*/
		} 
		catch(err) {
			return false;
		}
	}
	else if (op == 'translate-old-typeid') {
		var content = instanceId;
		var a = new Array();
		if (content == 'v') {
			a.push(window.sl_local.CT_USER_VIDEO);
			a.push(window.sl_local.CT_USER_VIDEO);
		}
		else if (content == 'fa') {
			a.push(window.sl_local.CT_AUTHOR_PHOTO);
			a.push(window.sl_local.CT_AUTHOR_PHOTO);
		}
		else if (content == 'f' || content == 'fu') {
			a.push(window.sl_local.CT_USER_PHOTO);
			a.push(window.sl_local.CT_USER_PHOTO);
		}
		return a;
	}
	return true;
}

sl._HTML = function(slideshow, cr, op, html) {
	if (op == 'draw')
		cr.ref.innerHTML = html;
}

/*sl._LIBERO_VIDEO = function(slideshow, cr, op, html) {
	if (op == 'draw') {
		var buff = '<div id="LIBEROVIDEO"><div id="'+slideshow.conf.placeHolder.id+'LiberoPlayer"></div><div id="LiberoSlideshow"></div></div>';
		// rifare animazione flash trasparente per il voto, riutilizza lo stesso codice actionscript delle anim.
		// animazione dei thumbs
		// rifare il dataentry con forms separate
	}
}*/

sl._EMPTY = function(slideshow, cr, op) {
}

// deve essere in grado di tenere traccia anche dello stato corrente
// uno slideshow pu• passare il suo descrittore a un altro
// Il ForwardDescriptor Š solo un descrittore, non si preoccupa
// dei presupposti dell'operazione/stato che rappresentaed Š garantisce
// solo questo: 1) ogni form vuole full-layout 2) una sola form aperta alla volta
function ForwardDescriptor(stageId, typeId, mmaId, showForm, layout, contentResource) {
	this.recursion = true; // prefef. ammette ricorsione
	this.tabid = new Array();
	if (arguments[0] instanceof ForwardDescriptor) {
		for (var o in arguments[0]) {
			if (o == "tabid") {
				this.tabid[window.sl_local.STAGES] = arguments[0].tabid[window.sl_local.STAGES] || -1;
				this.tabid[window.sl_local.TYPES] = arguments[0].tabid[window.sl_local.TYPES] || -1;
			}
			else if (!(arguments[0][o] instanceof Function))
				this[o] = arguments[0][o];
			//if (this.content == undefined)
			//	debugger;
		}
	}
	else {
		this.tabid[window.sl_local.STAGES] = stageId || -1;
		this.tabid[window.sl_local.TYPES] = typeId || -1;
		this.mmaId = mmaId || -1;
		this.showInsertForm = false;
		this.showModifyForm = false;
		this.showDeleteForm = false;
		this.showVotoForm = false;
		this.showForm = '';
		this.layout = layout || this.needsFullLayout();
		this.content = contentResource;
	}
}

ForwardDescriptor.prototype.needsFullLayout = function(descriptor) {
	return ((descriptor || this).showForm != '') ? SL_FULL_SIZE : this.layout;
}

ForwardDescriptor.prototype.setShowForm = function(a) { // i/m/e/v
	this.showForm = a || "";
	this.showInsertForm = a == 'i';
	this.showModifyForm = a == 'm';
	this.showDeleteForm = a == 'e';
	this.showVotoForm =   a == 'v';
}

ForwardDescriptor.prototype.setInsertForm = function(a) {
	if (a) 
		this.setShowForm('i');
}

ForwardDescriptor.prototype.setModifyForm = function(a) {
	if (a) 
		this.setShowForm('m');
}

ForwardDescriptor.prototype.setDeleteForm = function(a) {
	if (a) 
		this.setShowForm('e');
}

ForwardDescriptor.prototype.setVotoForm = function(a) {
	if (a) 
		this.setShowForm('v');
}

ForwardDescriptor.prototype.clearForms = function() {
	this.setShowForm();
}

ForwardDescriptor.prototype.setLayout = function(layout) {
	if (layout == SL_SMALL_SIZE)
		this.clearForms();
	this.layout = layout;
}

ForwardDescriptor.prototype.selectTab = function(tl_id, id) {
	try {
		return this.tabid[tl_id] = id;
	}
	catch (err) {
		return null;
	}
}

ForwardDescriptor.prototype.setContent = function(cr) {
	this.content = cr;
}

// non avendo a disposizione interfacce, l'handler non Š altro che una funzione
// che accetta come primo argomento l'istanza del contentresource client e 
// come argomenti successivi ogni altro argomento a seguire dopo tabitem
// ContentResource(id, handler, colors, tabitem, handler arguments...)
function ContentResource(id, handler, colors, tabitem) {
	this.id = id;
	this.handler = handler;
	if (!(handler instanceof Function))
		throw new Error("ContentResource() handler must be a function");
	this.colors = colors;
	this.tabItem = tabitem || null;
	this.arguments = new Array();
	for (var i=4; i<arguments.length; i++) {
		this.arguments[i-4] = arguments[i];
		//window.sl_local.trace("a=" + this.arguments[i-4]);
	}
}

ContentResource.prototype.draw = function(elem_ref, slideshow) {
	// non traccia pi— lo sfondo (Š sempre lo stesso DIV, ma cambia il contenuto)
	if (elem_ref == null) {
		if (SLIDESHOW_DEBUG || SLIDESHOW_DEMO)
			alert("slideshow: errore interno divHtmlElement=null!");
		else
			window.defaultStatus = "slideshow: errore interno divHtmlElement=null!"
	}
	else {
		var buff = '';
		this.ref = elem_ref;
		for (var i in this.arguments)
		{
			var a = i*1;
			if(!isNaN(a))
				buff += ", this.arguments["+i+"]";
		}		
		// this.handler() corrisponde alternativamente a _HTML()/_SLIDESHOW()/_EMPTY()
		eval("this.handler(slideshow, this, 'draw' "+buff+")");
	}
}

ContentResource.prototype.signal = function(signal) {
	this.handler(null, this, 'signal', signal);
}

// content = ContentResourceFactory(this, window.sl_local.CT_CUSTOM, new ContentResource(...));
// content = ContentResourceFactory(this, tabItem.ctype, tabItem.id, this.showInsertForm);
function ContentResourceFactory(s, cType, contentId, insTransf, insIdReferer, layout) {
	if (cType == window.sl_local.CT_CUSTOM) {
		if (!arguments[2] instanceof ContentResource)
			throw new Error("ContentResourceFactory() contentResource non valido");
		return arguments[2];
	}
	else {
		var id = (arguments[2] != undefined) ? arguments[2] : Math.round(Math.random()*0xFFFFFFFF);
		var f = new Array();
		var c = window.sl_local.colors.user;
		var t = null; //s.core.tablist[window.sl_local.TYPES].getItemById(arguments[2]);
		if (cType == window.sl_local.CT_USER_PHOTO && !insTransf) {
			f[SL_SMALL_SIZE] = "PhotoUserSmall.swf";
			f[SL_FULL_SIZE] = "PhotoUserFull.swf";
		}
		else if (cType == window.sl_local.CT_USER_VIDEO && !insTransf) {
			f[SL_SMALL_SIZE] = "VideoUserSmall.swf";
			f[SL_FULL_SIZE] = "VideoUserFull.swf";
		}
		else if (cType == window.sl_local.CT_AUTHOR_PHOTO && !insTransf) {
			c = window.sl_local.colors.author;
			f[SL_SMALL_SIZE] = "PhotoAuthorSmall.swf";
			f[SL_FULL_SIZE] = "PhotoAuthorFull.swf";
		}
		else if (cType == window.sl_local.CT_AUTHOR_VIDEO) {
			c = window.sl_local.colors.author;
			f[SL_SMALL_SIZE] = "VideoAuthorSmall.swf";
			f[SL_FULL_SIZE] = "VideoAuthorFull.swf";
		}
		else {
			if (layout == SL_FULL_SIZE) {
				if (cType == window.sl_local.CT_USER_VIDEO_INSERT || (cType == window.sl_local.CT_USER_VIDEO && insTransf)) {
					id = window.sl_local.CT_USER_VIDEO_INSERT;
					f[SL_FULL_SIZE] = "Ins-VideoUserFull.swf";
					// (						id, tIndex, oIndex, ctype, 																		caption, 																															 current, count, ref, short_details, full_details, cssClassName) {
					t = new TabItem(id, null, null, window.sl_local.CT_USER_VIDEO_INSERT, window.sl_local.txt[window.top.sl_global.lang].INSERT_USER_VIDEO, null, -1,       null, null,         null,        'colors_user');
				}
				else if (cType == window.sl_local.CT_USER_PHOTO_INSERT || (cType == window.sl_local.CT_USER_PHOTO && insTransf)) {
					id = window.sl_local.CT_USER_PHOTO_INSERT;
					f[SL_FULL_SIZE] = "Ins-PhotoUserFull.swf";
					t = new TabItem(id, null, null, window.sl_local.CT_USER_PHOTO_INSERT, window.sl_local.txt[window.top.sl_global.lang].INSERT_USER_PHOTO, null, -1,       null, null,         null,        'colors_user');
				}
				else if (cType == window.sl_local.CT_AUTHOR_PHOTO_INSERT || (cType == window.sl_local.CT_AUTHOR_PHOTO && insTransf)) {
					id = window.sl_local.CT_AUTHOR_PHOTO_INSERT;
					c = window.sl_local.colors.author;
					f[SL_FULL_SIZE] = "Ins-PhotoAuthorFull.swf";
					t = new TabItem(id, null, null, window.sl_local.CT_AUTHOR_PHOTO_INSERT, window.sl_local.txt[window.top.sl_global.lang].INSERT_AUTHOR_PHOTO, null, -1,       null, null,         null,        'colors_author');
				}
			}
			if (t == null) {
				//"seleziona una tappa"
				var html = '';
				var ins_html = '';
				var caption = '';
				if (s.conf.hasAuthorPrivileges)
					ins_html = window.sl_local.text('<ul style="margin-left:3em"><li><a href="javascript:window.sl_local._void()" onclick="window.top.sl_global.list['+s.index+'].openCrossInsertion('+window.sl_local.CT_AUTHOR_PHOTO+','+window.sl_local.CT_AUTHOR_PHOTO+',true);"/>%</a></li><li><a href="javascript:window.sl_local._void()" onclick="window.top.sl_global.list['+s.index+'].openCrossInsertion('+window.sl_local.CT_USER_PHOTO+','+window.sl_local.CT_USER_PHOTO+',true);"/>%</a></li><li><a href="javascript:window.sl_local._void()" onclick="window.top.sl_global.list['+s.index+'].openCrossInsertion('+window.sl_local.CT_USER_VIDEO+','+window.sl_local.CT_USER_VIDEO+',true);"/>%</a></li></ul>', window.sl_local.txt[window.top.sl_global.lang].INSERT_AUTHOR_PHOTO, window.sl_local.txt[window.top.sl_global.lang].INSERT_USER_PHOTO, window.sl_local.txt[window.top.sl_global.lang].INSERT_USER_VIDEO);
				//else if (s.conf.hasInsertPrivilege)
				ins_html = window.sl_local.text('<ul style="margin-left:3em"><li><a href="javascript:window.sl_local._void()" onclick="window.top.sl_global.list['+s.index+'].openCrossInsertion('+window.sl_local.CT_USER_PHOTO+','+window.sl_local.CT_USER_PHOTO+',true);"/>%</a></li><li><a href="javascript:window.sl_local._void()" onclick="window.top.sl_global.list['+s.index+'].openCrossInsertion('+window.sl_local.CT_USER_VIDEO+','+window.sl_local.CT_USER_VIDEO+',true);"/>%</a></li></ul>', window.sl_local.txt[window.top.sl_global.lang].INSERT_USER_PHOTO, window.sl_local.txt[window.top.sl_global.lang].INSERT_USER_VIDEO);
				if (cType == window.sl_local.CT_PLEASE_SELECT_STAGE_WELCOME) {
					caption = window.sl_local.txt[window.top.sl_global.lang].WELCOME;
					html = window.sl_local.text('<p>%</p>', window.sl_local.txt[window.top.sl_global.lang].PLEASE_SELECT_STAGE);
				}
				// idem cambia il titolo
				else if (cType == window.sl_local.CT_PLEASE_SELECT_STAGE_NEW) {
					caption = window.sl_local.txt[window.top.sl_global.lang].NEW;
					html = window.sl_local.text('<p>%</p>', window.sl_local.txt[window.top.sl_global.lang].PLEASE_SELECT_STAGE);
				}
				//b "benvenuti"
				//"siamo spiacenti"
				else if (cType == window.sl_local.CT_CRUISE_IS_EMPTY_VISITOR) {
					caption = window.sl_local.txt[window.top.sl_global.lang].WELCOME;
					html = window.sl_local.text('<p>%</p>', window.sl_local.txt[window.top.sl_global.lang].CT_CRUISE_IS_EMPTY_VISITOR);
				}
				//c "nuovo"
				//"inserisci foto, inserisci video"
				else if (cType == window.sl_local.CT_NEW_TAB_CRUISE) {
					caption = window.sl_local.txt[window.top.sl_global.lang].NEW;
					if (ins_html)
						html = window.sl_local.text('<p>%:<br/>&nbsp;<div>%</div></p>', window.sl_local.txt[window.top.sl_global.lang].CT_NEW_TAB_CRUISE, ins_html);
				}
				//d "tappa vuota"
				//"siamo spiacenti, per questa tappa nessun contenuto"
				else if (cType == window.sl_local.CT_STAGE_IS_EMPTY) {
					caption = window.sl_local.txt[window.top.sl_global.lang].EMPTY_STAGE;
					html = window.sl_local.text('<p>%</p>', window.sl_local.txt[window.top.sl_global.lang].CT_STAGE_IS_EMPTY);
				}
				//e "benvenuto"
				// "inserisci foto, inserisci video"
				else if (cType == window.sl_local.CT_WELCOME_NEW_TAB) {
					caption = window.sl_local.txt[window.top.sl_global.lang].WELCOME;
					if (ins_html)
						html = window.sl_local.text('<p>%:<br/>&nbsp;<div>%</div></p>', window.sl_local.txt[window.top.sl_global.lang].CT_WELCOME_NEW_TAB, ins_html);
				}
				//f "nuovo.."
				// "inserisci foto, inserisci video"
				else if (cType == window.sl_local.CT_NEW_TAB_KINDLY) {
					caption = window.sl_local.txt[window.top.sl_global.lang].NEW;
					if (ins_html)
						html = window.sl_local.text('<p>%:<br/>&nbsp;<div>%</div></p>', window.sl_local.txt[window.top.sl_global.lang].CT_NEW_TAB_KINDLY, ins_html);
				}
				//g "benveuto"
				// "siamo spiacenti"
				else if (cType == window.sl_local.CT_SLIDE_IS_EMPTY) {
					caption = window.sl_local.txt[window.top.sl_global.lang].WELCOME;
					html = window.sl_local.text('<p>%</p>', window.sl_local.txt[window.top.sl_global.lang].CT_SLIDE_IS_EMPTY);
				}
				else {
					throw new Error("ContentResourceFactory(): cType sconosciuto " + cType);
				}
				t = new TabItem(null, null, null, cType, caption, null, -1, null, null, null, 'colors_generic');
				return new ContentResource(id, window.sl_local._HTML, window.sl_local.colors.generic, t, html);
			}
		}
		try {
			f[SL_FULL_SIZE] = s.conf.resourcePath + f[SL_FULL_SIZE];
			f[SL_SMALL_SIZE] = s.conf.resourcePath + f[SL_SMALL_SIZE];
		}
		catch (err) {
		}
		var cr = new ContentResource(id, window.sl_local._SLIDESHOW, c, t, s.core.ref.placeHolder.id + "FlashID", f);
		if (insIdReferer != undefined) {
			if (t)
				t.referer = insIdReferer;
			cr.insIdReferer = insIdReferer;
		}
		return cr;
	}									
}

function Slideshow( id ) {
	window.sl_local.trace("Slideshow(" + id + ")");
	this.parent = null;
	window.top.sl_global.list[ this.index = window.top.sl_global.list.length ] = this;
	
	// Non usare Array in conf!
	this.conf = new Object();	// config data (cloned in copy() method)
	this.conf.layout = SL_SMALL_SIZE;
	this.conf.title = "Slideshow UomoinMare.it";
	this.conf.lang = "it";
	this.conf.placeHolderId = id;
	this.conf.contentId = 0;
	this.conf.userID = 0;
	this.conf.startMmaID = -1;
	this.conf.startStageID = -1;
	this.conf.startTypeID = -1;
	this.conf.showInsertForm = false;
	this.conf.showModifyForm = false;
	this.conf.showDeleteForm = false;
	this.conf.showVotoForm = false;
	this.conf.currentStageIndex = -1;
	this.conf.baseDataURL = "";
	this.conf.loginURL = "";
	this.conf.frittomistoURL = "";
	this.conf.uploadActionURL = "";
	this.conf.uploadInfoURL = "";
	this.conf.resourcePath = "./slideshow_resources/";
	this.conf.forceTypesOrder = "";
	this.conf.forceRefreshOnClose = false;
	this.conf.automaticPrivileges = true;
	this.conf.hasInsertPrivilege = true;
	this.conf.hasFullModifyPrivilege = false;
	this.conf.hasFullDeletePrivilege = false;
	this.conf.hasAuthorPrivileges = false;
	this.conf.textForegroundColor = null;
	this.conf.mainBackgroundColor = null;
	this.conf.enableShortTabs = false;
	this.conf.enableShortTabsFullSize = false;
	this.conf.canvasBackgroundColor = "#eee";
	
	this.core = new Object();		// runtime data
	this.core.ref = new Object();
	this.core.tablist = new Array(3); // tablist fino a max 3 livelli
	this.core.tablist[window.sl_local.STAGES] = new TabList(window.sl_local.STAGES, this.index);
	this.core.tablist[window.sl_local.TYPES] = new TabList(window.sl_local.TYPES, this.index);
	this.core.tablist[window.sl_local.TL_SUBTYPES] = new TabList(window.sl_local.TL_SUBTYPES, this.index);
	this.core.tablist[window.sl_local.TYPES].enableCaptionDetails = true;
	this.core.ref.tablist = new Array(this.core.tablist.length);
	this.core.ref.tablist_r = new Array(this.core.tablist.length);
	this.core.ref.roundedCorners = new Array();
	this.core.drawed = false;
	this.core.layoutWidth = 0;
	this.core.layoutHeight = 0;
	this.core.refreshCounters = false;
	//this.core.currentContent = null;
	
	this.core.fd = new ForwardDescriptor();
	this.core.selectedContentId = null;
	this.core.selectedPlaceId = null;
	this.core.selectedPlaceUrl = null;
	this.core.selectedCruiseId = null;
	this.core.selectedAuthorId = null;
	this.core.selectedItemUrl = null;
	this.core.selectedIsOwner = null;
	this.core.selectedTitle = null;
	this.core.selectedDate = null;
	this.core.selectedTags = null;
	this.core.selectedPlace = null;
	this.core.selectedStageId = null;
}

// "sposta" sull'oggetto 'conf' i parametri di configurazione
// eventualmente assegnati su root (fix retrocomp.)
Slideshow.prototype.updateConfParams = function() {
	for (var c in this.conf) {
		if (this[c] != undefined)
			this.conf[c] = this[c];
	}
	if (this.conf.layout == SL_SMALL_SIZE && this.conf.enableShortTabs)
		this.core.tablist[window.sl_local.TYPES].enableShortTabs = true;
	else if (this.conf.layout == SL_FULL_SIZE && this.conf.enableShortTabsFullSize)
		this.core.tablist[window.sl_local.TYPES].enableShortTabs = true;
	this.core.fd.setLayout(this.conf.layout);
	this.core.fd.setInsertForm(this.conf.showInsertForm);
	this.core.fd.setModifyForm(this.conf.showModifyForm);
	this.core.fd.setDeleteForm(this.conf.showDeleteForm);
	this.core.fd.setVotoForm(this.conf.showVotoForm);
	this.core.fd.selectTab(window.sl_local.STAGES, this.conf.startStageID);
	this.core.fd.selectTab(window.sl_local.TYPES, this.conf.startTypeID);
	this.core.fd.mmaId = this.conf.startMmaID;
	this.conf.startStageID = -1;
	this.conf.startTypeID = -1;
	this.conf.startMmaID = -1;
	
	if (parseInt(this.conf.contentId) == -1)
		this.conf.hasInsertPrivilege = false;
	else if (!(parseInt(this.conf.contentId) > 0))
		this.conf.contentId = 0;
		// window.sl_local.trace("ATTENZIONE: contentId predefinito non impostato!");
		// alert("ATTENZIONE: contentId non impostato!");
}

Slideshow.prototype.copy = function( s ) {
	if (!(s instanceof Slideshow)) {
		alert( "not a Slideshow instance: " + s );
		throw new Error( "not a Slideshow instance: " + s );
		return;
	}
	for (var c in this.conf)
		if (c != "placeHolderId")
			s.conf[c] = this.conf[c];
}

Slideshow.prototype.updateCurrentItem = function(data) {
	window.sl_local.trace( "selectedMMAID " + (this.core.fd.mmaId = data[1]) );
	window.sl_local.trace( "selectedCONTENTID " + (this.core.selectedContentId = data[2]) );
	window.sl_local.trace( "selectedPLACEID " + (this.core.selectedPlaceId = data[3]) );
	window.sl_local.trace( "selectedPLACEURL " + (this.core.selectedPlaceUrl = data[4]) );
	window.sl_local.trace( "selectedCRUISEID " + (this.core.selectedCruiseId = data[5]) );
	window.sl_local.trace( "selectedAUTHORID " + (this.core.selectedAuthorId = data[6]) );
	window.sl_local.trace( "selectedITEMURL " + (this.core.selectedItemUrl = data[7]) );
	window.sl_local.trace( "selectedOWNER " + (this.core.selectedIsOwner = data[8]) );
	window.sl_local.trace( "selectedTITLE " + (this.core.selectedTitle = data[9]) );
	window.sl_local.trace( "selectedDATE " + (this.core.selectedDate = data[10]) );
	window.sl_local.trace( "selectedTAGS " + (this.core.selectedTags = data[11]) );
	window.sl_local.trace( "selectedPLACE " + (this.core.selectedPlace = data[12]) );
	window.sl_local.trace( "selectedSTAGE " + (this.core.selectedStageId = data[13]) );
}

Slideshow.prototype.fixUrl = function(u) {
	var c = u.lastIndexOf('?');
	if (c == -1)
		u += '?';
	else if (c != 0 && u.charAt( u.length-1 ) != '&')
		u += '&';
	return u;
}

// cancella il contenuto senza modificare il ContentResource
// e lascia inalterati i colori. 
Slideshow.prototype.hideContent = function() {
	//var cr = ContentResourceFactory(this, window.sl_local.CT_CUSTOM_EMPTYTAB);
	//cr.draw(this.core.ref.contentPlaceHolder, this);
	while (this.core.ref.contentPlaceHolder.firstChild)
		this.core.ref.contentPlaceHolder.removeChild( this.core.ref.contentPlaceHolder.firstChild );
}

/*Slideshow.prototype.refreshContent = function() {
	var fd = new ForwardDescriptor(this.core.fd);
	fd.setContent(this.
}*/

Slideshow.prototype.setContent = function(cr) {
	if (cr == null)
		throw new Error("setContent(null)");
	try { 
		//this.core.fd.content.signal('unload'); 
	} 
	catch(err) {
	}
	finally {
		this.core.ref.contentCanvasPlaceHolder.style.backgroundColor = cr.colors.selectedBackgroundColor;
		this.core.ref.contentCanvasPlaceHolder.style.foregroundColor = cr.colors.selectedForegroundColor;
		var c = window.sl_local.colorCode(this.core.contentCanvasColor);
		for (var i in this.core.ref.roundedCorners)
			this.core.ref.roundedCorners[i].src = this.conf.resourcePath + this.core.ref.roundedCorners[i].name + c + ".gif";
		cr.draw(this.core.ref.contentPlaceHolder, this);
		this.core.fd.content = cr;
	}
}

Slideshow.prototype.show = function() 
{
	this.updateConfParams();

	// layout
	this.core.layoutWidth = this.conf.layout == SL_FULL_SIZE ? 680 : 468;
	this.core.contentWidth = this.conf.layout == SL_FULL_SIZE ? 656 : 456;
	this.core.contentHeight = this.conf.layout == SL_FULL_SIZE ? 480 : 200;
	this.core.layoutHeight = this.core.contentHeight + 16;

	this.core.ref.placeHolder = document.getElementById( this.conf.placeHolderId );
	this.core.ref.placeHolder.className = 'sl_canvas';
	this.core.ref.placeHolder.style.width = this.core.layoutWidth + "px";
	
	var tabframeId = this.core.ref.placeHolder.id + 'Tabframe';
	var contentCanvasId = this.core.ref.placeHolder.id + 'ContCanvas';
	var contentId = this.core.ref.placeHolder.id + 'Canvas';
	var cacheDataId = this.core.ref.placeHolder.id + 'CData';
	var rlineUpId = this.core.ref.placeHolder.id + 'RLUp';
	var rlineDnId = this.core.ref.placeHolder.id + 'RLDn';
	
	this.core.ref.placeHolder.innerHTML = 
	    '<div id="'+tabframeId+'" class="sl_tabframe" style="width:100%; height:auto"></div>'
		+ '<div id="'+contentCanvasId+'" class="sl_content_canvas" style="width:'+this.core.layoutWidth+'px; height:'+this.core.layoutHeight+'px">'
		+		'<span id="'+rlineUpId+'"></span>'
		+ 	'<div id="'+contentId+'" class="sl_content" style="overflow:hidden; width:'+this.core.contentWidth+'px; height='+this.core.contentHeight+'"></div>'
		/*	'<iframe id="'+contentId+'-IFrame" style="border:none; width:'+this.core.contentWidth+'px; height='+this.core.contentHeight+'"></iframe>' */
		+		'<span id="'+rlineDnId+'"></span>'
		+ '</div>'
		+ '<div id="'+cacheDataId+'"></div>';
		
	this.core.ref.tabFramePlaceHolder = document.getElementById(tabframeId);
	this.core.ref.contentCanvasPlaceHolder = document.getElementById(contentCanvasId);
	/*this.core.ref.contentIFrame = document.getElementById(contentId + "-IFrame");
	this.core.ref.contentPlaceHolder = 
		this.core.ref.contentIFrame.contentWindow.document.createElement("div");
	this.core.ref.contentIFrame.appendChild(this.core.ref.contentPlaceHolder);*/
	this.core.ref.contentPlaceHolder = document.getElementById(contentId);
	this.core.ref.contentPlaceHolder.id = contentId;
	this.core.ref.contentPlaceHolder.style.height = this.core.contentHeight + "px";
	this.core.ref.cacheData = document.getElementById(cacheDataId);
	
	var r = this.buildRoundedLine('up', 8, document.getElementById(rlineUpId));
	this.core.ref.roundedCorners.push(r.images[0]);
	this.core.ref.roundedCorners.push(r.images[1]);
	
	r = this.buildRoundedLine('dn', 8, document.getElementById(rlineDnId));
	this.core.ref.roundedCorners.push(r.images[0]);
	this.core.ref.roundedCorners.push(r.images[1]);
	
	if (!document.styleSheets) {
		this.setContent(new ContentResource(0, window.sl_local._HTML, null, null, "broswer non compatibile"));
		return -2;
	}	
	else if (!DetectFlashVer( 8, 0, 0 )) {
		this.setContent(new ContentResource(0, window.sl_local._HTML, null, null, "devi aggiornare il flash player"));
		return -1;
	}
	else {
		// url fixes
		this.conf.baseDataURL = this.fixUrl(this.conf.baseDataURL);
		this.conf.uploadInfoURL = this.fixUrl(this.conf.uploadInfoURL);
		this.conf.uploadActionURL = this.fixUrl(this.conf.uploadActionURL);
		if (this.conf.uploadActionURL.indexOf("~/") == 0)
			this.conf.uploadActionURL = '.' + this.conf.uploadActionURL.substr(1);
		if (this.conf.uploadInfoURL.indexOf("~/") == 0)
			this.conf.uploadInfoURL = this.conf.resourcePath + this.conf.uploadInfoURL.substr(2);
		if (this.conf.baseDataURL.indexOf("~/") == 0)
			this.conf.baseDataURL = this.conf.resourcePath + this.conf.baseDataURL.substr(2);
		
		// runtime conf.
		this.core.stylesheet = window.sl_local.findMyStylesheet();
		if (this.conf.startStageID == -1) {
			this.conf.startStageID = 0;
		}
		// arrivato qui, deve poter da subito aggiungere tabs. Ne inserisce uno di attesa.
		// (non essendo associato ad alcuna tablist, esso morir… con INITBLOCK)
		this.setContent(new ContentResource(0, window.sl_local._HTML, window.sl_local.colors.generic, null, window.sl_local.txt[window.top.sl_global.lang].WAIT));
		this.loadStageContent(this.core.fd.tabid[window.sl_local.STAGES], true);
	}
	return 0;
}

Slideshow.prototype.refresh = function() {
	// esegue il refresh
	this.forward(this.core.fd);
}

Slideshow.prototype.buildRoundedLine = function(dir, cornerSize, elemToReplace) {
	var o = new Object();
	o.element = elemToReplace || document.createElement("div");
	o.element.className = "roundedLineUp";
	o.element.style.height = cornerSize + "px";
	o.element.innerHTML = '<img name="corner-trans-'+dir+'-sx-" src="" class="cornerTopSx" width="'+cornerSize+'" height="'+cornerSize+'" alt="" border="0"/>' /* '+this.conf.resourcePath+'corner-trans-'+dir+'-sx-'+window.sl_local.colorCode(canvasColor)+'.gif */
							+ '<img style="margin-left:-'+cornerSize+'px" name="corner-trans-'+dir+'-dx-" src="" class="cornerTopDx" width="'+cornerSize+'" height="'+cornerSize+'" alt="" border="0"/>';
	o.images = o.element.getElementsByTagName("img");
	return o;
}

Slideshow.prototype.refreshTabList = function(id, canvasColor, tablistColor, arrowsColor) {
	var first_time;
	if (!this.core.ref.tablist[id]) {
		this.core.ref.tablist[id] = document.createElement("span");
		//sl.border(this.core.ref.tablist[id], 'red');
		this.core.ref.tablist[id].className = "sl_tabcanvas";
		this.core.ref.tablist_r[id] = this.buildRoundedLine('up', 6);
		this.core.ref.tablist[id].appendChild(this.core.ref.tablist_r[id].element); // RIMASTO QUI [+ controllare nuovo codice roundedcorners]
		this.core.ref.tablist[id].appendChild(document.createElement("span")); // place holder per TabList.draw() (nuovo elemento)
		this.core.ref.tabFramePlaceHolder.appendChild(this.core.ref.tablist[id]);
	}
	try {
		this.core.ref.tablist[id].childNodes[1].style.display = "block";
		this.core.ref.tablist[id].childNodes[1].style.position = "relative";
		this.core.tablist[id].draw(this.core.ref.tablist[id].childNodes[1], this.core.layoutWidth, this.conf.resourcePath, arrowsColor, tablistColor);
	}
	catch(err) {
		window.sl_local.trace("errore draw(): " + err);
	}
	try {
		this.core.ref.tablist[id].style.backgroundColor = tablistColor;
		this.core.contentCanvasColor = tablistColor;
		var n = this.core.ref.tablist_r[id].element.getElementsByTagName("img");
		n[0].src = this.conf.resourcePath + n[0].name + window.sl_local.colorCode(canvasColor) + ".gif";
		n[1].src = this.conf.resourcePath + n[1].name + window.sl_local.colorCode(canvasColor) + ".gif";
		if (this.core.tablist[id].isEmpty()) {
			this.core.ref.tablist[id].style.display = "none";
			return false;
		}
		else {
			this.core.ref.tablist[id].style.display = "block";
		}
	} 
	catch (err) {
		sl.trace("200 error:" + err);
		return false;
	}
	return true;
}

function inspect_items(a) {
	for (var i in a) {
		sl.trace("caption '"+a[i].caption);
		sl.trace("count '"+a[i].count);
		sl.trace("tIndex '"+a[i].tIndex);
		sl.trace("oIndex '"+a[i].oIndex);
	}
}

Slideshow.prototype.loadStageContent = function( stageId, isFirstCall ) { // se isFirstCall (ri)traccia anche le tappe
	window.sl_local.trace("[" +  this.core.ref.cacheData.id + "] loadStageContent( " + stageId + " )");
	window.sl_local.buildLocalProxyIfNotExists(); /* SlideshowProxy */
	//alert( this.conf.resourcePath + "CacheData.swf" );
	var swf = new SWFObject( null, this.conf.resourcePath + "CacheData.swf", this.core.ref.cacheData.id + "Swf", "0", "0", 8.0, "#FFFFFF" );
	if (stageId != undefined && stageId != -1) {
		swf.addVariable( "sl_stage_id", stageId );
		swf.addVariable( "sl_isFirstCall", isFirstCall );
	}
	swf.addVariable( "sl_baseDataURL", escape(this.conf.baseDataURL) );
	swf.addVariable( "sl_preferred_typeid", this.core.tablist[window.sl_local.TYPES].currentId );
	swf.addVariable( "sl_lc_id", window.sl_local.localConnId + this.core.ref.placeHolder.id );
	swf.addVariable( "sl_index", this.index );
	swf.addVariable( "sl_id", this.core.ref.placeHolder.id );
	var c = (isFirstCall ? window.sl_local.EXC_END_OF_INITBLOCK : window.sl_local.EXC_END_OF_STAGEBLOCK);
	swf.addVariable( "sl_close_char", c );
	swf.write( this.core.ref.cacheData.id );
	// azzera tablist
	if (isFirstCall) {
		try {
			this.core.tablist[window.sl_local.STAGES].destroy(window.sl_local.txt[window.top.sl_global.lang].WAIT);
		} 
		catch (err) {
		}
	}
	try {
		this.core.tablist[window.sl_local.TYPES].destroy(window.sl_local.txt[window.top.sl_global.lang].WAIT); // non potrai farlo quando chiederai il summary solo la prima volta! (!??)
	} 
	catch (err) {
	}
}

Slideshow.prototype.sendBlurSignal = function( formsOnly ) {
	this.core.fd.content.signal('blur');
}

Slideshow.prototype.sendFocusSignal = function( formsOnly ) {
	this.core.fd.content.signal('focus');
}

Slideshow.prototype.sendPauseSignal = function( formsOnly ) {
	this.core.fd.content.signal('pause');
}

Slideshow.prototype.sendWakeupSignal = function( formsOnly ) {
	this.core.fd.content.signal('wakeup');
}

Slideshow.prototype.sendUnloadSignal = function( formsOnly ) {
	try {
		//document.getElementById( this.core.ref.cacheData.id ).signalUnload();
		//this.core.fd.content.signal('unload');
	}
	catch (err) {
	}
}

Slideshow.prototype.forward = function(fd) {
	window.sl_local.trace( "<pre style='color:green'>-----------------------------------------"+
							"\nforward:\nlayout=" + ((fd.layout == SL_SMALL_SIZE) ? "small-size" : "full-size")+
							"\nshowForm="+fd.showForm+"\nshowInsertForm="+fd.showInsertForm+"\nshowModifyForm="+fd.showModifyForm+"\nshowDeleteForm="+fd.showDeleteForm+"\nshowVotoForm="+fd.showVotoForm+
							"\nmmaId="+fd.mmaId+"\ntabid[TYPES]="+fd.tabid[window.sl_local.TYPES]+"\ntabid[window.sl_local.STAGES]="+fd.tabid[window.sl_local.STAGES]+
							"\n-----------------------------------------</pre>" );
	if (this.core.fd.layout == fd.layout) {
		this.core.fd.setShowForm(fd.showForm); // (content) (fd garantisce compatibilit… con il layout)
		for (var tl in fd.tabid) {
			try {
				if (this.core.tablist[tl].select(fd.tabid[tl]))
					this.core.fd.selectTab(tl, fd.tabid[tl]);
			}
			catch (err) {
				window.sl_local.trace("ERRORE: forward select() tablist="+tl+" tab-id="+fd.tabid[tl]+" errore=" + err);
			}
		}
		// se richiesto, aggiorna il contenuto
		if (fd.content != null)
			this.setContent(fd.content);
		else
			sl.trace("forward(): setContent(null)");
	}
	else if (fd.layout == SL_FULL_SIZE) {
		this.core.refreshCounters = false;
		this.core.ref.fullPlaceHolder = document.createElement("div");
		this.core.ref.fullPlaceHolder.id = this.core.ref.placeHolder.id + "Full";
		document.body.appendChild(this.core.ref.fullPlaceHolder);
		var s = new Slideshow(this.core.ref.fullPlaceHolder.id);
		this.copy(s);
		fd.recursion = false;
		s.parent = this;
		s.conf.layout = fd.layout;
		s.conf.showInsertForm = fd.showInsertForm;
		s.conf.showModifyForm = fd.showModifyForm;
		s.conf.showDeleteForm = fd.showDeleteForm;
		s.conf.showVotoForm = fd.showVotoForm;
		s.conf.startStageID = fd.tabid[window.sl_local.STAGES];
		s.conf.startTypeID = fd.tabid[window.sl_local.TYPES];
		s.conf.startMmaID = fd.mmaId;
		s.conf.canvasBackgroundColor = "#fff";
		s.show();
		sl_tb_show(document.title + " (BETA)", "#TB_inline?height=" + (this.core.tablist[window.sl_local.STAGES].isEmpty() ? 550 : 580) + "&width=680&inlineId=" + this.core.ref.fullPlaceHolder.id + "", false );
		window.top.sl_global.current = s;
		// this.hideContent(); // sostituito da sl.hideAll() direttamente in sl_tb_show()
	}
	else if (fd.layout == SL_SMALL_SIZE) {
		for (var s in window.top.sl_global.list) {
			if (s != this.index)
				try {
					window.top.sl_global.list[s].sendWakeupSignal();
				}
				catch (err) {
				}
		}
		document.body.removeChild(this.parent.core.ref.fullPlaceHolder);
		// se richiesta ricarica interamente il summary
		if (this.parent.core.refreshCounters || this.conf.forceRefreshOnClose) {
			// nota: il forward() seguir… su END_OF_INITBLOCK
			this.setContent(new ContentResource(0, window.sl_local._HTML, window.sl_local.colors.generic, null, window.sl_local.txt[window.top.sl_global.lang].WAIT));
			this.parent.core.fd = new ForwardDescriptor(this.core.fd); // propaga tab da selezionare, mmaId, ecc.
			this.parent.core.fd.setLayout(SL_SMALL_SIZE);
			this.parent.loadStageContent(this.parent.core.fd.tabid[window.sl_local.STAGES] || 0, true);
		}
		// sostituito da showAll in tb_remove()
		// this.parent.forward(this.parent.core.fd); // "risveglia" del suo content corrente
		// window.top.sl_global.current = null;
	}
}

Slideshow.prototype.openFullLayout = function(form, ctype) {
	var fd = new ForwardDescriptor(this.core.fd);
	fd.setLayout(SL_FULL_SIZE);
	if (ctype && form != 'i')
		throw new Error("openFullLayout(): puoi specificare un tab solo se Š un inserimento");
	if (ctype)
		fd.selectTab(sl.TYPES, ctype); // sa che ctype/id corrispondono nei "tipi" predefiniti
	if (form != 'i' || this.conf.hasInsertPrivilege) {
		fd.setShowForm(form);
		this.forward(fd);
	}
}

Slideshow.prototype.closeFullLayout = function() {
	var fd = new ForwardDescriptor(this.parent.core.fd);
	fd.setLayout(SL_SMALL_SIZE);
	this.forward(fd);
}

// Se necessario aggiunge il tab "NUOVO..."/"BENVENUTI"
// IMPORTANTE: le tablist devono essere gi… tracciate
Slideshow.prototype.checkAndApplyFeedbackTab = function(fd) {
	var ctype = null;
	var sl = this.core.tablist[window.sl_local.STAGES];
	var tl = this.core.tablist[window.sl_local.TYPES];
	if (!sl.isEmptyBefore()) { // Š una crociera
		if (fd.tabid[window.sl_local.STAGES] == sl.getItemId(0)) { // Š la prima tappa
			if (this.conf.hasInsertPrivilege) { // Š proprietario
				// Š vuota
				if (tl.isEmptyBefore()) {
					ctype = window.sl_local.CT_PLEASE_SELECT_STAGE_WELCOME;
				}
				// "nuovo..."
				else {
					ctype = window.sl_local.CT_PLEASE_SELECT_STAGE_NEW;
				}
			}
			else if (tl.isEmptyBefore()) { // non Š il proprietario e la prima tappa Š vuota
				//b "benvenuti"
				//"siamo spiacenti"
				ctype = window.sl_local.CT_CRUISE_IS_EMPTY_VISITOR;
			}
		}
		else { // Š una tappa successiva
			if (this.conf.hasInsertPrivilege) { // Š il proprietario
				ctype = window.sl_local.CT_NEW_TAB_CRUISE;
				//c "nuovo"
				//"inserisci foto, inserisci video"
			}
			else { // non Š il proprietario
				if (tl.isEmptyBefore()) { // solo se la tappa Š vuota
					//d "tappa vuota"
					//"siamo spiacenti, per questa tappa nessun contenuto"
					ctype = window.sl_local.CT_STAGE_IS_EMPTY;
				}
			}
		}	
	}
	else { // non Š una crociera
		// se ha poteri d'inserimento
		if (this.conf.hasInsertPrivilege) {	
			// non c'Š alcun contenuto
			if (tl.isEmptyBefore()) {
				//e "benvenuto"
				// "inserisci foto, inserisci video"
				ctype = window.sl_local.CT_WELCOME_NEW_TAB;
			}
			// c'Š del contenuto
			else {
				//f "nuovo.."
				// "inserisci foto, inserisci video"
				ctype = window.sl_local.CT_NEW_TAB_KINDLY;
			}
		}
		// non ha poteri d'inserimento
		else {
			// non c'Š alcun contenuto
			if (tl.isEmptyBefore()) {
				//g "benveuto"
				// "siamo spiacenti"
				ctype = window.sl_local.CT_SLIDE_IS_EMPTY;
			}
			// altrimenti
				// niente
		}
	}
	if (ctype != null && !tl.visible(ctype)) {
		var c = ContentResourceFactory(this, ctype, ctype, false, null, fd.layout);
		tl.insert(c.tabItem, ctype);
	}
}

// Prima di tutto, bisogna assicurarsi che riesca a creare per conto suo
// la form d'inserimento per contenuti assenti, in modo trasparente
// se da piccolo, imposto layout FULL, insert e l'ID/ctype richiesto
// se da grande, idem
Slideshow.prototype.openCrossInsertion = function(id, ctype, forceFullLayout) {
	if (this.core.fd.layout == SL_SMALL_SIZE) {
		if (forceFullLayout)
			this.openFullLayout('i', ctype);
		else
			throw new Error("impossibile aprire un tab d'inserimento nel layout piccolo");
	}
	else {
		var fd = new ForwardDescriptor(this.core.fd);
		fd.setInsertForm(true);
		var tl = this.core.tablist[window.sl_local.TYPES];
		var ref_id = id;
		if (id == sl.CTYPE_AUTHOR_PHOTO)
			ref_id = sl.CTYPE_USER_PHOTO;
		var cr = ContentResourceFactory(this, id, ctype, !tl.visible(id), ref_id, fd.layout);
		if (!tl.visible(cr.id))
			tl.insert(cr.tabItem, cr.id, true);
		fd.selectTab(tl.id, cr.id);
		fd.content = cr;
		this.forward(fd);
	}
}

function esitoVotazione( esito ) {
	//alert("slideshow.js callback: esitoVotazione("+esito+")");
	if (SLIDESHOW_DEMO && window.sl_local.is_Microsoft && esito == undefined)
		esito = 1;
	try {
		window.sl_local.current_voto.core.fd.content.flashInstanceRef.notifyEsitoVotazione( esito );
	}
	catch (err) {
	}
}

function esitoSalvaVideo( esito ) {
	if (SLIDESHOW_DEMO && window.sl_local.is_Microsoft && esito == undefined)
		esito = 1;
	try {
		window.top.sl_global.current.core.fd.content.flashInstanceRef.notifyEsitoSalvaVideo( esito );
		if (esito == 1)
			window.top.sl_global.current.parent.core.refreshCounters = true;
	}
	catch (err) {
	}
}

function esitoSalvaFoto( esito ) {
	if (SLIDESHOW_DEMO && window.sl_local.is_Microsoft && esito == undefined)
		esito = 1;
	try {
		window.top.sl_global.current.core.fd.content.flashInstanceRef.notifyEsitoSalvaFoto( esito );
		if (esito == 1)
			window.top.sl_global.current.parent.core.refreshCounters = true;
	}
	catch (err) {
	}
}

function esitoEliminaMMA( esito ) {
	if (SLIDESHOW_DEMO && window.sl_local.is_Microsoft && esito == undefined)
		esito = 1;
	try {
		window.top.sl_global.current.core.fd.content.flashInstanceRef.notifyEsitoElimina( esito );
		if (esito == 1)
			window.top.sl_global.current.parent.core.refreshCounters = true;
	}
	catch (err) {
	}
}

sl.execute = function( cmd, value ) {
	this.trace("this.execute( " + cmd + ", " + value + ")");
	var i = cmd.indexOf(":");
	if (i != -1) {
		var index = parseInt(cmd.substring( i+1 ));
		cmd = cmd.substring( 0, i );
		var i, s = window.top.sl_global.list[ index ];
		switch (cmd) {
		case this.EXC_ITEM_INFO: // info oggetto selezionato corrente
			var tl = s.core.tablist[this.TYPES];
			sl.trace(tl.items[tl.currentIndex].caption+" ID="+tl.items[tl.currentIndex].id+" s.core.fd.tabid[TYPES]="+s.core.fd.tabid[this.TYPES]);
			if (s.core.fd.tabid[this.TYPES] < 9000) {
				var buff = value.split('|');
				for (var i in buff)
					buff[i] = unescape( buff[i] );
				s.core.tablist[this.TYPES].setCurrentOrCount( parseInt(buff[0]) + 1 );
				s.updateCurrentItem(buff);
			}
			break;
		case this.EXC_INS_FOTO_SUCCESS:
			s.parent.core.refreshCounters = true;
		  break;
		case this.EXC_ITEM_INDEX: // sempre types
			if (s.core.fd.tabid[this.TYPES] < 9000)	
			 	s.core.tablist[this.TYPES].setCurrentOrCount( undefined, parseInt(value) );
			break;
		case this.EXC_DEFAULT_STAGE: // inviato sempre da cachedata
			s.core.tablist[this.STAGES].setDefault( value );
		 	break;
		case this.EXC_DEFAULT_TYPE:
		 	s.core.tablist[this.TYPES].setDefault(value);
			break;
		case this.EXC_TYPE_DATA:
			this.trace("EXC-TYPE-DATA " + value);
		 	var a = value.split("|");
		 	// il ctype, per ora, corrisponde ancora all'id
		 	s.core.tablist[this.TYPES].insert(a[0], a[0], a[2], unescape(a[1]), unescape(a[3]), unescape(a[4]), 'colors_' + this.getColorSchemeByCType(parseInt(a[0]))); //ok
			if (parseInt(a[2]) > 0) {
				sl.trace("ORDERED-ITEMS: " + s.core.tablist[this.TYPES].orderedItems.length );
			}
			break;
		case this.TYPES_ORDER: // sempre notificata dopo i types
			s.core.tablist[this.TYPES].updateOrder(s.core.forceTypesOrder || value.split(","));
		 	break;
		case this.EXC_END_OF_INITBLOCK:
			var fd = new ForwardDescriptor(s.core.fd);
			var arrows = 'blue';
			var canvas = s.conf.canvasBackgroundColor; 
			var tab = canvas; // lo sfondo della prima tab corrisponde al "canvas"
			//alert("result="+result);
		  if (s.refreshTabList( this.STAGES, canvas, tab, arrows )) {
				// seleziona la tappa
				var tl = s.core.tablist[this.STAGES];
				if (!tl.isEmpty()) {
					if (s.core.fd.tabid[this.STAGES] != -1 && tl.visible(s.core.fd.tabid[this.STAGES]))
						fd.selectTab(this.STAGES, s.core.fd.tabid[this.STAGES]);
					else
						fd.selectTab(this.STAGES, tl.getDefaultVisible());
				}
		  	canvas = tab;
				tab = '#ccc';
				arrows = 'yellow';
			}
			// seleziona la tipologia e crea il contenuto
			var cr = null;
			var t = null;
			var tlv = null;
			s.core.tt_canvas = canvas;
			s.core.tt_tab = tab;
			tl = s.core.tablist[this.TYPES];
			if (tl.isEmptyBefore())
				s.core.cruiseIsEmpty = true;
			//esegue il refresh delle tablist
			//s.refreshTabList( this.TYPES, canvas, tab, arrows );
			//se Š richiesta una form d'inseirmento (E tabid Š > 0 E il lyaout Š grande)
			var id = parseInt(fd.tabid[this.TYPES]); // cosŤ facendo, potenzialmente aggiunge tab inesistenti non d'inserimento
			if (id > 0 && fd.showInsertForm && fd.layout == SL_FULL_SIZE) {
				//la deve selezionare, se presente, oppure creare il rispettivo "inserisci"
				if (!tl.willBeVisible(id)) {
					cr = ContentResourceFactory(s, fd.tabid[this.TYPES], undefined, true, fd.tabid[this.TYPES], fd.layout); // auto-id, insIdReferer
					tl.insert(cr.tabItem, cr.id);
					id = cr.id;
				}
			}
			//aggiunge il tab per il feedback
			s.checkAndApplyFeedbackTab(fd);
			s.refreshTabList( this.TYPES, canvas, tab, arrows );
			//se Š presente l'id da selezionare lo seleziona, altrimenti seleziona il predefinito
			if (!tl.visible(id))
				id = parseInt(tl.getDefaultVisible());
			// crea il contenuto
			if (id <= 0) {
				throw new Error("errore interno, tablist completamente vuota, neppure un feedback per l'utente");
				alert("errore");
			}
			fd.selectTab(this.TYPES, id);
			if (cr == null)
				cr = ContentResourceFactory(s, id, id, false, null, fd.layout);
			fd.content = cr;
			s.forward(fd);
			break;
		case this.EXC_END_OF_STAGEBLOCK: // cambio di tappa
			var tl = s.core.tablist[this.TYPES];
			var fd = new ForwardDescriptor(s.core.fd);
			s.checkAndApplyFeedbackTab(fd);
			if (!s.refreshTabList( this.TYPES, s.core.tt_canvas, s.core.tt_tab, s.core.tt_arrows )) {
				// superfluo, adesso
				s.core.contentCanvasColor = s.core.tablist[this.STAGES].canvasColor;
			}
			//if (fd.tabid[this.STAGES] != s.core.tablist[this.STAGES].items[0].id)
			// se l'ID precedente non esiste mostra predefinito
			if (!tl.visible(fd.tabid[this.TYPES]))
				fd.selectTab(this.TYPES, tl.getDefaultVisible());
			t = tl.getItem(tl.getItemIndexById(fd.tabid[this.TYPES]));
			fd.content = ContentResourceFactory(s, t.id, t.ctype );
			s.forward(fd);
		 	break;
		case this.EXC_CROSS_INSERTION: // 'a' inserimento, altrimenti chiusura, poi segue 'v' (ins-video), 'fa' (ins-foto-author) 'fu' (ins-foto-user)
			if (!s.conf.hasInsertPrivilege)
				break;
			var tl = s.core.tablist[this.TYPES];
			var op = value.charAt(0);
			if (op == 'a') { // inserimento
				// fix bug animazione PhotoAuthorFull che manda cmq 'af' su "inserisci video..."
				if (value == 'af' && s.core.fd.tabid[this.TYPES] == window.sl_local.CT_AUTHOR_PHOTO && s.conf.hasAuthorPrivileges && s.core.fd.layout == SL_FULL_SIZE)
					value = 'av';
				// v/fa/fu/f
				var id = window.sl_local._SLIDESHOW(null, null, 'translate-old-typeid', value.substring(1));
				s.openCrossInsertion(id[0], id[1]); 
			}
			else { // chiusura
				var fd = new ForwardDescriptor(s.core.fd);
				fd.clearForms();
				value = value.substring(1).split(':'); // ID:OP
				var id = null;
				var t = tl.getItem(tl.getItemIndexById(value[0]));
				var close_subop = parseInt(value[1]);
				var referer = tl.getSelected().referer;
				tl.remove(t.tIndex);
				if (close_subop == 0) {
					// ritorno a un content precedente
					if (tl.visible(s.core.fd.content.insIdReferer))
						id = s.core.fd.content.insIdReferer;
					else
						id = tl.getDefaultVisible();
					t = tl.getItem(tl.getItemIndexById(id));
					fd.content = ContentResourceFactory(s, t.ctype, t.id, null, null, fd.layout);
				}
				else {
					// visualizzazione dell'oggetto appena inserito
					id = referer /* || tl.getDefaultVisible()*/;
					if (id == undefined)
						throw new Error("insIdReferer non impostato! Impossibile riselezionare la tipologia di contenuto di origine");
					if (!tl.exists(id))
						throw new Error("Il tabitem non conosce il referer, non posso selezionarlo");
					else if (!tl.visible(id))
						tl.activate(id);
					var t = tl.getItem(tl.getItemIndexById(id));
					if (t.count == 0) // forza l'apertura (unici casi)
						t.count = -1;
					fd.content = ContentResourceFactory(s, t.ctype, t.id, null, null, fd.layout);
				}
				fd.selectTab(this.TYPES, id);
				s.forward(fd);
			}
			break;
		case this.EXC_CONFIRM_DATA: // interazione con le procedure di dataentry di ITS
			window.top.sl_global.current = s;
			// 0, mmaid, title, date, tags, video, thumb
			var buff = value.split("|");
			for (var i in buff)
				buff[i] = unescape( buff[i] );
			if (buff[0].charAt(0) != 'i' && buff[1] != s.core.fd.mmaId.toString()) // modifica/elimina
				throw new Error("errore interno: mmaId inconsistente");
			if (buff[0] == 'mf') {
				salvaFoto( s.core.fd.mmaId, s.core.selectedContentId, s.core.selectedStageId, buff[2], this.lang, buff[4], s.core.selectedPlaceId, buff[3] ); 
			}
			else if (buff[0] == 'ef') {
				eliminaMMA( buff[1] ); 
			}
			else if (buff[0] == 'iv') { // inserimento, la tappa Š quella conosciuta
				salvaVideo( 0, s.conf.contentId, Math.max(s.core.fd.tabid[this.STAGES], 0), buff[2], this.lang, buff[4], buff[5], null, null, buff[3] );
			}
			else if (buff[0] == 'mv') {
				salvaVideo( s.core.fd.mmaId, s.core.selectedContentId, s.core.selectedStageId, buff[2], this.lang, buff[4], buff[5], null, s.core.selectedPlaceId, buff[3] );
			}
			else if (buff[0] == 'ev') {
				eliminaMMA( s.core.fd.mmaId ); 
			}
		  break;
		case this.EXC_VOTO:
			this.current_voto = s;
			vota( s.core.fd.mmaId, value ); // API 
			break;
		case this.EXC_TRACE:
		 	this.trace("<span style=\"color:red\">" + value +"</span>", 1);
		 	break;
		case this.EXC_WINDOW:
			this.openWindow(parseInt(value.charAt(0)), value.substring(1)); 
		 	break;
		case this.EXC_FULL_LAYOUT:
			s.openFullLayout(value);
		 	break;
		case this.EXC_SMALL_LAYOUT:
		 	s.closeFullLayout();
		 	break;
		default: 
		  // stages
		  if ((i = cmd.indexOf("s")) == 0) {
		  	var stage = parseInt(cmd.substring( 1 ));
				var a = value.split("|");
				s.core.tablist[this.STAGES].insert(this.CT_STAGE, a[0], -1, unescape(a[1]), null, null, 'colors_stages'); //ok
		  }
		}	
	}
	else {
		this.trace("ALERT: Unknown command '" + cmd + "' value'=" + value + "'");
	}
}

function SlideshowProxyCall( cmd ) { // cmd="cmd!]value"
	window.sl_local.trace("SlideshowProxyCall("+cmd+")");
	var i = cmd.indexOf(";]");
	if (cmd == window.sl_local.last_cmd && cmd.charAt(0) == '+') // fix
		return;
	window.sl_local.last_cmd = cmd;
	if (i == -1) {
		window.sl_local.execute( cmd, "" );
	}
	else {
		var value = cmd.substring( i+2 );
		cmd = cmd.substring( 0, i );
		window.sl_local.execute( cmd, value );
	}
}
























function TabItem(id, tIndex, oIndex, ctype, caption, current, count, ref, short_details, full_details, cssClassName, referer) {
	this.id = id;
	this.parent = null; // Impostato da draw()
	window.top.sl_global.tabitems[ this.uid = window.top.sl_global.tabitems.length ] = this;
	this.referer = 0;
	this.count = -1;
	this.ref = new Object();
	this.full_details = null;
	this.short_details = null;
	this.current = '...'; // oppure '1'
	this.ctype = null; // ContentResourceFactory
	this.caption = "Tab-" + this.uid;
	this.tIndex = -1;
	this.oIndex = -1;
	this.cssClassName = "sl_user"; // definita in slideshow.css
	this.update( tIndex, oIndex, ctype, caption, current, parseInt(count), ref, short_details, full_details, cssClassName, referer );
}

TabItem.prototype.update = function(tIndex, oIndex, ctype, caption, current, count, root, short_details, full_details, cssClassName, referer) {
	if (ctype == 0)
		throw new Error("TabItem: ctype non pu• essere zero");
	this.tIndex = isNaN(parseInt(tIndex)) ? this.tIndex : tIndex; 
	this.oIndex = isNaN(parseInt(oIndex)) ? this.oIndex : oIndex; 
 	this.referer = referer || this.referer;
 	this.ctype = ctype || this.ctype;
	this.caption = caption || this.caption;
	this.current = current || this.current;
	if (!isNaN(this.count = parseInt(count)))
		this.count = count;
	this.ref.root = root || this.ref.root;
	this.full_details = full_details || this.full_details;
	this.short_details = short_details || this.short_details;
	this.cssClassName = cssClassName || this.cssClassName;
}

// nota: crea l'elemento HTML e lo restituisce
// nota 2: perche' la linguetta dinamica richiede sia enableCaptionDetails che un count > 0
// imposta ref all'elemento creato.
TabItem.prototype.draw = function(parent, tagName, resourcePath, canvasColor) {
	if (parent != undefined) {
		if (this.parent == null)
			this.parent = parent;
		else if (this.parent != parent && update)
			throw new Error("TabItem.draw() Š specificato un parent che non corrisponde con quello che dovrebbe essere");
	}
	if (this.parent == null || parent == undefined)
		throw new Error("TabItem.draw() non Š assegnato a una TabList");
	if (this.id == null)
		throw new Error("TabItem.draw() non ha id");
	if (resourcePath == undefined)
		resourcePath = this.parent.resourcePath;
	if (canvasColor == undefined)
		canvasColor = this.parent.canvasColor;
	if (this.ref.root == null)
		this.ref.root = document.createElement(tagName || "div");
	this.ref.root.setAttribute("nobr", "true");
	this.ref.root.style.whiteSpace = "nowrap"; //("nobr", "true");
	//this.ref.root.height = "32px";
	var events = '';
	if (this.parent.enableShortTabs)
		events = 'onmouseover="window.sl_local.tabOverEvent('+this.uid+')" onmouseout="window.sl_local.tabOutEvent('+this.uid+')"';
	//(window.sl_local.is_Microsoft ? ' style="left:'+'0'+'px"' : '')
	this.ref.root.innerHTML =
		'<nobr><a href="javascript:window.sl_local._void()" style="display:block; height:32px; position:relative; text-decoration:none; border-bottom:none" onclick="window.sl_local.tabClick('+this.uid+')" '+events+'>'
		+	'<img class="sl_tabcrn_dx" src="' + resourcePath + 'corner-trans-up-dx-'+window.sl_local.colorCode(canvasColor)+'.gif" width="8" height="8"/>'
		+	'<img class="sl_tabcrn_sx" src="' + resourcePath + 'corner-trans-up-sx-'+window.sl_local.colorCode(canvasColor)+'.gif" width="8" height="8"/>'
		+	'&nbsp;&nbsp;<span class="sl_tabcaption">' + this.getCaption(false) + '</span><span class="sl_tabdetails"></span>&nbsp;&nbsp;'
		+	'</a></nobr>'; // nobr fixes msie layout bug
	var n = this.ref.root.getElementsByTagName("span");
	if (n.length != 2)
		throw new Error("errore interno dhtml/DOM");
	this.ref.captionPlace = n[0];
	this.ref.captionDetails = n[1];
	this.refreshCaptionDetails();	
	this.ref.root.className = this.cssClassName;
	return this.ref.root;
}

TabItem.prototype.getCaption = function(selected) {
	var c = this.caption;
	if (!selected && this.parent.enableShortTabs && this.parent.enableCaptionDetails && this.count > -1)
		c = '';
	c = window.sl_local.nobreak_text(c);
	//alert("'"+c+"'");
	return c;
}

TabItem.prototype.refreshCaptionDetails = function(full) {
	if (!this.ref.captionDetails)
		throw new Error("errore interno, elemento captionDetails non disponibile");
	if (!this.parent.enableCaptionDetails || this.count == -1)
		return;
	var details = this.full_details;
	if (!full && '' + this.short_details != '')
		details = this.short_details;
	this.ref.captionDetails.innerHTML = window.sl_local.nobreak_text(details)
		.replace( "$NUMBER$", "<span class='sl_current'>"+this.current+"</span>" )
		.replace( "$SIZE$", "<span class='sl_count'>"+this.count+"</span>" );
	var n = this.ref.captionDetails.getElementsByTagName("span");
	this.ref.currentPlace = null;
	this.ref.countPlace = null;
	for (var i in n)
		if (n[i].className == 'sl_current')
			this.ref.currentPlace = n[i];
		else if (n[i].className == 'sl_count')
			this.ref.countPlace = n[i];
}

TabItem.prototype.isDrawed = function() {
	return this.ref.root != null;
}

/**
 * TabList Š in grado di gestire un elenco di TabItem
 *
 */
function TabList(id, si) {
	this.id = id;
	this.slideshowIndex = si;
	this.rnd = Math.round(Math.random()*0xFFFFFFFF);
	this.ref = new Object();
	this.ref.canvas = null;
	this.ref.root = null;
	this.ref.currentItem = null;
	this.ref.currentCount = null;
	this.enableShortTabs = false;
	this.enableCaptionDetails = true;
	this.scroller = new TabListScroller(this);
	this.resourcePath = null;
	this.canvasColor = null;
	this.destroy();
}

TabList.prototype.destroy = function(message) {
	this.order = new Array();
	this.items = new Array();
	this.orderedItems = new Array();
	this.defaultId = null;
	this.dt_ev_over = 1;
	this.dt_ev_out = 2;
	this.tabVoiceOverDelay = 100;
	this.tabVoiceOutDelay = 1000;
	this.dtEventsCount = 0;
	this.dtEvents = new Array();
	this.dtv = new Array();
	this.clear(message);
}

// attento: NON pulisce items n‚ orderedItems n‚ order
// la tablist Š subito pronta per essere ridisegnata
// Usare altrimenti destroy()
TabList.prototype.clear = function(message) {
	this.currentIndex = -1; // Š tIndex!
	this.currentId = null;
	this.drawed = false; // perch‚ avevo dovuto toglierlo? cosa non tracciava pi—?
	if (this.scroller == window.sl_local.scroller)
		window.sl_local.stopScroll();
	//this.orderUpdated = false;
	if (this.ref.root instanceof Object)
		this.ref.root.innerHTML = message || "";
}

TabList.prototype.isEmpty = function() {
	return this.orderedItems.length == 0;
}

TabList.prototype.isEmptyBefore = function() {
	if (!this.isEmpty())
		return false;
	for (var i in this.items) {
		if (parseInt(this.items[i].count) > 0 || this.items[i].count == -1)
			return false;
	}
	return true;
}

// (alias) simulazione di inserimento per gli items 
// esistenti, ma non visibili
// activate(id [, count])
TabList.prototype.activate = function(id, count) {
	this.insert(id, count == undefined ? -1 : count);
}

// restituisce il tIndex.
// si pu• usare anche:
//   insert(TabItem, id [, update]) (*)
//   insert(existent-id, count) vedi activate()
// (*: il referer si pu• impostare solo con questo metodo) 
TabList.prototype.insert = function(ctype, id, count, caption, shortDetails, fullDetails, cssClassName, update) {
	var t = null;
	var n = false;
	referer = 0;
	if (ctype instanceof TabItem) { // insert(TabItem, id [, update])
		n = true;
		referer = arguments[0].referer;
		count = arguments[0].count;
		caption = arguments[0].caption;
		shortDetails = arguments[0].short_details;
		fullDetails = arguments[0].full_details;
		cssClassName = arguments[0].cssClassName;
		ctype = arguments[0].ctype; // lasciare per ultimo (arguments[] sembrano alias, non altri puntatori)
		update = arguments[2];
	}
	else if (arguments.length == 2) { // insert(existent-id, count)
		id = arguments[0];
		t = this.getItemIndexById(id);
		if (t == -1)
			throw new Error("TabList.insert(id='"+id+"', count='"+arguments[1]+"') l'item non esiste");
		if (this.visible(id))
			throw new Error("TabList.insert(id='"+id+"', count='"+arguments[1]+"') l'item Š gi… visibile, non puoi usare insert()");
		if (this.items[t].count > 0)
			throw new Error("TabList.insert(id='"+id+"', count='"+arguments[1]+"') l'item ha gi… un count maggiore di zero (errore interno: doveva essere sollevata eccezione per visible())");
		count = parseInt(arguments[1]);
		if (isNaN(count) || count == 0)
			throw new Error("TabList.insert(id='"+id+"', count='"+arguments[1]+"') count deve essere un valore numerico diverso da zero");
		this.items[t].count = count;
		this.items[t].referer = referer;
		this.items[t].activated = true; // fix per remove()
		update = false; // Š un inserimento in orderedItems senza 
	}
	if (t == null)
		t = this.getItemIndexById(id);
	if (arguments.length != 2 || n) {
		if (t != -1) {
			if (!update) {
				window.sl_local.trace('TabList.insert(): item ' + id + ' exists');
				throw new Error('TabList.insert(): item ' + id + ' exists');
			}
			else {
				// aggiornamento
				update = true;
				this.items[t].update(t, -1, ctype, caption.update("&apos;", "'"), 1, parseInt(count), undefined, undefined, undefined, cssClassName, referer);
				if (shortDetails != undefined)
					this.items[t].short_details = shortDetails;
				if (fullDetails != undefined)
					this.items[t].full_details = fullDetails;
			}
		}
		else {
			// inserimento (reale)
			update = false;
			t = this.items.length;
			caption = caption.replace("&apos;", "'");
			count = parseInt(count);
			shortDetails = (shortDetails != undefined) ? shortDetails : window.sl_local.txt[window.top.sl_global.lang].DEFAULT_SHORT_DETAILS;
			fullDetails = (fullDetails != undefined) ? fullDetails : window.sl_local.txt[window.top.sl_global.lang].DEFAULT_FULL_DETAILS;	
			this.items[t] = new TabItem(id, t, -1, ctype, caption, 1, count, undefined, shortDetails, fullDetails, cssClassName, referer);
		}
	} 
	if (this.drawed && this.items[t].count != 0) {
		if (!update) {
			this.orderedItems.push(this.items[t]);
			this.updateOrderedItems(); //sostituisce this.items[t].oIndex = this.orderedItems.length-1;	
		}
		var elem = this.drawItem(t);
		//if (elem == null ^ update)
		if ((elem != null && update) || (elem == null && !update))
			throw new Error("TabList.insert() lo stato di tracciamento del TabItem non Š sincronizzato con l'operazione richiesta");
	}
}

// cancella un tab. Se Š necessario, aggiorna currentIndex Se il tab 
// era visibile ricostruisce orderedItems e chiama draw(), ma non 
// riseleziona il currentId se Š visibile cambia l'ordine di tutti gli items. 
// se si toglie l'items selezionato reimposta currentId e currnetIndex a null/-1
// in questo caso deve essere il client a decidere una nuova selezione
// e chiama 
TabList.prototype.remove = function(tIndex) {
	if (!this.drawed)
		throw new Error("TabList.remove() non puoi usarlo PRIMA di draw()"); // prob. sarebbe possibile
	if (tIndex < 0 || tIndex > this.items.length-1 || isNaN(parseInt(tIndex)))
		throw new Error("error tIndex="+tIndex);
	var id = this.items[tIndex].id;
	if (!this.exists(id))
		return false;
	if (this.currentId == id) {
		this.currentId = null;
		this.currentIndex = -1;
	}
	// rimuove
	this.ref.root.removeChild(this.items[tIndex].ref.root);
	window.sl_local.array_remove(this.orderedItems, this.items[tIndex].oIndex);
	this.updateOrderedItems();
	if (this.items[tIndex].activated) {// TODO: impostare solo count=0 e controllare che slideshow.js consideri che tutti i tab possano gi… esistere, anche quelli "interni"
		this.items[tIndex].count = 0; // importante che activate() reimposti count a -1
		this.items[tIndex].activated = false;
	}
	else
		this.items[tIndex] = new TabItem(null, tIndex, -1, null, "deleted");
}

TabList.prototype.isDrawed = function() {
	return this.drawed;
}

// scrive la prima volta e/o aggiorna la tablist secondo
// l'ordine corrente. restituisce 'null' se ha solo aggiornato
// la lista (era gi… scritta) oppure l'elemento da aggiungere
// alla pagina. (oppure il client poteva confrontara con una
// esistente). NON AGGIORNA currentId e currnetIndex che adesso
// sono indipendenti dall'orderedList (se prima l'elemento html
// veniva referenziato chiamando l'ID html, ora l'istanza DOM
// resta in vita nell'oggetto TabItem)
// Quando TabList chiama TabItem.draw() deve gi… conoscere slideshowIndex
TabList.prototype.draw = function(canvas, width, resourcePath, arrow_color, canvasColor) {
	// quindi attento: Š normale che draw() non sappia tracciare items aggiunti
	// dopo la prima chiamata. Se ci si prova, restituisce errore.
	//sl.trace(1001 + " this.ref.root=" + this.ref.root);
	if (this.ref.root == null) {
		//sl.trace(10);
		this.canvasColor = canvasColor;
		this.resourcePath = resourcePath;
		//sl.trace(11);
		if (arrow_color == undefined) // freccia blue predefinita
			arrow_color = "blue";
		/*
		<table class="sl_tablist_canvas" border="0" cellspacing="0" cellpadding="0">
			<tr> a
				<td b class="sl_tabarrow_sx"><img onmouseover="s.stagesScroller.startToLeft(s.getTypesPanelContentWidth())" onmouseout="sl_stop_scroll()" src="./slideshow_resources/sl_blue_corner_sx.gif" height="12" width="9" border="0"/></td>
				<td> b
					<div c class="sl_mask">
					[<div class="tl_tablist_div">]
						<table a class="sl_tablist" border="0" cellspacing="0" cellpadding="0"> <!-- fornire width precisa in px! oppure usare due table annidate -->
							<tr>
								items...
		*/
		
		/*
		var a, b;
		this.ref.canvas = document.createElement("table"); // tl_tablist_canvas
		this.ref.canvas.setAttribute("cellpadding", "0");
		this.ref.canvas.setAttribute("cellspacing", "0");
		this.ref.canvas.className = "sl_tablist_canvas";
		this.ref.canvas.style.width = width + "px";
		this.ref.canvas.appendChild(a = document.createElement("tr"));
		a.appendChild(b = document.createElement("td")); // tl_tabarrow_sx
		b.className = "sl_tabarrow_sx";
		b.innerHTML = '<img onmouseover="window.sl_local.scrollLeft('+this.slideshowIndex+',\''+this.id+'\')" onmouseout="window.sl_local.stopScroll()" src="'+resourcePath+'sl_'+window.sl_local.colorCode(arrow_color)+'_corner_sx.gif" height="12" width="7" border="0"/>';
		a.appendChild(b = document.createElement("td")); // td > tl_mask
		b.appendChild(this.ref.mask = document.createElement("div")); // tl_mask
		this.ref.mask.className = "sl_mask";
		this.ref.mask.style.width = (width - 24) + "px";
		a.appendChild(b = document.createElement("td")); // tl_tabarrow_dx
		b.className = "sl_tabarrow_dx";
		b.innerHTML = '<img onmouseover="window.sl_local.scrollRight('+this.slideshowIndex+',\''+this.id+'\')" onmouseout="window.sl_local.stopScroll()" src="'+resourcePath+'sl_'+window.sl_local.colorCode(arrow_color)+'_corner_dx.gif" height="12" width="7" border="0"/>';
		
		a = document.createElement("table"); // tl_tablist
		a.className = "sl_tablist";
		a.style.position = "absolute";
		a.setAttribute("cellpadding", "0");
		a.setAttribute("cellspacing", "0");
		this.ref.root = document.createElement("tr"); // root
		a.appendChild(this.ref.root);
	
		this.ref.list = a;
		this.ref.mask.appendChild(this.ref.list);
		*/
		
		//sl.trace(10);
		var canvasId = this.rnd + "Canvas";
		var maskId = this.rnd + "Mask";
		var listId = this.rnd + "List";
		var rootItemsId = this.rnd + "Items";

		// subito montato nel documento
		//sl.trace(13);
		canvas.innerHTML =
			'<table border="0" id="'+canvasId+'" class="sl_tablist_canvas" style="width:'+width+'px;" cellspacing="0" cellpadding="0">' // this.ref.canvas
			+	'<tr>'
			+		'<td class="sl_tabarrow_sx"><img onmouseover="window.sl_local.scrollLeft('+this.slideshowIndex+',\''+this.id+'\')" onmouseout="window.sl_local.stopScroll()" src="'+resourcePath+'sl_'+window.sl_local.colorCode(arrow_color)+'_corner_sx.gif" height="12" width="9" style="'+window.sl_local.msiefix3+'" border="0"/></td>'
			+		'<td>'
			+			'<div id="'+maskId+'" class="sl_mask" style="; '+window.sl_local.msie6fix1+'width:'+(width-24)+'px">' // this.ref.mask
			+				'<table id="'+listId+'" class="sl_tablist" style="position:absolute;" border="0" cellspacing="0" cellpadding="0">' //this.ref.list
			+					'<tr id="'+rootItemsId+'">' // this.ref.root
			+					'</tr>'
			+				'</table>'
			+			'</div>'
			+		'</td>'
			+		'<td class="sl_tabarrow_dx"><img onmouseover="window.sl_local.scrollRight('+this.slideshowIndex+',\''+this.id+'\')" onmouseout="window.sl_local.stopScroll()" src="'+resourcePath+'sl_'+window.sl_local.colorCode(arrow_color)+'_corner_dx.gif" height="12" width="9" style="'+window.sl_local.msiefix3+'" border="0"/></td>'
			+	'</tr>'
			+ '</table>';
		
		//sl.trace(14);
		this.ref.canvas = document.getElementById(canvasId);
		this.ref.mask = document.getElementById(maskId);
		this.ref.list = document.getElementById(listId);
		this.ref.root = document.getElementById(rootItemsId);
		
		/*
		<table id="sl-tl-TabListCanvas" cellpadding="0" cellspacing="0" class="tl_tablist_canvas" style="width:Npx">
			<tr>
				<td><img onmouseover="window.sl_local.scrollLeft('+this.slideshowIndex+',\''+this.id+'\')" onmouseout="window.sl_local.stopScroll()" src="'+resourcePath+'sl_'+window.sl_local.colorCode(arrow_color)+'_corner_sx.gif" height="12" width="7" border="0"/></td>
				<td><div class="sl_mask">
					<table class="sl_tablist" cellspacing="0" cellpadding="0" style="position:aboslute">
					<tr id="TabItemsRoot">
					</tr>
					</table>
				</div></td>
				<td><img onmouseover="window.sl_local.scrollRight('+this.slideshowIndex+',\''+this.id+'\')" onmouseout="window.sl_local.stopScroll()" src="'+resourcePath+'sl_'+window.sl_local.colorCode(arrow_color)+'_corner_dx.gif" height="12" width="7" border="0"/></td>
			</tr>
		</table>
		
		prob. explorer, finch‚ non fa parte della pagina, non restituisce risultati consistenti.
		*/
	}
	// elimina il messaggio d'attesa
	else if (!this.drawed) {
		//sl.trace(15);
		//alert(this.ref.root.nodeType + " inner=" + this.ref.root.childNodes.length);
		//this.ref.root.innerHTML = "TEST";
		while (this.ref.root.firstChild) {
			//sl.trace("---");
			this.ref.root.removeChild(this.ref.root.firstChild);
		}
	}
	//sl.trace(15.1);
	if (this.orderedItems.length == 0) {
		//sl.trace(16);
		this.buildOrderedItems(); // questa deve essere l'unica chiamata a orderedItems!
		// quindi ripr. throw drawed
	}
	for (var o in this.orderedItems) {
		//sl.trace(17);
		if (this.drawItem(this.orderedItems[o].tIndex) == null)
			throw new Error("TabList.draw() un item risulta gi… tracciato! Lo hai tracciato, oppure hai chiamato draw() due volte. Usare TabList.isDrawed()"); 
	}
	var d = this.drawed;
	//sl.trace(18);
	this.drawed = true;
	//sl.trace(19);
	return (!d) ? this.ref.canvas : null;
}

// traccia l'item. Se era gi… tracciato lo aggiorna altrimenti lo aggiunge con appendChild
// nel primo caso restituisce null, nel secondo il nuovo elemento. Accetta tIndex, quindi
// un item non ancora tracciato deve essere manualmente aggiunto a orderedItems (se ancora
// ha senso aggiungerli lŤ...) [in effetti orderedItems puoi deprecarlo del tutto e
// "incorporarlo" in draw()]
// vuole poter tracciare items non ancora tracciati, quindi che ancora non fanno parte di
// orderedItems
TabList.prototype.drawItem = function(tIndex, rp, canvasColor) {
	if (this.items[tIndex].isDrawed()) {
		this.items[tIndex].draw(this, "td", rp, canvasColor); // il this non ha resource/canvas!?
		return null;
	}
	// ogni voce dovrebbe ricordarsi degli empty e rimuoverli su remove()
	/*var empty_td = document.createElement("td");
	empty_td.style.width = "10px";
	empty_td.innerHTML = '<img src="'+rp+'blank.gif" width="10" height="1"/>";
	this.ref.root.appendChild( empty_td );*/
	this.ref.root.appendChild( this.items[tIndex].draw(this, "td", rp, canvasColor) );
	return this.items[tIndex].ref.root;
}

TabList.prototype.getDefaultVisible = function() {
	//if (!this.orderUpdated)
	//	throw new Error("TabList.getDefaultVisible() ordine non aggiornato");
	if (this.orderedItems.length == 0)
		throw new Error("TabList.getDefaultVisible() ordine inesistente");
	try {
		return this.orderedItems[0].id;
	}
	catch (err) {
		return null;
	}
}

TabList.prototype.updateOrder = function(order_ids) {
	if (this.drawed) {
		window.sl_local.trace('ERRORE INTERNO slideshow: buildorderedItems() drawed=true');
		throw new Error('TabList.updateOrder() drawed=true');
	}
	//this.orderUpdated = false;
	this.order = new Array( order_ids.length );
	for (var i in order_ids)
		// deve rintracciare qual'č il type-id
		// se non esiste, lascia undefined
		// (l'order č letto una volta sola)
		for (var t in this.items)
			try {
				if (this.items[t].id == order_ids[i]) {
					this.order[i] = t;
					break;
				}
			}
			catch (e) {
				window.sl_local.trace("'o': errore sconosciuto [length="+this.items.length+" i="+t+"]");
				break;
			}
}

// si pu• usare solo PRIMA di draw() e/o dopo un destroy()
// Se si fornisce typeIdToTrack ne restituisce l'indice, altrimenti -1
// NON INFLUISCE SU currentId/currentIndex
TabList.prototype.buildOrderedItems = function(IdToTrack) { // non deve essere permesso force!
	if (this.drawed) {
		window.sl_local.trace('ERRORE INTERNO slideshow: buildorderedItems() drawed=true');
		throw new Error('slideshow: buildorderedItems() drawed=true');
	}
	// TODO: deprecare orderUpdated come detto e gestire nuovo blocco qui
	var x = -1, t, lp = 0, last, tmp = new Array();
	this.orderedItems = new Array();
	for (var o=0; o<this.order.length; o++)
		if ((t = this.order[o]) != undefined && (this.items[t].optional || this.items[t].count != 0)) {
			if (IdToTrack && IdToTrack == this.items[t].id)
				 x = lp;
			this.orderedItems[ lp ] = this.items[t];
			this.items[t].oIndex = lp;
			lp++;
			tmp[t] = 1;
		}
	for (var t=0; t<this.items.length; t++)
		if (tmp[t] != 1 && (this.items[t].optional || this.items[t].count != 0)) {
			if (IdToTrack && IdToTrack == this.items[t].id)
				 x = lp;
			this.orderedItems[ lp ] = this.items[t];
			this.items[t].oIndex = lp;
			lp++;
		}
	//this.orderUpdated = true;
	return x;
}

// non riordina affatto n‚ modifica orderedItems (l'operazione di ordinameneto 
// ha effetto con buildOrderedItems soltanto) ma aggiorna oIndex dei TabItems. 
// Ignora incongruenze tra orderedItems e items (per cui non da errore se orderedItems
// contempla items con count=0 e/o viceversa items assenti con count!=0)
// Una operazione di inserimento successiva al primo draw().
// (ma ignora quando items[n] ha ID pari a null, lo considera come rimosso)
// Dato che non modifica niente, pu• essere usato per debug.
// che succede con una rimozione precedente il draw() ? deve dare eccezione! La logica di
// TabList non Š in grado di gestirla
TabList.prototype.updateOrderedItems = function() {
	for (var o in this.orderedItems) {
		if (this.orderedItems[o].id != null)
			if (this.orderedItems[o].uid != this.items[this.orderedItems[o].tIndex].uid)
				throw new Error("Errore di inconsistenza orderedItems/items oIndex " + o);
			else
				this.orderedItems[o].oIndex = o;
	}
}

// restituisce '-1' sono lo sono tutti, altrimenti la quantit… riscontrata
TabList.prototype.exists = function( itemId ) {
	var c = 0;
	if (!(itemId instanceof Array)) {
		var t = itemId;
		(itemId = (new Array())).push(t);
	}
	for (var i in this.items)
		for (var t in itemId)
			try {
				if (this.items[i].id == itemId[t])
					c++;
				if (c == itemId.length)
					return -1;
			}
			catch (err) {
				window.sl_local.trace("tabExists("+itemId+"): errore sconosciuto t="+t+" i="+i);
				break;
			}
	return c;
}

// restituisce '-1' sono lo sono tutti, altrimenti la quantit… riscontrata
TabList.prototype.visible = function( itemId ) {
	var c = 0;
	if (!(itemId instanceof Array)) {
		var t = itemId;
		(itemId = (new Array())).push(t);
	}
	for (var i in this.orderedItems)
		for (var t in itemId)
			try {
				if (this.orderedItems[i].id == itemId[t])
					c++;
				if (c == itemId.length)
					return -1;
			}
			catch (err) {
				window.sl_local.trace("tabExists("+itemId+"): errore sconosciuto t="+t+" i="+i);
				break;
			}
	return c;
}

// come visible(), ma utilizabile prima di draw(), utile tra un destroy() e un draw()
TabList.prototype.willBeVisible = function( itemId ) {
	var c = 0;
	if (!(itemId instanceof Array)) {
		var t = itemId;
		(itemId = (new Array())).push(t);
	}
	for (var i in this.items)
		for (var t in itemId)
			try {
				if (this.items[i].id == itemId[t] && !isNaN(parseInt(this.items[i].count)) && this.items[i].count != 0)
					c++;
				if (c == itemId.length)
					return -1;
			}
			catch (err) {
				window.sl_local.trace("tabExists("+itemId+"): errore sconosciuto t="+t+" i="+i);
				break;
			}
	return c;
}


TabList.prototype.getItemIdByOrderedIndex = function( oIndex ) {
	try {
		return this.orderedItems[ oIndex ].id;
	}
	catch (e) {
		return 0;
	}
}

TabList.prototype.getItem = function( tIndex ) {
	try {
		return this.items[ tIndex ];
	}
	catch (e) {
		return null;
	}
}

TabList.prototype.getItemId = function( tIndex ) {
	try {
		return this.items[ tIndex ].id;
	}
	catch (e) {
		return null;
	}
}

TabList.prototype.getOrderedItemIndex = function( itemId ) {
	for (var t in this.orderedItems)
		try {
			if (this.orderedItems[t].id.toString() == itemId.toString())
				return t;
		}
		catch (e) {
			window.sl_local.trace("getOrderedItemIndex("+itemId+"): errore sconosciuto [length="+this.orderedItems.length+" i="+t+"]");
			break;
		}
	return -1
}

TabList.prototype.getItemIndexById = function( itemId ) {
	for (var t in this.items)
		try {
			if (this.items[t].id != null && this.items[t].id.toString() == itemId.toString())
				return t;
		}
		catch (e) {
			window.sl_local.trace("getItemIndexById("+itemId+"): errore sconosciuto [length="+this.items.length+" i="+t+"]");
		}
	return -1
}

TabList.prototype.setCurrentOrCount = function( newCurrentItem, customTotCount ) {
	var o = this.items[this.currentIndex].oIndex;
	if (newCurrentItem != undefined)
		this.orderedItems[o].current = parseInt(newCurrentItem) || this.orderedItems[o].current;
	if (customTotCount != undefined)
		this.orderedItems[o].count = parseInt(customTotCount) || this.orderedItems[o].count;
	try {
			if (this.orderedItems[o].ref.currentPlace)
				this.orderedItems[o].ref.currentPlace.innerHTML = this.orderedItems[o].current;
			if (this.orderedItems[o].ref.countPlace)
				this.orderedItems[o].ref.countPlace.innerHTML = this.orderedItems[o].count;
	}
	catch (err) {
	}
}

// restituisce true se il tab Š visibile, altrimenti false
// quindi restituisce true anche se il tab Š gi… quello 
// selezionato. e quindi inoltre FALLISCE la selezione
// se restituisce false, solo una linguetta visibile pu•
// essere selezionata
// evidenzia il tab se non lo Š
TabList.prototype.select = function(id, selected) {
	if (this.visible(id)) {
		if (this.currentIndex != -1)
			try {
				this.items[this.currentIndex].ref.root.className = this.items[this.currentIndex].cssClassName;
				this.items[this.currentIndex].refreshCaptionDetails();
			}
			catch (err) {
			}
		var t = this.getItemIndexById(id);
		try {
			if ("" + this.items[t].cssClassName != '')
				this.items[t].ref.root.className = this.items[t].cssClassName + "_selected";
			if (this.enableShortTabs)
				this.items[t].ref.captionPlace.innerHTML = this.items[t].getCaption(true);
			this.items[t].refreshCaptionDetails(true);
			this.scroller.fixElementAsVisible(t);
		}
		catch (err) {
		}
		this.currentIndex = t;
		this.currentId = id;
		return true;
	}
	else {
		return false;
	}
}

// se nessun tab risulta selezionato solleva eccezione
TabList.prototype.getSelected = function() {
	if (this.currentIndex == -1)
		throw new Error("TabList.getSelected() nessun tab Š stato ancora selezionato");
	return this.items[this.currentIndex];
}

//--------------------------------------------

TabList.prototype.eventDriver = function(ev_id) {
	// se nel frattempo č nato un nuovo intercettore interrompe 
	// e lascia ad esso il suo stesso evento e/o quelli che gli
	// resterebbero
	while (ev_id == this.dtEventsCount && this.dtEvents.length > 0) {
		try {
			var e = this.dtEvents.shift();
			this.dtv[e.itemIndex] = new Array();
			this.dtv[e.itemIndex][0] = e.type;
			this.dtv[e.itemIndex][1] = e.itemIndex;
		}
		catch (err) {
			return false;
		}
		if (e.type == this.dt_ev_over) {
			this.tabItemOver(e);
		}
		else if (e.type == this.dt_ev_out) {
			this.tabItemOut(e);
		}
		else
			throw new("errore interno evento " + e.type + " sconosciuto");
	}
	// fix
	if (ev_id == this.dtEventsCount && e.type == this.dt_ev_out) { 
		for (i=0; i<this.dtv.length; i++)
			if (typeof(this.dtv[i]) == "array" && this.dtv[i][0] == this.dt_ev_over)
				this.pushEvent( this.dt_ev_out, i, 0 );
		if (window.sl_local.scrollInterval == 0 || (window.sl_local.scroller != undefined && window.sl_local.scroller != this.scroller))
			this.scroller.fixElementAsVisible(this.currentIndex);
	}
	return true;
}

TabList.prototype.pushEvent = function( type, itemIndex, delay ) {
	this.dtEventsCount++;
	var e = new Object();
	e.time = (new Date()).getTime();
	e.type = type;
	e.itemIndex = itemIndex;
	e.id = this.dtEventsCount;
	this.dtEvents.push( e );
	setTimeout( "try{window.top.sl_global.list["+this.slideshowIndex+"].core.tablist['"+this.id+"'].eventDriver("+this.dtEventsCount+")}catch(e){alert('errore ' + e);}", (delay != undefined ? delay : 250) );
}

TabList.prototype.tabOverEvent = function(tIndex, delay) { // slideshowIndex, tabItem.uid
	if (tIndex != this.currentIndex) {
		this.pushEvent( this.dt_ev_over, tIndex, (delay == undefined ? this.tabVoiceOverDelay : delay) );
	}
}

TabList.prototype.tabOutEvent = function(tIndex, delay) { // idem
	if (tIndex != this.currentIndex) {
		if (window.sl_local.scrollInterval == 0 || window.sl_local.scroller != this)
		this.pushEvent( this.dt_ev_out, tIndex, (delay == undefined ? this.tabVoiceOutDelay : delay));
	}
}

TabList.prototype.tabItemOver = function( e ) {
	if (this.enableShortTabs)
		this.items[e.itemIndex].ref.captionPlace.innerHTML = this.items[e.itemIndex].getCaption(true);
	this.scroller.fixElementAsVisible(e.itemIndex);
}

TabList.prototype.tabItemOut = function( e ) {
	if (this.enableShortTabs)
		this.items[e.itemIndex].ref.captionPlace.innerHTML = this.items[e.itemIndex].getCaption(false);
}

//--------------------------------------------

function TabListScroller( tablist ) {
	this.tablist = tablist;
	this.ref = tablist.ref;
	this.position = 0;
	this.step = 0; // in realtŕ, step e amount qui sono un errore, vanno a scope globale
	this.amount = 0;
}

TabListScroller.prototype.pos = function(new_pos) {
	if (!isNaN(parseInt(new_pos)))
		this.ref.list.style.left = (this.position = new_pos) + "px";
	return this.position;
}

// non ha pi— senso perch‚ le frecce sono esterne all'offset
TabListScroller.prototype.offset = function() {
	return Math.min(0, this.visibleWidth() - this.contentWidth());
}

TabListScroller.prototype.contentWidth = function() {
	return this.ref.list.offsetWidth || 0;
}

TabListScroller.prototype.visibleWidth = function() {
	return this.ref.mask.offsetWidth || 0;
}

// tipicamente si usa su un elemento che si Š appena espanso
TabListScroller.prototype.fixElementAsVisible = function( tIndex ) {
	var d, x = this.tablist.items[tIndex].ref.root.offsetLeft, 
			w = this.tablist.items[tIndex].ref.root.offsetWidth;
	if (this.contentWidth() < this.visibleWidth() && this.pos() < 0)
		this.pos(0);
	else if ((d = (x + w) - (Math.abs(this.pos()) + this.visibleWidth())) > 0) {
		this.pos(this.pos() - d);
		if (Math.abs(this.pos()) > x) {
			this.pos(this.pos() - x);
			//if (this.items[tIndex].oIndex < this.orderedItems.length)
			//	this.pos(this.pos() - 30);
		}
	}
	/*else if (x + this.pos() < 0) // p Š negativo, quando x + p < 0 la sua parte sx Š nascosta
		this.pos(x);
	if (this.pos() > 0)
		this.pos(0);*/
	else if (x + this.pos() < 0) // p Š negativo, quando x + p < 0 la sua parte sx Š nascosta
		this.pos(-x + 30);
	if (this.pos() > 0)
		this.pos(0);
	return false;
}

TabListScroller.prototype.exists = function() {
	return this.ref.list != null;
}

TabListScroller.prototype.startToRight = function() {
	this.step = 0;
	this.amount = 5;
	window.sl_local.scroller = this;
	window.sl_local.scrollInterval = setInterval( "window.sl_local.executeScrollRight()", window.sl_local.stages_scroll_mms );
	//sl.trace("window.sl_local.scroller=" + window.sl_local.scroller );
	return false;
}

TabListScroller.prototype.startToLeft = function() {
	this.step = 0;
	this.amount = 5;
	window.sl_local.scroller = this;
	window.sl_local.scrollInterval = setInterval( "window.sl_local.executeScrollLeft()", window.sl_local.stages_scroll_mms );
	//sl.trace("window.sl_local.scroller=" + window.sl_local.scroller );
	return false;
}




