
/**
 * Provides a zoom effect
 */

(function() {

	var Preview = function(element, previewBox) {
		this.element = element;
		this.previewBox = previewBox;
		this.initialize();
	};

	// bind events and prepare the preview
	Preview.prototype.initialize = function() {
		// add an overlay shim
		this.element.append('<span class="previewoverlay"> </span>');

		var over = function(preview) { return function(e) { preview.load(e); }; }(this);
		var out = function(preview) { return function(e) { preview.hide(e); }; }(this);

		// why does hoverIntent not work on Opera?
		if(jQuery.browser.opera) {
			jQuery(this.element).hover(over,out);
		} else {
			jQuery(this.element).hoverIntent({
				sensitivity: 3,
				interval: 50,
				over: over,
				timeout: 0,
				out: out
			});
		}

		// fire preload on mouseover
		jQuery(this.element).mouseover(
			function(preview) { return function(e) { preview.preload(e); }; }(this));
	};

	// builds an image url from the preview image/link used
	Preview.prototype.getImageUrl = function(size) {

		var thumbImage = this.element.find('img'),
			url = (thumbImage.length ?
				thumbImage.attr('src') : this.element.attr('href')),
			designId = url.match(/(\d+)(?:\D+)?$/)[1];

		return '/designs/' + designId + '-' + size;
	};

	// preloads an image for later use
	Preview.prototype.preload = function() {
		if(!this.image) {
			var url = this.getImageUrl('largecrop');
			this.image = new Image();
			this.image.src = url;
		}
	};

	// load the preview image, show the preview when ready
	Preview.prototype.load = function(e) {
		this.previewImage = jQuery(document.createElement('img'));
		this.previewBox.find('img').remove();
		this.previewBox.append(this.previewImage);
		this.previewImage.attr('src',this.getImageUrl('largecrop'));
		this.show();
	};

	// display the preview box
	Preview.prototype.show = function(e) {
		window.activePreview = this;

		// display the preview
		this.move(window.mouseX,window.mouseY);
		this.previewBox.show();

		this.element.bind('mousemove',function(preview) {
			return function(e) {
				preview.move(e.pageX, e.pageY);
			};
		}(this));
	};

	// hide the preview box
	Preview.prototype.hide = function(e) {
		this.previewBox.hide();
		this.element.unbind('mousemove');
		window.activePreview = false;
	};

	// move the preview to as close to the provided x and y as possible
	Preview.prototype.move = function(x,y) {
		var viewport = {};
		viewport.x = $(window).scrollLeft();
		viewport.y = $(window).scrollTop();
		viewport.cx = $(window).width();
		viewport.cy= $(window).height();
		var height = 378;
		var width = 508;
		var xdiff = (viewport.x + viewport.cx) - (x + width);
		var ydiff = (viewport.y + viewport.cy) - (y + height);

		// handle clashing by flipping image to other side of mouse
		if(xdiff < 0) x = x - width - 80;
		if(ydiff < 0) y = y - height - 30;

		var bodyOffset = jQuery(document.body).offset();
		var left = x - bodyOffset.left + 20;
		var top = y - bodyOffset.top + 20;

		this.previewBox.css('left', left+'px').css('top', top+'px');
	};

	// add a globally accessible jQuery plugin interface
	jQuery.fn.imagePreview = function() {
	  return this.each(function(){

		// bind the actual preview object
		if(!this.preview) {
			this.preview = new Preview(jQuery(this),jQuery('#previewbox'));
		}
	  });
	};

	// initialize and bind on ready
	jQuery(document).ready(function(){
		// set up preview div
		if(jQuery('#previewbox').size() == 0) {
			jQuery('body').append('<div id="previewbox"></div>');
			jQuery('#previewbox').hide();
		}

		jQuery('a[rel*=preview]').imagePreview();
	});

	/* make all rel=preview links show previews
	jQuery('a[rel*=preview]').each(function(){

	});*/

	// move the active preview
	window.activePreview = false;
	$().mousemove(function(e){
		window.mouseX = e.pageX;
		window.mouseY = e.pageY;
	});

}());

