
//********************************************************//
//	Effect Class Ver. 0.9
//  작성자 : 정병태
//  작성일 : 2008-04-01
//********************************************************//

// IE BackgroundImage Flicker 버그 처리
if(Prototype.Browser.IE) document.execCommand("BackgroundImageCache",false,true);

var Effect = {};
Effect.Version = "0.9";

var IE6 = navigator.appVersion.toLowerCase().indexOf("msie 6.0") > 0 ? true : false;
var SP1 = IE6 > 0 ? (navigator.appMinorVersion.toLowerCase().indexOf("sp1") > 0 ? true : false) : false;

//////////////////////////////////////////////
//    페이지 사이즈 구하기
//////////////////////////////////////////////
var getPageSize = function(){
	var xScroll, yScroll;
	if (window.innerHeight && window.scrollMaxY) {	
		xScroll = document.body.scrollWidth;
		yScroll = window.innerHeight + window.scrollMaxY;
	} else if (document.body.scrollHeight > document.body.offsetHeight){
		xScroll = document.body.scrollWidth;
		yScroll = document.body.scrollHeight;
	} else {
		xScroll = document.body.offsetWidth;
		yScroll = document.body.offsetHeight;
	}
	
	var windowWidth, windowHeight;
	if (self.innerHeight) {
		windowWidth = self.innerWidth;
		windowHeight = self.innerHeight;
	} else if (document.documentElement && document.documentElement.clientHeight) {
		windowWidth = document.documentElement.clientWidth;
		windowHeight = document.documentElement.clientHeight;
	} else if (document.body) {
		windowWidth = document.body.clientWidth;
		windowHeight = document.body.clientHeight;
	}	
	
	if(yScroll < windowHeight){
		pageHeight = windowHeight;
	} else { 
		pageHeight = yScroll;
	}

	if(xScroll < windowWidth){	
		pageWidth = windowWidth;
	} else {
		pageWidth = xScroll;
	}

	arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight); 
	return arrayPageSize;
};


///////////////////////////////////////////////
//    윈도우 가시화면 높이값 구하기
///////////////////////////////////////////////
var getPageScroll = function(){

	var yScroll;

	if (self.pageYOffset) {
		yScroll = self.pageYOffset;
	} else if (document.documentElement && document.documentElement.scrollTop){
		yScroll = document.documentElement.scrollTop;
	} else if (document.body) {
		yScroll = document.body.scrollTop;
	}

	arrayPageScroll = new Array('',yScroll); 
	return arrayPageScroll;
};

Effect.Offset = function(element) {
	var offsetParent = element.offsetParent;
	var width = element.offsetWidth;
	var height = element.offsetHeight;
	var top = element.offsetTop;
	var left = element.offsetLeft;
	//var right = offsetParent.offsetWidth - (left+width);
	//var bottom = offsetParent.offsetHeight - (top+height);
	return {width:width, height:height, top:top, left:left};
},

Effect.Tween = Class.create({
	initialize : function(element, options) {

		// 기본 option 객체를 생성한다.
		this.options = {
			top: NaN, left: NaN, width: NaN, height: NaN, 
			speed: 5,				// 클수록 느려짐
			mode : "smooth",	// smooth, regular, accel
			onComplete: Prototype.emptyFunction
		};

		Object.extend(this.options, options || {});

		this.element = $(element);
		var now = new Date();
		this.element.id = this.element.id || this.element.identify();
		this.element.setStyle({visibility:"visible"});
		this.params = $A();
		this.mNo = $A();
		this.cPos = $A();
		this.completeDone = 0;
		var offsetAll = Effect.Offset(this.element);
		$w("top bottom left right width height").each(function(param){
			if(!isNaN(parseInt(this.options[param], 0))) {
				var offset = offsetAll[param];
				this.params.push(param);
				this.cPos.push(offset);
				this.mNo.push(offset < parseInt(this.options[param], 0) ? 1 : -1);
				this.completeDone++;
			}
		}.bind(this));
		this.bPos = this.cPos.clone();

		ProcessInterval.set("tween_"+this.element.id,this.process.bind(this));
		ProcessInterval.setComplete("tween_"+this.element.id, this.options.onComplete);

	},

	// 레이어가 목표까지 모션을 취하도록 계속 실행한다.
	process : function()  {
		var completeCheck = 0;
		this.params.each(function(p,i){
			var pos = parseInt (this.options[p], 0);
			var speed = this.options.speed;
			switch(this.options.mode) {
				case "regular" : this.cPos[i]+= Math.ceil((pos-(this.bPos[i]))/(speed*2))+this.mNo[i]; break;
				case "smooth" : this.cPos[i]+= Math.ceil((pos-this.cPos[i])/speed)+this.mNo[i]; break;
				case "accel" : this.cPos[i]+= Math.ceil((pos-(this.bPos[i])-(pos-this.cPos[i]))/(speed/2))+this.mNo[i]; break;
			}
			if (pos * this.mNo[i] <= this.cPos[i] * this.mNo[i]) {
				this.cPos[i] = pos;
				completeCheck++;
			}
			this.element.style[this.params[i]] = this.cPos[i]+"px";
		}.bind(this));	

		if(this.completeDone <= completeCheck) {
			return false;
		} else {
			return true;
		}
	}
});

