// DONE: image description rollover
// DONE: thumbnail gallery
// DONE: IE Naviagtion fix
// DONE: window.onresize element reposition
// TODO: window scroll - gallery must be centered

/**
 * Generic popover gallery
 */
(function($) {

	// defautl configuration
	var default_config = {
		opacity: 0.8,						// overlay opacity
		data_source: '', // data script url or false for inline gallery
		
		slideshow_enabled: true,			// do we have a slideshow toggle button?
		slideshow_speed: 5,					// no. seconds between transitions
		slideshow_auto_start: false,		// no. seconds between transitions
		
		thumbnail_preview: true,			// do we have thumbnail preview?
		
		mode: 'gallery'						// gallery mode - "single" image or "gallery" image
	}
	
	// actual merged configuration
	var config = {};
	
	var collection = false;					// collection of images
	var current_index = 0;					// current image index
	var slideshow_interval = false;			// slideshow interval handler
	/**
	 * constructor
	 */
	$.fn.popover_gallery = function(options) {
		
		config = $.extend({}, default_config, options);
		
		if (typeof config.placeholder == "string") config.placeholder = $(config.placeholder);
		
		// build the image dataset
		build_dataset();
		
		$(window).resize(function() {
			$.fn.popover_gallery.reposition();
		});
		
		return this.each(function() {
			// find all links that are wrapped around an image in the placeholder element
			$(this).find("a.generic").each(function(i) {
				$(this).bind('click', function(event) {
					event.preventDefault();
					if (this.rel == '') {
						current_index = i;
					} else {
						current_index = parseInt(this.rel)-1;
					}
					$.fn.popover_gallery.open();
					this.blur();
				});
			});
		});	
		
	}
	
	/**
	 * opens the popover galery 
	 */
	$.fn.popover_gallery.open = function (i) {
		if (typeof(i)!='undefined') {
			current_index = i;
		}

		try {
			// init objects and properties
			
			init();
			
			// opening sequence
			$("#pg_overlay").fadeIn('normal', function() {
				$("#pg_toolbox").slideDown('normal', function() {
					return;
				});
			});
			
			// attach the close event on the overlay
			$("#pg_overlay").bind('click', $.fn.popover_gallery.close);
			$("#pg_close").click($.fn.popover_gallery.close);
			
			$('#pg_loading').attr('className', 'black');
			show_image();
			
			if (config.slideshow_auto_start) {
				$.fn.popover_gallery.start_slideshow(true);
			}
			
		} catch (e) {
			// do nothing	
			return false;
		}
	}

	$.fn.popover_gallery.get_collection = function() {
		return collection;
	}
	
	/**
	 * creates all the elements needed for the UI
	 */
	function init() {
		// creating transparent overlay
		if (typeof($('#pg_overlay')[0]) == 'undefined') {
			var overlay  = '<div id="pg_overlay"></div>';
			$("body").append(overlay);
		
			// applying style
			$("#pg_overlay").css({
				opacity: config.opacity
			});
		}
		
		show_loader();
		
		// creating the toolbox
		if (typeof($('#pg_toolbox')[0]) == 'undefined') {

			var toolbox = '<div id="pg_toolbox"></div>';
			
			$("body").append(toolbox);
			
			var append_str  = '<a id="pg_close" href="#"><span>Close</span></a>';
			
			if (config.slideshow_enabled == true && collection.length > 1) {
				append_str += '<div id="pg_slide">';
				append_str += '<a id="pg_play" href="#"><span>Play</span></a>';
				append_str += '<a id="pg_minus" href="#"><span>-</span></a>';
				append_str += '<span id="pg_speed">' + config.slideshow_speed + 's</span>';
				append_str += '<a id="pg_plus" href="#"><span>+</span></a>';
				append_str += '</div>';
			}
			
			append_str += '<div id="pg_nav">';
			if (collection.length > 1) {
				append_str += '<a href="#" id="pg_prev"><span> << </span></a>';
				append_str += '<a href="#" id="pg_next"><span> >> </span></a>';
			}
			append_str += '<span id="pg_index">0/0</span>';
			if (collection.length > 1)
				
			append_str += '</div>';
			
			$("#pg_toolbox").append(append_str);
			
			$('#pg_next').click($.fn.popover_gallery.next);
			$('#pg_prev').click($.fn.popover_gallery.prev);
			
			if (config.slideshow_enabled) {
				$('#pg_play').click($.fn.popover_gallery.start_slideshow);
				$('#pg_minus').click($.fn.popover_gallery.speed_down);
				$('#pg_plus').click($.fn.popover_gallery.speed_up);
			}
			
			if (config.thumbnail_preview && collection.length > 1) {
				
				$("#pg_nav").append('<div id="pg_show_thumbs"></div>');
				$("#pg_toolbox").append('<div id="pg_thumbnails"></div>');
				
				if ($.browser.msie) {
					$("#pg_thumbnails").css({ borderBottom: '1px solid'});
				}
				
				// open thumbnails list
				$("#pg_show_thumbs").click(function() {
					$('#pg_thumbnails').slideDown(400);
					return false;
				});
				
				
				var pg_timer_out;
				
				// close thumbnails lisr
				$("#pg_thumbnails").mouseout(function() {
					pg_timer_out = setTimeout(function() {
						$('#pg_thumbnails').slideUp(400);
					}, 400);
				});
				
				$("#pg_thumbnails").mouseover(function() {
					clearTimeout(pg_timer_out);
				});
				
				// load thumbnails
				var append_string= '';
				for (i=0; i<collection.length;i++) {
					append_string += '<div></div>';
				}
				
				$('#pg_thumbnails').append(append_string);
				
				$('#pg_thumbnails div').each(function(i) {
					if ( i!=0 && i%9 == 0) $(this).css({marginRight: -2});
					
					$(this).css({
						display: 'block',
						background: 'transparent url('+collection[i].thumbnail+') center center no-repeat',
						width: 55,
						height: 55
					})
					
					$(this).src = '';
					
					$(this).click(function() {
						$.fn.popover_gallery.set_index(i);
					});
				});
				
			}
			
		}
		
		if (typeof($('#pg_frame')[0]) == 'undefined') {
			content_placeholder = '<div id="pg_frame"><div id="pg_content"><img src="" alt="" title=""></img><div id="pg_desc"></div><div id="pg_desc_text"></div><div id="pg_info"></div></div></div>';
			$('body').append(content_placeholder);
		}
		
		$.fn.popover_gallery.reposition();
		
		$("#pg_thumbnails").css({
			left: 0,
			top: tb_height - 1,
			width: tb_width - 3
		});
		
		if (collection.length > 1) {
			$('#pg_content img').click($.fn.popover_gallery.next).css({
				cursor: 'pointer'
			});
			
		}
		
	}
	
	/**
	 * reposition all elements (on window rezize / scroll??)
	 */
	$.fn.popover_gallery.reposition = function() {
		// get document dimensions
		body_width = $(document).width();
		body_height = $(document).height();
		
		$("#pg_overlay").css({ height: body_height });
		
		tb_width	= parseInt($("#pg_toolbox").outerWidth());
		tb_height	= parseInt($("#pg_toolbox").outerHeight());
		tb_left 	= Math.round((body_width - tb_width)/2);
		tb_top		= 50;
		
		// ~vm
		// Opera dirty fix
		if($.browser.opera) {
			tb_left = Math.round((body_width - 563)/2);
			tb_width = 563;
			$("#pg_thumbnails").css({
				'margin-top': 18
			});
		}
		
		// positioning the toolbox ~vm fix
		if (typeof(document.body.style.maxHeight) != "undefined") {
			tb_top_scrolled = tb_top;
		} else {
			tb_top_scrolled = tb_top + $(document).scrollTop();
		}
		
		$("#pg_toolbox").css({
			left: tb_left,
			top: tb_top_scrolled
		});
		
		frame_width = $('#pg_frame').width();
		frame_height = $('#pg_frame').height();
			
		// position: the frame
		frame_left = ($(document).width()/2) - (frame_width/2);
		frame_top = $(document).scrollTop() + Math.round(($(window).height() - frame_height)/2);
		
		$('#pg_frame').css({
			width: frame_width,
			height: frame_height,
			left: frame_left,
			top: frame_top
		});
		
		// IE 7 hack
		// Ce ni IE6, pozicioniraj fixed
		if (typeof document.body.style.maxHeight != "undefined") {
			$('#pg_frame').css({ position: 'fixed' });
			$('#pg_toolbox').css({ position: 'fixed' });
		} else {
			$(window).one('scroll', $.fn.popover_gallery.reposition);
		}

	}
	
	/**
	 * closes the gallery and removes everything.
	 */
	$.fn.popover_gallery.close = function(event) {
		try {
			event.preventDefault();
			clearInterval(slideshow_interval);
		} catch (e) {}
		
		$("#pg_overlay").unbind('click');
		$("#pg_toolbox, #pg_loading, #pg_frame, #pg_overlay").fadeOut('fast', function() {
			current_index = 0;
		});
	}
	
	/**
	 * make an ajax call to the server to get the image array
	 */
	function build_dataset(params) {
		// inline gallery
		if (!config.data_source) {
			// return false;
		} else {
			$.ajax({
				cache: true,
				type: 'POST',
				url: config.data_source,
				data: {
					popover_gallery: 1,
					size: config.thumbnail_size
				},
				dataType: 'json',
				success: function(result) {
					// server returned json array of objects
					collection = result;
				},
				error: function(obj, status, error) {
				}
			});
		}
	}
	
	// starts the slideshow
	$.fn.popover_gallery.start_slideshow = function(event) { 
		try {
			event.preventDefault();
		} catch (e) {}
		
		// ui update
		$("#pg_play").blur();
		$("#pg_play").unbind('click');
		$("#pg_play").bind('click', $.fn.popover_gallery.stop_slideshow);
		$("#pg_play").addClass('started');
		
		// refresh the interval time
		if (slideshow_interval) clearInterval(slideshow_interval);
		// run slidehow
		slideshow_interval = setInterval($.fn.popover_gallery.next, config.slideshow_speed * 1000);
	}
	
	// show next image
	$.fn.popover_gallery.next = function(event) {
		try {
			if (this!=window) {
				this.blur();
				event.preventDefault();
			}
		} catch (e) {}
		current_index++;
		if (current_index >= collection.length) current_index = 0;
		show_image();
	}
	
	// show previous image
	$.fn.popover_gallery.prev = function(event) {
		try {
			event.preventDefault();
		} catch (e) {}
		
		$("#pg_minus").blur();
		
		current_index--;
		
		if (current_index < 0) current_index = collection.length-1;
		
		show_image();
	}
	
	// set the current image index
	$.fn.popover_gallery.set_index = function (num) {
		current_index = num;
		show_image();
	}
	
	// increase slideshow speed
	$.fn.popover_gallery.speed_up = function(event) {
		try {
			event.preventDefault();
		} catch (e) {}
		
		$("#pg_plus").blur();
		
		config.slideshow_speed = config.slideshow_speed + 1;
		if (config.slideshow_speed > 15) 
			config.slideshow_speed = 15;
		
		$('#pg_speed').html(config.slideshow_speed + 's');

		$.fn.popover_gallery.start_slideshow();
	}
	
	// decrease slideshow speed
	$.fn.popover_gallery.speed_down = function(event) {
		try {
			this.blur();
			event.preventDefault();
		} catch (e) {
			
		}
		
		config.slideshow_speed = config.slideshow_speed - 1;
		if (config.slideshow_speed < 1) 
			config.slideshow_speed = 1;
			
		$('#pg_speed').html(config.slideshow_speed + 's');
		
		$.fn.popover_gallery.start_slideshow();
	}
	
	
	
	// stops the slideshow
	$.fn.popover_gallery.stop_slideshow = function(event) {
		try {
			event.preventDefault();
		} catch (e) {}
		
		$("#pg_play").blur();
		$("#pg_play").removeClass('started');
		$("#pg_play").unbind('click');
		$("#pg_play").bind('click' ,$.fn.popover_gallery.start_slideshow);
		
		if (slideshow_interval != false) {
			clearInterval(slideshow_interval);
			slideshow_interval = false;
		}
	}
	
	/**
	 * load and show the current image
	 */
	function show_image() {
		current_image = collection[current_index];
		
		var is_video = false;
		if (typeof(current_image.is_video)!='undefined' && current_image.is_video) {
			is_video = true;
		}

		if (!is_video) {
			if (config.thumbnail_preview == true) {
				$('#pg_thumbnails').slideUp(300);
			}
		}

		$('#pg_content').hide();

		show_loader();

		var replaceEl;
		if ($('#pg_content img').size()>0) {
			replaceEl = $('#pg_content img');
		} else {
			replaceEl = $('#pg_content #gallery_video_container');
		}

		if (!is_video) {
			replaceEl.replaceWith('<img />');
		}


		var _imgOnLoad = function() {
			frame_width = this.width + 50;
			frame_height = this.height + 50;

			// position: the frame
			frame_left = ($(document).width()/2) - (frame_width/2);
			frame_top = Math.round(($(window).height() - frame_height)/2);
			if (!(typeof document.body.style.maxHeight != "undefined")) {
				frame_top += $(document).scrollTop();
			}

			// we do not have the main frame visible, lets make it (first time use)
			if ($('#pg_frame').css('display') != 'block') {
				$('#pg_frame').css({
					width: frame_width,
					height: frame_height,
					left: frame_left,
					top: frame_top
				});
			} else { // frame is allready present! just resize and display the content
				$('#pg_frame').animate({
					width: frame_width,
					height: frame_height,
					left: frame_left,
					top: frame_top
				}, 500);
			}

			if (!is_video) {
				$('#pg_content img').attr('src', tmp_img.src);
			}

			hide_loader();

			$('#pg_index').html((current_index+1) + "/" + collection.length);


			$('#pg_btn_info').unbind('mouseover');
			$('#pg_btn_info').unbind('mouseout');
			$('#pg_info').empty()
			if (current_image.title != '') {
				$('#pg_info').append('<span>' + current_image.title + '</span>');
			}

			if (current_image.description != '') {

				$('#pg_desc, #pg_desc_text').empty().html('<div>' + current_image.description + '</div>').css({
					position: 'absolute',
					left: -5000,
					bottom: ($.browser.msie) ? 25 : 0,
					opacity: 0.7,
					height: 'auto',
					width: this.width
				});

				// IE layout fix
				if ($.browser.msie){
					$("#pg_info").css({bottom:0});
				}

				$('#pg_desc_text').css({
					opacity: 1,
					left: -5000
				});

				$('#pg_info').append('<a href="#" id="pg_btn_info"><span>info</span></a>');

				$('#pg_btn_info').click(function() {
					return false;
				});
			}

			$('#pg_frame').fadeIn('normal', function() {
				$('#pg_content').fadeIn('fast', function() {

					// get tje height of the desctiption box while visible
					tmp_height = $('#pg_desc').height();

					$('#pg_desc, #pg_desc_text').css({
						left: 25,
						height: 0,
						display: 'none'
					});

					// handle the mouse events on info button
					$('#pg_btn_info').hover(
						function() {
							$('#pg_desc, #pg_desc_text').css({display: 'block'})
							$('#pg_desc, #pg_desc_text').animate({
								height: tmp_height
							}, 400);
						},
						function() {
							$('#pg_desc, #pg_desc_text').animate({
								height: 0
							}, 400, function() {
								$('#pg_desc, #pg_desc_text').css({display: 'none'})
							})
						}
					);
				});

			});
		};

		
		if (is_video) {

			var width=400;
			var height=300;

			if (typeof(current_image.info)!='undefined') {
				width = current_image.info.width;
				height = current_image.info.height;
			}

			_imgOnLoad.call({
				width:width,
				height:height
			});

			replaceEl.replaceWith('<div id="gallery_video_container"></div>');

			var so = new SWFObject("flash/player.swf?rnd="+parseInt(Math.random()*10000), "product_video_player", width, height, "9", "#336699");
			so.addVariable('file', current_image.picture);
			so.addVariable('autostart', 'true');
			so.addParam('allowfullscreen', 'true');
			so.addParam('allowscripaccess', 'always');
			so.write("gallery_video_container");
		} else {
			tmp_img = new Image();
			tmp_img.onload = _imgOnLoad;

			tmp_img.src = current_image.picture;
		}
	}
	
	/**
	 * shows the loading animation
	 */
	function show_loader() {
		
		// creating loading animation if not present
		if (typeof($('#pg_loading')[0]) == 'undefined') {
			$('body').append('<div id="pg_loading"></div>');
		}
	
		loader_w = $('#pg_loading').outerWidth();
		loader_h = $('#pg_loading').outerHeight();
		
		loader_l = Math.round(($(document).width() - loader_w)/2);
		loader_t = $(document).scrollTop() + Math.round(($(window).height() - loader_h)/2);
		
		$('#pg_loading').css({
			left: loader_l,
			top: loader_t,
			zIndex: 1000
		});
	
		$('#pg_loading').fadeIn('normal');
	}
	
	/**
	 * hides the loading animation
	 */
	function hide_loader() {
		$('#pg_loading').fadeOut('normal');
	}
	
	//-----------------------------------------------------

	/**
	 * simple firebug debug function
	 */
	function debug(param) {
		
		if (typeof(param) == "object") {
			output = 'OBJECT\n';
			for ( a in param) {
				output += "\t" + a + ": " + param[a] + "\n"; 
			}
			
			param = output;
		}
		
		if (window.console && window.console.log) {
			window.console.log('[generic_gallery] '+ param);
		} else {
			alert(param);
		}
	};

})(jQuery)
