(function () {
this.MainDisplay = Class.extend({
	init: function (domEl) {
		this.domElement = domEl;
		this.domInitialized = false;
	},
	show: function () {
		this.domElement.style.display = 'block';
		if (!this.domInitalized) {
			this.initDom();
		}
	},
	hide: function () {
		var _this = this,
			zIndexCache = this.domElement.style.zIndex;
		// si el dom no esta iniciado solo ocultamos, de lo contrario ocultamos con moneria
		if (!this.domInitialized) {
			this.domElement.style.display = 'none';
		}
		else {
			$(this.domElement).css('z-index', 100).fadeOut('fast', function () {
				_this.domElement.style.zIndex = zIndexCache
			});
		}
	},
	initDom: function () {
		this.domInitialized = true;
		$("#main-display h1").hide();
	}
});

this.FlashDisplay = MainDisplay.extend({
	initDom: function () {
		var $flash			= $(this.domElement).children(),
			$input			= $flash.children('input:hidden'),
			swfUrl			= $input.filter('[name=swfUrl]').val(),
			divId			= $flash.attr('id'),
			width			= $input.filter('[name=width]').val() || $flash.parent().width(),
			height			= $input.filter('[name=height]').val() || $flash.parent().height(),
			version			= $input.filter('[name=version]').val() || '8.0.0',
			expressInstall	= $input.filter('[name=expressInstall]').val() || false,
			flashvars		= false,
			parameters		= false,
			attributes		= false;
		// check flag and call the original initDom method:
		if (this.domInitialized) {
			return false;
		}
		this._super();
		// try evaluating the objects:
		try {
			eval('flashvars=' + $input.filter('[name=flashvars]').val());
		} catch(e) {};
		try {
			eval('parameters=' + $input.filter('[name=parameters]').val());
		} catch(e) {};
		try {
			eval('attributes=' + $input.filter('[name=attributes]').val());
		} catch(e) {};
		// insert the code:
		swfobject.embedSWF(swfUrl, divId, width, height, version, expressInstall, flashvars, parameters, attributes); 
	}
});


this.GoogleMapsDisplay = MainDisplay.extend({
	init: function (domEl) {
		this._super(domEl);
		this.map;
	},
	initDom: function () {
		var _this = this,
			options,
			$input = $('input:hidden', this.domElement),
			$marker = $('span.GMarker', this.domElement),
			aCenter;
		// check flag and call the original initDom method:
		if (this.domInitialized) {
			return false;
		}
		this._super();
		// get the center and zoom
		aCenter = $input.filter('[name=center]').val().split(',');
		options = {
			center: new google.maps.LatLng(aCenter[0], aCenter[1]),
			zoom: parseInt($input.filter('[name=zoom]').val(), 10),
			mapTypeId: google.maps.MapTypeId.ROADMAP,
			mapTypeControl: false
		};
		_this.map = new google.maps.Map(_this.domElement, options);
		// create the markers
		$marker.each(function () {
			var $t = $(this),
				$markerInput = $t.children('input'),
				aMarkerCoords = $markerInput.filter('[name=coords]').val().split(','),
				marker,
				infoWindow;
			marker = new google.maps.Marker({
				position: new google.maps.LatLng(aMarkerCoords[0], aMarkerCoords[1]), 
				map: _this.map
			});
			infowindow = new google.maps.InfoWindow({
				content: $t.html()
			});
			google.maps.event.addListener(marker, 'click', function () {
				infowindow.open(_this.map, marker);
			});
		});
	}
});


this.Slider = MainDisplay.extend({
	/**
	 * Constructor
	 * Only assings the DOM element, creates the empty array of slides and sets some flags
	 */
	init: function (domEl) {
		this._super(domEl);
		this.slides = [];
		this.active = false;
		this.activityShown = false;
		this.formShown = false;
		this.activityTimer;
		this.playTimer;
	},
	/**
	 * Adds a new slide to the slider
	 * @param {Slide} slide
	 */
	addSlide: function (slide) {
		this.slides.push(slide);
		if (this.active === false) {
			this.active = 0;
		}
	},
	/**
	 * Show the slide required in index parameter, also controls the activity display and the controls classes
	 * @param {Number} index
	 */
	goToSlide: function (index, callback) {
		var _t = this,
			$thumbs = $('#main-slider-thumbs li'),
			fCallback = callback || function () {};
		if (this.active !== index && !this.activityShown) {
			// handle classes of thumbs
			$thumbs.eq(this.active).removeClass('active');
			$thumbs.eq(index).addClass('active');
			this.showActivity();
			// show the slide and set callback
			this.slides[index].show(function () {
				_t.hideActivity().slides[_t.active].hide();
				_t.active  = index;
				fCallback();
			});
		}
	},
	/**
	 * Starts looping automatically and hides the controls
	 */
	play: function () {
		var _t = this,
			$t = $(this.domElement),
			nToShow = this.active + 1;
		if (!this.formShown) {
			if (nToShow === this.slides.length) {
				nToShow = 0;
			}
			this.playTimer = setTimeout(function () {
				_t.goToSlide(nToShow, _t.play());
			}, 5000);	
		}
	},
	/**
	 * Stops the autoplay loop and shows the controls
	 */
	pause: function () {
		clearTimeout(this.playTimer);
	},
	/**
	 * Slides the main slider controls into viewport
	 */
	showControls: function () {
		if (!this.formShown) {
			$(this.domElement).find('#main-slider-controls').stop().animate({
				paddingTop:'5px',
				height:'35px',
				paddingBottom:'5px'
			}, 400).show();
		}
	},
	/**
	 * Hides the main slider controls off viewport
	 */
	hideControls: function (paramTime) {
		var nTime = typeof paramTime === 'number' && paramTime >= 0 ? nTime : 400;
		$(this.domElement).find('#main-slider-controls').stop().animate({
				paddingTop:'0',
				height:'0',
				paddingBottom:'0'
			}, nTime);
	},
	/**
	 * Shows the form "send to a friend"
	 */
	showForm: function () {
		var _t = this,
			$t = $(this.domElement);
		this.formShown = true;
		// hide control and pause animation 
		this.hideControls();
		this.pause();
		// toggle visibility of elements
		$t.siblings('h1, ul').hide();
		$t.find('fieldset').show();
		$t.find('#main-slider-email-tab').one('click', function () {
			_t.hideForm();
		});
	},
	hideForm: function () {
		var _t = this,
			$t = $(this.domElement);
		this.formShown = false;
		// toggle visibility of elements
		$t.siblings('h1, ul').show();
		$t.find('fieldset').hide();
		$t.find('#main-slider-email-tab').one('click', function () {
			_t.showForm();
		});
	},
	/**
	 * Shows the slider loader
	 * @return the slider element
	 */
	showActivity: function () {
		var $loader = $('div.loader', this.domElement).show().css('backgroundPosition', '0 0');
		this.activityShown = true;
		this.activityTimer = setInterval(function () {
			var nCurrent = parseInt($loader.css('backgroundPosition').split(' ')[1], 10);
			$loader.css('backgroundPosition', '0 ' + ((nCurrent - 40) % 480) + 'px')
		}, 66);
		return this;
	},
	/**
	 * Hides the slider loader
	 * @return the slider element
	 */
	hideActivity: function () {
		$('div.loader', this.domElement).hide();
		this.activityShown = false;
		clearInterval(this.activityTimer);
		return this;
	},
	/**
	 * implementation of show
	 */
	show: function () {
		this._super();
		this.play();
	},
	/**
	 * implementation of hide
	 */
	hide: function () {
		this._super();
		this.pause();
	},
	/**
	 * assings all the events and manipulates all DOM elements necessary to launch the Slider
	 */
	initDom: function () {
		var _this = this,
			$main = $(this.domElement),
			$imgLi = $main.find('#main-slider-images').find('li'),
			$mainControls = $('#main-display-controls');
		// check flag and call the original initDom method
		if (this.domInitialized) {
			return false;
		}
		this._super();
		
		this.hideControls(0);
		
		/* add the slides */
		$imgLi.each(function () {
			_this.addSlide(new Slide(this));
		});
		
		/* define the slide change events */
		$('#main-slider-thumbs li', this.domElement).each(function (index) {
			$(this).click(function () {
				_this.goToSlide(index);
			});
		}).eq(0).addClass('active');
		
		/* parent's hover event */
		$main.parent().mouseover(function () {
			_this.showControls();
			_this.pause();
		}).mouseleave(function () {
			_this.hideControls();
			_this.play();
		});
		
		/*
		 * events and dom initialization for the thumbnails controls 
		 */
		$("#main-display h1").hide();
		$('div.h-slider', this.domElement).each(function () {
			var $slider = $(this),
				$controls = $slider.find('a.nav'),
				$ul = $slider.find('ul'),
				$li = $ul.children(),
				limiteIzq = 0,
				limiteDer,
				nDelta = $li.length > 1 ? ($li.eq(1).offset().left - $li.eq(0).offset().left) : 0;
			// en primer lugar forzamos la anchura del $ul y comprobamos si basta con eliminar el slider o los controles 
			$ul.width(nDelta * $li.length);
			if ($li.length < 2) {
				$slider.remove();
				return;
			}
			else if ($ul.width() <= $ul.parent().width()) {
				$controls.remove();
			}
			else {
				// de lo contrario asignamos variables y eventos
				limiteIzq = 0;
				limiteDer = $ul.parent().width() - $ul.width();
				$controls.click(function () {
					var $t = $(this),
						desplaz = ($t.is('.next') ? -1 : 1) * nDelta * 4,
						destino = desplaz + parseInt($ul.css('margin-left'));
					// comprobamos que este dentro de los limites	
					if (destino<limiteDer) {
						destino=limiteDer;
					} else if (destino>limiteIzq) {
						destino=limiteIzq;
					}
					// animamos y cancelamos la propagacion del evento
					$ul.animate({marginLeft:destino+'px'},400)
					return false;
				});				
			}
			// finalmente controlamos la visiblidad del div
			$slider.css({
				visibility: 'visible',
				display: 'none'
			});
		});
		
		/*
		 * Events and dom initialization for the send-to-friend form
		 */
		$('#main-slider-email-tab').css({
			top: parseInt($mainControls.css('top'), 10),
			marginTop: $mainControls.children().length * ($mainControls.children().eq(0).height() + parseInt($mainControls.children().eq(0).css('marginBottom'), 10) + 2 * parseInt($mainControls.children().eq(0).css('borderBottomWidth'), 10))
		});
		this[this.formShown ? 'showForm' : 'hideForm']();
		$("#main-display h1").show();
	}
});

/**
 * Constructor
 * Creates a new slide for the main slider and sets its hotpoints coordinates
 * @param {Object} the DOM element to build the slide with
 */
function Slide(domEl) {
	this.domElement = domEl;
	// init hotpoints
	$('span.hotpoint', this.domElement).each(function () {
		var $t = $(this),
			$input = $t.find('input:hidden').filter(function () {
				return (/\d+,\d+/).test(this.value);
			}),
			aXY = $input.val().split(',');
		$t.css({
			left:aXY[0]+'px',
			top:aXY[1]+'px'
		});
		$input.remove();
	});
}
/**
 * Shows the slide, inserting the image if it has not yet been created
 * @param {Object} callback
 */
Slide.prototype.show = function (callback) {
	var _el = this.domElement,
		$input = $('input',_el),
		$img = $('img', _el),
		fCallback = callback || function () {},
		i, l;
	if (!$img.length) {
		$('<img src="'+$input.eq(0).val()+'"/>').load(function () {
			// hay que volver a comprobar si la imagen ya ha sido insertada
			if (!$('img', _el).length){
				$(this).appendTo(_el);
			}
			$input.eq(0).remove();
			$(_el).show();
			// after appending the actual image we insert the hotpoints images (if any)
			for (i=1, l=$input.length; i<l; ++i) {
				$input.eq(i).replaceWith('<img src="'+$input.eq(i).val()+'" />');
			}
			fCallback();
		});
	} else {
		$(_el).show();
		fCallback();
	}
}
/**
 * Fades out the slide
 * @param {Object} callback
 */
Slide.prototype.hide = function (callback) {
	$(this.domElement).css('zIndex', 7).fadeOut('fast', function () {
		var fCallback = callback || function () {};
		$(this).css('zIndex', 5);
		fCallback();
	});
}
})();



