var TemplatePreview = Class.create({
	initialize: function(thumbnailImg, previewOptions) 
  				{
    				this.thumbnailImg = $(thumbnailImg);
    				this.previewOptions = previewOptions || {};

					this.thumbnailImg.observe('mouseover', this.onMouseOver.bindAsEventListener(this));
					this.thumbnailImg.observe('mouseout', this.onMouseOut.bindAsEventListener(this));

    				// Cache the bound onMouseMove handler for Event.stopObserving method
    				this.onMouseMoveHandler = 	function(event) 
												{
      												PreviewWindow.getInstance().followMouse(event.pointerX(), event.pointerY());
    											}.bindAsEventListener(this);
  				},

	onMouseOver:function(event) 
  				{
    				this.thumbnailImg.observe('mousemove', this.onMouseMoveHandler);
    				PreviewWindow.getInstance().show(event.pointerX(), event.pointerY(), this.previewOptions);
  				},

  	onMouseOut: function(event) 
  				{
    				this.thumbnailImg.stopObserving('mousemove', this.onMouseMoveHandler);
    				PreviewWindow.getInstance().hide();
  				}
});

var PreviewWindow = Class.create({
	initialize:	function() 
				{
					this.windowElement = new Element('div', {id:'tplPreview', style:'display:none; position:absolute;'});
					//this.titleElement = new Element('h2', {id:'tplPreviewTitle'});
					this.imageElement = new Element('img', {id:'tplPreviewImage'});
					this.progressBarElement = new Element('div', {id:'tplPreviewProgressBar', style:'display:none;'});
    				//this.windowElement.insert(this.titleElement).insert( new Element('div', {id:'tplPreviewBody'}).insert( this.imageElement ).insert(this.progressBarElement.update('Loading template preview...')));
					this.windowElement.insert( new Element('div', {id:'tplPreviewBody'}).insert( this.imageElement ).insert(this.progressBarElement.update('Loading template preview...')));
					//document.body.insert(this.windowElement);
					$(document.body).insert(this.windowElement);
				},

  	loadPreview:function(options) 
				{
    				//this.titleElement.update(options.title);
    				var oldImg = this.imageElement;
    				this.imageElement = new Element('img', {
											  id: 'tplPreviewImage',
											  src: options.src,
											  width: options.width,
											  height: options.height
    				});
    				oldImg.replace(this.imageElement);
    				if (!this.imageElement.complete) 
					{
      					this.progressBarElement.show();
      					this.imageElement.observe('load', function(event) {
        													this.progressBarElement.hide();
      														}.bindAsEventListener(this));
    				}
					// Refresh this.width, this.height
    				Object.extend(this, this.windowElement.getDimensions());
  				},
	
	show: 		function(x, y, options) 
				{
    				var viewport = document.viewport.getDimensions();
    				if (viewport.width < 600 || viewport.height < 450) 
					{
      					return;
    				}

    				if (typeof options == 'object') 
					{
      					this.loadPreview(options);
    				}
    				this.followMouse(x, y);
    				this.timerId = function() {
      									if (this.imageElement.src.length > 0) 
										{
        									this.windowElement.show();
      									}
    								}.bind(this).delay(0.25);
  				},

  	hide: 		function() 
				{
    				window.clearTimeout(this.timerId);
					this.windowElement.hide();
					this.windowElement.setStyle({ top: '-' + this.height + 'px', left: '-' +  this.width + 'px'});
  				},

  	followMouse:function(mouseX, mouseY) 
				{
					var x = 0, y = 0;
					var mouseOffset = 24;
					var mouseXpos = '', mouseYpos = '';
				
					var viewport = Object.extend( document.viewport.getDimensions() , document.viewport.getScrollOffsets() );
					mouseX -= viewport.left;
					mouseY -= viewport.top;
	    			if (mouseY + mouseOffset < (viewport.height - this.height) / 2) 
					{
      					mouseYPos = 'top';
      					y = mouseY + mouseOffset;
    				} 
					else if (mouseY - mouseOffset > (viewport.height + this.height) / 2) 
					{
						mouseYPos = 'bottom';
						y = mouseY - mouseOffset - this.height;
    				}	 
					else 
					{
      					mouseYPos = 'middle';
      					y = (viewport.height - this.height) / 2;
    				}
    				if (mouseYPos != 'middle' && ((mouseX + mouseOffset > (viewport.width - this.width) / 2) && (mouseX - mouseOffset < (viewport.width + this.width) / 2))) 
					{
      					mouseXPos = 'center';
      					x = (viewport.width - this.width) / 2;
    				} 
					else if (mouseX > viewport.width / 2) 
					{
      					mouseXPos = 'right';
      					x = mouseX - mouseOffset - this.width;
    				} 
					else 
					{
      					mouseXPos = 'left';
      					x = mouseX + mouseOffset;
    				}
    				this.windowElement.setStyle({top: y + viewport.top + 'px',left: x + viewport.left + 'px'});
  				}
			});

PreviewWindow.getInstance = function() 
							{
	  							if (PreviewWindow.instance == null) 
								{
    								PreviewWindow.instance = new PreviewWindow();
  								}
  								return PreviewWindow.instance;
							}