Effect.Opacity = Class.create({
	initialize : function(element, options) {

		// 기본 option 객체를 생성한다.
		this.options = {
			opacity: 0,
			speed: 4,				// 클수록 느려짐
			mode : "smooth",	// smooth, regular, accel
			onComplete: Prototype.emptyFunction
		};

		Object.extend(this.options, options || {});

		this.element = $(element);
		var now = new Date();
		this.element.id = this.element.id || this.element.identify();
		this.cOpa = this.element.getOpacity() ? this.element.getOpacity()*100 : 0;
		this.bOpa = this.cPos;
		this.mNo = this.cOpa < this.options.opacity ? 1 : -1;

		ProcessInterval.set("opacity_"+this.element.id, this.process.bind(this));
		ProcessInterval.setComplete("opacity_"+this.element.id, this.options.onComplete);
	},

	// 레이어가 목표까지 모션을 취하도록 계속 실행한다.
	process : function()  {
		var completeCheck = false;
		var speed = this.options.speed;
		var opacity = this.options.opacity;
		switch(this.options.mode) {
			case "regular" : this.cOpa+= Math.ceil((opacity-(this.bOpa))/(speed*2))+this.mNo; break;
			case "smooth" : this.cOpa+= Math.ceil((opacity-this.cOpa)/speed)+this.mNo; break;
			case "accel" : this.cOpa+= Math.ceil((opacity-(this.bOpa)-(opacity-this.cOpa))/(speed/2))+this.mNo; break;
		}
		if (opacity * this.mNo <= this.cOpa * this.mNo) {
			this.cOpa = opacity;
			completeCheck = true;
		}
		this.element.setOpacity(this.cOpa/100);

		if(completeCheck) {
			//var onComplete = this.options.onComplete.bind(this);
			//onComplete();
			return false;
		} else {
			return true;
		}
	}
});

