/**
 * $URL:$
 * $Date:$
 * $Revision:$
 * $Author:$
 *
 * Copyright (C) 2009 seso media group <www.seso.at>
 * 
 * This program is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU General Public License as published by the 
 * Free Software Foundation; either version 2 of the License, or 
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
 * for more details: <http://www.gnu.org/licenses/>
 * 
 * powered by Prototype JavaScript framework <http://www.prototypejs.org/>
 * powered by scriptaculous <http://script.aculo.us/>
 * 
 * @author: gg@seso.at
 */


/*******************************************************************************
	LIGHTBOX
*******************************************************************************/

var lightBoxObserver = Class.create(Observer, {

	
	bgLayer : null,
	loadingIcon : null,
	currentItem : null,
	
	
	initialize : function($super, name) {

		$super(name);
		
		// default properties
		this.p.bgOpacity = 0.5;
		this.p.duration = 0.5;
		this.p.prefix = 'lightBox';
	},

	
	startUp : function() {

		this.createContainer();
		
		this.bgLayer = new Element('DIV');
		this.bgLayer.className = 'bgLayer';
		this.container.appendChild(this.bgLayer);
		/*
		this.loadingIcon = new Element('DIV', {className:'ajaxLoadingIcon'});
		this.container.appendChild(this.loadingIcon);
		*/
		for (var i=0; i<this.cache.length; i++) {
			
			this.prepeareItem(this.cache[i]);
		}
	},

	
	getDefaultConfig : function() {
		
		var item = {};
			item.cid = null;
			item.name = null;
			item.link = null;
			item.content = null;
			item.classes = '';
			
			item.hAlign = null;
			item.vAlign = null;
			
			item.bgLayer = true;
			item.closeable = true;
			item.dragable = false;
			
			// open
			item.open = {};
			item.open.fade = false;
			item.open.slide = null;
			item.open.scale = false;
			item.open.beforeStart = null;
			item.open.afterFinish = null;
			
			// close
			item.close = {};
			item.close.fade = false;
			item.close.slide = null;
			item.close.scale = false;
			item.close.beforeStart = null;
			item.close.afterFinish = null;
			
			// internals
			item.box = null;
			item.contentLayer = null;
			item.closeIcon = null;
			item.ajaxTarget = null;
			item.imgTarget = null;
			
			item.isOpen = false;
			item.swfContainer = null;
			item.collectionIndex = null;
		
		return item;
	},

	
	update : function() {

		log("update lightbox");
	},

	
	prepeareItem : function(item) {

		var collection = false;

		/* link ***************************************************************/
		
		if (item.link !== null) {
			
			var link = $(item.link);

			if (!link) {
				
				log("["+item.cid+"] prepeare - invalid link-id: "+item.link, 2, this.name);
				return false;
			}
			
			// single link
			
			if (link.nodeName == 'A') {
				
				item.link = link;
				item.link.setAttribute('cid', item.cid);
				
				Event.observe(item.link, 'click', util.lightBox.open);
				
			// link-collection	
			
			} else if (link.nodeName == 'DIV') {
				
				collection = true;
				item.link = [];
				
				var links = link.getElementsByTagName('A');
				
				for (var i=0; i<links.length; i++) {

					links[i].setAttribute('cid', item.cid+'-'+i);
					Event.observe(links[i], 'click', util.lightBox.open);
					
					item.link.push(links[i]);
				}
			}
		}

		
		/* content ************************************************************/
		
		// check for link-anchor

		if (item.content === null && collection === false) {
		
			var href = item.link.getAttribute('href');
			
			var anchor = href.split('#')[1];

			if (anchor && anchor.length > 0) {
				
				item.content = anchor;
			}
		}
		
		if (item.content !== null && collection === false) {
			
			// check for swf
			
			if (typeof item.content == 'object') {
				
				if (swfobject && typeof swfobject.embedSWF == 'function') {
				
					if (!item.content.version) item.content.version = '6.0.0';
					if (!item.content.expressInstall) item.content.expressInstall = null;
					
					item.swfContainer = 'swfContainer';
					
					var swf = "swfobject.embedSWF('"+item.content.swf+"','"+item.swfContainer+"','"+item.content.width+"','"+item.content.height+"','"+item.content.version+"','"+item.content.expressInstall+"',"+item.content.flashvars+","+item.content.params+","+item.content.attributes+");";
					
					item.open.afterFinish = swf + item.open.afterFinish;					
					item.close.beforeStart = "var tmp=$('"+item.swfContainer+"'); tmp.parentNode.removeChild(tmp);" + item.close.beforeStart;
					
				} else {
					
					log("["+item.cid+"] prepeare - missing swfobject", 2, this.name);
					return false;
				}
				
			} else {
			
				var content = $(item.content);
				
				if (!content) {
					
					log("["+item.cid+"] prepeare - invalid content-id: "+item.content, 2, this.name);
					return false;
				}
				
				item.content = content.innerHTML;
				content.parentNode.removeChild(content);
				
				content.removeClassName('lightBoxContent');
				item.classes += ' '+content.className;
			}
		}
	},


	
	createBaseModel : function(item) {
		
		item.box = new Element('DIV', {className: 'lightBox'});
		item.box.className = 'lightBox '+item.classes;
		item.box.style.display = 'none';
		
		this.container.appendChild(item.box);
		
		item.container = new Element('DIV', {className: 'container'});
		item.box.appendChild(item.container);

		item.loadingIcon = new Element('DIV', {className: 'ajaxLoadingIcon'});
		item.container.appendChild(item.loadingIcon);

		item.contentLayer = new Element('DIV', {className: 'contentLayer'});
		item.container.appendChild(item.contentLayer);
		
		if (item.swfContainer !== null) {
			
			item.contentLayer.style.width = item.content.width + 'px';
			item.contentLayer.style.height = item.content.height + 'px';
			item.contentLayer.setAttribute('id', item.swfContainer);
			// item.contentLayer.innerHTML = "<div class='ajaxLoadingIcon'></div>";
		
		} else {
			
			item.contentLayer.innerHTML = item.content; 
		}
		
		item.closeIcon = new Element('DIV', {className: 'closeIcon'});
		item.closeIcon.style.display = 'none';
		item.closeIcon.setAttribute('cid', item.cid);
		item.box.appendChild(item.closeIcon);

		Event.observe(item.closeIcon, 'click', util.lightBox.close);
	},
	

	
	parseContentSource : function(item) {
		
		// single link
		
		if (item.collectionIndex === null) {
			
			var a = item.link;
			
		// link-collection
			
		} else {
			
			var a = item.link[item.collectionIndex];
		}
		
		
		// parse href
		
		var href = a.getAttribute('href');
		var query = null;

		// anchor
		if (href.indexOf('#') != -1) {
			return true;

		// get-parameter
		} else if (href.indexOf('?') != -1) {
			
			query = href.split('?')[1];
			href = href.split('?')[0];
		}

		// check file-type

		var pos = href.lastIndexOf('.') + 1;

		if (pos > 0) {
		
			var type = href.substr(pos);
			
			if (type == 'jpg' || type == 'jpeg' || type == 'png' || type == 'gif') {
	
				item.imgTarget = href;
	
			} else if (type == 'swf') {
				
				log('todo SWF', 3);
			
			} else {
				
				item.ajaxTarget = href+'?'+query;
			}
		}


		if (item.content === null && item.ajaxTarget === null && item.imgTarget === null) {
			
			log("["+item.cid+"] prepeare - no content defined: "+item.content, 2, this.name);
			return false;
		}
	},
	
	
	
	open : function(event) {
		
		event.stop();
		
		var e = event.element();
			e.blur();
		
		if (e.nodeName == 'IMG') {
			e = e.parentNode;
		}

		var id = e.getAttribute('cid');

		try {
			
			id = id.split('-');
			
		} catch (e) {}

		var cid = (typeof id == 'object') ? id[0] : id;

		var item = util.lightBox.cache[cid];
			item.collectionIndex = id[1] || null;

		if (!item) {
			
			log("open - invalid cid: "+cid, 2, this.name);
			return false;
		}
		
		
		if (item.isOpen === true) {
			
			log("["+item.cid+"] open - box already opend ", 2, this.name);
			return false;
		}
		
		item.isOpen = true;

		util.lightBox.parseContentSource(item);

		// check for ajax-call

		if (item.ajaxTarget !== null) {

			var ajax = new Ajax.Request(item.ajaxTarget, {	

				method: 'get',
				onSuccess: function(transport) {
				
					item.content = transport.responseText;
					util.lightBox.goOnStage(item);
				},
			    onFailure: function() { 
					
					log("["+item.cid+"] open - ajax-request failed: "+item.ajaxTarget, 2, this.name);
				}
			});
		
		// image-target
		
		} else if (item.imgTarget !== null) {

			util.imageLoader.load(item.imgTarget, function(img) {
				
				item.content = "<img src='"+img.src+"' width='"+img.width+"' height='"+img.height+"' />";
				util.lightBox.goOnStage(item);
			});

		} else {
			
			util.lightBox.goOnStage(item);
		}

		// bgLayer

		if (item.bgLayer === true) {
		
			util.lightBox.bgLayer.style.display = 'block';
			
			if (item.closeable === true) {
			
				util.lightBox.bgLayer.setAttribute('cid', item.cid);
				Event.observe(util.lightBox.bgLayer, 'click', util.lightBox.close);
			}

			var html = document.getElementsByTagName('HTML')[0];
			var h = html.scrollHeight;
			var w = html.scrollWidth;

			if (env.browser == 'sa') {
				h = document.body.scrollHeight;
			}

			util.lightBox.bgLayer.style.height = h + 'px';
			util.lightBox.bgLayer.style.width = w + 'px';

			util.lightBox.bgLayer.setOpacity(0);
	
			new Effect.Fade(util.lightBox.bgLayer, {
				from: 0.0,
				to: util.lightBox.p.bgOpacity,
				duration: 0.5,
				afterFinish : function() {
				
					// util.lightBox.setLoading(item, true);
				}
			});

		} else {

			// util.lightBox.setLoading(item, true);
		}
	},
	
	
	
	setLoading : function(item, flag) {
		
		if (item.ajaxTarget !== null || item.imgTarget !== null || typeof item.content == 'object') {
		
			if (flag === true) {
				
				if (item.bgLayer === false) {
					
					item.loadingIcon.addClassName('nobg');
				}
				
				item.loadingIcon.style.display = 'block';
				document.body.style.cursor = 'wait';
				
			} else {
				
				if (item.bgLayer === false) {
					
					util.lightBox.loadingIcon.removeClassName('nobg');
				}
				
				item.loadingIcon.style.display = 'none';
				document.body.style.cursor = 'default';
			}
		}
	},

	
	
	parseContent : function(item) {
		
		// check for ajax-links
		
		var links = item.contentLayer.getElementsByTagName('A');
		
		for (var i=0; i<links.length; i++) {
			
			if (links[i].hasAttribute('target')) {
				
				if (links[i].getAttribute('target') == '_self') {
					
					links[i].setAttribute('cid', item.cid);
					Event.observe(links[i], 'click', util.lightBox.reloadContent)
				}
			}
		}
	},	
	
	
	reloadContent : function(event) {
		
		event.stop();
		
		var e = event.element();
			e.blur();

		var id = e.getAttribute('cid').split('-');
		var cid = parseInt(id[0]);
	
		var item = util.lightBox.cache[cid];
			item.collectionIndex = id[1] || null;

		if (!item) {
			
			log("reloadContent - invalid cid: "+cid, 2, this.name);
			return false;
		}
		
		
		util.lightBox.parseContentSource(item);

		
		new Effect.Fade(item.contentLayer, {
			from: 1.0,
			to: 0.0,
			duration: 0.5,
			afterFinish : function() {

				// check for ajax-call

				if (item.ajaxTarget !== null) {

					var ajax = new Ajax.Request(item.ajaxTarget, {	

						method: 'get',
						onSuccess: function(transport) {
						
							item.contentLayer.innerHTML = transport.responseText;
							
							item.contentLayer.setOpacity(0);
							item.contentLayer.style.display = 'block';
							
							util.lightBox.parseContent(item);
	
							new Effect.Fade(item.contentLayer, {
								from: 0.0,
								to: 1.0,
								duration: 0.5
							});
						},
					    onFailure: function() { 
							
							log("["+item.cid+"] parseContent - ajax-request failed: "+item.ajaxTarget, 2, this.name);
						}
					});
				
				// image-target
				
				} else if (item.imgTarget !== null) {

					util.imageLoader.load(item.imgTarget, function(img) {

						item.contentLayer.innerHTML = "<img src='"+img.src+"' width='"+img.width+"' height='"+img.height+"' />";

						item.contentLayer.setOpacity(0);
						item.contentLayer.style.display = 'block';
						
						new Effect.Fade(item.contentLayer, {
							from: 0.0,
							to: 1.0,
							duration: 0.5
						});
						
					});

				} else {
					
					log("["+item.cid+"] parseContent - nothing to do...", 2, this.name);
				}
			}
		});
		
		util.lightBox.checkCollectionArrows(item);
	},
	
	
	
	goOnStage : function(item) {

		// create box

		util.lightBox.createBaseModel(item);
		util.lightBox.parseContent(item);

		
		// clone box & get dimensions
		
		var clone = item.box.cloneNode(true);
			clone.style.top = '-9999px';
			clone.style.display = 'block';

		util.lightBox.container.appendChild(clone);
		
		var w = clone.getWidth();
		var h = clone.getHeight();
		
		util.lightBox.container.removeChild(clone);
		
		var l = (document.viewport.getWidth() - w) / 2;
		var t = (document.viewport.getHeight() - h) / 2;

		// check align
		
		if (item.hAlign !== null) {

			if (item.hAlign == 'left') {
				
				l -= (l/3)*2;
			
			} else if (item.hAlign == 'right') {
					
				l += (l/3)*2;
	
			} else {
				
				log("["+item.cid+"] open - invalid parameter 'hAlign': "+item.hAlign, 2, this.name);
			}
		}
		
		if (item.vAlign !== null) {

			if (item.vAlign == 'top') {
				
				t -= (t/3)*2;
			
			} else if (item.vAlign == 'bottom') {
					
				t += (t/3)*2;
	
			} else {
				
				log("["+item.cid+"] open - invalid parameter 'vAlign': "+item.vAlign, 2, this.name);
			}
		}
		
		
		if (env.browser == 'ie6') {

			t += document.documentElement.scrollTop;
		}

		
		// set target-position
		
		item.box.style.width = Math.round(w) + 'px';
		item.box.style.height = Math.round(h) + 'px';
		item.box.style.left = Math.round(l) + 'px';
		item.box.style.top = Math.round(t) + 'px';
		
		// beforeStart
		
		if (item.open.beforeStart !== null) {
			
			util.lightBox.currentItem = item;
			
			try {
				
				eval(item.open.beforeStart);
				
			} catch (e) {
				
				log(e);
			}
			
			util.lightBox.currentItem = null;
		}
		
		
		// selects ie6
		
		if (env.browser == 'ie6') {
			
			var selects = document.getElementsByTagName('SELECT');
			
			for (var i=0; i<selects.length; i++) {
				
				selects[i].style.visibility = 'hidden';
			}
		}
		
		
		// create effects
		
		var effects = [];

		
		// scale

		if (item.open.scale === true) {
			
			item.contentLayer.setOpacity(0);
			item.box.setOpacity(0);
			item.open.fade = true;

			var e = new Effect.Scale(item.container, 100, {
				sync: true,
				scaleFrom: 0,
				scaleFromCenter: true,
				scaleContent: false,
				afterFinish : function() {
				
					item.contentLayer.fade({
						from: 0.0,
						to: 1.0,
						duration: 0.5
					});
				}
			});

			effects.push(e);
		}

		
		// fade
		
		if (item.open.fade === true) {
			
			var e = new Effect.Fade(item.box, {
				sync: true,
				from: 0.0,
				to: 1.0
			});

			effects.push(e);
		}
		

		// slide
		
		if (item.open.slide !== null) {
			
			var x, y;
		
			switch (item.open.slide) {
			
				case 'top':
					x = null;
					y = (t+h);
					t = (h*-1);
					break;
					
				case 'bottom':
					x = null;
					y = (document.viewport.getHeight()-t)*-1;
					t = document.viewport.getHeight();
					break;
					
				case 'left':
					x = (l+w);
					y = null;
					l = (w*-1);
					break;
					
				case 'right':
					x = (document.viewport.getWidth()-l)*-1;
					y = null;
					l = document.viewport.getWidth();
					break;
					
				default:
					log("["+item.cid+"] open - invalid parameter 'slide': "+item.open.slide, 2, this.name);
					break;
			}
			
			item.box.style.top = Math.round(t) + 'px';
			item.box.style.left = Math.round(l) + 'px';

			var e = new Effect.Move(item.box, {
				sync: true,
				x: x,
				y: y, 
				transition: Effect.Transitions.sinoidal
			});

			effects.push(e);
		}
		
		
		// execute effects
		
		item.box.style.display = 'block';

		if (effects.size() > 0) {
		
			new Effect.Parallel(effects, { 
				
				duration: util.lightBox.p.duration,
				afterFinish : function() {
	
					util.lightBox.finishOpen(item);
				}
			});
		
		} else {
			
			util.lightBox.finishOpen(item);
		}
	},
	
	
	finishOpen : function(item) {

		// afterFinish
		
		if (item.open.afterFinish !== null) {
			
			util.lightBox.currentItem = item;
			
			try {
				
				eval(item.open.afterFinish);
				
			} catch (e) {
				
				log(e);
			}
			
			util.lightBox.currentItem = null;
		}

		
		// closeIcon
		
		if (item.closeable === true) {
		
			item.closeIcon.style.display = 'block';
		}
		
		
		// collectionArrows
		
		util.lightBox.checkCollectionArrows(item);
		
		
		// dragable
		
		if (item.dragable === true) {
			
			new Draggable(item.box, { 

				zindex: 999998,
				starteffect: null,
				endeffect: null,
				onStart : function() {
				
					document.body.style.cursor = 'move';
				},
				onEnd : function() {
					
					document.body.style.cursor = 'default';
				}
			});
		}
		
		util.lightBox.setLoading(item, false);
	},
	
	
	checkCollectionArrows : function(item) {

		if (item.collectionIndex !== null) {
			
			var nodeLeft = $$('div.arrowLeft')[0];
			
			if (item.collectionIndex > 0) {
				
				if (nodeLeft) {
					
					nodeLeft.setAttribute('cid', item.cid+'-'+(parseInt(item.collectionIndex)-1));
				
				} else {
				
					var arrow = new Element('DIV', {
						className: 'arrowLeft',
						cid: item.cid+'-'+(parseInt(item.collectionIndex)-1)
					});
		
					item.box.appendChild(arrow);
					Event.observe(arrow, "click", util.lightBox.reloadContent);
				}
				
			} else if (nodeLeft) {

				nodeLeft.parentNode.removeChild(nodeLeft);
			}

			var nodeRight = $$('div.arrowRight')[0];

			if (item.collectionIndex < item.link.length-1) {
				
				if (nodeRight) {
					
					nodeRight.setAttribute('cid', item.cid+'-'+(parseInt(item.collectionIndex)+1));
				
				} else {
				
					var arrow = new Element('DIV', {
						className: 'arrowRight',
						cid: item.cid+'-'+(parseInt(item.collectionIndex)+1)
					});
		
					item.box.appendChild(arrow);
					Event.observe(arrow, "click", util.lightBox.reloadContent);
				}
				
			} else if (nodeRight) {
	
				nodeRight.parentNode.removeChild(nodeLeft);
			}
			
		}
	},
	
	
	close : function(event) {

		event.stop();

		var cid = parseInt(event.element().getAttribute('cid'));
		var item = util.lightBox.cache[cid];

		if (!item) {
			
			log("close - invalid cid: "+cid, 2, this.name);
			return false;
		}
			
		
		// beforeStart
		
		if (item.close.beforeStart !== null) {
			
			util.lightBox.currentItem = item;
			
			try {
				
				eval(item.close.beforeStart);
				
			} catch (e) {
				
				log(e);
			}
			
			util.lightBox.currentItem = null;
		}

		
		// get box-dimensions

		var w = item.box.getWidth();
		var h = item.box.getHeight();
		var t = parseInt(item.box.getStyle('top').split('px')[0]);
		var l = parseInt(item.box.getStyle('left').split('px')[0]);

		
		// create effects
		
		var effects = [];

		
		// scale

		if (item.close.scale === true) {
			
			item.contentLayer.style.display = 'none';
			item.close.fade = true;

			var e = new Effect.Scale(item.container, 0, {
				sync: true,
				scaleFrom: 100,
				scaleFromCenter: true,
				scaleContent: false
			});

			effects.push(e);
		}

		
		// fade
		
		if (item.close.fade === true) {
			
			var e = new Effect.Fade(item.box, {
				sync: true,
				from: 1.0,
				to: 0.0
			});

			effects.push(e);
		}
		

		// slide
		
		if (item.close.slide !== null) {
			
			var x, y;

			switch (item.close.slide) {
			
				case 'top':
					x = null;
					y = (t+h)*-1;
					break;
					
				case 'bottom':
					x = null;
					y = (document.viewport.getHeight()-t);
					break;
					
				case 'left':
					x = (l+w)*-1;
					y = null;
					break;
					
				case 'right':
					x = (document.viewport.getWidth()-l);
					y = null;
					break;
					
				default:
					log("["+item.cid+"] open - invalid parameter 'slide': "+item.open.slide, 2, this.name);
					break;
			}

			var e = new Effect.Move(item.box, {
				sync: true,
				x: x,
				y: y, 
				transition: Effect.Transitions.sinoidal
			});

			effects.push(e);
		}

		
		// execute effects
		
		item.closeIcon.style.display = 'none';
		
		if (effects.size() > 0) {
			
			new Effect.Parallel(effects, { 
				
				duration: util.lightBox.p.duration,
				afterFinish : function() {
	
					util.lightBox.finishClose(item);
				}
			});
		
		} else {
			
			util.lightBox.finishClose(item);
		}

		
		// bgLayer
		
		if (item.bgLayer === true) {
			
			if (item.closeable === true) {
		
				Event.stopObserving(util.lightBox.bgLayer, 'click', util.lightBox.close);
			}
			
			new Effect.Fade(util.lightBox.bgLayer, {
				from: util.lightBox.p.bgOpacity,
				to: 0.0,
				duration: 0.5,
				afterFinish : function() {
				
					util.lightBox.bgLayer.style.display = 'none';
				}
			});
		}
	},
	
	
	finishClose : function(item) {
		
		util.lightBox.container.removeChild(item.box);
		item.box = null;
		item.contentLayer = null;
		
		// afterFinish
		
		if (item.close.afterFinish !== null) {
			
			util.lightBox.currentItem = item;
			
			try {
				
				eval(item.close.afterFinish);
				
			} catch (e) {
				
				log(e);
			}
			
			util.lightBox.currentItem = null;
		}
		
		// selects ie6
		
		if (env.browser == 'ie6') {
			
			var selects = document.getElementsByTagName('SELECT');
			
			for (var i=0; i<selects.length; i++) {
				
				selects[i].style.visibility = 'visible';
			}
		}
		
		item.collectionIndex = null;
		item.isOpen = false;
	}

});

util.prototype.lightBox = new lightBoxObserver('lightBoxObserver');



