/**
 * CNM Presentation Library
 * This file holds the procedures to build interface elements.
 * @author Cirici New Media
 */
CNMInterface = function(){ this.initialize() };
CNMInterface.prototype = {
	
	// Initialize the Interface Agent
	initialize: function() {
		// The height of the List of CommentRows
		this.CommentRowsHeight;
		
		// Selected item in the UCList
		this.selectedUCListItem;
	},
	
	// Things that need to be done, in order to initialize the interface
	initializeInterfaceAgent: function(){
		// When the page is done loading, we execute the onPageLoaded() method
		// of the InterfaceAgent instance. We bind the InterfaceAgent.onPageLoaded as an event listener,
		// so that the onPageLoaded() method keeps binding with this class!
		Event.observe(window,'load',this.onPageLoaded.bindAsEventListener(this));
		
		// Whenever the window/viewport is resized, we execute the onResizedViewport() method
		// of the InterfaceAgent instance. We bind the InterfaceAgent.onResizedViewport as an event listener,
		// so that the onResizedViewport() method keeps binding with this class!
		Event.observe(window,'resize',this.onResizedViewport.bindAsEventListener(this));
		
		// IE6-Specific PNG Alpha Transparency Rendering Fix
		// We don't want to put these properties directly in our stylesheet, So we add a CSS Rule with JS.
		// This little script assumes that you have at least one stylesheet included already.
		if( Prototype.Browser.IE && navigator.appVersion.indexOf('MSIE 6')!=-1 ) {
			if(document.all && document.styleSheets && document.styleSheets[0] && document.styleSheets[0].addRule) {
				// PNG Alpha Transparency Fix
				//document.styleSheets[0].addRule('*', 'behavior: url(css/iepngfix.htc)');
				
				// make an exception for the postit window
				//document.styleSheets[0].addRule('.postit_window', 'behavior: none');
				document.styleSheets[0].addRule('.postit_window', 'background: url(../img/postit_window_ie6.gif) no-repeat top left;');
				document.styleSheets[0].addRule('.postit_salmo', 'background: url(../img/postit_window_ie6_salmo.gif) no-repeat top left;');
				document.styleSheets[0].addRule('h1', 'behavior: url(css/iepngfix.htc)');
				document.styleSheets[0].addRule('.window_mail', 'behavior: url(css/iepngfix.htc)');
				document.styleSheets[0].addRule('.window_phone', 'behavior: url(css/iepngfix.htc)');
				document.styleSheets[0].addRule('.window_loginfail', 'behavior: url(css/iepngfix.htc)');
				document.styleSheets[0].addRule('.window_anonymous_id', 'behavior: url(css/iepngfix.htc)');
				document.styleSheets[0].addRule('.webcam', 'behavior: url(css/iepngfix.htc)');
			}
		}
	},
	
	// Executed when the page is done loading
	onPageLoaded: function() {
		//We need to do this before start creating components, because if we waits
		//for pageLoaded, maybe we destroy the commentsContainer before we backup them
		//this.CommentsContainerBackup = $('CommentsContainer').innerHTML;
	},
	
	/**
	 * Executed whenever the window/viewport is resized:
	 * 
	 * This function is called whenever the viewport has been (or is being) resized.
	 * It is needed to keep some (dynamically created) elements in place.
	 */
	onResizedViewport: function(e) {
		// Release the viewport dimensions in d.width and d.height
		var d = document.viewport.getDimensions();
		
		// Maintain the position of the scroll buttons, in the UC List!
		// To do so, we check if scroll buttons are showing:
		var su = $('scrollU');
		var sd = $('scrollD');
		
		// if so,
		if(su && sd) {
			// Get the absolute X-Y-position of the UC List
			var os = Position.cumulativeOffset($$('.uclist ul')[0]);
			
			// apply the X-position of the UC List to the Scroll Buttons
			su.style.left = os[0]+'px';
			sd.style.left = os[0]+'px';
		}
		// Position the Mosca Window Layer
		this.moscaPositionLayer();		
	},
	
	// Launch the Help Viewer of the Flash Live Radio Player/Jugon
	launchLiveRadioPlayerHelp: function() {
		//alert('Live Radio Player Help Viewer');
		var HelpUrlPage = "http://www.catradio.cat/comescoltarnos/faq.htm";
		window.open(HelpUrlPage);		
	},

	/**
	 * doFadeOutIn
	 */
	doFadeOutIn: function(divId, innerHtml) {
		var vDiv = $(divId);

		// 1: Fade OUT the current Live Title
		var efx1 = new Effect.Fade(vDiv,{ 
			to:0, 
			duration: 0.3,
			afterFinish: function(){
				// 2: Fade IN the current Live Title
				vDiv.innerHTML = innerHtml;
				var efx2 = new Effect.Appear(vDiv,{duration:1});
			}
		});
	},
	
	/**
	 * Make live bar glowing, or set back to normal live bar
	 * 
	 * Optionally, you can remove or change the image in the live bar:
	 * - to remove, provide an empty thumb string
	 * - to leave unaffected, do not provide thumb at all
	 * - to change, provide thumb string
	 * 
	 * @param boolean b
	 * 		TRUE to glow, FALSE for normal live bar
	 * @param string thumb
	 * 		The thumb image (source)
	 */
	glowLiveBar: function(b, thumb) {
		if(b) {
			$('livebar').removeClassName(currentTheme+'livebar');
			$('livebar').addClassName(currentTheme+'livebar_glowing');
		} else {
			$('livebar').removeClassName(currentTheme+'livebar_glowing');
			$('livebar').addClassName(currentTheme+'livebar');
		}
		
		if( typeof thumb != 'undefined' ) {
			var elm = $('livebarTitleThumb');
			if(elm) {
				elm.remove();
			}
			
			if(thumb != '') {
				var img = new Element('img', { 
					src: thumb, 
					id: 'livebarTitleThumb',
					'class': 'livethumb'
				});
				
				$('livebar').insert({ top : img });
			}
		}
		
	},	 

	/**
	 * Disable Live Interface
	 * 
	 * This method is called to replace the UC part of the interface, when
	 * no live programme is broadcasting.
	 * 
	 * @param string title
	 * 		The title to be shown as alternative
	 * @param Array thumbs
	 * 		The thumb navigation to be mounted. Each element in this array
	 * 		is in turn another array, that contains values for the following
	 * 		keys: source, title, description
	 * @param string thumbs_intro
	 * 		Introduction text to thumbnails
	 * @param string thumbs_outro
	 * 		Postfix text to thumbnails
	 */
	disableLiveInterface: function(title, thumbs, thumbs_intro, thumbs_outro) {
		var DIV = $('ucarea');
		if(DIV) {
			var t, d;
			var e = new Array();
			
			var op = '';
			op += '<div class="nolive">';
			op +=    '<div class="nolive_content">';
			op +=       '<h3>';
			op +=          title;
			op +=       '</h3>';
			
			if(thumbs.length > 0) {
				op += '<div class="nolive_thumbs">';
				
				if(typeof thumbs_intro != 'undefined' && thumbs_intro != '') {
					op += '<div class="nolive_thumbs_intro" id="nolive_thumbs_intro">' + thumbs_intro + '</div>';
				}
				
				op +=    '<ul>';
				for(var i = 0; i < thumbs.length; i ++) {
					op += '<li class="nopointer">';
					op +=    '<a href="javascript:void(0);" onmouseover="InterfaceAgent.appendTooltip(\'nolive_thumb_'+ i +'\', \''+ this.escapeString(thumbs[i]['title']) +'\', \''+ this.escapeString(thumbs[i]['description']) +'\')" onmouseout="InterfaceAgent.removeTooltip()">';
					op +=       '<img src="'+ thumbs[i]['source'] +'" alt="" id="nolive_thumb_'+ i +'" />';
					op +=    '</a>';
					op += '</li>';
					
					e[i] = 'nolive_thumb_' + i;
				}
				op +=    '</ul>';
				
				if(typeof thumbs_outro != 'undefined' && thumbs_outro != '') {
					op += '<div class="nolive_thumbs_outro" id="nolive_thumbs_outro">' + thumbs_outro + '</div>';
				}
				
				op += '</div>';
			}
			
			op +=    '</div>';
			op += '</div>';
			
			DIV.innerHTML = op;
			
			for(var i = 0; i < thumbs.length; i ++) {
				Element.extend(e[i]);
			}
			
			Element.extend('nolive_thumbs_intro');
			Element.extend('nolive_thumbs_outro');
		}
	},
	
	/**
	 * Restore Live Interface
	 * 
	 * This function is called to restore the live interface, previously
	 * disabled with the disableLiveInterface() method.
	 * 
	 * @param function callback_finish
	 * 		The function to be called, when the (empty) Live Interface has
	 * 		been restored.
	 */
	restoreLiveInterface: function(callback_finish) {
		//_restoreLiveInterfaceCallback = callback_finish;
		
		var DIV = $('ucarea');
		if(DIV && typeof this.LiveInterfaceBackup != 'undefined') {
			// remove tooltip
			this.removeTooltip();
			
			var O = $('nolive_thumbs_outro');
			if(O) {
				var efx = new Effect.Fade(O, {from: 100, to: 0, duration: 0.3});
			}
			
			// Fade out thumbs
			var e = $('nolive_thumb_0');
			var i = 0;
			var t = null;
			var c = null;
			
			while(e) {
				t = e;
				
				i ++;
				e = $('nolive_thumb_' + i);
				
				if(!e) {
					c = function() {
						$('ucarea').innerHTML = InterfaceAgent.LiveInterfaceBackup;
						if(typeof callback_finish == 'function') {
							callback_finish();
						}
					}
				}
				
				Effect.DropOut(t.identify(), {delay: (0.02*i), afterFinish: c});
			}
		}
	},
	
	/**
	 * Append Tooltip
	 * 
	 * This function is used to append a temporary tooltip to any HTML Element
	 * of the page.
	 * 
	 * @param string elm
	 * 		The HTMLElement to append the tooltip to
	 * @param string title
	 * 		The title of the tooltip
	 * @param string description
	 * 		The description
	 */
	appendTooltip: function(elm, title, description) {
		var E = $(elm);
		if(E) {
			var op = '';
			op += '<div class="tooltip_content">';
			op +=    '<div class="tooltip_title">';
			op +=       this.unescapeString(title);
			op +=    '</div>';
			op +=    this.unescapeString(description);
			op += '</div>';
			
			var T = new Element('div', {'class': 'tooltip', id : 'tooltip_window'}).update(op);
			document.body.appendChild(T);
			
			// Extend both the element to which the tooltip is attached,
			// and to the new tooltip element
			Element.extend(E);
			Element.extend(T);
			
			// Release the viewport dimensions in d.width and d.height. We 
			var d = document.viewport.getDimensions();
			var O = Position.cumulativeOffset(E);
			
			if((E.viewportOffset().top + E.getHeight() + T.getHeight()) > d.height) {
				T.setStyle({ position: 'absolute', left : O[0] + 'px', top : (O[1] - T.getHeight() - 2) + 'px' });
			} else {
				T.setStyle({ position: 'absolute', left : O[0] + 'px', top : (O[1] + E.getHeight() + 2) + 'px' });
			}
			
			T.hide();
			//if(!Prototype.Browser.IE) {
				var efx = new Effect.Appear('tooltip_window', {duration: 0.5, from: 0, to: 1});
			//} else {
			//	T.show();
			//}
		}
	},
	
	/**
	 * Hover Tooltip
	 * 
	 * This function is used to remove a tooltip, previously appended to the
	 * page with the appendTooltip() method
	 * 
	 * @param string elm
	 * 		The HTMLElement to append the tooltip to
	 * @param string title
	 * 		The title of the tooltip
	 * @param string description
	 * 		The description
	 */
	removeTooltip: function() {
		var DIV = $('tooltip_window');
		if(DIV) {
			DIV.remove();
		}
	},
	
	/**
	 * Escape string
	 * 
	 * This method will escape a string, for use in a quoted syntax
	 * 
	 * @param string str
	 * 		The string to be escaped
	 */
	escapeString: function(str) {
		return str.replace(/"/g, '&quot;').replace(/'/g, '\\\'');
	},
	
	unescapeString: function(str) {
		return str.replace(/&quot;/g, '"').replace(/\\'/g, '\'');
	},
		
	/**
	 * Get UC Box
	 * 
	 * Mounts the HTML Code to include a UC Box, used on the grey background 
	 * of the main Content/Zone
	 * 
	 * @param string bTitle
	 * 		The title of the UC box
	 * @param string bContents
	 * 		The contents of the box
	 * @param string bTitleClass
	 * 		OPTIONAL; The css class to be applied (additionally) on the title
	 * @param string bContentClass
	 * 		OPTIONAL; The css class to be applied (additionally) on the 
	 * 		content's DIV container
	 * @return string
	 * 		The HTML needed to show the UC box
	 */
	getUCBOX: function(bTitle, bContents, bTitleClass, bContentClass, bContentID) {
		var op = '';
		op += '<div class="ucbox">';
		op += 	'<div class="frame">';
		op += 		'<div class="body">';
		op += 			'<div class="content">';
		
		if(bTitle!='')
		{
			op += 			'<h3';
			if(typeof bTitleClass != 'undefined' && bTitleClass != '') {
				op += 		' class="' + bTitleClass + '"';
			}
			
			op += '>'+bTitle+'</h3>';
		}
		
		op += '<div'
		if(typeof bContentClass != 'undefined' && bContentClass != '') {
			op += 			' class="' + bContentClass + '"';
		}
		
		if(typeof bContentID != 'undefined' && bContentID != '') {
			op += 			' id="' + bContentID + '"';
		}
		
		op += '>';
		op += 			bContents;
		op += '</div>';
		
		
		op += 			'</div>';
		op += 		'</div>';
		op += 	'</div>';
		op += '</div>';
		
		return op;
	},

	/**
	 * Disable CommentRows view
	 * 
	 * This replaces the Comment Interface by another box.
	 * 
	 * @param string bTitle
	 * 		The title of the UC box
	 * @param string bContents
	 * 		The contents of the box
	 */
	hideCommentRows: function(bTitle, bContents) {
		if(this.isParticipationContent()) {		
			// paint a new UCBOX
			// ------: IMPORTANT NOTE :-------
			// we replace the now-replaced comment/row div's ID, with 'modulComments' 
			$('CommentsContainer').innerHTML = this.getUCBOX(bTitle, '<p>' + bContents + '</p>', 'bold', 'pidisabled', 'modulComments');

			// reset the height of the CommentRows
			this.CommentRowsHeight = $('modulComments').getHeight();

			// adapt to participation content, if blinded downwards:
			var pc = $('modulParticipacio');
			if(pc) {
				if(pc.getHeight() > 0) {
					$('modulComments').style.height = (this.CommentRowsHeight - pc.getHeight()) + 'px';
				}
			}

			// hide currently opened participation content
			this.hideParticipationContent();
			//this.hideContactContent();

			// visually disable buttons and disable roll-overs
			this.updateParticipationButtons(false);
		}
		
	},
	
	showCommentRows: function() {
		if(!this.isParticipationContent()) {
			// Restore the Comments Container backup
			$('CommentsContainer').innerHTML = this.CommentsContainerBackup;
			
			// reset the height of the CommentRows
			this.CommentRowsHeight = $('modulComments').getHeight();
			
			this.updateParticipationButtons(true);
		}
	},
	
	//visually disable/enable buttons and disable/enable roll-overs
	updateParticipationButtons: function(enable){
		var vClassToRemove = enable? 'thumbnail_off' : 'thumbnail';
		var vClassToAdd = enable? 'thumbnail' : 'thumbnail_off';
		var vOpacity = enable? 1 : 0.5;
		
		// visually disable/enable buttons:
		Element.setOpacity($('ButtonWEBMSGContainer'), vOpacity);
		//Element.setOpacity($('ButtonRECORDContainer'), vOpacity);
		//Element.setOpacity($('ButtonSMSContainer'), vOpacity);
		
		// disable/enable roll-overs
		try{
			$('ButtonWEBMSGContainer_href').removeClassName(vClassToRemove);
			//$('ButtonRECORDContainer_href').removeClassName(vClassToRemove);
			//$('ButtonSMSContainer_href').removeClassName(vClassToRemove);
		} catch(error){}
		try{
			$('ButtonWEBMSGContainer_href').addClassName(vClassToAdd);
			//$('ButtonRECORDContainer_href').addClassName(vClassToAdd);
			//$('ButtonSMSContainer_href').addClassName(vClassToAdd);		
		} catch(error){}
	},
	
	// Show UC Interface: Content Unit + List of UC
	// iTitle:  Title of the UC Interface
	// bTitles: Titles of the buttons in the UC List
	showUCInterface: function(iTitle,bTitles) {
		/*,bScrollLeft,bScrollRight*/
		var op = '';
		op += '<h3 id="lastPlayed">';
		op += HTML('HeaderLastPlayed',iTitle);
		op += '</h3>';
		op += '<div class="uccontent" id="uccontent" >&nbsp;</div>';
		
		// Show the UC Interface
		$('contingutUC').innerHTML = op;
		
		// Build the UC List
		this.showUCList(bTitles);
		
		// By default, we show the first UC
		if(bTitles.length>0) this.showUC(0);
	},
	
	// Write/Show UC List
	// A number is provided to this method: the number/index of the original array with which the
	// UCList was created (starting from ZERO)
	// When it's called by the user, it stops refreshing main content and does a OJD/Ads Hit
	showUC: function(UCListNumber, pStopRefreshMainContent) {
		if (pStopRefreshMainContent){
			updatePubli(vIdPubli);
			ajaxSite_DoHit();	
			stopRefreshMainContent();
		}
		var op = '';
		
		//if ( UCListNumber > (vdivLlistaUc.vNumUcs-1) ) UCListNumber=0;
		
		var data= vdivLlistaUc.data["ucContent"][UCListNumber];
		//trace("[showUC] ucType: "+data["ucType"]);
		
		switch(data["ucType"]) {
			case 'icr_apunt':
				UCTitle = data["title"];
				UCClass = '';
				UCContent = '';
				if( data["image"] != '' ) {
					UCContent += '<div class="caption left"><img src="'+data["image"]+'"';
					if( data["footer"] != '' ) UCContent += ' alt="'+data["footer"]+'"';
					UCContent += '" />';
					if( data["footer"] != '' ) UCContent += data["footer"];
					UCContent += '</div>';
				}
				if( data["text"] != '' ) {
					if (data["ucSubType"] == 'video') {
					UCContent += '<p><object width="349" height="269">';
					UCContent += '<param name="movie" value="'+data["text"]+'"></param>';
					UCContent += '<param name="wmode" value="transparent"></param>';
					UCContent += '<embed src="'+data["text"]+'" type="application/x-shockwave-flash" wmode="transparent" width="349" height="269"></embed>';
					UCContent += '</object></p>';					
					} else if (data["ucSubType"] == 'tresac') {
					UCContent += '<p><object height="277" width="320">';
					UCContent += '<param name="id" value="SVP_instance1" />';
					UCContent += '<param name="flashvars" value="VIDEO_ID='+data["text"]+'&WIDTH=320&HEIGHT=240" />';
					UCContent += '<param name="allowscriptaccess" value="always" /><param name="allowFullScreen" value="true" />';
					UCContent += '<param name="wmode" value="transparent"></param>';
					UCContent += '<param name="menu" value="true" /><param name="swliveconnect" value="true" />';
					UCContent += '<param name="quality" value="high" /><param name="bgcolor" value="#FFFFFF" />';
					UCContent += '<param name="name" value="SVP_instance1" /><param name="style" value="" />';
					UCContent += '<param name="movie" value="http://www.tv3.cat/svp2/svp2.swf" />';
					UCContent += '<embed height="277" width="320" wmode="transparent" id="SVP_instance1" flashvars="VIDEO_ID='+data["text"]+'&amp;WIDTH=320&amp;HEIGHT=240" allowscriptaccess="always" allowfullscreen="true" menu="true" swliveconnect="true" quality="high" bgcolor="#FFFFFF" name="SVP_instance1" style="" src="http://www.tv3.cat/svp2/svp2.swf" type="application/x-shockwave-flash"></embed>';
					UCContent += '</object></p>';	
					} else {
					UCContent += '<p>'+data["text"]+'</p>';
					}
				}
				break;
		
			case 'icr_foto':
				UCTitle = '';//data["title"]; FOTO do not show the title
				UCClass = '';
				UCContent = '';
				if( data["image"] != '' ) {
					UCContent += '<p><img src="'+data["image"]+'"';
					if( data["footer"] != '' ) UCContent += ' alt="'+data["footer"];
					UCContent += '" /></p>'
					if( data["footer"] != '' ) UCContent += '<p>'+data["footer"]+'</p>';
				}
				break;
		
			case 'wcr_galeria':
				UCTitle = data["title"];
				UCClass = '';
				var ID = InterfaceAgent.addGallery(data["title"], "", data["gallery"]);
				UCContent = InterfaceAgent.getUCGalleryInterface(ID);
				break;
		
			// POLL
			case 'dty_enquest':
				UCTitle = data["title"];
				UCClass = '';
				
				// prepare array of options for the poll:
				var answers = new Array();
				for ( var c = 0 ; c < data["options"].length ; c++ ) {
					answers[c] = {};
					answers[c].value = data["values"][c]; //1 
					answers[c].label = data["options"][c];
				}
				
				UCContent = '<p>'+ this.getPoll(data["text"], answers, data["idServei"] , 'results_'+data["id"] ) +'</p>';
				break;
			
			// LINK list
			case 'icr_link':
				UCTitle = data["title"];
				trace ("enableTN " + data["enableTN"] );
				trace ("length " + data["itemsText"].length );
				trace ("text " + data["itemsText"][0] );
				
				var links = new Array();

				if(data["enableTN"] ) {
					UCClass = 'links_3cat24'; //Especial!!
					for ( var c = 0 ; c < data["itemsText"].length ; c++ ) {
						links[c] = {};
						links[c].title = data["itemsText"][c];
						links[c].url = data["itemsUrl"][c];
						links[c].target = '_blank';
						links[c].image = data["itemsImage"][c];
						if( data["itemsFooter"][c] != '' ) links[c].footer = data["itemsFooter"][c];
						links[c].description = data["itemsComment"][c];
					}
				}else if (data["enableESP"]){	
					UCClass = 'links_esports'; //Especial!!
					for ( var c = 0 ; c < data["itemsText"].length ; c++ ) {
						links[c] = {};
						links[c].title = data["itemsText"][c];
						links[c].url = data["itemsUrl"][c];
						links[c].target = '_blank';
						links[c].image = data["itemsImage"][c];
						if( data["itemsFooter"][c] != '' ) links[c].footer = data["itemsFooter"][c];
						links[c].description = data["itemsComment"][c];
					}					
				}else{
					UCClass = '';
					for ( var c = 0 ; c < data["itemsText"].length ; c++ ) {
						links[c] = {};
						links[c].title = data["itemsText"][c];
						links[c].url = data["itemsUrl"][c];
						links[c].target = '_blank';
						//links[c].image = data["itemsImage"][c];
						links[c].description = data["itemsComment"][c];
					}
				}
				
				UCContent = this.getLinks( data["text"] , links );
				break;
		}
		
		// Mount HTML for UC:
		if(typeof UCClass != 'undefined' && UCClass!= '') {
			op += '<div class="'+UCClass+'">';
		}		
		
		op += '<h4>'+UCTitle+'</h4>';
		op += UCContent;
		op += '<div style="clear: both"></div>';
		
		if(typeof UCClass != 'undefined' && UCClass!= '') {
			op += '</div>';
		}
		
		// Show selection in UC List
		this.showUCListSelection(UCListNumber);
				
		// Show the UC
		$('uccontent').innerHTML = op;
	},
	
	addGallery: function(gTitle, gDescription, gallery) {
		// Save the gallery:
		if(typeof this.galleryInfo == 'undefined') {
			this.galleryInfo = new Array();
		}
		
		// get the ID for the new gallery:
		var c = this.galleryInfo.length;
		
		// save the gallery
		this.galleryInfo['gallery' + c] = {title : gTitle, description : gDescription, images : gallery};
		
		// return the ID
		return 'gallery' + c;
	},
	
	getGallery: function(ID, what) {
		if(typeof this.galleryInfo[ID] == 'undefined') {
			return false;
		} else {
			if(typeof this.galleryInfo[ID][what] == 'undefined') {
				return this.galleryInfo[ID];
			} else {
				return this.galleryInfo[ID][what];
			}
		}
	},
	
	// Create Gallery Interface
	// gallery is an array, of which each of the elements contain the following keys:
	// - src: the image source URL (full image)
	// - thumb: the image's thumb source URL
	// - title: the image's name
	// - desc: the image's description
	getUCGalleryInterface: function(ID) {
		// Get information on the gallery:
		var g = this.getGallery(ID);
		if(g) {
			// Mount HTML code to show the gallery:
			var op = '';
			if (g['description']!=""){
				op += '<p>'+ g['description'] +'</p>';
			}
			// Start Gallery container:
			op += '<div class="gallery">';
			
			// Start the list of items in the gallery
			op += 	'<ul>';
			
			// for each of the items in the gallery array
			for(var i = 0; i < g['images'].length; i++ ) {
				// add the current image to the interface
				op += '<li>';
				op += 	'<a href="#" onclick="InterfaceAgent.launchGallery(\''+ ID +'\', '+ i +')">';
				op += 		'<img src="'+g['images'][i]['thumb']+'" alt="" />';
				op += 	'</a>';
				op += '</li>';
			}
			
			// Finish the list of items in the gallery:
			op += 	'</ul>';
			
			// Finish the gallery container
			op += '</div>';
			
			// return the interface HTML Code
			return op;
		}
	},
	
	launchGallery: function(ID, start) {
		// Create a new LITBox
		var LB = new LITBox('', {
			type:'alert', 
			width: 50,
			height: 50,
			draggable: false,
     		resizable: false,
			overlay:true } );
		
		LB.createGalleryWindow(this.getGallery(ID, 'images'), start);
	},
	
	// Get UC List
	showUCList: function(bTitles) {
		// Get the UC List (HTMLDIVElement)
		var DIV = $('listUC');
		
		// Remove the current items in the UC List
		var d = DIV.down();
		while(d) {
			d.remove();
			d = DIV.down();
		}
		
		// Start UC List
		var op = '';
		op += '<ul id="listUC_ul">';
		
		// For each of the listed UC
		for( var i=0; i<bTitles.length; i++ ) {
			// add the current UC to the list
			op += '<li>';
			op += 	'<a href="#" onclick="InterfaceAgent.showUC('+i+', true);return false;" id="listUC'+i+'">';
			op += 		bTitles[i];
			op += 	'</a>';
			op += '</li>';
		}
		
		// Finish UC List
		op += '</ul>';
		
		// Show the list
		DIV.innerHTML = op;
		
		// reset the selected item number in the UC List
		this.selectedUCListItem = -1;
		
		// Show/remove Scroll buttons
		this.showUCListScrollButtons();
	},
	
	// Show UC List Selection
	showUCListSelection: function(UCListNumber) {
		// remove the visual selection from previously clicked button
		// in the UC List
		if(typeof this.selectedUCListItem == 'number' && this.selectedUCListItem>=0) {
			$('listUC'+this.selectedUCListItem).removeClassName('on');
		}
		
		// Show the activated button in the UC List!
		$('listUC'+UCListNumber).addClassName('on');
		
		// Remember the new selection
		this.selectedUCListItem = UCListNumber;
	},
	
	// Add/Remove UC List Scroll buttons
	showUCListScrollButtons: function() {
		var UL, ULid, ULh, P, Ph, i, a;
		
		// Get the UC List (UL HTMLElement)
		////UL = $$('.uclist ul')[0];
		UL = $('listUC_ul');
		
		// Get the height of the list:
		ULh = UL.getHeight();
		
		// Get the parent element of the list:
		P = UL.up();
		
		// Initialize the scroll position to Y-Position 0 (ZERO)
		this.scrollPositionUCList = 0;
		P.scrollTop = 0;
		
		// Get the height of the parent element:
		Ph  = P.getHeight();
		
		// If the height of the parent element is lower than the height of the list,
		// we need to add a scroll interface to the container!
		if(Ph<ULh) {
			// Make sure the scroll arrows have not been created yet!
			if(!$('scrollU')) {
				// Get the absolute X- and Y-position of the UC List
				var os = Position.cumulativeOffset(UL);
				
				// Create a new Element (A), for the ScrolL UP button, and append it 
				// to the parent element of the list
				a = new Element('a', { 
					href: 'javascript:InterfaceAgent.scrollUCList(\'U\')', 
					id: 'scrollU',
					style: 'position: absolute; top: '+os[1]+'px; left: '+os[0]+'px;'
				}).update('<img src="img/scrollup.gif" alt="" />');
				
				P.appendChild(a);
				
				// Create a new Element (A), for the ScrolL DOWN button, and append it 
				// to the parent element of the list
				a = new Element('a', { 
					href: 'javascript:InterfaceAgent.scrollUCList(\'D\')', 
					id: 'scrollD',
					style: 'position: absolute; top: '+(Ph+os[1]-27)+'px; left: '+os[0]+'px;'
				}).update('<img src="img/scrolldown.gif" alt="" />')
				
				P.appendChild(a);
				
				// The list should now leave some space for the scroll arrows :)
				UL.style.marginTop = '29px';
				UL.style.height = (ULh+29)+'px';
			}
		}
		// if no scrolling is required in the UC List, we remove the scroll buttons
		// that may have been created previously
		else {
			//$('scrollU'+i).remove();
			//$('scrollD'+i).remove();
		}
	},
	
	// Scroll UC List
	scrollUCList: function(direction) {
		// Convert the direction string into a number:
		var d = direction=='U' ? -125 : 125;
		
		// Add-to/Reduce the current scroll position, in order to calculate the
		// new (target) position.
		var newPosition = this.scrollPositionUCList+d;
		
		// The scroll position cannot be negative!
		if(direction=='U' && newPosition<0) {
			newPosition=0;
		}
		
		// The maximum Y-position is:
		var maxY = $('listUC').down().getHeight()-$('listUC').getHeight();
		
		// We cannot scroll further than the maximum Y-position
		if(direction=='D' && newPosition>maxY) {
			newPosition = maxY + 27;
		}
		
		// re-calculate the direction:
		d = newPosition-$('listUC').scrollTop; // 3-JAN-2008: this.scrollPositionUCList;
		
		// remember new scroll position
		this.scrollPositionUCList = newPosition;
		
		// Scroll to the target position
		var efx = new Effect.Scroll('listUC',{ y:d, duration:0.6});
	},
	
	// Get Comment
	// This will mount a Comment Row, in the list of Comments
	getCommentRow: function(cNumber,cType,cTime,cUserName,cLocation,cText,cUrlMultimedia) {
		// Prepare the HTML for the Icon
		var ico = '';
		
		//trace("CNM cType: "+cType);
		switch(cType)
		{
			// SMS (Cell Phone Icon)
			case 'sms':
				ico = '<img src="img/comment_sms.gif" alt="" class="typeimg" />';
				break;
			// Web-based Comment
			case 'web':
			case 'anonimo':
			case 'admin':
				ico = '<img src="img/comment_web.gif" alt="" class="typeimg" />';
				break;
			
			// Recording (Flash Player)
			case 'micro':
				var url = 'flash/player-mic.swf';
				var w   = 76;
				var h   = 11;
				ico+='<span class="typeimg">&nbsp;<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,28,0" width="'+ w +'" height="'+ h +'">';
				ico+='<param name="movie" value="'+url+'" />';
				ico+='<param name="quality" value="high" />';
				ico+='<param name="wmode" value="transparent" />';
				ico+='<param name="menu" value="false" />';
				ico+='<param value="exactfit" name="scale" />';
				ico+='<param value="streamName='+cUrlMultimedia+'&notify=si" name="FlashVars"/>';
				ico+='<embed src="'+url+'" flashvars="streamName='+cUrlMultimedia+'&notify=si" quality="high" wmode="transparent" scale="exactfit" menu="false" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" allowScriptAccess="sameDomain" width="'+ w +'" height="'+ h +'"></embed>';
				ico+='</object>&nbsp;</span>';
				break;
		}

		var op = '';
		if(cType != "admin") {
			op += '<div class="commentrow">';
		}else{
			op += '<div class="commentrow commentadmin">';
		}
		op += 	'<div class="addon">';
		op += 		'<span class="number">'+cNumber+'</span>';
		op += 		ico;
		op += 		cTime;

		if(cType != "admin") {
			//op += 		' | ' + cUserName;
			op += 		' | <span class="username">' + cUserName + '</span>';
		}else{
			op += 		' | <span class="administrator">' + vNomModerador + '</span>'; //defined in Component.js
		}

		if(cLocation!='') {op += ' | ' + cLocation;}
		op += 	'</div>';
		op += 	'<div class="textpreview">';
		op += 		cText.replace('<','&lt;').replace('>','&gt;');
		op += 	'</div>';
		op += '</div>';
		
		return op;
	},
	
	// Show Comments
	updateCommentRows: function(rows) {
		// Add "View All" to the rows:
		rows += '<div class="commentrow_viewall">';
		var vParamIdDebat= (idDebat!=0)? '&cvalue='+idDebat : '';
		rows += 	'<a href="/siteindex/siteIndex.jsp?pid=5'+vParamIdDebat+'&ctype=prog1" target="_blank">Veure tots</a>';
		rows += '</div>';

		var vTmp= this.isParticipationContent();
		if (vTmp){
			$('modulComments').innerHTML = rows;
		}
	},

	/**
	 * Check if Participation Content is available
	 * 
	 * This function will check if the comments (participation contents) 
	 * are enabled.
	 * 
	 * @return boolean
	 * 		TRUE if participation content is available, FALSE if not.
	 */
	isParticipationContent: function(  ) {
		// we check if the textarea exists, to send comments. If that textarea does not 
		// exist, we assume that the comments have been disabled.
		var elm = $('comentArea');
		if(elm) {
			return true;
		} else {
			return false;
		}
	},
	
	/**
	 * Alert about disabled Participation Content
	 * 
	 * @return
	 * 		void
	 */
	alertParticipationContent: function() {
		//alert('Els comentaris no estan activats!');
		InterfaceAgent.showWindowLoginFail('ButtonWEBMSGContainer','InactiveMessages');
	},


	
	/**
	 * Load Participation Content (from external XML)
	 * 
	 * This function was originally created to load requested "Participation Content"
	 * (SMS, phone, mail, record)
	 * 
	 * Since these options have been split up into separate menu's, this menu still does
	 * the same, for both of the menu's. BUT, a response_callback argument has been added
	 * to handle the content that is returned by the AJAX call.
	 * 
	 * @param string which
	 * 		Requested participation content ('sms', 'record', 'mail', 'phone'). If this
	 * 		argument equals 'sms', this function will load xml/ParticipationSMS.xml to
	 * 		fetch the contents.
	 * @param function init_callback
	 * 		This argument is optional. This is the callback function that is called 
	 * 		before loading the requested content.
	 * @param function response_callback
	 * 		This argument is optional. This is the callback function that handles
	 * 		the response of the AJAX call. Defaulted to this.showParticipationContent()
	 * @return
	 * 		void
	 */
	loadParticipationContent: function(which, init_callback, response_callback) {
		// init callback?
		if(typeof init_callback == 'function') {
			init_callback();
		}
		
		// unselect the previously selected:
		if(typeof selectedParticipationContent != 'undefined') {
			this.toggleParticipationButton(selectedParticipationContent, false);
		}
		
		// remember about the selected content
		selectedParticipationContent = which;
		
		// Set the response callback handler, if not provided by argument:
		if(typeof response_callback != 'function') {
			response_callback = this.showParticipationContent;
		}

		// On phone and mail, we use the Programa Component info
		if (which=='phone' || which=='mail'){
			var vContingut= vcPrograma.data[which];
			this.showContactContent(vContingut);
		}
		else{ //static xml		
			// Load the requested content
			// Set up objects and parameters to load the requested content:
			var xmlObjTree = new XML.ObjTree();
			var params = {
				method: 'get',
				parameters:	'which='+which	
			};
			var xmlObj = xmlObjTree.parseHTTP('xml/Participation' + which.toUpperCase() + '.xml', params, response_callback);
		}
	},
	
	/**
	 * Select, or unselect, a button in the Participation/Contact Menu
	 * 
	 * @param string which
	 * 		The requested content, as provided to the loadParticipationContent() function
	 * @param boolean b
	 * 		Set to TRUE if you want to select the button, or FALSE if you want to
	 * 		unselect it.
	 * @return
	 * 		void
	 */
	toggleParticipationButton: function(which, b) {
		// try to get the requested button:
		var bttn = $('Button' + which.toUpperCase() + 'Container');
		if(bttn) {
			if(b) {
				bttn.removeClassName(which);
				bttn.addClassName(which + '_on');
			} else {
				bttn.removeClassName(which + '_on');
				bttn.addClassName(which);
			}
		}
	},
	
	/**
	 * Show Participation (Contact) Content
	 * 
	 * This is the response callback function, used to show the content of contact buttons
	 * (phone, mail). The other participation buttons (record, sms) are still handled by the
	 * showParticipationContent() function.
	 * 
	 * IMPORTANT NOTE:
	 * Please note that this function refers to the 'InterfaceAgent' instance, because the 
	 * 'this' variable is not available, due to the AJAX Call!
	 * 
	 * @param String vContingut
	 * 		Content to paint
	 * @return
	 * 		void
	 */
	showContactContent: function(vContingut){
		// Get a Window:
		// (add the hideContactContent() as callback function)
		var wl = InterfaceAgent.showWindow(selectedParticipationContent, {x:0, y:0}, vContingut, '', null, null, InterfaceAgent.hideContactContent);
		
		// check if we can find the Contact Menu Container
		var m = $('ContactMenuContainer');
		if(m) {
			// Apply the position of the button onto the window
			Element.clonePosition(wl, m, { offsetTop: m.getHeight(), offsetLeft: -5 });
		}
		
		// select the active button
		InterfaceAgent.toggleParticipationButton(selectedParticipationContent, true);
	},
	
	/**
	 * Hide Participation (Contact) Content
	 * 
	 * As the showParticipationContent() has a counterpart hideParticipationContent() function,
	 * so does the showContactContent() have the corresponding hideContactContent().
	 * 
	 * This function is now being used as a callback function when a window is closed.
	 * 
	 * @return
	 * 		void
	 */
	hideContactContent: function() {
		if(typeof selectedParticipationContent != 'undefined') {
			InterfaceAgent.toggleParticipationButton(selectedParticipationContent, false);
		}
	},
	
	/**
	 * Show Participation Content
	 * 
	 * IMPORTANT NOTE:
	 * Please note that this function refers to the 'InterfaceAgent' instance, because the 
	 * 'this' variable is not available, due to the AJAX Call!
	 * 
	 * @param DOM xmlObj
	 * 		The DOM (XML) object, as returned by the xmlObjTree.parseHTTP() call
	 * @return
	 * 		void
	 */
	showParticipationContent: function(xmlObj) {
		// we only continue if participation content is available!!
		if(!InterfaceAgent.isParticipationContent()) {
			InterfaceAgent.alertParticipationContent();
			return;
		}
		
		var c = '';
		c += '<div class="pibox_win" id="BlindContentContainer">';
		c += 	'<div class="content">'+xmlObj.item.body+'</div>';
		c += 	'<a href="#" class="close" onclick="InterfaceAgent.hideParticipationContent()">Tancar</a>';
		c += '</div>';
		
		// Get the container of the Participation Content
		var pc = $('modulParticipacio');
		
		// If Participation Container should be opened first:
		// if(pc.getHeight()==0) {
		if(pc.getHeight()<15) { // IE7 Bug Fix
			
			// Show the Participation Content
			pc.style.display = !Prototype.Browser.IE ? 'none' : 'block'; // Firefox/Safari is set to 'none', to avoid flash before animation
			pc.style.visibility = 'hidden';
			pc.style.clear = 'both';
			pc.innerHTML = c;
			
			// Backup the height of the CommentRows, if not done yet!
			if(typeof InterfaceAgent.CommentRowsHeight != 'number') {
				InterfaceAgent.CommentRowsHeight = $('modulComments').getHeight();
			}
			
			// Set the new height of the
			// - Participation Content Container
			var efx1 = Effect.BlindDown('modulParticipacio', {} );
			
			// - CommentRows container (scrollable DIV)
			var efx2 = new Effect.Scale('modulComments', Math.floor(((InterfaceAgent.CommentRowsHeight-pc.getHeight())/InterfaceAgent.CommentRowsHeight)*100), { 
				scaleX: false, 
				scaleContent: false,
				scaleMode: { originalHeight: InterfaceAgent.CommentRowsHeight },
				afterFinish: function(){ $('modulParticipacio').style.visibility = 'visible'; }
				} );
			
		}
		// If Participation Container is already open
		else {
			pc.innerHTML = c;
		}
		
		// select the active button
		InterfaceAgent.toggleParticipationButton(selectedParticipationContent, true);
		// The XML may come with a 'javascript' tag, in order to include some extra functionality 
		// in the requested participation content. We check if that's the case:
		if(typeof xmlObj.item.javascript != 'undefined') {
			// execute the javascript, if provided
			eval(xmlObj.item.javascript);
		}
		
	},
	
	/**
	 * Hide Participation Content
	 * 
	 * This function is called when the "Tancar" button is clicked in the (black)
	 * participation window
	 * 
	 * @return
	 * 		void
	 */
	hideParticipationContent: function() {
		// Hide the Participation Content
		$('modulParticipacio').style.visibility = 'hidden';
		
		// Hide the Participation Content Container
		var efx = Effect.BlindUp('modulParticipacio');
		
		// Get the current scaleY of the CommentRows Container
		var currentScaleY = ($('modulComments').getHeight()/this.CommentRowsHeight)*100;
		
		// Restore the original height of the CommentRows Container (Scrollable DIV)
		var efx = new Effect.Scale('modulComments', 100, { 
			scaleX: false, 
			scaleContent: false, 
			scaleFrom: currentScaleY, 
			scaleMode: { originalHeight: this.CommentRowsHeight }, 
			afterFinish: function(){ $('modulParticipacio').innerHTML = ''; } 
		});
		
		if(typeof selectedParticipationContent != 'undefined') {
			this.toggleParticipationButton(selectedParticipationContent, false);
		}

	},

	/**
	 * Called when the "Publica la teva opinio" is clicked
	 * 
	 * (makes the textarea blink, and focusses the textarea with the 
	 * mouse cursor)
	 * 
	 * @param string el
	 * 		The field's ID
	 * @return
	 * 		void
	 */
	blinkCommentField: function(el) {
		var elm = $(el);
		if(this.isParticipationContent() && elm) {
			if(elm.select) {
				elm.select();
			}
			else if(elm.focus) {
				elm.focus();
			}
			
			this.blink(el, '', 'blink');
			
		} else {
			this.alertParticipationContent();
		}
		$('ButtonWEBMSGContainer_href').blur();
	},
	
	/**
	 * Make an HTML element blink
	 * 
	 * Blinking is done by switching the element's between two defined colors, every n 
	 * milliseconds.
	 * 
	 * @param string el
	 * 		The element to be blinked
	 * @param string color_1
	 * 		The first color (later applied as permanent background color)
	 * @param string color_2
	 * 		The second color
	 * @param integer milliseconds
	 * 		The amount of milliseconds in the blinking interval
	 * 		(optional; defauled to 100 milliseconds)
	 * @param integer blinks
	 * 		The number of blinks you want to the element to do!
	 * 		(optional; defaulted to 10);
	 * @return
	 * 		void
	 */
	blink: function(el, class_1, class_2, milliseconds, blinks, iteration) {
		// clear timeout
		if(this.BlinkingInterval != 'undefined') {
			window.clearTimeout(this.BlinkingInterval);
		}
		
		// default the amount of milliseconds
		if(typeof milliseconds == 'undefined') {
			var milliseconds = 100;
		}
		
		// default the number of blinks
		if(typeof blinks == 'undefined') {
			var blinks = 10;
		}
		
		// is this the first iteration?
		if(typeof iteration == 'undefined') {
			var iteration = 0;
		}
		
		// get the element
		var elm = $(el);
		if(elm && iteration < blinks) {
			// Blink!
			if(elm.className == class_2) {
				elm.removeClassName(class_2);
				var newclass = class_1;
			} else {
				elm.removeClassName(class_1);
				var newclass = class_2;
			}
			
			if(newclass != '') {
				elm.addClassName(newclass);
			}
			
			// call again in n milliseconds:
			this.BlinkingInterval = window.setTimeout("InterfaceAgent.blink('"+ el +"', '"+ class_1 +"', '"+ class_2 +"', "+ milliseconds +", "+ blinks +", "+ (iteration + 1) +")", milliseconds);
		}
		// if the element cannot be found, stop blinking!
		else {
			this.stopBlinking();
		}
	},
	
	/**
	 * Stop the blinking, previously started by blink()
	 * 
	 * @return
	 * 		void
	 */
	stopBlinking: function() {
		// clear timeout
		if(this.BlinkingInterval != 'undefined') {
			window.clearTimeout(this.BlinkingInterval);
		}
	},

	// Enable Login Interface
	// - fields clear the default value when focused, and restore the default value when left empty.
	// - Submit button appears when values are introduced
	enableLoginInterface: function() {
		var op = '';
		op += '<form name="login" action="#/doAjaxLogin" onsubmit="doAjaxLogin();return false;" id="idFormLogin">';
		op += 	'<div id="loginButton" class="login_buttons"></div>';
		op +=   '<div class="login_fields">';
		op += 	'	<strong>Identifica\'t: </strong>';
		op += 	'	<input id="loginFieldUsername" type="text" name="U" value="Usuari" class="field" />';
		op += 	'	<input id="loginFieldPassword" type="password" name="P" value="Clau" class="field" />';
		op +=   '</div>';		
		op += '</form>';
		
		// Show the Login Interface
		$('LoginInterface').innerHTML = op;
		
		// Make smart field out of the Username Field
		$('loginFieldUsername').onfocus = function(){
			if(this.value==this.defaultValue) this.value = '';
		};
		$('loginFieldUsername').onblur = function(){
			if(this.value=='') this.value = this.defaultValue;
		};
		
		// Make smart field out of the Password Field
		$('loginFieldPassword').onfocus = function(){
			this.type = 'password';
			if(this.value==this.defaultValue) this.value = '';
		};
		$('loginFieldPassword').onblur = function(){
			if(this.value=='') {
				this.type = 'text';
				this.value = this.defaultValue;
			}
			else {
				this.type = 'password';
			}
		};
		
		// Whenever the user strikes a key inside the Login Interface
		$('loginFieldUsername').onKeyUp = function(){ InterfaceAgent.toggleLoginButton(); };
		$('loginFieldPassword').onkeyup = function(){ InterfaceAgent.toggleLoginButton(); };
		this.toggleLoginButton();
	},
	
	// Focus the Login Interface
	// (places cursor in the Username field)
	focusLoginInterface: function() {
		// Close whatever window is open
		this.closeWindow();
		
		// focus the Username field
		var elm = $('loginFieldUsername');
		if(elm) {
			elm.focus();
		}
	},
	
	// Enable/Disable Login Interface's Submit Button
	toggleLoginButton: function() {
		// Prepare a boolean: "Show the Login Button?"
		var f1 = $('loginFieldUsername');
		var f2 = $('loginFieldPassword');
		
		var b  = ( f1.value != '' && f1.value != f1.defaultValue && f2.value != '' && f2.value != f2.defaultValue );
		
		// Show the Login Button:
		if(b) {
			// if not already showing
			var elm = $('loginFieldSubmitButton');
			if(!elm) {
				var op = '';
				op += '<input type="image" name="go" value="Entrar" src="img/button_login.gif" id="loginFieldSubmitButton" />';
				op += '<a href="#" onclick="InterfaceAgent.resetLoginInterface()"><img src="img/button_loginreset.gif" alt="" style="vertical-align: middle; margin: 0px 5px;" /></a>';
				op += '<a href="">Recordar clau</a>';
				$('loginButton').innerHTML = op;
			}
		
		// Hide the Login Button:	
		}
		else {
			$('loginButton').innerHTML = '<div class="login_links"><a href="https://secure.ccrtvi.com/su/cr/crReg1.jsp" target="_blank" class="register_link">Registra\'t</a> &middot; <a href="https://secure.ccrtvi.com/su/cr/crClauOblidada.jsp" target="_blank" class="forgotpwd_link">Recordar clau</a></div>';
		}
	},
	
	// Reset the Login Interface
	resetLoginInterface: function() {
		// Reset the value of the Username Field
		var f = $('loginFieldUsername');
		if(f) {
			f.value = f.defaultValue;
		}
		
		// Reset the value of the Password Field
		var f = $('loginFieldPassword');
		if(f) {
			f.value = f.defaultValue;
			if(!Prototype.Browser.IE) {
				f.writeAttribute('type', 'text');
			}
		}
		
		// Reset the Login Button
		this.toggleLoginButton();
	},
	
	// Show the Registered User's Dashboard Interface.
	// Once a user logs in to the system, the Login Interface changes. This method is in charge 
	// of making that change happen!
	showLoggedUserInterface: function(username){
		var op = '';
		op += 'Benvingut/da <strong>'+username+'</strong>';
		op += ' | ';
		op += ' <a href="#" onclick="doAjaxExitLogin();return false;" class="logout">Desconecta\'t</a>';
		
		$('LoginInterface').innerHTML = op;
	},
	
	/**
	 * Show window
	 * 
	 * @param string CSSClass
	 * 		The css class to be applied to the window. If this argument equals 'mail', the
	 * 		window DIV will have the class 'window_mail' applied to it
	 * @param array wPosition
	 * 		x and y position of the window
	 * @param string wContents
	 * 		The window contents
	 * @param string wTitle
	 * 		The window title (h3)
	 * @param integer wLifeTime
	 * 		The window's lifetime, in milliseconds. When this number of milliseconds is over,
	 * 		The window auto-closes...
	 * @param HTMLElement attachToElement
	 * 		The HTML element to which to attach the window
	 * 		(optional; if not provided, the window is attached to div id "windowLayer")
	 * @param function close_callback
	 * 		Callback function, when the window is closed
	 * @param function closeOnClick
	 * 		apply a 'close' onClick behaviour to the whole window
	 * @return HTMLElement
	 * 		The window's DIV element
	 */
	showWindow: function(CSSClass, wPosition, wContents, wTitle, wLifeTime, attachToHTMLElement, close_callback, closeOnClick) {
		// Close previous window
		this.closeWindow();
		
		if(typeof close_callback == 'function') {
			IAWindowCloseCallback = close_callback;
		} else {
			IAWindowCloseCallback = null;
		}
				
		// Prepare Window HTML
		var op = '';
		var closeOnClickString = (closeOnClick != undefined)?'':'onclick="javascript:InterfaceAgent.closeWindow();" style="cursor:pointer;"';
		op += 	'<div class="window_'+CSSClass+'" '+closeOnClickString+'>';
		op += 		'<a href="javascript:InterfaceAgent.closeWindow()" style="float: right; padding: 13px 13px 0px 0px">';
		op += 			'<img src="img/window_close.gif" alt="" />';
		op += 		'</a>';
		if( typeof wTitle != 'undefined' && wTitle!='' ) op += '<h3>'+wTitle+'</h3>';
		op += 		'<div class="content">';
		op += 			wContents;
		op += 		'</div>';
		op += 	'</div>';
		
		// Create the Window's DIV container
		var DIV_window = new Element('div',{
			'id': 'windowLayerW',
			'style': 'display: none'
		}).update(op);
		
		// A window can be attached to a HTMLElement, but that's optional. We check
		// if this method has been requested to attach the window to an existing HTMLElement.
		if( typeof attachToHTMLElement != 'undefined' && attachToHTMLElement != null) {
			// attach the window to an existing HTMLElement
			attachToHTMLElement.appendChild(DIV_window);
		}
		// If not attached to an existing HTMLElement, 
		// we place it in the Window Layer
		else {
			// Show the Window, in the Window layer
			$('windowLayer').appendChild(DIV_window);
		}
		
		// Make the Window Position Absolute:
		var w = $('windowLayerW');
		w.style.position = 'absolute';
		w.style.top = wPosition.y+'px';
		w.style.left = wPosition.x+'px';
		
		// We animate the window, in order to draw some attention to it :)
		// Unfortunately, we cannot do this for IE, but we do so for other browsers...
		if(!Prototype.Browser.IE) {
			// Other browsers...
			var efx = new Effect.Appear('windowLayerW',{duration:0.3, from:0, to:1});
		} else {
			// IE
			w.style.display = 'block';
		}
		
		// If a lifetime (in milliseconds) has been defined
		// - clear the previous interval
		if(typeof CNMInterfaceWindowInterval != 'undefined') {
			clearTimeout(CNMInterfaceWindowInterval);
		}
		
		// - set a new interval, to close the window when the lifetime is over
		if(typeof wLifeTime == 'number' && wLifeTime > 0) {
			CNMInterfaceWindowInterval = setTimeout('InterfaceAgent.closeWindow()',wLifeTime);
		}
		
		// Return the Window (HTML)Element
		return w;
	},
	
	/**
	 * Close the active window
	 * 
	 * This closes the active window, and calls the callback function (previously
	 * provided to showWindow(), if defined)
	 */
	closeWindow: function(){
		// Remove previously created window:
		var W = $('windowLayerW');
		if(W) {
			W.remove();
			
			// callback function
			if(typeof IAWindowCloseCallback == 'function') {
				IAWindowCloseCallback();
			} else {
				// alert('no callback');
			}
			
			IAWindowCloseCallback = null;
		}
	},
	
	// Show Login Failure Message
	showWindowLoginFail: function(referenceDiv, message){
		// Get the Username Field, of the Login Interface
		var f = $(referenceDiv).viewportOffset();
		if(f){
			// Get a Window:
			var wl = this.showWindow('loginfail',{x:0, y:0},HTML(message),'', 5000);
			
			// Apply the position of the Username Field onto the window
			Element.clonePosition(wl,referenceDiv,{ offsetTop: 15, offsetLeft: -14 });
		}
	},
	
	// Show "Loading" Status of the Login Interface
	showLoginLoading: function() {
		$('loginButton').innerHTML = '<img src="img/sending1.gif" alt="Enviant" style="vertical-align: middle" />Enviant';
	},
	
	// Show window for Anonymous Identification
	showWindowAnonymousID: function(){
		// Get the TextArea(s) in "Send Your Comment"
		var ID= 'comentArea';
		
		// We will attach a window to the 'CommentsContainer' DIV Container, so it is part of the <FORM> inside.
		// First, we get the Form Element:
		var F =$('commentForm');		
		// Attach the window to the Form:
		var wl = this.showWindow('anonymous_id',{x:0, y:0},HTML('AnonymousID'),'Identifica\'t','',F,undefined,false);
		
		// Apply the position of the Username Field onto the window
		Element.clonePosition(wl,ID,{ offsetTop: -wl.getHeight(), offsetLeft: -11 });
	},
	
	// Show "Loading" Status of the Anonymous Identification
	showAnonymousIDLoading: function(){
		// Get the TextArea(s) in "Send Your Comment"
		var ID= 'comentArea';
		
		// Get a Window:
		var wl = this.showWindow('anonymous_id',{x:0, y:0},HTML('AnonymousIDLoading'),'Enviant',undefined,undefined,undefined,false);
		
		// Apply the position of the Username Field onto the window
		Element.clonePosition(wl,ID,{ offsetTop: -wl.getHeight(), offsetLeft: -11 });
	},

	/**
	 * Show the result window of Anonymous ID (success/failure)
	 * 
	 * This function will show the result of the Anonymous Identification: a success message,
	 * or a message that indicates the failure of the identification.
	 * 
	 * @param boolean success
	 * 		TRUE if the identification has been completed successfully, FALSE if not.
	 * @return
	 * 		void
	 */
	showAnonymousIDResult: function(success) {
		// Get the TextArea(s) in "Send Your Comment"
		var el  = $('comentArea');
		
		// Which window should we show?
		// (the window's content is stored in the CNM.HTML.js)
		var win = success ? 'AnonymousIDSuccess' : 'AnonymousIDFailure';
		
		// Set the window's title:
		var tit = success ? 'OK' : '<div style="color: #cc0000">Error</div>';
		
		// Get a Window:
		var wl = this.showWindow('anonymous_id', {x:0, y:0}, HTML(win), tit);
		
		// Apply the position of the Comments Field onto the window
		Element.clonePosition(wl, el, { offsetTop: -wl.getHeight(), offsetLeft: -11 });
	},
	
	/**
	 * 
	 */
	showPollResults: function (data, idDiv){
		var answers = new Array;
		try{
			for (var i=0; i< data["ucContent"]["options"].length; i++){
				answers[i]= new Hash();
				//answers[i]['percentage']= data["ucContent"]["results"][i];
				answers[i]['percentage']= Math.round(Number(data["ucContent"]["results"][i]));
				answers[i]['label']= data["ucContent"]["options"][i];
			}
		}catch(error){}
		var myHtml= this.getPollResults(answers,idDiv);
		$(idDiv).innerHTML= myHtml;
	},

	/**
	 * Get Poll's voting interface
	 * 
	 * @param string question
	 * 		The question
	 * @param Array answers
	 * 		An array that contains the possible answers. Each of the elements of this array
	 * 		is another array, with 2 elements: 'value' and 'label'
	 * @param String idServei
	 * 		Poll service id
	 * @param String idContainer
	 * 		container's div id
	 */
	 
	getPoll: function(question, answers, idServei , idContainer ) {
		var op = '';
		
		// Mount the HTML code for Question + answers
		op += '<form method="post" name="_'+idServei+'" id="_frm'+idServei+'" action="#/ParticipaEnquesta">';
		op += '<div class="poll">';
		
		// Question:
		if(question!=''){
			op += 	'<div class="question">';
			op += 		question;
			op += 	'</div>';
		}
		op += 	'<div id="'+idContainer+'">';
		
		// Answers:
		op += '<div class="answers">';
		
		for( var i=0; i<answers.length; i++ ) {
			op += '<div class="answer">';
			op += 	'<input type="radio" name="answer'+idServei+'" value="'+ answers[i]['value'] +'" id="id_poll'+i+'" />';
			op += 	'<label for="id_poll'+i+'">'+ answers[i]['label'] +'</label>';
			op += '</div>';
		}
		
		op += 	'</div>';
		
		// Add the options to the interface ("Vote" + "View Results"):
		op += '<div class="options">';
		op += 	'<div class="results">';
		op += 		'<a href="#/VeureResultats" onclick="doAjaxResultEnq(\''+idServei+'\', \''+idContainer+'\'); return false;" class="popup">Resultats</a>';
		op += 	'</div>';
		op += 	'<img src="img/button_vote.gif" alt="Votar" onclick="doAjaxParticipaEnq(\''+idServei+'\', this, \''+idContainer+'\'); return false;"/>';
		op += '</div>';
		
		op += '</div>'; // idContainer
		op += '</div>';
		op += '</form>';
		
		return op;
	},

	/**
	 * Get Poll's results window
	 * @param Array answers
	 * 		An array that contains the possible answers. Each of the elements of this array
	 * 		is another array, with 2 elements: 'label' (string) and 'percentage' (string)
	 * @return string
	 * 		The results interface HTML
	 */
	getPollResults: function(answers, idDiv) {
		var op = '';
		
		// Answers:
		op += 	'<div class="answers">';
		
		for( var i=0; i<answers.length; i++ ) {
			op += '<div class="percentage_title">';
			op += 	answers[i]['label'];
			op += '</div>';
			op += '<div class="percentage" style="width: '+ answers[i]['percentage'] +'%">';
			op += 	'<div class="number">'+ answers[i]['percentage'] +'%</div>';
			op += '</div>';
		}
		
		// Link to show the questions
		op += '<div class="options">';
		op += 	'<div class="results">';
		op += 		'<a href="#/Actualitza" onclick="InterfaceAgent.updatePollResults(\''+idDiv+'\'); return false;" class="popup">Actualitza</a>';
		op += 	'</div>';
		op += '</div>';
		
		
		op += 	'</div>';
		
		// return the HTML
		return op;
	},
	
	updatePollResults: function(idDiv){
		var idContainer= idDiv;
		var postitId= idDiv.replace('results_','postit');
		var idServei = vpostitLayer.getPostit(postitId).data["idServei"];
		doAjaxResultEnq(idServei,idContainer);
	},
	
	/**
	 * Get list of links
	 * 
	 * @param string intro
	 * 		The introduction text to the list of links
	 * @param Array answers
	 * 		An array of links. Each of the elements in this array is in turn another
	 * 		array, with the following 5 elements: 'title', 'url', 'target', 'image' (optional),
	 * 		'description'
	 */
	getLinks: function(intro, links) {
		var op = '';
		
		// Add the introduction text to the list of links:
		if(intro != '') {
			op += '<div class="link_intro"><p>'+ intro +'</p></div>';
		}
		
		// for each of the links in the array:
		for( var i=0; i<links.length; i++ ) {
			// Start the row, and add the link
			op += '<div class="link_row">';
			op += 	'<a href="'+ links[i]['url'] +'" target="'+ links[i]['target'] +'">';
			op += 		links[i]['title'];
			op += 	'</a>';
			
			// Mount the HTML code to show the image, if an image has been provided 
			// for the current link in the list
			var image = '';
			
			//alert("img:  "+links[i]['image']);			
			if(typeof links[i]['image'] != 'undefined' && links[i]['image'] != '' && links[i]['image'] != undefined) {
				image = '<img width="125" src="'+ links[i]['image'] +'" alt="" />';				
			}
			
			if(links[i]['description']!='' || image!='') {
				op += '<p>';
				op += 	image + links[i]['description'];
				op += '</p>';
			}
			
			// finish the row of the current link
			op += 	'<div class="clear"></div>';
			op += '</div>';
		}
		
		return op;
	},
	
	/**
	 * Get Webcam Start Screen
	 * 
	 * @param string intro
	 * 		The introduction text
	 */
	getWebcam: function(intro, url) {
		var op = '';
		if(intro == '' || intro == undefined){ intro = '<br/><br/>'}
		
		op += '<div class="webcam"><div class="webcam_content">';
		op += 	intro;
		op += '</div></div>';
		
		//op += '<a href="javascript:InterfaceAgent.popup(\''+url+'\',375,640)"><img src="img/button_webcam.gif" alt="Veure webcam" /></a>';
		op += '<a href="javascript:InterfaceAgent.popup(\''+url+'\', 328, 340, {resizable: 0, titlebar: 0})"><img src="img/button_webcam.gif" alt="Veure webcam" /></a>';
		
		return op;
	},
	
	
	/**
	 * Get Webcam amb so Start Screen
	 * 
	 * @param string intro
	 * 		The introduction text
	 */
	getWebcamAmbSo: function(intro, url) {
		var op = '';
		if(intro == '' || intro == undefined){ intro = '<br/><br/>'}
		
		
		
		op += '<strong>Escolta’ns i mira’ns!!</strong><br />Aquesta webcam té so. Si estàs escoltant el directe i vols escoltar el so de la webcam, <strong>atura el directe</strong>.';
		op += '<img src="img/webcam_so_anime.gif" alt="Atura el directe" class="webcam_center"/>';
		
		
		op += '<div class="webcam"><div class="webcam_content">';
		op += 	intro;
		op += '</div></div>';	
		op += '<a href="javascript:InterfaceAgent.popup(\''+url+'\', 328, 340, {resizable: 0, titlebar: 0})"><img src="img/button_webcam_salmo.gif" alt="Veure webcam" /></a>';
		
		return op;
	},
	
	/**
	 * Pop up a window
	 * 
	 * @param string url
	 * 		The URL to load in the pop-up window
	 * @param integer width
	 * 		The width of the window
	 * @param integer height
	 * 		The height of the window
	 * @param integer options
	 * 		Additional options; eg {resizable : 1, titlebar : 1}
	 */
	popup: function(url, width, height, options) {
		// calculate the window's X and Y position
		var x = (screen.width  - width ) / 2;
		var y = (screen.height - height) / 2;
		
		// Default the additional options:
		var defaults = {
			resizable : 'yes',
			titlebar : 'no',
			directories : 'no',
			toolbar : 'no',
			menubar : 'no',
			scrollbars : 'yes',
			status : 'no'
		};
		
		if(typeof options == 'undefined') {
			options = {};
		}
		
		for(var i in defaults) {
			if(typeof options[i] == 'undefined') {
				options[i] = defaults[i];
			} else {
				if(typeof options[i] == 'number') {
					options[i] = options[i] == 1 ? 'yes' : 'no';
				}
			}
		}
	
		// Prepare the popup window's parameter string
		var param = '';
		param +=  'left=' + x.toString();
		param += ',top=' + y.toString();
		param += ',width=' + width.toString();
		param += ',height=' + height.toString();
		param += ',location=no';
		param += ',resizable=' + options.resizable;
		param += ',titlebar=' + options.titlebar;
		param += ',directories=' + options.directories;
		param += ',toolbar=' + options.toolbar;
		param += ',menubar=' + options.menubar;
		param += ',scrollbars=' + options.scrollbars;
		param += ',status=' + options.status;
		
		// open the window
		var x = window.open(url, 'pwin', param);
		x.focus();
	},
	
	/**
	 * Show "Mosca" Window
	 * 
	 * @param string title
	 * 		The title of the window
	 * @param integer text
	 * 		the full text (HTML) of the window
	 * @param integer image
	 * 		(Optional) An image, which will be displayed inline with the text 
	 * 		(aligned to the left).
	 * @return
	 * 		void
	 */
	mosca: function(title, text, image) {
		var op = '';
		
		// is client's browser IE?
		var is_IE  = Prototype.Browser.IE;
		
		// is browser IE, minor to the version 7?
		var is_IE6 = ( is_IE && navigator.appVersion.indexOf('MSIE 6')!=-1 );
		
		// Prepare mosca
		op  = '<div class="mosca'+ ( is_IE6 ? '_ie' : '' ) +'" id="moscaWindowInner">';
		op += 	'<div class="frame" id="moscaWindowInnerFrame">'
		op += 		'<div class="winbuttons">';
		op += 			'<a href="#" onclick="InterfaceAgent.moscaCloseWin()">';
		op += 				'<img src="img/mosca_close.gif" alt="Tancar" />';
		op += 			'</a>';
		op += 		'</div>';
		op += 		'<div class="content">';
		op += 			'<h3>'+ title +'</h3>';
		
		if(typeof image != 'undefined' && image != '') {
			op += '<img src="'+ image +'" alt="" class="alignleft" />';
		}
		
		op += 			text;
		op += 			'<div class="clear"></div>';
		op += 		'</div>';
		op += 	'</div>';
		op += '</div>';
		
		// get the DIV where we will show the window:
		var DIV = $('moscaLayer');
		
		// print the mosca window's content
		DIV.innerHTML = op;
		
		// get the mosca window we have printed!
		var MOS = $('moscaWindowInner');
		Element.extend(MOS); // IE Bug Fix
		
		// get dimensions before we hide the mosca window
		var MOSw = MOS.getWidth();
		var DIVh = DIV.getHeight();
		
		MOS.hide();
		
		// Make the container position absolutely, to avoid extra scroll in the global page!
		DIV.style.width = '100%';
		DIV.style.position = 'absolute';
		DIV.style.top = '0px';
		DIV.style.left = '0px';
		DIV.style.margin = (544 - DIVh)+'px 0px 0px 0px';
		DIV.style.width = MOSw+'px';

		
		// We animate the window, in order to draw some attention to it :)
		// Unfortunately, we cannot do this for IE, but we do so for other browsers...
		if(!is_IE) {
	       // Other browsers...
	       var efx = new Effect.Appear('moscaWindowInner',{duration:0.9, from:0, to:1});
		} else {
    	   // All IE versions
	       MOS.show();
		}
		// apply initial position in ALL browsers:
		this.moscaPositionLayer();
	},
	
	moscaPositionLayer: function() {
		// Get the mosca window layer:
		var LAYER = $('moscaLayer');
		if(LAYER) {
			// Get the absolute X-Y-position of the UC List
			var os = Position.cumulativeOffset($('ContentMainFrame'));
			
			// apply the X-position of the UC List to the Scroll Buttons
			LAYER.setStyle({ left : (os[0] - 10) + 'px' });
		}
	},
	
	/**
	 * Close "Mosca" Window
	 * 
	 * This function will close the mosca window, if that window has been opened
	 * previously with the mosca() function.
	 * 
	 * @return
	 * 		void
	 */
	moscaCloseWin: function() {
		var W = $('moscaWindowInner');
		if(W) W.remove();
	},
	
	/**
	 * Skins Utility
	 */
	swapSkin: function(colorRef){
		var themeElements = [ "livebar_glowing" , "livebar"];	
		for ( var i = 0; i < themeElements.length ; i++) {
			var vListElement = $$( "." + currentTheme + themeElements[i] );
			for ( var j = 0; j < vListElement.length ; j++) {
				vListElement[j].removeClassName( currentTheme + themeElements[i] );
				vListElement[j].addClassName(colorRef + themeElements[i]);
			}
		}
		currentTheme = colorRef;
	},
	
	updateMainHeader: function( newTitle , newBG ) {
		$("mainHeader").writeAttribute( "style" , "background:url("+newBG+") no-repeat top center" );
		$("mainHeaderTitle").innerHTML = newTitle;
	}

};



// Initialize an Interface Agent
var InterfaceAgent = new CNMInterface();
InterfaceAgent.initializeInterfaceAgent();

/**
 * mostraUC
 * @param String IdUC: UC's idint
 * @description: shows the UC having id == IdUc (if exists)
 */
function mostraUC(IdUC){
	var vIndex= -1;
	for (var i=0; (i<vdivLlistaUc.data["ucContent"].length) && (vIndex==-1); i++){
		if (vdivLlistaUc.data["ucContent"][i]["id"]==IdUC){
			vIndex=i;
		}
	}
	if (vIndex!= -1){
		InterfaceAgent.showUC(vIndex, true);
	}

}

// Get Text Snippet
// (e.g. Currently used to show the title of a minimized PostIt Window)
function getStringSnippet(str,maxlength) {
	// get the current # of characters in the string
	var l = str.length;
	
	// if that number is greater than the maximum
	if(l>maxlength) {
		// get a snippet
		str = str.substr(0,maxlength)+'...';
	}
	
	// return the snippet
	return str;
}
