/**
 * jqLeafBox
 *
 * @version    0.1
 * @copyright    (c)2008 Takeshi Takatsudo (http://zudolab.net/)
 * @lisence    MIT (http://www.opensource.org/licenses/mit-license.php)
 */

(function($){

	/* browser detector */
	var IE = $.browser.msie;
	var IE6 = $.browser.msie && $.browser.version==6;
	var oldSafari = $.browser.safari && ($.browser.version*1)<418; // ignore safari less than 2.0.4
	
	/* external parts path */
	var showColorOverlay = true; // set false if you dont need this
	var emptyHTMLPath = "/common/js/hidedummy.html"; // set null if you dont need this
	var nowLoadingImgPath = "/common/imgs/js_jqLeafBox/loading.gif"; // set null if you dont need this
	
	/* overlays */
	var $colorOverlay = null;
	var $iframeOverlay = null;
	var $nowLoading = null;
	
	/* vars to save current settings */
	var currentBoxType = null;
	var currentImagePreloaded = null;
	var currentBoxContainer = null;
	var currentBoxContent = null;
	var currentBoxAjaxContent = null;
	var currentFadeSpeed_overlay  = null;
	var currentFadeSpeed_box  = null;
	var whileAnimation = false;
	
	var blindSetupCompleted = false;
	var escKeyEventSetCompleted = false;
	
	/* setup blind */
	function setupBlind()
	{
		if(blindSetupCompleted) return;
		$colorOverlay = 
			showColorOverlay ? 
				$('<div id="jqLeafBox-colorOverlay"></div>') :
				null;
		$iframeOverlay = 
			emptyHTMLPath ? 
				$('<iframe id="jqLeafBox-iframeOverlay" frameborder="0" src="'+emptyHTMLPath+'"></iframe>') :
				$('<iframe id="jqLeafBox-iframeOverlay" frameborder="0"></iframe>');
		$nowLoading = 
			nowLoadingImgPath ? 
				$('<div id="jqLeafBox-nowLoading"><table><tr><td><img src="'+nowLoadingImgPath+'" alt="" /></td></tr></table></div>') : 
				null;
		if($colorOverlay) $(document.body).append($colorOverlay);
		if($iframeOverlay) $(document.body).append($iframeOverlay);
		if($nowLoading) $(document.body).append($nowLoading);
		blindSetupCompleted = true;
	}
	
	/**
	 * jqLeafBox object
	 */
		jqLeafBox = function(settings)
		{
			this.selector = settings.selector ? settings.selector : null;
			this.type = settings.type ? settings.type : null;
			this.fadeSpeed_overlay = settings.fadeSpeed_overlay ? settings.fadeSpeed_overlay : 100;
			this.fadeSpeed_box = settings.fadeSpeed_box ? settings.fadeSpeed_box : 120;
			this.preloadImage = settings.preloadImage ? settings.preloadImage : false;
			this.boxHTML = settings.boxHTML ? settings.boxHTML : (function(){
				var html = "";
				html+= '<div class="jqLeafBox-container">';
				html+= '<table class="jqLeafBox-positionTable"><tr><td class="jqLeafBox-positionTd">';
				html+= '<div class="content">';
				html+= '<div class="contentHeader">';
				html+= '<p class="closeButton"><a href="javascript:void(0)">close</a> or Esc key</p>';
				html+= '<p class="title"></p>';
				html+= '</div>';
				html+= '<div class="ajaxContent"></div>';
				html+= '<div class="imgContent"></div>';
				html+= '</div>';
				html+= '</td></tr></table>';
				html+= '</div>';
				return html;
			})();
			this.grouped = settings.grouped ? settings.grouped : false;
			this.elemSets = [];
		}
		jqLeafBox.prototype.setup = function()
		{
			if(oldSafari) return false;
			setupBlind();
			this.prepareElems();
			this.setEvents();
		}
		jqLeafBox.prototype.prepareElems = function()
		{
			var self = this;
			var $triggerElems = $(self.selector);
			for(var i=0,triggerElem; triggerElem=$triggerElems[i]; i++){
				if(self.type=="image" && self.grouped){
					prepareBox_groupedImage(triggerElem);
				}else if(self.type=="image"){
					prepareBox_singleImage(triggerElem);
				}else if(self.type=="iframe"){
					prepareBox_iframeContent(triggerElem);
				}else if(self.type=="ajax"){
					prepareBox_ajaxContent(triggerElem);
				}
			}
			function prepareBox_groupedImage(triggerElem)
			{
				/*
					
					not implemented yet
					
				 */
			}
			function prepareBox_singleImage(triggerElem)
			{
				var $boxContainer = $(self.boxHTML);
				if(self.preloadImage){
					$boxContainer.find("div.imgContent").html('<img src="'+triggerElem.href+'" alt="" />');
				}
				if(triggerElem.title){
					$boxContainer.find("p.title").html(triggerElem.title);
				}else{
					$boxContainer.find("p.title").remove();
				}
				$boxContainer.find("div.ajaxContent").remove();
				self.elemSets.push({
					triggerElem: triggerElem,
					posTable: $boxContainer.find("table.jqLeafBox-positionTable").get(0),
					boxContainer: $boxContainer.get(0),
					boxContent: $boxContainer.find("div.content").get(0),
					closeButton: $boxContainer.find("p.closeButton a").get(0),
					imagePath: triggerElem.href
				});
				$(document.body).append($boxContainer);
			}
			function prepareBox_iframeContent(triggerElem)
			{
				/*
					
					not implemented yet
					
				 */
			}
			function prepareBox_ajaxContent(triggerElem)
			{
				var $boxContainer = $(self.boxHTML);
				$boxContainer.find("div.imgContent").remove();
				if(triggerElem.title){
					$boxContainer.find("p.title").html(triggerElem.title);
				}else{
					$boxContainer.find("p.title").remove();
				}
				self.elemSets.push({
					triggerElem: triggerElem,
					posTable: $boxContainer.find("table.jqLeafBox-positionTable").get(0),
					boxContainer: $boxContainer.get(0),
					boxContent: $boxContainer.find("div.content").get(0),
					boxAjaxContent: $boxContainer.find("div.ajaxContent").get(0),
					closeButton: $boxContainer.find("p.closeButton a").get(0),
					linkURL: triggerElem.href
				});
				$(document.body).append($boxContainer);
			}
		}
		jqLeafBox.prototype.setEvents = function()
		{
			var self = this;
			setKeyPushCloseEvents();
			setResizeEvents();
			setScrollEvents();
			
			for(var i=0,elemSet; elemSet=self.elemSets[i]; i++){
				$(elemSet.boxContent).click(function(evt){
					evt.stopPropagation();
				});
				$(elemSet.triggerElem).click(function(){
					if(currentBoxContent) return false;
					var elemSet = self.getElemSetsFromTriggerElem(this);
					openBox(elemSet);
					return false;
				});
				$(elemSet.closeButton).click(function(){
					if(whileAnimation) return false;
					hideCurrentBox();
					return false;
				});
			}
			function setCurrentBox(elemSet){
				currentBoxType = self.type;
				currentImagePreloaded = self.preloadImage;
				currentPosTable = elemSet.posTable;
				currentBoxContainer = elemSet.boxContainer;
				currentBoxContent = elemSet.boxContent;
				currentBoxAjaxContent = elemSet.boxAjaxContent;
				currentFadeSpeed_overlay = self.fadeSpeed_overlay;
				currentFadeSpeed_box = self.fadeSpeed_box;
				currentLinkURL = elemSet.linkURL;
			}
			function openBox(elemSet){
				whileAnimation = true;
				if(self.type=="image" && !self.preloadImage){
					var $content=$(elemSet.boxContent);
					if($content.find("div.imgContent img").length==0){
						$content.find("div.imgContent").html('<img src="'+elemSet.imagePath+'" alt="" />');
						elemSet.boxContent = $content.get(0);
					}
				}
				setCurrentBox(elemSet);
				setLeafBoxPosition();
				showOverlay();
				showCurrentBox();
			}
			
			/* esc key push close */
			
			function setKeyPushCloseEvents(){
				if(escKeyEventSetCompleted) return;
				// esc key remove
				$(document).keyup(closeIfEscKey);
				escKeyEventSetCompleted = true;
				function closeIfEscKey(evt){
					if(!currentBoxContainer) return;
					var key = evt.keyCode;
					if(key == 27) hideCurrentBox();
				}
			}
			
			/* set position when resize */
			
			function setResizeEvents()
			{
				$(window).resize(function(){
					if(currentBoxContainer){
						setLeafBoxPosition();
						setOverlayPosition();
					}
				});
			}
			
			/* set position when scroll */
			
			function setScrollEvents()
			{
				$(window).scroll(function(){
					if(currentBoxContainer){
						setLeafBoxPosition();
						setOverlayPosition();
					}
				});
			}
		}
		jqLeafBox.prototype.getElemSetsFromTriggerElem = function(triggerElem)
		{
			for(var i=0,elemSet; elemSet=this.elemSets[i]; i++){
				if(triggerElem==elemSet.triggerElem){
					return elemSet;
				}
			}
		}
	/**
	 * release LeafBox
	 */
		function releaseCurrentBox(){
			currentBoxType = null;
			currentImagePreloaded = null;
			currentPosTable = null;
			currentBoxContainer = null;
			currentBoxContent = null;
			currentBoxAjaxContent = null;
			currentFadeSpeed_overlay = null;
			currentFadeSpeed_box = null;
			currentLinkURL = null;
		}
	/**
	 * box/overlay visibility control
	 */
		function showCurrentBox()
		{
			if(currentBoxType=="ajax"){
				setTimeout(function(){ // keep min time
					$(currentBoxContainer).appendTo($(document.body)).show();
					$(currentBoxAjaxContent).load(noCache(currentLinkURL), fadeInInsideContent);
				},50);
			}else{
				setTimeout(function(){ // keep min time
					$(currentBoxContainer).appendTo($(document.body)).show();
					fadeInInsideContent();
				},50);
			}
			function fadeInInsideContent(){
				if($nowLoading) $nowLoading.hide();
				if(IE6){
					$(currentPosTable).height($(window).height()); // IE6 sometimes cant caliculate table's height 100% correctly
					$(currentBoxContent).show();
					whileAnimation = false;
					$(currentBoxContainer).click(hideCurrentBox);
				}else{
					$(currentBoxContent).fadeIn(currentFadeSpeed_box, function(){
						whileAnimation = false;
						$(currentBoxContainer).click(hideCurrentBox);
					});
				}
			}
		}
		function hideCurrentBox()
		{
			whileAnimation = true;
			if(IE6){
				/* IE6 can't fadeout */
				$(currentBoxContainer)
					.unbind("click",hideCurrentBox)
					.hide();
				$(currentBoxContent).hide();
				hideOverlay(); // chain to hideOverlay
			}else{
				$(currentBoxContainer)
					.unbind("click",hideCurrentBox)
					.fadeOut(currentFadeSpeed_box, function(){
						$(currentBoxContent).hide();
						$(currentBoxContainer).hide();
						hideOverlay(); // chain to hideOverlay
					});
			}
		}
		function showOverlay()
		{
			if($colorOverlay) $colorOverlay.show();
			if($iframeOverlay) $iframeOverlay.show();
			if($nowLoading) showNowLoading();
			
			function showNowLoading()
			{
				if(IE6){ // for IE6
					var style = {
						"top" : $(document).scrollTop(),
						"height" : $(window).height(),
						"display" : "block"
					};
					$nowLoading.css(style);
				}else{
					$nowLoading.show();
				}
				setOverlayPosition();
			}
		}
		function hideOverlay()
		{
			if(IE){
				if($colorOverlay) $colorOverlay.hide();
				if($iframeOverlay) $iframeOverlay.hide();
				whileAnimation = false;
			}else{
				if($iframeOverlay) $iframeOverlay.hide();
				if($colorOverlay){
					$colorOverlay.fadeOut(currentFadeSpeed_overlay, function(){
						whileAnimation = false;
					});
				}else{
					whileAnimation = false;
				}
			}
			releaseCurrentBox();
		}
	
	/**
	 * position adjustment functions
	 */
		function setOverlayPosition()
		{
			if(!IE6) return;
			var cssWidth = $(document.body).width();
			var cssHeight = $(document).height();
			var style={
				"top" : 0,
				"left" : 0,
				"width" : cssWidth,
				"height" : cssHeight
			}
			$colorOverlay.css(style);
			$iframeOverlay.css(style);
		}
		function setLeafBoxPosition()
		{
			if(IE6){
				var style={
					"top" : $(document).scrollTop(),
					"left" : $(document).scrollLeft()
				};
				$(currentBoxContainer).css(style);
				$(currentPosTable).height($(window).height()); // IE6 sometimes cant caliculate table's height 100% correctly
				return;
			}
			return;
		}
		
	/*
	 * avoid browser ajax cache
	 */
		function noCache(url){
			return url.concat(/\?/.test(url)?"&":"?","noCache=",(new Date).getTime(),".",Math.random()*1234567)
		}

	/* override width,height methods for opera 9.5 jQuery height problem */
	(function(){
		if(!$.browser.opera || $.browser.version < 9.5) return;
		$.each([ 'Height', 'Width' ], function(i, name){
			var type = name.toLowerCase();
			var originalMethod = $.fn[ type ];
			$.fn[ type ] = function( size ) {
				return this[0] == window
					? document.documentElement[ 'client' + name ] 
					: originalMethod.call(this,size);
			};
		});
	})();
	
})(jQuery);