/*
 * events and initalization for the main slider behavior
 */
HttpCom.extensions.mainDisplay = function (scope) {
	var $display = $('#main-display > div', scope),
		$controls = $('#main-display-controls > li', scope),
		displayCollection = [],
		activeDisplayIndex = $display.index( $display.filter('.active') );
	
	if (activeDisplayIndex === -1) {
		activeDisplayIndex = 0;
	}
	
	$display.each(function (nIndex) {
		var $control = $controls.eq(nIndex);
		
		// elements
		if (this.id === 'main-slider') {
			displayCollection.push(new Slider(this));
		}
		else if (this.className.indexOf('flash-display') > -1) {
			displayCollection.push(new FlashDisplay(this));
		}
		else if (this.className.indexOf('map-display') > -1) {
			displayCollection.push(new GoogleMapsDisplay(this));
		}
		else {
			displayCollection.push(new MainDisplay(this));
		}
		// initialization
		displayCollection[nIndex][(nIndex === activeDisplayIndex) ? 'show' : 'hide']();
		if (nIndex === activeDisplayIndex) {
			$control.addClass('active');
		}
		
		// controls
		$control.click(function () {
			if (nIndex === activeDisplayIndex) {
				return;
			}
			else {
				displayCollection[activeDisplayIndex].hide();
				activeDisplayIndex = nIndex;
				displayCollection[activeDisplayIndex].show();
				$(this).addClass('active').siblings().removeClass('active');
			}
		});
	});
}

