﻿/*
 *
 *	QuickBox (Another Lightbox clone)
 *
 *	Version: 1.0
 *	Documentation: AndrewPlummer.com (http://www.andrewplummer.com/code/quickbox/)
 *	Heavily inspired by: Slimbox by Christophe Beyls (http://www.digitalia.be)
 *	Written for: Mootools 1.2
 *	License: MIT-style License
 *	
 *	Copyright (c) 2008 Andrew Plummer
 *
 *
 */

var QuickBox = new Class({


	Implements: Options,

	options: {
		resizeDuration: 250,
		resizeTransition: Fx.Transitions.Circ.easeOut,
		initialWidth: 800,
		initialHeight: 600,
		padding: 0,
		animateCaption: true,
		counter: "Image {NUM} of {TOTAL}"
	},

	initialize: function(options){
	

		this.setOptions(options);
		this.anchors = $$("a[rel=quickbox]");
		this.anchors.each(function(a){
			a.store("caption", a.get("title") || a.getElement("img").get("alt"));
			a.addEvent("click", this.open.bindWithEvent(this, a));
		}, this);
		
		
		this.overlay = new Element("div", {
			id: "qbOverlay",
			events: {
				//click: this.close.bindWithEvent(this)
			}
		}).inject(document.body, "top");
		
		this.quickBox = new Element("div", {
			id: "qbBox",
			styles: {
				width: this.options.initialWidth,
				height: this.options.initialHeight,
				marginLeft: -(this.options.initialWidth/2),
				position: "absolute"
			}
		}).inject(document.body, "top");
		
		this.prevLink = new Element("a", {id: "qbPrev", href: "#"}).inject(this.quickBox);		
		this.nextLink = this.prevLink.clone().setProperty("id", "qbNext").injectInside(this.quickBox);
		
		//////////////////////////////////// OVER LEFT EVENT
		/*this.prevLink.addEvent('mouseenter', function(e){
			this.setStyle('cursor','url(' + base_url + '"libraries/img/prev.jpg")');
			alert(event.client.x);
		});*/
		/////////////////////////////////////////////////////////////////////////////
		
		this.stage = new Element("div", {id: "qbStage"}).inject(this.quickBox);
		
		this.prevLink.addEvent("click", this.changeImage.bindWithEvent(this, -1));
		this.nextLink.addEvent("click", this.changeImage.bindWithEvent(this, 1));

		this.bottom = new Element("div", {id: "qbBottom"}).inject(document.body);
		
		this.closeButton = new Element("div", {
			id: "qbClose",
			events: {
				click: this.close.bindWithEvent(this)
			}
		}).inject(this.bottom);
		
		this.caption = new Element("div", {id: "qbCaption"}).inject(this.bottom);
		this.counter = new Element("div", {id: "qbCounter"}).inject(this.bottom);
				
		var nextEffect = this.nextEffect.bind(this);
		
		this.fx = {
			overlay: new Fx.Tween(this.overlay, {
				property: "opacity"
			}),
			resize: new Fx.Morph(this.quickBox, {
				duration: this.options.resizeDuration,
				transition: this.options.resizeTransition,
				onComplete: nextEffect
			}),
			show: new Fx.Tween(this.stage, {
				property: "opacity",
				onComplete: nextEffect
			}),
			bottom: new Fx.Tween(this.bottom, {
				property: "top",
				duration: 400,
				onComplete: nextEffect
			})
		};

		this.active = false;
		//document.addEvent("mousewheel", this.mouseWheelListener.bindWithEvent(this));
		document.addEvent("keydown", this.keyboardListener.bindWithEvent(this));
				
	},

	open: function(event, link){
	
		this.active = true;
						
		var size = window.getSize();
		var scroll = window.getScroll();
		var scrollSize = window.getScrollSize();
		
		/* The images should be 640x480(max). They're easily clipped at 1024x768,
		 * so we get them as close as possible to the top of the window. */
		var offset = Math.round((size.y < 768) ? size.y / 36 : size.y / 10);
		
		var top = 50;
		
		this.overlay.setStyles({
			opacity: 0,
			display: "block"
			//width: scrollSize.x,
			//height: scrollSize.y
		});
		this.quickBox.setStyles({
			display: "block",
			top: top
		});
		this.fx.overlay.start(1);
		this.startLoad(link);
		
		return false;
	},
	
	startLoad: function(link, preload){
	
		if(!link) return;
		var image = new Asset.image(link.get("href"), {
			onload: function(){
				if(!preload && this.currentLink == link) this.nextEffect();
			}.bind(this)
		});
		if(!preload){
			this.stage.addClass("loading");
			this.stage.setStyle("display", "block");
			this.stage.empty();
			this.bottom.setStyle("opacity", 0);
			this.prevLink.setStyle("display", "none");
			this.nextLink.setStyle("display", "none");
			this.currentLink = link;
			this.currentCaption = link.retrieve("caption");
			this.currentImage = image;
			this.currentIndex = this.anchors.indexOf(link);
			this.step = 1;
		}
	},

	keyboardListener: function(event){
		if(!this.active) return;
		if(event.key != "f5") event.preventDefault();
		switch (event.key){
			case "esc": case "x": case "q": this.close(); break;
			case "b": case "p": case "left": this.changeImage(event, -1); break;	
			case "f": case "n": case "right": this.changeImage(event, 1);
		}
	},


	/*mouseWheelListener: function(event){
		if(!this.active) return;
		if(event.wheel > 0) this.changeImage(event, -1);
		if(event.wheel < 0) this.changeImage(event, 1);
	},*/

	changeImage: function(event, step){
		event.preventDefault();
		var link = this.anchors[this.currentIndex+step];
		if(!link) return false;
		for(var f in this.fx) this.fx[f].cancel();
		this.startLoad(link);
	},
	
	nextEffect: function(){
		
		switch(this.step++){
			case 1:
				//var w = this.currentImage.width + this.options.padding * 2;
				//var h = this.currentImage.height + this.options.padding * 2;
				
				var w = window.getWidth() - 200;
				var h = window.getHeight() - 100;
				var newHeight = h;
				var newWidth = w;
				
				if (this.currentImage.width > this.currentImage.height){
					var ratio = this.currentImage.width / this.currentImage.height;
					newHeight = (w / ratio);
					
					if (newHeight > h){
						newHeight = h;
						var ratio =  this.currentImage.height / this.currentImage.width;
						newWidth = (h / ratio);
					}
				}else {
					var ratio =  this.currentImage.height / this.currentImage.width;
					newWidth = (h / ratio);
				}
				
				
				//this.prevLink.setStyle("height", newHeight);
				//this.nextLink.setStyle("height", newHeight);
				this.fx.resize.start({
					width: newWidth,
					height: newHeight,
					marginLeft: -(newWidth/2)
				});	
	
				break;
			case 2:
			
				var w = window.getWidth() - 200;
				var h = window.getHeight() - 100;
				var newHeight = h;
				var newWidth = w;
				
				if (this.currentImage.width > this.currentImage.height){
					
					var ratio = this.currentImage.width / this.currentImage.height;
					newHeight = (w / ratio);
					
					if (newHeight > h){
						newHeight = h;
						var ratio =  this.currentImage.height / this.currentImage.width;
						newWidth = (h / ratio);
					}
					
				}else {
					var ratio =  this.currentImage.height / this.currentImage.width;
					newWidth = (h / ratio);
				}
				
				thisCopy = this;

				this.stage.removeClass("loading");
				this.stage.setStyle("opacity", 0);
				this.currentImage.setStyles({margin: this.options.padding, width: newWidth, height: newHeight});
				this.currentImage.inject(this.stage);
				this.fx.show.start(1);
				
				window.addEvent('resize', function (){
				
					var w = window.getWidth() - 200;
					var h = window.getHeight() - 100;
					var newHeight = h;
					var newWidth = w;
					
					if (thisCopy.currentImage.width > thisCopy.currentImage.height){
						var ratio = thisCopy.currentImage.width / thisCopy.currentImage.height;
						newHeight = (w / ratio);
						
						if (newHeight > h){
							newHeight = h;
							var ratio =  thisCopy.currentImage.height / thisCopy.currentImage.width;
							newWidth = (h / ratio);
						}
					}else {
						var ratio =  thisCopy.currentImage.height / thisCopy.currentImage.width;
						newWidth = (h / ratio);
					}				
					
					thisCopy.currentImage.set('morph', {
						duration: 300
					}).morph({ 
						'width': newWidth,
						'height': newHeight
					});
					
					thisCopy.fx.resize.start({
						width: newWidth,
						height: newHeight,
						marginLeft: -(newWidth/2)
					});	

				});
				
				
				break;
			case 3:
			
				this.prevLink.setStyle("display", "block");
				this.nextLink.setStyle("display", "block");
				if(this.options.animateCaption){
					if(this.options.counter){
						var total = this.anchors.length;
						var num = this.currentIndex + 1;
						var counterText = this.options.counter;
						counterText = counterText.replace(/\{NUM\}/, num);
						counterText = counterText.replace(/\{TOTAL\}/, total);
						//this.counter.set("text", counterText);
					}
					this.caption.set("text", this.currentCaption);
					var height = this.bottom.getStyle("height").toInt();
					this.bottom.setStyles({
						opacity: 1,
						top: -height
					});
					this.fx.bottom.start(0);
				}
				break;
			case 4:
				this.startLoad(this.anchors[this.currentIndex-1], true);
				this.startLoad(this.anchors[this.currentIndex+1], true);
				break;
		}
	},

	close: function(){
		this.quickBox.setStyle("display", "none");
		this.overlay.fade("out");
		this.active = false;
		$('qbBottom').fade("out");
	}
});


