var DEBUG_OBSERVER = false;
var Observer = (function() { 
	// Private members. 
	var eventListeners = [];
	var debug = DEBUG_OBSERVER || false;
	function _debug(str){
		if (debug && console && console.log){
			console.log('Observer debug message: ' + str);			
		}
	};
	function _removeListener(name, callback){
		var spliceElement = [name, callback];
		for(var i = 0, len = eventLiseners.length; i < len; i++){
			if(eventListeners[i] == spliceElement){
				eventListeners.splice(i);
				break;
			}
		}
		return this;
	};
	function _sendEvent(name, args){
		for(var listener in eventListeners){
			if(eventListeners[listener][0] == name){
				// call the callback
				_debug('Called listener by event ' + name);
				eventListeners[listener][1](args);
				
			}
		}	
		return this;
	};
	
	return { // Public members. 	 
	addListener: function(name, callback) { 
		eventListeners.push([ name, callback ]);
		_debug('Added listener by event name ' + name);
		return this;
	},
	addEvent: function(name, args){
		_sendEvent(name, args);
		return this;
	},
	removeListener: function(name, callback){
		_removeListener(name, callback);
		return this;
	}
}})();

var Preview = (function(){
		/**
		 *  Local method to show/hide progress bar
		 */
		var that = this;
		that.offset = { top : 0, left : 0 };
		that.size = { width: 0, height: 0 };
		that.elem = null;
		
		// constants and properties		
		that.previewImage = null;
		that.smallImg = null;
		that.preview = null;
		
		that.img = null;
		that.dstWidth = 0;
		that.dstHeight = 0;	
		
		that.srcWidth = 140;
		that.srcHeight = 298;
		that.dstWidth = 0;
		that.dstHeight = 0;	
		that.enlargeImg = null;
		that.enlargeLoaded = false;
		that.reflection = null;
		that.preloaderVisible = false;
		that.visible = false;
		
		var showProgress = function(){
			if(that.preloaderVisible)return;
			var img = $('#preloader').clone();			
			$('body').append(img);
			that.preloaderImage = img;
			img.hide();
			var offset = that.smallImg.offset();

			styleImage(img, offset.top + 177, offset.left + 43, 1010);
			img.fadeIn(50, function(){
				that.preloaderVisible = true;
			});
		};
		var hideProgress = function(){
			if(!that.preloaderVisible)return;
			img.fadeOut(50, function(){ that.preloaderImage.remove(); that.preloaderVisible = false;});			
		};
		var styleImage = function(img, top, left, index){
			img.css('position', 'absolute');
			img.css('z-index', index);
			img.css('top', top + 'px');
			img.css('left', left + 'px');
		};
		
		
		var enlargePreview = function(){
			var enlargeImg = that.enlargeImg;
			var dstWidth = that.dstWidth;
			var dstHeight = that.dstHeight;
			
			var top = $(document).scrollTop();
			var left = Math.floor($(window).width()/2 - dstWidth/2);
			that.offset.top = top;
			that.offset.left = left;
			that.size.width = dstWidth;
			that.size.height = dstHeight;
			
			enlargeImg.animate({
				'left' : left + 'px',
				'top' : top + 'px',
				'width' : dstWidth,
				'height' : dstHeight
			}, 200, null, function(){
				Observer.addEvent('preview', this);			
			});
			
		}
		
		var loadReflection = function(){
			if(that.reflection != null){
				Observer.addEvent('reflectionLoaded');
				return;
			}
			var offset = that.offset;
			var reflection = new Image(that.dstWidth, that.dstHeight);
			reflection.src = $('#iphoneReflection').attr('src');
			
			reflection.onload = function(){
				$('body').append(reflection);
				reflection = $(reflection);
				styleImage(reflection, offset.top, offset.left, 1001);
				reflection.hide();
				that.reflection = reflection;
				
				Observer.addEvent('reflectionLoaded');
			}
		}
		
		/**
		 *  show reflection of the iPhone Preview
		 */
		var showReflection = function(){					
			that.reflection.fadeIn(350, function(){				
				Observer.addEvent('reflectionCreated');
				Observer.addEvent('hideProgress');
			});				
		};
		/**
		 *  Hide and destroy reflection
		 */
		var hideReflection = function(){
			that.reflection.fadeOut(350, function(){
				$(this).remove();
				that.reflection = null;
				Observer.addEvent('reflectionDestroyed');
			});		
		};
		var hideEnlarge = function(){
			//reflectionDestroyed
			that.enlargeImg.fadeOut('150', function(){
				$(this).remove();
				Observer.addEvent('enlargeDestroyed');
			});						
		};
		
		var createEnlarge = function(){	
			Observer.addEvent('showProgress');
			
			// load
			var enlargeImg = new Image(that.dstWidth, that.dstHeight);
			enlargeImg.src = that.previewImage;		
			enlargeImg.width = that.srcWidth;
			enlargeImg.height = that.srcHeight;
			enlargeImg.onload = function(){ that.enlargeLoaded = true; Observer.addEvent('enlargeCreated'); };		
			enlargeImg = $(enlargeImg);

			// offsets
			styleImage(enlargeImg, that.preview.top, that.preview.left, 1050);
			enlargeImg.css('cursor', 'pointer');
			enlargeImg.hide();

			// append to document body
			$('body').append(enlargeImg);
			
			that.enlargeImg = enlargeImg;
			
			if(that.enlargeLoaded == true){				
				Observer.addEvent('enlargeCreated');
			}
		};
		
		var enlargeImage = function(){
			var maxHeight = $(window).height();
			Observer.addEvent('hideProgress');
			if(maxHeight < that.dstHeight){
				var coef = maxHeight/that.dstHeight;
				that.dstHeight = maxHeight;
				that.dstWidth = that.dstWidth * coef;		
			}
			that.enlargeImg.fadeIn(50, function(){
				Observer.addEvent('previewPositioned')
			});			
		};
	
	// add event listeners
	Observer.addListener('preview', loadReflection);
	Observer.addListener('reflectionLoaded', showReflection);
	Observer.addListener('previewPositioned', enlargePreview);
	Observer.addListener('enlargeCreated', enlargeImage);
	Observer.addListener('createEnlarge', createEnlarge);
	Observer.addListener('hide', hideReflection);
	Observer.addListener('reflectionDestroyed', hideEnlarge);
	Observer.addListener('showProgress', showProgress);
	Observer.addListener('hideProgress', hideProgress);
	
	return {
		show : function(elem){
			if(that.visible == true){
				return;
			}
			// define constants
			that.elem = elem;
			that.preview = $('#preview-image').offset();
			that.previewImage = elem.attr('href');
			that.smallImg = elem.find('img:first');
			
			that.img = $('#iphoneImage');
			that.dstWidth = that.img.attr('width');
			that.dstHeight = that.img.attr('height');				
			
			
			// hide on escape key
			elem.keyup(function(k){
				if(k.keyCode == 27){
					Preview.hide();
				}
			});
			
			// hide on click
			Observer.addListener('enlargeCreated', function(){ 
				that.enlargeImg.click(Preview.hide); 
			});
			Observer.addEvent('createEnlarge', elem);
			that.visible = true;			
		},
		hide : function(){
			Observer.addEvent('hide');
			that.visible = false;
		}
}})();
