/**
 * @alias bindPopupEvent
 * @alias JSH.bindPopupEvent
 * @param {String} triggerObj 
 * @param {String} popupObj
 * @param {Interger} respTime
 * @param {String} popType
 * @param {Function} callback
 * 
 * @author Cyan
 * @version 2009.08.12 v0.5
 * 
 * @projectDescription Popup here and there <br />
 * <b>Demo:</b><br />
 * var testPopup = new bindPopupEvent("#trigger","#popup",250,"mm",callback);<br />
 * means trigger will correspond a mouseover event to show popup, and when mouse moveout of <br />
 * trigger and popup, the popup will be hidden.<br />
 * &nbsp;<br />
 * <a href="changelog.txt">Click here to see the ChangeLog</a>
 */

var bindPopupEvent = function(triggerObj,popupObj,respTime,popType,callback) {

	if(typeof(triggerObj) == "string")
		triggerObj = [triggerObj];
		
	// Debug Mode
	this.debug = 0;
	
	var that = this;
	this.callback = callback;
	// Constructor here
	this.triggerObj = triggerObj;
	this.triggerIndex,this.triggerChildIndex;
	this.popupObj = popupObj;
	this.respTime = respTime;
	this.popType = popType;
	
	// Status Variable
	this.overTrigger = Boolean(0);
	this.overPopup = Boolean(0);
	this.showType = "";
	this.hideType = "";
	
	// Time handle
	this.timerhandle = null;
	
	// Define showtype
	if (popType.substr(0,1) == "c") 
		this.showType = "click";	
	if (popType.substr(0,1) == "m") 
		this.showType = "mouseover";
	
	if (popType.substr(1,2) == "c") 
		this.hideType = "click";	
	if (popType.substr(1,2) == "m") 
		this.hideType = "mouseover";
	
	// Click show
	if(this.showType == "click"){
		for (i = 0; i < this.triggerObj.length; i++) {
			$(this.triggerObj[i]).click(function(){
				for (j =0 ; j < that.triggerObj .length; j++){
					if($(this) == $(that.triggerObj[j]))
						that.triggerIndex = j;
						that.triggerChildIndex = k;
				}
				if ($(that.popupObj + ":hidden").length) {
					that.showPopup();
				}
				else {
					that.hidePopup();
				}
				if (that.debug == 1) {
					$("#triCliCount").html((parseInt($("#triCliCount").html()) + 1).toString());
					$("#popupStatus").html("show");
				}
			})
		}
	}
	
	// Click hide
	if (this.hideType == "click"){
		$("body").click(function(){
			if (!Boolean($(that.popupObj + ":hidden").length) && !that.overTrigger && !that.overPopup) {
				that.hidePopup();
			}
			
			if(that.debug == 1){
				$("#bodyCliCount").html((parseInt($("#bodyCliCount").html()) + 1).toString());
				$("#popupStatus").html("hide");
			}
		})
	}
	
	
	// Mouseover show
	for (i = 0; i < this.triggerObj.length; i++) {
		$(this.triggerObj[i]).mouseover(function(e){
			for (j =0 ; j < that.triggerObj.length; j++){
				for (k = 0; k < $(that.triggerObj[j]).length; k++) {
					if (this == $(that.triggerObj[j])[k]) {
						that.triggerIndex = j;
						that.triggerChildIndex = k;
						
						that.overTrigger = 1;
						clearTimeout(that.timerhandle);
						
						that.timerhandle = setTimeout(function(){
							$("#onTrigger").html("yes");
							if (that.showType == "mouseover") {
								if (that.debug == 1) 
									$("#popupStatus").html("show");
								that.showPopup(e);
							}
						}, respTime)
						
						break;
					}
				}
			}
		});
	}
	
	$(this.popupObj).mouseover(function(){
		that.overPopup = 1;
		clearTimeout(that.timerhandle); 
		that.timerhandle = setTimeout(function(){
			if(that.debug == 1) {
				$("#onPopup").html("yes");
				$("#popupStatus").html("show");
			}
			that.showPopup();
		},respTime)
	})
	

	// Mouseout hide
	for (i = 0; i < this.triggerObj.length; i++) {
		$(this.triggerObj[i]).mouseout(function(){
			that.overTrigger = 0;
			if (that.debug == 1) 
				$("#onTrigger").html("no");
			for (j =0 ; j < that.triggerObj .length; j++){
				for (k = 0; k < $(that.triggerObj[j]).length; k++) {
					if (this == $(that.triggerObj[j])[k]) 
						break;
				}
				isMouseout(j);
			}
		})
	}
	
	$(this.popupObj).mouseout(function(){
		that.overPopup = 0;
		if(that.debug == 1) $("#onPopup").html("no");
		isMouseout(-1);
	})
	

	/**
	 * @alias isMouseout
	 * @alias JSH.bindPopupEvent.isMouseout
	 * @return {null}
 	 * @projectDescription mouseout event for mouseover trigger
	 */
	var isMouseout = function(outIndex){
		if (outIndex == that.triggerIndex || outIndex == -1) {
			clearTimeout(this.timerhandle);
			
			if (that.hideType == "mouseover") {
				that.timerhandle = setTimeout(function(){
					if (!that.overTrigger && !that.overPopup) {
						if (that.debug == 1) 
							$("#popupStatus").html("hide");
						that.hidePopup();
					}
				}, that.respTime)
			}
		}
	}
	
	
}

/**
 * @alias hidePopup
 * @alias JSH.bindPopupEvent.hidePopup
 * @return {null}
 * @projectDescription hide the popup
 */
bindPopupEvent.prototype.hidePopup = function(){
	$(this.popupObj).fadeOut(100);
}


/**
 * @alias showPopup
 * @alias JSH.bindPopupEvent.showPopup
 * @return {null}
 * @projectDescription show the popup
 */
bindPopupEvent.prototype.showPopup = function(e){
	if(this.callback)
		if(!this.callback(e,this.triggerObj[this.triggerIndex],this.popupObj,this.triggerChildIndex))
			return;
	$(this.popupObj).fadeIn(100);
}

/**
 * @alias getBrowserRules
 * @alias JSH.BgetBrowserRules
 * @return {Array} [height,width,sTop,sLeft,sHeight,sWidth] 
 * @projectDescription Return browser size param
 */
var getBrowserRules = function() {
	return {
		height : document.documentElement.clientHeight,
		width : document.documentElement.clientWidth,
		sTop: document.documentElement.scrollTop,
		sLeft: document.documentElement.scrollLeft,
		sHeight: document.documentElement.scrollHeight,
		sWidth: document.documentElement.scrollWidth
	}
}

/**
 * @alias getMousePos
 * @alias JSH.getMousePos
 * @return {Array} [x,y] 
 * @projectDescription Return mouse position
 */
var getMousePos = function(ev) {
	if (ev.pageX || ev.pageY) {
		return {x:ev.pageX, y:ev.pageY}
	} 
	return {
		x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
		y:ev.clientY + document.body.scrollTop  - document.body.clientTop
	}
}