/**
 * @fileOverview 특정영역을 강조하기 위해 이외의 부분전체를 안개처럼 뿌옇게 가려주는 컴포넌트
 * @author hooriza, modified by senxation
 */
nhn.Foggy = jindo.$Class({
	/** @lends nhn.Foggy */
	_elFog : null,
	_bFogAppended : false,
	_oExcept : null,
	_bFogVisible : false,
	_oTransition : null,
	/**
	 * Foggy 컴포넌트를 생성한다.
	 * Foggy 컴포넌트는 특정영역을 highlighting하기 위해 이외의 부분을 안개처럼 뿌옇게 가려주는 기능을 한다.
	 * @constructs 
	 * @param {Object} oOptions
	 * @requires nhn.Effect
	 * @requires nhn.Transition
	 * @example
var foggy = new nhn.Foggy({
	showDuration : 200, //(Number) fog 레이어가 완전히 나타나기까지의 시간 (ms)
	showOpacity : nhn.Effect.linear(1), //(nhn.Effect) fog 레이어가 보여질 때의 transition 효과와 투명도 (0~1사이의 값)    
	hideDuration : 200, //(Number) fog 레이어가 완전히 사라지기까지의 시간 (ms)
	hideOpacity : nhn.Effect.linear(0), //(nhn.Effect) fog 레이어가 숨겨질 때의 transition 효과와 투명도 (0~1사이의 값)
	zIndex : 32000, //(Number) fog 레이어의 zIndex 값
	fps : 15 //(Number) 효과가 재생될 초당 frame rate
}).attach({
	show : function() {
		//fog 레이어가 화면에 보여지고나서 발생
	},
	hide : function() {
		//fog 레이어가 화면에서 숨겨지고나서 발생
	}
});

//컴포넌트에 의해 생성된 fog레이어에 대한 설정
foggy.getFog().className = 'fog'; 
foggy.getFog().onclick = function() { foggy.hide(); };
	 */
	$init : function(oOptions) {
		
		this.option({
			showDuration : 200,
			showOpacity : nhn.Effect.linear(0.5),
			hideDuration : 200,
			hideOpacity : nhn.Effect.linear(0),
			zIndex : 32000,
			fps : 15
		});
		
		this.option(oOptions || {});
		
		this._elFog = jindo.$('<div>');
		//this._elFog.style.position = 'fixed'; //ie6 fixed 안됨 ㅠㅠ
		
		this._bFogAppended = false;
		this._oExcept = {};
		
		this._oTransition = new nhn.Transition().fps(this.option("fps"));
		
		this._fOnResize = jindo.$Fn(this._fitFogToDocument, this);
		this._fOnScroll = jindo.$Fn(this._fitFogToDocumentScrollSize, this);
	},
	
	_appendFog : function() {
		if (this._bFogAppended) return;
		document.body.insertBefore(this._elFog, document.body.firstChild);
		jindo.$Element(this._elFog).opacity(0);
		this._bFogAppended = true;
	},
	
	_getScroll : function(wDocument) {
		var o = {
			top : 0,
			left : 0
		}
		
		o.top = window.pageYOffset || document[wDocument._docKey].scrollTop;
		o.left = window.pageXOffset || document[wDocument._docKey].scrollLeft;
		return o;
	},
	
	_fitFogToDocument : function() {
		
		var wDocument = jindo.$Document(); 

		this._elFog.style.left = this._getScroll(wDocument).left + 'px';		 
		this._elFog.style.width = wDocument.clientSize().width + 'px';
		
		var self = this;
		clearTimeout(this._nTimer);
		this._nTimer = null;

		//가로스크롤이 생겼다 사라지는경우의 버그를 수정하기위한 setTimeout		
		this._nTimer = setTimeout(function(){
		
			var oSize = wDocument.clientSize();
			 
			self._elFog.style.top = self._getScroll(wDocument).top + 'px';
			self._elFog.style.height = oSize.height + 'px';
			
			self._elFog.style.left = self._getScroll(wDocument).left + 'px';		 
			self._elFog.style.width = wDocument.clientSize().width + 'px';
			
		}, 100);
		
	},
	_fitFogToDocumentScrollSize : function() {
		var oSize = jindo.$Document().scrollSize();
		this._elFog.style.left = "0";
		this._elFog.style.top = "0";
		this._elFog.style.width = oSize.width + 'px';
		this._elFog.style.height = oSize.height + 'px';
	},

	/**
	 * 생성된 fog 레이어 엘리먼트를 가져온다.
	 * @return {HTMLElement} fog 레이어 엘리먼트
	 */
	getFog : function() {
		return this._elFog;
	},
	
	/**
	 * fog 레이어를 보여준다. (elExcept는 가리지 않는다.)
	 * @param {HTMLElement} elExcept
	 */
	show : function(elExcept) {
		
		var self = this;
		
		if (this._bFogVisible) return;
		
		if (elExcept) {
			this._oExcept.element = elExcept;
			var sPosition = jindo.$Element(elExcept).css('position');
	
			if (sPosition == 'static') {
				this._oExcept.position = elExcept.style.position;
				elExcept.style.position = 'relative';
			}

			this._oExcept.zIndex = elExcept.style.zIndex;
			elExcept.style.zIndex = this.option('zIndex') + 1;
		}
		
		this._elFog.style.zIndex = this.option('zIndex');
		this._elFog.style.display = 'none';
		
		this._appendFog();
		this._fitFogToDocument();
		this._fOnResize.attach(window, "resize");
		this._fOnScroll.attach(window, "scroll");
		
		this._elFog.style.display = 'block';
		this._bFogVisible = true;
		
		this._oTransition.start(this.option('showDuration'),
			this._elFog, { '@opacity' : this.option('showOpacity') }
		).precede(function() {
			self.fireEvent('show');
		});
		
	},
	
	/**
	 * fog 레이어를 숨긴다.
	 */
	hide : function() {
		
		var self = this;
		
		if (!this._bFogVisible) return;
		
		this._bFogVisible = false;

		this._oTransition.start(this.option('hideDuration'),
			this._elFog, { '@opacity' : this.option('hideOpacity') }
		).precede(function() {
			self._elFog.style.display = 'none';
			
			var elExcept = self._oExcept.element;
			if (elExcept) {
				if (self._oExcept.position) elExcept.style.position = self._oExcept.position;
				elExcept.style.zIndex = self._oExcept.zIndex;
			}
			this._oExcept = {};
			self._fOnResize.detach(window, "resize");
			self._fOnScroll.detach(window, "scroll");
			
			self.fireEvent('hide');
		});
		
	}
	
}).extend(nhn.Component);
