/**
 * Cinema Display coded for LTB by H2G Internetagentur, 5000 Aarau
 *
 * This instance handles all aspects of the larger cinema display
 * view. The cinema display overlays a transparent background over
 * the screen and renders the head navigation and closer parts
 * as fixed positioned elements onto the screen. Second the given
 * image will be triggered to load into a canvas element and will
 * be resized to fit the entire screen.
 *
 * For cinema display functionality the HTML page does not need
 * to have any elements written hardcoded. The use of classnames
 * are only this two elements: .overlay and .cinema.
 *
 * @author michael.kuck@h2g.ch
 * @version 1.01 25-11-2010
 */
var display = {
	init: function(src, container, opts) {
		
		var $this = this;
		
		// creating transparent overlay layer
		var overlay = $("<div></div>").addClass('overlay').css({
			'opacity':'0',
			'-moz-opacity':'0',
			'-ms-opacity':'0',
			'filter':'alpha(opacity=0)'
		});
		
		// attach layer to body document
		$("body").append($(overlay).css({'display':'block'}));
		
		// fade in overlay
		$(overlay).animate({
			'opacity':opts.overlay['opacity']
		}, opts.overlay['speed'], function() {
			
			var closer;
			
			// create cinema layer to hold elements and picture
			var cinema = $("<div></div>").addClass('cinema').css({
				'width': $(window).width()+'px',
				'height': $(window).height()+'px'
			});
			
			// create canvas to carry picture and controls
			var canvas = $("<div></div>").addClass('canvas').css({
				'width': $(window).width()+'px',
				'height': ($(window).height()-60)+'px',
				'top': '60px'
			}).append($("<img />").addClass('image').attr({
				'src': opts.basepath+opts.icons['empty']['src'],
				'width': opts.icons['empty']['width'],
				'height': opts.icons['empty']['height'],
				'alt': ''
			}).css({
				'display':'block',
				'opacity':'0',
				'-moz-opacity':'0',
				'-ms-opacity':'0',
				'filter':'alpha(opacity=0)'
			})).append($("<div></div>").addClass('top'));
			
			// bind resize event to canvas layer
			$this.resize(cinema);
			
			// attach canvas to cinema layer
			$(cinema).append(canvas);
			
			// attaching controls to cinema layer
			controls.init(canvas, $this);
			
			// loading head navigation and bounce in
			$this.head(cinema, opts);
			
			// attach cinema display to document body
			$("body").append(cinema);
			
			// loading closer element into window
			$this.closer.init($this, container, opts);
			
			// binding keyboard events to screen (esc|space|return)
			$(window).bind('keyup', function(event) {
				if (parseInt(event.keyCode) == 27) $this.detach(true);
				if (parseInt(event.keyCode) == 13) $this.detach(true);
				if (parseInt(event.keyCode) == 32) $this.detach(true);
			});
			
			// binding onclick event to image
			$(canvas).find('.image').one('click', function() { $this.detach(true); });
			
			// start loading big image
			$this.load(src, canvas, function() {
				$(canvas).find('.loader').remove();	
			});
			
		});
	},
	head: function(display, opts) { 
		$.ajax({
			url: opts.navigation,
			success: function(data) {
				$(display).append(data);
				$(display).find('.head').animate({
					'top':'0px'
				}, 500, 'easeOutQuint', function() {
					// adding shadow below head navigation
					$(display).find('.top').addClass('shadow');
				});
			}
		});
	},
	load: function(src, canvas, callback) {
		
		var $this = this;
		
		this.loader.init(function() {
			
			// show loader in cinema box
			$(canvas).append(this);
			
			$.fn.mediabox.preload(src, function() {
				
				// setting image dimensions
				var img = new Image(); img.src = src;
				var size = $this.scale($(canvas), img);
				
				$(canvas).find('.image').attr({
					'src':src,
					'width':size.width,
					'height':size.height,
					'top':size.top+'px',
					'left':size.left+'px'
				}).animate({
					'opacity':'1.0'
				}, 500, function() { });
				
				if (typeof callback == "function")
					callback.call(this);
				
			});
			
		});
	},
	scale: function(screen, img) {
		
		var width = 0, height = 0, top = 0, left = 0, ratio;
		
		// screen format widescreen or equal (screen ratio >= 1)
		if (($(screen).width() / $(screen).height()) >= 1) {
			// setting image width to screen width
			width = $(screen).width();
			ratio = img.width / $(screen).width();
			height = Math.round(img.height / ratio);
			// blowing up image height if height lower screen height
			if (height < $(screen).height()) {
				height = $(screen).height();
				ratio = img.height / $(screen).height();
				width = Math.round(img.width / ratio);
			}
		}
		
		// screen format portrait (screen ratio < 1)
		if (($(screen).width() / $(screen).height()) < 1) {
			// setting image height to screen height
			height = $(screen).height();
			ratio = img.height / $(screen).height();
			width = Math.round(img.width / ratio);
			// blowing up image width if width smaller than screen width
			if (width < $(screen).width()) {
				width = $(screen).width();
				ratio = img.width / $(screen).width();
				height = Math.round(img.height / ratio);
			}
		}
		
		// calculating top and left offset values regarding to screen
		left = new String(0 - Math.round((width - $(screen).width()) / 2));
		top = new String(0 - Math.round((height - $(screen).height()) / 2));
		
		return { 'width': new String(width), 'height': new String(height), 'top': top, 'left': left };
	},
	resize: function(display) {
		
		var $this = this;
		
		$(window).bind('resize', function() {
			
			// resizing display viewport according to window size
			$(display).css({'width':$(this).width()+'px','height':$(this).height()+'px'});
			
			// resizing canvas according to display viewport
			$(display).find('.canvas').css({'width':$(this).width()+'px','height':($(this).height()-60)+'px'});
			
			// resizing picture
			var img = new Image(); img.src = $(display).find('.image').attr('src');
			var size = $this.scale($(display).find('.canvas'), img);
			$(display).find('.image').attr({
				'width':size.width,
				'height':size.height,
				'top':size.top+'px',
				'left':size.left+'px'
			});
			
		});
	},
	detach: function(bool) {
		
		// detach events
		$(window).unbind('resize');
		$(window).unbind('keyup');
		
		// removing controls immediately
		$(".cinema").find('.controls').each(function() { $(this).remove(); });
		$.fn.mediabox.controls();
		
		// fading closer element out and remove from dom tree
		this.closer.hide(function() { $(".closer").remove(); });
		
		$(".cinema").find(".canvas .image").fadeOut('slow', function() {
			
			$(this).parent().parent().find('.head').animate({
				'top':'-60px'
			}, 1000, function() {
				
				// fading out overlay background layer
				$(".overlay").fadeOut('slow', function() {
					$(".cinema").remove(); $(this).remove();
				});
				
			});
		});
		
	},
	next: function(callback) {
		
		var $this = this;
		
		$.fn.mediabox.next(function() {
			
			// fade out current image view
			$(".cinema").find('.image').animate({
				'opacity':'0'
			}, 500, function() {
				
				// getting new image source to load from launcher
				var src = $($.fn.mediabox.defaults.mediabox).find('.launcher a').attr('href');
				
				// getting new description label
				var desc = $($.fn.mediabox.defaults.mediabox).find('.launcher p').html();
				
				// loading new image into canvas
				$this.load(src, $(".cinema").find('.canvas'), function() {
					// remove ajax loader icon from canvas on success
					$(".cinema").find('.canvas').find('.loader').remove();
					// update label of closer element
					$this.closer.update(desc);
					// execute callback on controller (return caller)
					if (typeof callback == "function")
						callback.call($this);
					
				});
			});
		});
	},
	prev: function(callback) {
		
		var $this = this;
		
		$.fn.mediabox.prev(function() {
			
			// fade out current image view
			$(".cinema").find('.image').animate({
				'opacity':'0'
			}, 500, function() {
				
				// getting new image source to load from launcher
				var src = $($.fn.mediabox.defaults.mediabox).find('.launcher a').attr('href');
				
				// getting new description label
				var desc = $($.fn.mediabox.defaults.mediabox).find('.launcher p').html();
				
				// loading new image into canvas
				$this.load(src, $(".cinema").find('.canvas'), function() {
					// remove ajax loader icon from canvas on success
					$(".cinema").find('.canvas').find('.loader').remove();
					// update label of closer element
					$this.closer.update(desc);
					// execute callback on controller (return caller)
					if (typeof callback == "function")
						callback.call($this);
				});
			});
		});
	},
	hasNext: function() {
		return $.fn.mediabox.hasNext();
	},
	hasPrev: function() {
		return $.fn.mediabox.hasPrev();
	},
	closer: {
		obj: false,
		init: function(display, mediabox, opts) {
			
			// getting description from current mediabox impression
			var desc = $(mediabox).find('.launcher p').html();
			
			// create closer element layer
			this.obj = $("<div></div>").addClass('closer')
				.append($("<a></a>").attr({'href':'javascript:void(0);'})
					.append($("<img />").attr({
					'src': opts.basepath+opts.icons['closer']['src'],
					'width': opts.icons['closer']['width'],
					'height': opts.icons['closer']['height'],
					'alt': ''
				}))).append($("<p></p>").html(desc));
				
			// adding onclick event to close cinema display
			$(this.obj).one('click', function() {
				display.detach(true);
				return false;
			});
			
			// attaching closer to document body
			$("body").append(this.obj);
			
			// animating closer into window
			$(this.obj).animate({
				'bottom':'0px'
			}, 1000, 'easeOutQuint', function() { });
			
			return this;
			
		},
		update: function(desc) {
			$(this.obj).find('p').fadeOut('fast', function() {
				$(this).html(desc); $(this).fadeIn('slow');
			});
		},
		hide: function(callback) {
			$(this.obj).animate({
				'bottom':'-40px'
			}, 1000, 'easeInQuint', function() {
				if (typeof callback == "function")
					callback.call(this);	
			});
		}
	},
	loader: {
		init: function(callback) {
			var loader;
			// setting media box defaults
			var o = $.fn.mediabox.defaults;
			// preloading ajac loader icon graphic
			$.fn.mediabox.preload(o.basepath+o.icons['cinemaloader']['src'], function() {
				loader = $("<img />").attr({
					'src':o.basepath+o.icons['cinemaloader']['src'],
					'width':o.icons['cinemaloader']['width'],
					'height':o.icons['cinemaloader']['height'],
					'style':'position:absolute;top:50%;left:50%;'
				}).css({'display':'block'})
					.css({'margin-top':'-'+Math.round(parseInt(o.icons['cinemaloader']['height'])/2)+'px'})
					.css({'margin-left':'-'+Math.round(parseInt(o.icons['cinemaloader']['width'])/2)+'px'})
					.addClass('loader');
				if (typeof callback == "function")
					callback.call(loader);
			});
		}
	},
	debug: function($msg) {
		if (window.console && window.console.log)
			window.console.log('debug: '+$msg);
	}
}
