/*
	mizuki lightbox clone
*/


/*jslint browser: true */
/*global window: false, encodeURIComponent: false, decodeURIComponent: false, $: false, MIZUKI: true, alert: false */
/**/

if (typeof MIZUKI === 'undefined') { 
	MIZUKI = {}; 
}

MIZUKI.Lightbox = (function () {
	'use strict';
	var Main = {},
		Fnc = {},
		reLB = /^lightbox/,
		CNST = {
			textPerm1: 'src permalink',
			textPerm2: 'gallery view permalink',
			textShare: 'share on FB',
			textHelp: 'use <b>left arrow</b> or <b>P</b> to navigate to previous image<br/>' + 
				'use <b>right arrow</b> or <b>N</b> to navigate to next image<br/>' +
				'use <b>ESC</b>, <b>X</b> or <b>C</b> to exit<br/>' + 
				'<b>click darkened area</b> to exit<br/>' + 
				'<b>click image border</b> to move image around<br/>',
			parName: '@',
			baseName: '=',
			clsLoading: 'lbLoading',
			cssNodisp: {'display': 'none'},
			cssDisp: {'display': ''},
			cssLink: {
				'position': 'absolute',
				'display': 'block',
				'outline': 'none',
				'width': '50%'
			},
			cssPerma: {
				'color': '#00f'
			},
			/*cssFB: {
				'float': 'right',
				'clear': 'right',
				'margin-top': '.5em'
			},*/
			cssOverlay: {
				'position': 'absolute',
				'z-index': 1000,
				'width': '100%',
				'left': '0',
				'cursor': 'pointer'
			},
			cssOverlay2: {
				'position': 'absolute',
				'z-index': 1100,
				'width': '100%',
				'left': '0',
				'cursor': 'move'
			},
			cssOverlayDim: {
				'position': 'absolute',
				'z-index': 1001,
				'background-color': '#000',
				'width': '100%',
				'height': '100%',
				'opacity': 0.75
			},
			cssOverlayHelp: {
				'position': 'absolute',
				'left': '.5em',
				'bottom': '.5em',
				'border': 'dotted 1px #eee',
				'z-index': 1002,
				'background': '#000', 
				'color': '#ccc',
				'padding': '0.5em', 
				'font-size': '1.5em'
			},
			cssContainer: {
				'position': 'absolute',
				'padding': '2em',
				'z-index': 1010
			},
			cssCenter: {
				'display': 'block',
				'width': '',
				'height': '',
				'cursor': 'auto'
			},
			cssImage: {
				'position': 'relative',
				'cursor': 'auto',
				'background': '#fff center center no-repeat'
			},
			cssBottom: {
				'padding-top': '1em',
				'cursor': 'auto'
			}
		};

	function alignOverlay() {
		var tmp = [Main.jParts.overlay[0], Main.jParts.overlay2[0]];
		$(tmp).css({
			'top': Main.jWin.scrollTop()
		}).height(Main.jWin.height());
	}

	function alignOverlayPos() {
		var tmp = [Main.jParts.overlay[0], Main.jParts.overlay2[0]];
		$(tmp).css({
			'top': Main.jWin.scrollTop()
		});
	}
	
	function getSize(jEl, bOuter) {
		if (typeof bOuter === 'undefined' || !bOuter) {
			return {
				x: jEl.width(),
				y: jEl.height()
			};
		} else {
			return {
				x: jEl.outerWidth(),
				y: jEl.outerHeight()
			};
		}
	}
	
	function alignContainer() {
		var szWin = getSize(Main.jWin),
			szCont = getSize(Main.jParts.container, true),
			pos2, pos3, rbx;
		Main.top = Main.jWin.scrollTop();
		if (!Main.move.posSet) {
			pos3 = {
				left: ((szWin.x - szCont.x) / 2),
				top: ((szWin.y - szCont.y) / 2)
			};
			pos2 = {
				left: Math.max(Main.move.margin, pos3.left),
				top: Math.max(Main.move.margin, pos3.top)
			};
			pos2.top += Main.top;
			Main.jParts.container.offset(pos2);
		} else {
			rbx = Main.move.contPos.left + szCont.x;
			if (Main.alignRight) {
				Main.move.contPos.left = Math.max(Main.move.margin, szWin.x - Main.move.rx - szCont.x);
			} else if (rbx > (szWin.x - Main.move.margin)) {
				Main.move.contPos.left = Math.max(Main.move.margin, szWin.x - Main.move.margin - szCont.x);
			}
			Main.move.contPos.top = Math.max(Main.move.margin, ((szWin.y - szCont.y) / 2)) + Main.top;
			Main.jParts.container.offset(Main.move.contPos);
		}
	}
	
	function evtScroll(evnt) {
		return alignOverlayPos(evnt);
	}
	
	function evtSize(evnt) {
		alignOverlay();
		alignContainer();
	}

	function evtKeyDown(evnt) {
		switch (evnt.keyCode) {
			case 27: case 88: case 67: Main.close(); break;
			case 37: case 80: Main.previous(); break;	
			case 39: case 78: Main.next();
		}
	}
	
	function setup(bStartup) {
		var jElements = $('object, select, embed');
		if (bStartup) { 
			Main.backup = {};
			jElements.each(function () {
				Main.backup[this] = this.style.visibility; 
				this.style.visibility = 'hidden';
			});
			Main.jWin.bind({
				'scroll': evtScroll,
				'resize': evtSize
			});
			Main.jDoc.bind('keydown', evtKeyDown);
			Main.step = 0;
		} else {
			jElements.each(function () {
				this.style.visibility = Main.backup[this];
			});
			Main.jWin.unbind('scroll', evtScroll);
			Main.jDoc.unbind('keydown', evtKeyDown);
		}
	}

	
	// image move handling
	// ->
	
	function resetMove(bUseDrag) {
		var drag = (typeof bUseDrag === 'boolean') ? bUseDrag : (Main.move && Main.move.bUseDrag);
		Main.move = {
			margin: 10,
			clicked: false,
			posSet: false,
			useDrag: drag,
			rx: 0,
			clickPos: {x: 0, y: 0},
			contPos: {x: 0, y: 0},
			contSize: getSize(Main.jParts.container, true)
		};
	}

	function evtMouseMove(evnt) {
		if (Main.move.clicked) {
			Main.top = Main.jWin.scrollTop();
			var sz = getSize(Main.jWin),
				pos3 = {
					left: evnt.pageX - Main.move.clickPos.x + Main.move.contPos.left,
					top: evnt.pageY - Main.move.clickPos.y + Main.move.contPos.top
				},
				pos2 = {
					left: Math.min(sz.x - Main.move.contSize.x - Main.move.margin, pos3.left),
					top: Math.min(sz.y - Main.move.contSize.y - Main.move.margin + Main.top, pos3.top)
				},
				pos1 = {
					left: Math.max(Main.move.margin, pos2.left),
					top: Math.max(Main.move.margin + Main.top, pos2.top)
				};
			Main.move.rx = sz.x - pos1.left - Main.move.contSize.x;
			if (Main.move.rx < Main.move.margin) {
				pos1.left = Math.max(Main.move.margin, sz.x - Main.move.contSize.x - Main.move.rx - Main.move.margin);
				Main.move.rx = Main.move.margin;
			}
			Main.jParts.container.offset(pos1);
			Main.move.posSet = true;
		}
	}

	function evtMouseClick(evnt) {
		if (Main.move.clicked) {
			return Fnc.evtMouseUp(evnt);
		} else {
			if (evnt.target === evnt.currentTarget) {
				return Fnc.evtMouseDown(evnt);
			} else {
				return true;
			}
		}
	}
	
	function evtMouseUp(evnt) {
		if (Main.move.clicked) {
			Main.move.clicked = false;
			Main.move.contPos = Main.jParts.container.offset();
			var wx = Main.jWin.width();
			Main.alignRight = (Main.move.contPos.left + (Main.move.contSize.x / 2)) > (wx / 2);
			Main.jParts.overlay2.css(CNST.cssNodisp);
			if (Main.move.useDrag) {
				Main.jParts.overlay2.unbind('mouseup', Fnc.evtMouseUp);
			} else {
				Main.jParts.overlay2.unbind('click', Fnc.evtMouseClick);
			}
			return false;
		}
	}
	
	function evtMouseDown(evnt) {
		if (evnt.target === evnt.currentTarget) {
			Main.move.clicked = true;
			Main.move.clickPos = { x: evnt.pageX, y: evnt.pageY };
			Main.move.contPos = Main.jParts.container.offset();
			Main.move.contSize = getSize(Main.jParts.container, true);
			Main.jParts.overlay2.css(CNST.cssDisp);
			if (Main.move.useDrag) {
				Main.jParts.overlay2.bind('mouseup', Fnc.evtMouseUp);
			} else {
				Main.jParts.overlay2.bind('click', Fnc.evtMouseClick);
			}
			alignOverlay();
			return false;
		}
	}
		
	Fnc.evtMouseClick = evtMouseClick;
	Fnc.evtMouseUp = evtMouseUp;
	Fnc.evtMouseDown = evtMouseDown;
		
	function initMove(bUseDrag) {
		resetMove(bUseDrag);
		if (bUseDrag) {
			Main.jParts.container.bind({
				'mousedown': evtMouseDown
			}).css('cursor', 'move');
			Main.jDoc.bind({
				'mousemove': evtMouseMove,
				'mouseup': evtMouseUp
			});
		} else {
			Main.jParts.container.bind({
				'click': evtMouseClick
			}).css('cursor', 'auto');
			Main.jDoc.bind({
				'mousemove': evtMouseMove
			});
		}
	}
	// <-
	// image move handling
	

	function open(images, imageNum) {
		Main.images = images;
		alignOverlay();
		setup(true);
		Main.jParts.overlay.css(CNST.cssDisp);
		Main.jParts.container.css($.extend({}, CNST.cssDisp, CNST.cssContainer));
		resetMove();
		alignContainer();
		return Main.changeImage(imageNum);
	}

	function anchorClick(link) {
		if (link.rel === 'lightbox') {
			return Main.show(link.href, link.title);
		}

		var imageNum = -1, 
				images = [];

		$(Main.anchors).each(function () {
			var j;
			if (this.rel === link.rel) {
				for (j = 0; j < images.length; j++) {
					if (images[j][0] === this.href) { break; }
				}
				if (j === images.length) {
					images.push([this.href, this.title]);
					if (this.href === link.href) {
						imageNum = j;
					}
				}
			}
		});
		
		return open(images, imageNum);
	}
	
	function evtAnchorClick(evnt) {
		if (!anchorClick(evnt.currentTarget)) {
			evnt.preventDefault();
			return false;
		} else {
			return true;
		}
	}
	
	// link open processing
	// ->
	
	function myescape(text) {
		return encodeURIComponent(text);
	}

	function myunescape(text) {
		return decodeURIComponent(text);
	}

	function parseURL(url) {
		var out = {}, base = url, p1, i, tmp, a1;
		p1 = url.indexOf('?');
		if (p1 !== -1) {
			base = url.substring(0, p1);
			a1 = url.substring(p1 + 1).split('&');
			for (i = 0; i < a1.length; i++) {
				tmp = a1[i].split('=');
				if (tmp.length === 2) {
					out[myunescape(tmp[0])] = myunescape(tmp[1]);
				}
			}
		} else {
			base = url;
		}
		out[CNST.baseName] = base;
		return out;
	}
	
	function combineURL(vars) {
		var url = vars[CNST.baseName], vals = [], name;
		for (name in vars) {
			if (vars.hasOwnProperty(name) && name !== CNST.baseName) {
				vals.push(myescape(name) + '=' + myescape(vars[name]));
			}
		}
		if (vals.length > 0) {
			url += '?' + vals.join('&');
		}
		return url;
	}

	function generateEnhancedPerm(perm) {
		var url = Main.jWin.attr('location').href,
			vals = parseURL(url),
			enh = url, name = perm, pos;
		pos = perm.lastIndexOf('/');
		if (pos > 0) {
			name = perm.substring(pos + 1);
		}
		vals[CNST.parName] = name;
		enh = combineURL(vals);
		return enh;
	}

	function generateLikePerm(perm) {
		var url = Main.jWin.attr('location').href,
			vals = parseURL(url),
			name = perm, pos;
		pos = perm.lastIndexOf('/');
		if (pos > 0) {
			name = perm.substring(pos + 1);
		}
		url = vals[CNST.baseName];
		if (url.charAt(url.length - 1) === '/') {
			url = url.substring(0, url.length - 1);
		}
		return url + '/' + name;
	}
	
	function checkUrlShow() {
		var url = Main.jWin.attr('location').href,
			vals = parseURL(url),
			name = vals[CNST.parName];
		if (name && name.length > 0) {
			Main.showImage(name);
		}
	}

	// <-
	// link open processing

	/*function generate_fb_like(link) {
		return '<iframe src="http://www.facebook.com/plugins/like.php?href=' + myescape(link) + 
			'&amp;layout=button_count&amp;show_faces=false&amp;width=70' + 
			'&amp;action=like&amp;font=tahoma&amp;colorscheme=light"' + 
			' scrolling="no" frameborder="0" allowTransparency="true" style="width:75px;height:21px;" />';
	}*/
	
	function generate_fb_share(link) {
		return 'http://www.facebook.com/share.php?u=' + myescape(link);
	}
	
	function evtImageLoad(evnt) {
		if (Main.step === 1) {
			var imgWid = Main.imgWid = Math.max(350, Main.data.preload.width),
					imgHig = Main.imgHig = Math.max(250, Main.data.preload.height),
					perma = Main.images[Main.activeImage][0],
					permaEnh = generateEnhancedPerm(perma),
					//permaLike = generateLikePerm(perma),
					textCaption = Main.images[Main.activeImage][1] || '';

			Main.jParts.center.removeClass(CNST.clsLoading).css(CNST.cssCenter);
			Main.jParts.image.css($.extend({}, CNST.cssImage, {
				'backgroundImage': 'url("' + Main.data.preload.src + '")',
				'width': imgWid,
				'height': imgHig,
				'display': ''
				}));
			Main.jParts.bottom.css($.extend({}, CNST.cssDisp, {
				'width': imgWid
			}));
			
			Main.jParts.caption.text(textCaption);
			Main.jParts.permalink1.attr('target', '_blank').attr('href', generate_fb_share(permaEnh)).text(CNST.textShare);
			Main.jParts.permalink2.attr('href', permaEnh).text(CNST.textPerm2);
			Main.jParts.permalink3.attr('href', perma).text(CNST.textPerm1);
			
			//Main.jParts.fbdiv.html(generate_fb_like(permaLike));

			alignContainer();

			if (Main.activeImage > 0) {
				Main.data.preloadPrev.src = Main.images[Main.activeImage - 1][0];
				Main.jParts.prevLink.css($.extend({}, CNST.cssLink, {
					'height': imgHig,
					'left': 0
					}));
			}
			if (Main.activeImage < (Main.images.length - 1)) {
				Main.data.preloadNext.src = Main.images[Main.activeImage + 1][0];
				Main.jParts.nextLink.css($.extend({}, CNST.cssLink, {
					'height': imgHig,
					'right': 0
					}));
			}
			Main.step = 0;
		}
	}
	
	Main.show = function(url, title) {
		return open([[url, title]], 0);
	};
	
	Main.showImage = function (href) {
		$('a[href$="' + href + '"]').click();
	};

	Main.previous = function () {
		return Main.changeImage(Main.activeImage - 1);
	};

	Main.next = function () {
		return Main.changeImage(Main.activeImage + 1);
	};

	function resizeCenter() {
		Main.jParts.center.css({
			'width': Main.imgWid,
			'height': Main.imgHig
		});
	}
	
	Main.changeImage = function(imageNum) {
		if (Main.step > 0 || (imageNum < 0) || (imageNum >= Main.images.length)) {
			return false;
		}
			
		Main.step = 1;
		Main.activeImage = imageNum;
		
		Main.jParts.container.css(CNST.cssDisp);
		Main.jParts.center.addClass(CNST.clsLoading);
		resizeCenter();
		Main.jParts.prevLink.css(CNST.cssNodisp);
		Main.jParts.nextLink.css(CNST.cssNodisp);
		Main.jParts.image.css(CNST.cssNodisp);
		Main.jParts.bottom.css(CNST.cssNodisp);

		Main.data.preload = new Image();
		Main.data.preload.onload = evtImageLoad;
		Main.data.preload.src = Main.images[imageNum][0];
		return false;
	};

	Main.close = function () {
		if (Main.step < 0) { return; }
		Main.step = -1;
		if (Main.data.preload) {
			Main.data.preload.onload = null;
		}
		Main.jParts.container.css(CNST.cssNodisp);
		Main.jParts.overlay.css(CNST.cssNodisp);
		setup(false);
		return false;
	};

	function init(options) {
		var elParent = Main.parent = document.body;
		
		Main.anchors = [];
		Main.data = {};
		Main.step = 0;
		
		Main.jWin = $(window);
		Main.jDoc = $(document);
		Main.jParts = {};

		Main.imgWid = Main.imgHig = Main.top = 0;
		
		Main.jParts.overlay = $('<div/>').appendTo(elParent).css($.extend({}, CNST.cssOverlay, CNST.cssNodisp)).click(Main.close);
		Main.jParts.overlay2 = $('<div/>').appendTo(elParent).css($.extend({}, CNST.cssOverlay2, CNST.cssNodisp));
			
		Main.jParts.container = $('<div id="lbContainer"/>').appendTo(elParent).css($.extend({}, CNST.cssContainer, CNST.cssNodisp));
		Main.jParts.center = $('<div id="lbCenter"/>').appendTo(Main.jParts.container);
		Main.jParts.image = $('<div id="lbImage"/>').appendTo(Main.jParts.center);
		Main.jParts.prevLink = $('<a id="lbPrevLink" href="#"/>').appendTo(Main.jParts.image).click(Main.previous);
		Main.jParts.nextLink = $('<a id="lbNextLink" href="#"/>').appendTo(Main.jParts.image).click(Main.next);
		Main.jParts.bottom = $('<div id="lbBottom"/>').appendTo(Main.jParts.container).css(CNST.cssBottom);
		Main.jParts.closeLink = $('<a id="lbCloseLink" href="#"/>').appendTo(Main.jParts.bottom).click(Main.close);
		Main.jParts.caption = $('<div id="lbCaption"/>').appendTo(Main.jParts.bottom);
		
		Main.jParts.permalink1 = $('<a/>').css(CNST.cssPerma);
		Main.jParts.permalink2 = $('<a/>').css(CNST.cssPerma);
		Main.jParts.permalink3 = $('<a/>').css(CNST.cssPerma);
		
		Main.jParts.bottom.append(
			Main.jParts.permalink1,
			$('<span> | </span>'),
			Main.jParts.permalink2, 
			$('<span> | </span>'),
			Main.jParts.permalink3
		);
		
		//Main.jParts.fbdiv = $('<div />').css(CNST.cssFB).appendTo(Main.jParts.bottom);
		
		$('<div/>').css({'clear': 'both'}).appendTo(Main.jParts.bottom);

		initMove(false);

		Main.jParts.overlay.append($('<div/>').css(CNST.cssOverlayDim)).append($('<div/>').html(CNST.textHelp).css(CNST.cssOverlayHelp));
		
		Main.data.preloadPrev = new Image();
		Main.data.preloadNext = new Image();		
		
		$('a').each(function () {
			var rel = $(this).attr('rel');
			if (typeof rel === 'string' && reLB.test(rel)) {
				$(this).click(evtAnchorClick);
				Main.anchors.push(this);
			}
		});
		
		checkUrlShow();
	}

	$(init);

	Main.init = init;
	return Main;
}());
/**/