Effect.Overlay = {
	
	initialize : function(options) {
		// 기본 option 객체를 생성한다.
		this.options = {
			zIndex : 1000,
			smooth : true,
			opacity: 60,
			speed: 2,				// 클수록 느려짐
			color:"#000000",
			onComplete: Prototype.emptyFunction
		};

		Object.extend(this.options, options || {});
	},

	// 오버레이 레이어를 초기화하고 화면을 띄운다.
	show : function() {
		if(!$("overlayDiv")) {
			var arrayPageSize = getPageSize();
			var elementHegiht = arrayPageSize[1]+"px";
			this.element = new Element("div",{id:'overlayDiv'});
			this.element.setStyle({
				position : "absolute", 
				top : "0px", 
				left : "0px", 
				width : "100%", 
				height : elementHegiht, 
				backgroundColor : this.options.color, 
				zIndex : this.options.zIndex
			});
			this.element.setOpacity((this.options.smooth?0:this.options.opacity));
			this.currentOpacity = 0;
			$("wrapper").insert(this.element);

			new Effect.Opacity("overlayDiv",{
				opacity:this.options.opacity,
				speed:this.options.speed,
				onComplete:this.options.onComplete
			});

			if(IE6) selectboxHidden("overlayDiv");
			
			this.mouseDownHandler = this.doMouseDown.bindAsEventListener(this);
			this.mouseStopHandler = this.doMouseStop.bindAsEventListener(this);
			this.resizeWindowHandler = this.doResizeWindow.bindAsEventListener(this);
			this.element.observe("mousedown",this.mouseDownHandler);
			Event.observe(window, "resize",this.resizeWindowHandler);
		}
	},

	// 오버레이를 삭제한다.
	hide : function() {
		if($("overlayDiv")) {
			if(IE6) selectboxVisible();
			new Effect.Opacity("overlayDiv",{
				opacity:0,
				speed:this.options.speed,
				onComplete : function() {
					Event.stopObserving(window,"resize",this.resizeWindowHandler);
					$("overlayDiv").remove();
				}.bind(this)
			});
		}
	},

	doMouseDown : function() {
		document.observe('selectstart', this.mouseDragHandler);
		document.observe('dragstart', this.mouseDragHandler);
		$("overlayDiv").observe("mouseup",this.mouseStopHandler);
	},

	doMouseStop : function() {
		document.stopObserving('selectstart', this.mouseDragHandler);
		document.stopObserving('dragstart', this.mouseDragHandler);
		$("overlayDiv").stopObserving("mousedown",this.mouseDownHandler);
		$("overlayDiv").stopObserving("mouseup",this.mouseStopHandler);
	},

	doResizeWindow : function() {
		var arrayPageSize = getPageSize();
		var elementHegiht = arrayPageSize[1]+"px";
		$("overlayDiv").setStyle({
			width : "100%", 
			height : elementHegiht
		});
	},

	mouseDragHandler : function(e) {
		Event.stop(e);
	}
};

Effect.Drag = Class.create({

	// 클래스 생성자 함수
	initialize: function(element, options)	 {

		// 기본 option 객체를 생성한다.
		this.options = {
			handler : "",
			onDragStart: Prototype.emptyFunction,
			onDragEnd : Prototype.emptyFunction
		};

		Object.extend(this.options, options || {});

		this.element = $(element);
		this.handler = $(this.options.handler);
		this.mouseDownHandler = this.doMouseDown.bindAsEventListener(this);
		this.mouseMoveHandler = this.doMove.bindAsEventListener(this);
		this.mouseStopHandler = this.doMoveStop.bindAsEventListener(this);
		this.mouseDragHandler = this.doDrag;
		if(this.handler) this.handler.observe('mousedown', this.mouseDownHandler);
		else this.element.observe('mousedown', this.mouseDownHandler);
	},
	
	// 해당 객체 위에 마우스를 클릭하면 드래그 속성을 시작한다.
	doMouseDown : function(e) {	
		var srcObj=(e.srcElement||e.target);
		var nodeName = srcObj.nodeName.toUpperCase();
		if(nodeName == "DIV" || nodeName == "INPUT" || nodeName == "SELECT"
			 || nodeName == "OPTION" || nodeName == "BUTTON" || nodeName == "TEXTAREA") return;
		var offset = Position.cumulativeOffset(this.element);
		this.element._x = (e.pageX||e.clientX) - offset[0];
		this.element._y = (e.pageY||e.clientY) - offset[1];

		document.observe('mousemove', this.mouseMoveHandler);
		document.observe('mouseup', this.mouseStopHandler);
		document.observe('selectstart', this.mouseDragHandler);
		document.observe('dragstart', this.mouseDragHandler);
		this.element.style.zIndex++;
		this.options.onDragStart();
	},
	
	// 해당 객체 위에서 마우스를 누른 상태에서 이동하면 팝업을 마우스의 위치로 이동시킨다.
	doMove : function(e) {
		var arrayPageSize = getPageSize();
		if((e.pageX||e.clientX)-this.element._x < 20) this.element.style.left = "0px";
		else if(((e.pageX||e.clientX)-this.element._x)+this.element.offsetWidth > arrayPageSize[0]-20)  
			this.element.style.left = (arrayPageSize[0]-this.element.offsetWidth)+"px";
		else this.element.style.left = (e.pageX||e.clientX)-this.element._x+"px";
		
		if((e.pageY||e.clientY)-this.element._y < 20) this.element.style.top = "0px";
		else if(((e.pageY||e.clientY)-this.element._y)+this.element.offsetHeight > arrayPageSize[1]-20) 
			this.element.style.top = (arrayPageSize[1]-this.element.offsetHeight)+"px";
		else this.element.style.top = (e.pageY||e.clientY)-this.element._y+"px";
	},
	
	// 마우스 클릭을 놓으면 이동하는 이벤트를 삭제한다.
	doMoveStop : function(e) {
		this.options.onDragEnd();
		document.stopObserving('mousemove', this.mouseMoveHandler);
		document.stopObserving('mouseup', this.mouseStopHandler);
		document.stopObserving('selectstart', this.mouseDragHandler);
		document.stopObserving('dragstart', this.mouseDragHandler);
	},
	
	// 팝업 이동 시 내용이 드래그 되는것을 막는다.
	doDrag : function(e) {
		Event.stop(e);
	},

	// 드래그 속성을 삭제한다.
	stop : function() {
		Event.stopObserving(this.element, 'mousedown', this.mouseDownListener);
	}
});


