/** FancyZoom with Prototype By Jerome GLATIGNY
 * based on : http://github.com/jnunemaker/fancy-zoom
 */
Object.extend(String.prototype, {
	// if a string doesn't end with str it appends it
	ensureEndsWith: function(str) {
		return this.endsWith(str) ? this : this + str;
	},

	// makes sure that string ends with px (for setting widths and heights)
	px: function() {
		return this.ensureEndsWith('px');
	}
});

Object.extend(Number.prototype, {
	// makes sure that number ends with px (for setting widths and heights)
	px: function() {
		return this.toString().px();
	}
});

var WinSize = {
	// returns correct dimensions for window, had issues with prototype's sometimes. this was ganked from apple.
	size: function() {
		var width  = window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth);
		var height = window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight);
		var x      = window.pageXOffset || (window.document.documentElement.scrollLeft || window.document.body.scrollLeft);
		var y      = window.pageYOffset || (window.document.documentElement.scrollTop || window.document.body.scrollTop);
		return {'width':width, 'height':height, 'x':x, 'y':y}
	}
}

var FancyZoomBox = {
	directory : '/rsc/common/img/fancyzoom',
	zooming   : false,
	setup     : false,

	init: function(directory) {
		if (FancyZoomBox.setup) return;
		FancyZoomBox.setup = true;

		var ie = navigator.userAgent.match(/MSIE\s(\d)+/);
		if (ie) {
			var version = parseInt(ie[1]);
			Prototype.Browser['IE' + version.toString()] = true;
			Prototype.Browser.ltIE7 = (version < 7) ? true : false;
		}

		var html = '<div id="fancyoverlay" style="display:none; background-color: Black;"></div> \
			<div id="fancyzoom" style="display:none;"> \
			<table id="zoom_table" style="border-collapse:collapse; width:100%; height:100%;"><tbody><tr>\
			<td class="tl" style="background:url(' + FancyZoomBox.directory + '/tl.png) 0 0 no-repeat; width:20px; height:20px; overflow:hidden;" /> \
			<td class="tm" style="background:url(' + FancyZoomBox.directory + '/tm.png) 0 0 repeat-x; height:20px; overflow:hidden;" /> \
			<td class="tr" style="background:url(' + FancyZoomBox.directory + '/tr.png) 100% 0 no-repeat; width:20px; height:20px; overflow:hidden;" /> \
			</tr><tr> \
			<td class="ml" style="background:url(' + FancyZoomBox.directory + '/ml.png) 0 0 repeat-y; width:20px; overflow:hidden;" /> \
			<td class="mm" style="background:#fff; vertical-align:top; padding:10px;"> \
			<div id="zoom_content"></div> \
			</td> \
			<td class="mr" style="background:url(' + FancyZoomBox.directory + '/mr.png) 100% 0 repeat-y;  width:20px; overflow:hidden;" /> \
			</tr><tr> \
			<td class="bl" style="background:url(' + FancyZoomBox.directory + '/bl.png) 0 100% no-repeat; width:20px; height:20px; overflow:hidden;" /> \
			<td class="bm" style="background:url(' + FancyZoomBox.directory + '/bm.png) 0 100% repeat-x; height:20px; overflow:hidden;" /> \
			<td class="br" style="background:url(' + FancyZoomBox.directory + '/br.png) 100% 100% no-repeat; width:20px; height:20px; overflow:hidden;" /> \
			</tr></tbody></table>\
			<a href="#" title="Close" id="zoom_close" style="position:absolute; top:0; right:0;"><img src="' + FancyZoomBox.directory + '/closebox.png" alt="Close" style="border:none; margin:0; padding:0;" /></a>\
			</div> \
			<div id="fancyloading" style="display:none;"><div style="width:100%; text-align: center"><img src="' + FancyZoomBox.directory + '/loading.gif" alt="loading"/></div></div>';

		var body  = $$('body').first();
		body.insert(html);

		FancyZoomBox.zoom = $('fancyzoom');
		FancyZoomBox.overlay = $('fancyoverlay');
		FancyZoomBox.zoom_table = $('zoom_table');
		FancyZoomBox.zoom_close = $('zoom_close');
		FancyZoomBox.zoom_content = $('zoom_content');
		FancyZoomBox.zoom_close.observe('click', FancyZoomBox.hide);
		FancyZoomBox.middle_row = $A([$$('td.ml'), $$('td.mm'), $$('td.mr')]).flatten();
		FancyZoomBox.cells = FancyZoomBox.zoom_table.select('td');

		// hide zoom if click fired is not inside zoom
		$$('html').first().observe('click', function(e) {
			var click_in_zoom = e.findElement('#fancyzoom'),
				zoom_display  = FancyZoomBox.zoom.getStyle('display');
			if (zoom_display == 'block' && !click_in_zoom) {
				FancyZoomBox.hide(e);
			}
		});

		// esc to close zoom box
		$(document).observe('keyup', function(e) {
			var zoom_display = FancyZoomBox.zoom.getStyle('display');
			if (e.keyCode == Event.KEY_ESC && zoom_display == 'block') {
				FancyZoomBox.hide(e);
			}
		});

		// just use gifs as ie6 and below suck
		if (Prototype.Browser.ltIE7) {
			FancyZoomBox.switchBackgroundImagesTo('gif');
			var loading = $('fancyloading');
			loading.setStyle({ width: '240px', height: '100px' });
		}
	},

	show: function(e, elem, cur_x, cur_y) {
		var event = false;
		if( typeof(e) == 'object' ) event = true;
		if( event ) e.stop();
		if (FancyZoomBox.zooming) return;
		FancyZoomBox.zooming = true;
		var element;
		var related_div;
		if( event ) {
			element = e.findElement('a');
			related_div = element.content_div;
		} else {
			element = {};
			related_div = $(elem);
		}
		var width         = (element.zoom_width || related_div.getWidth()) + 60;
		var height        = (element.zoom_height || related_div.getHeight()) + 60;
		var d             = WinSize.size();
		var yOffset       = document.viewport.getScrollOffsets()[1];
		// ensure that newTop is at least 0 so it doesn't hide close button
		var newTop        = Math.max((d.height/2) - (height/2) + yOffset, 0);
		var newLeft       = (d.width/2) - (width/2);
		if( event ) {
			FancyZoomBox.curTop  = e.pointerY();
			FancyZoomBox.curLeft = e.pointerX();
		} else {
			FancyZoomBox.curTop  = cur_y;
			FancyZoomBox.curLeft = cur_x;
		}
		FancyZoomBox.moveX   = -(FancyZoomBox.curLeft - newLeft);
		FancyZoomBox.moveY   = -(FancyZoomBox.curTop - newTop);
		var winW = window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth);
		var winH = window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight);
		if (Prototype.Browser.ltIE7) { 
			var lh = 0;
			if( navigator.appVersion.indexOf("Win") != -1 )
				lh = document.documentElement.scrollHeight;
			else
				lh = document.documentElement.offsetHeight;
			if( lh < d.height ) lh = d.height;
			FancyZoomBox.overlay.hide().setStyle({ position: 'absolute', top: '0px', left:'0px', height: lh.px(), width: (d.width).px() });
		}else{
			FancyZoomBox.overlay.hide().setStyle({
				position : 'fixed',
				top	     : '0px',
				left     : '0px',
				width    : '100%',
				height   : '100%'
			});
		}
		FancyZoomBox.zoom.hide().setStyle({
			position : 'absolute',
			top      : FancyZoomBox.curTop.px(),
			left     : FancyZoomBox.curLeft.px()
		});

		new Effect.Parallel([
			new Effect.Appear(FancyZoomBox.zoom, {sync:true}),
			new Effect.Appear(FancyZoomBox.overlay, {sync:true, from: 0.0, to: 0.8}),
			new Effect.Move(FancyZoomBox.zoom, {x: FancyZoomBox.moveX, y: FancyZoomBox.moveY, sync: true}),
			new Effect.Morph(FancyZoomBox.zoom, {
				style: { width: width.px(), height: height.px() },
				sync: true,
				beforeStart: function(effect) {
					// middle row height must be set for IE otherwise it tries to be "logical" with the height
					if (Prototype.Browser.IE) {
						FancyZoomBox.middle_row.invoke('setStyle', {height:(height-40).px()});
					}
					FancyZoomBox.fixBackgroundsForIE();
				},
				afterFinish: function(effect) {
					FancyZoomBox.zoom_content.innerHTML = related_div.innerHTML;
					FancyZoomBox.unfixBackgroundsForIE();
					FancyZoomBox.zoom_close.show();
					FancyZoomBox.zooming = false;
					if( related_div == $('fancyloading') ) {
						FancyZoomBox.loadImage(e, element);
					}
				}
			})
		], { duration: 0.5 });
	},

	// Special feature which load the dest image and morph it
	loadImage: function(e, element) {
			var imgloader = new Image();
			imgloader.onload = (function(){
				element.content_div = Builder.node('div');
				element.content_div.hide();
				var html = '<img src="' + element.readAttribute('href') + '" alt=""/>';
				element.content_div.insert(html);
				var body  = $$('body').first();
				body.appendChild(element.content_div);

				var width   = element.content_div.getWidth() + 60;
				var height  = element.content_div.getHeight() + 60;
				var d       = WinSize.size();
				var yOffset = document.viewport.getScrollOffsets()[1];
				var newTop  = Math.max((d.height/2) - (height/2) + yOffset, 0);
				var newLeft = (d.width/2) - (width/2);
				FancyZoomBox.moveX     = -(FancyZoomBox.curLeft - newLeft);
				FancyZoomBox.moveY     = -(FancyZoomBox.curTop - newTop);

				FancyZoomBox.zoom_close.hide();
				FancyZoomBox.zooming = true;
				new Effect.Parallel([
					new Effect.Move(FancyZoomBox.zoom, {x: newLeft, y: newTop, mode: 'absolute', sync: true}),
					new Effect.Morph(FancyZoomBox.zoom, { 
						style: {
							width: width.px(),
							height: height.px()
						},
						sync: true,
						beforeStart: function(effect) {
							FancyZoomBox.fixBackgroundsForIE();
						},
						afterFinish: function(effect) {
							FancyZoomBox.zoom_content.innerHTML = element.content_div.innerHTML;
							FancyZoomBox.unfixBackgroundsForIE();
							FancyZoomBox.zoom_close.show();
							FancyZoomBox.zooming = false;
						}
					})
				], { duration: 0.5 });
			}).bind(this);
			if( typeof(element) != "undefined") {
				imgloader.src = element.readAttribute('href');
			} else {
				alert("error");
			}
	},

	hide: function(e) {
		if( typeof(e) == 'object') e.stop();
		if (FancyZoomBox.zooming) return;
		FancyZoomBox.zooming = true;		
		new Effect.Parallel([
			new Effect.Move(FancyZoomBox.zoom, {x: FancyZoomBox.moveX*-1, y: FancyZoomBox.moveY*-1, sync: true}),
			new Effect.Morph(FancyZoomBox.zoom, {
				style: {
					width: '1'.px(),
					height: '1'.px()
				},
				sync : true,
				beforeStart: function(effect) {
					FancyZoomBox.fixBackgroundsForIE();
					FancyZoomBox.zoom_content.innerHTML = '';
					FancyZoomBox.zoom_close.hide();
				},
				afterFinish: function(effect) {
					FancyZoomBox.unfixBackgroundsForIE();
					FancyZoomBox.zooming = false;
				}
			}),
			new Effect.Fade(FancyZoomBox.zoom, {sync:true}),
			new Effect.Fade(FancyZoomBox.overlay, {sync:true})
		], { duration: 0.5 });
	},

	// switches the backgrounds of the cells and the close image to png's or gif's
	// fixes ie's issues with fading and appearing transparent png's with 
	// no background and ie6's craptacular handling of transparent png's
	switchBackgroundImagesTo: function(to) {
		FancyZoomBox.cells.each(function(td) {
			var bg = td.getStyle('background-image').gsub(/\.(png|gif|none)\)$/, '.' + to + ')');
			td.setStyle('background-image: ' + bg);
		});
		var close_img = FancyZoomBox.zoom_close.firstDescendant();
		var new_img = close_img.readAttribute('src').gsub(/\.(png|gif|none)$/, '.' + to);
		close_img.writeAttribute('src', new_img);
	},

	// prevents the thick black border that happens when appearing or fading png in IE
	fixBackgroundsForIE: function() {
		if (Prototype.Browser.IE7) { FancyZoomBox.switchBackgroundImagesTo('gif'); }
	},

	// swaps back to png's for prettier shadows
	unfixBackgroundsForIE: function() {
		if (Prototype.Browser.IE7) { FancyZoomBox.switchBackgroundImagesTo('png'); }
	}
}

var FancyZoom = Class.create({
	initialize: function(element) {
		this.options = arguments.length > 1 ? arguments[1] : {};
		FancyZoomBox.init();
		this.element = $(element);
		if (this.element) {
			var ref = this.element.readAttribute('href');
			if( ref.substr(0,1) == '#' ) {
				this.element.content_div = $(this.element.readAttribute('href').gsub(/^#/, ''));
				this.element.content_div.hide();
			} else {
				this.element.content_div = $('fancyloading');
			}
			this.element.zoom_width = this.options.width;
			this.element.zoom_height = this.options.height;
			this.element.observe('click', FancyZoomBox.show);
		}
	}
});

document.observe('dom:loaded', function () {
	$$('a[rel="zoom"]').each(function(el) { new FancyZoom(el); }) 
});
document.observe('ajax:load', function () {
	$$('a[rel="zoom"]').each(function(el) { new FancyZoom(el); }) 
});