Effect.slideBar = Class.create({

	// 클래스 생성자 함수
	initialize: function(element, target)	 {
		this.element = $(element);
		this.target = $(element);
		this.mouseDownHandler = this.doMouseDown.bindAsEventListener(this);
		this.mouseMoveHandler = this.doMove.bindAsEventListener(this);
		this.mouseStopHandler = this.doMoveStop.bindAsEventListener(this);
		this.mouseDragHandler = this.doDrag;
		this.element.observe('mousedown', this.mouseDownHandler);
	},
	
	// 해당 객체 위에 마우스를 클릭하면 드래그 속성을 시작한다.
	doMouseDown : function(e) {	
		var srcObj=(e.srcElement||e.target);
		var nodeName = srcObj.nodeName.toUpperCase();
		var offset = Position.cumulativeOffset(this.element);
		this.element._x = (e.pageX||e.clientX) - this.element.offsetLeft;

		document.observe('mousemove', this.mouseMoveHandler);
		document.observe('mouseup', this.mouseStopHandler);
		document.observe('selectstart', this.mouseDragHandler);
		document.observe('dragstart', this.mouseDragHandler);
		this.element.style.zIndex++;
	},
	
	// 해당 객체 위에서 마우스를 누른 상태에서 이동하면 팝업을 마우스의 위치로 이동시킨다.
	doMove : function(e) {
		var arrayPageSize = getPageSize();
		if((e.pageX||e.clientX)-this.element._x < 20) this.element.style.left = "0px";
		else if(((e.pageX||e.clientX)-this.element._x)+this.element.offsetWidth > arrayPageSize[0]-20)  
			this.element.style.left = (arrayPageSize[0]-this.element.offsetWidth)+"px";
		else this.element.style.left = (e.pageX||e.clientX)-this.element._x+"px";
	},
	
	// 마우스 클릭을 놓으면 이동하는 이벤트를 삭제한다.
	doMoveStop : function(e) {
		document.stopObserving('mousemove', this.mouseMoveHandler);
		document.stopObserving('mouseup', this.mouseStopHandler);
		document.stopObserving('selectstart', this.mouseDragHandler);
		document.stopObserving('dragstart', this.mouseDragHandler);
	},
	
	// 팝업 이동 시 내용이 드래그 되는것을 막는다.
	doDrag : function(e) {
		Event.stop(e);
	},

	// 드래그 속성을 삭제한다.
	stop : function() {
		Event.stopObserving(this.element, 'mousedown', this.mouseDownListener);
	}
});

Effect.StartLoading = function(element) {
	element = $(element);
	element.update("<div class='alignC' style='width:100%'><img src='/images/common/loading.gif' /></div>");
};


var ProcessInterval = {
	
	timing : 30,
	entry : {},
	entryComplete : {},

	set : function(id, intance) {
		this.entry[id] = intance;
		if(!this.interval) this.start();
	},

	setComplete : function(id, intance) {
		this.entryComplete[id] = intance;
		if(!this.interval) this.start();
	},

	start : function() {
		this.interval = setInterval(this.excute, this.timing);
	},
	
	excute : function() {
		var entry = ProcessInterval.entry;
		var entryComplete = ProcessInterval.entryComplete;
		if(entry.length <= 0) clearInterval(this.interval);
		for (var key in entry) {
			if(!entry[key].call()) {
				delete entry[key];
				if(entryComplete[key]) {
					var complete = entryComplete[key];
					delete entryComplete[key];
					setTimeout(complete,100);
				}
			}
		}
	}
};
