/**
 * @projectDescription Empas Prototye & UI
 * @copyright Empas Corp. <http://www.empas.com>
 * @author ifsnow ifsnow@empascorp.com
 * @version 1.0
 * 
 * Empas > UI > View > Tab, Rotate, Toggle, Scroller, Floating
 */

if(typeof Prototype == "undefined")
	throw("empas.ui.view.js requires including Prototype library");

if (!$D(Empas)) var Empas = {};
if (!$D(Empas.UI)) Empas.UI = {};

/*============================================================================*
 * ViewItem
 *============================================================================*/
Empas.UI.ViewItem = Class.create();

Empas.UI.ViewItem.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * 
	 * @param {String} tab_id ÅÇ°ú ¿¬°áÇÒ ¿¤¸®¸ÕÆ® ¾ÆÀÌµð
	 * @param {Object} request Ajax ¿äÃ» ¿É¼Ç
	 * @constructor
	 */
	initialize: function(id, request) {
		this._el = $(id);
		this.setRequest(request);
	},
	
	/**
	 * Ajax ¿äÃ» ¿É¼Ç ¼³Á¤
	 * 
	 * @param {Object} request ¿É¼Ç
	 */
	setRequest: function(request) {
		this._request = Object.extend({
			url: '',			// Ajax È£Ãâ URL
			lazyLoading: false,	// Áö¿¬ ·Îµù À¯¹«
			isLoad: false		// ·Îµù ¿Ï·á À¯¹«
		}, request || {});
		
		if (this._request.lazyLoading) 
			Event.observe(window, "load", this._load.bind(this));
	},
	
	/**
	 * ¼û±â±â
	 */
	hide: function() {
		this._el.hide();
	},

	/**
	 * º¸ÀÌ±â
	 */	
	show: function() {
		this._el.show();
		this._load();
	},
	
	/**
	 * Ajax ¼³Á¤ÀÌ µÈ °æ¿ì ¿äÃ»ÇØ ¿¤¸®¸ÕÆ® °»½ÅÇÏ±â
	 */
	_load: function() {
		if (this._request.url!='' && !this._request.isLoad) {
			if(!$D(Ajax))
				throw("Empas.UI.View.js requires including Prototype.Ajax library");
			
			this._request.isLoad = true;
			new Empas.Ajax.Updater(this._el, this._request.url);
		}
	}
};

/*============================================================================*
 * Tab
 *============================================================================*/
Empas.UI.Tab = Class.create();

Empas.UI.Tab.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * 
	 * @param {Object} options ¿É¼Ç
	 * @constructor
	 */
	initialize: function(options) {
		this._options = Object.extend({
			changeAction: true,		// ÅÇ º¯°æ½Ã ¾×¼Ç ¿©ºÎ
			clickMode: false,		// Å¬¸¯ ¸ðµå(Å¬¸¯ÇØ¾ß ÅÇ º¯°æ). ±âº»°ªÀº ¸¶¿ì½º ¿À¹ö½Ã º¯°æ
			afterChange: null,		// º¯°æÈÄ ½ÇÇàµÉ ÇÔ¼ö
			noActive: false			// ÃÊ±â ÅÇ ºñÈ°¼ºÈ­ ¿©ºÎ
		}, options || {});
		
		this._TabItems = {};
		this._selectedTab = null;
	},
	
	/**
	 * ·çÆ®ÅÇ °´Ã¼ ¹ÙÀÎµù
	 * 
	 * @param {Empas.UI.View.TabItem} ÅÇ ¾ÆÀÌÅÛ °´Ã¼
	 */	
	add: function(TabItem) {
		if ($D(TabItem.el)) {
			this._TabItems[TabItem.id] = TabItem;
		}
	},	
	
	/**
	 * ÅÇ¿¡ ¸¶¿ì½º ¿À¹ö ÀÌº¥Æ® ¿¬°á
	 * 
	 * @param {String} focusTabId ÃÊ±â º¸¿©Áú ÅÇ ¾ÆÀÌµð (±âº»°ª : Ã¹¹øÂ° ÅÇ)
	 */
	start: function(focusTabId) {
		var initTabId = focusTabId || null;
		var options = this._options;
		var eventKey = options.clickMode ? 'click':'mouseover';
		
		// ÅÇ ¾ÆÀÌÅÛº° ÀÌº¥Æ® ¿¬°á
		$H(this._TabItems).each(function(tab) {
			Event.observe(tab.key, eventKey, this._onChangeTab.bindAsEventListener(this, tab.value));
			if (initTabId==null) initTabId = tab.key;
		}.bind(this));
		
		// ÃÊ±âÅÇ È°¼ºÈ­
		if (!options.noActive && (this._selectedTab = this._TabItems[initTabId])) {
			this._selectedTab._setVisible(true, options.changeAction);
		}
	},
	
	/**
	 * ÅÇ º¯°æ½Ã ½ÇÇà
	 * 
	 * @param {Empas.UI.View.TabItem} TabItem ÀÌº¥Æ®°¡ ¹ß»ýÇÑ ÅÇ ¾ÆÀÌÅÛ °´Ã¼
	 */
	_onChangeTab: function(e, TabItem) {
		var options = this._options;

		// Å¬¸¯ ¸ðµåÀÏ °æ¿ì ÀÌº¥Æ® Àü´Þ ¸·±â
		if (options.clickMode) {
			Event.stop(e);
		}
		
		// ÀÌÀüÅÇ ºñÈ°¼ºÈ­
		if (this._selectedTab != null) {
			if (this._selectedTab == TabItem) return; // ÇöÀç È°¼ºÈ­ ÅÇ°ú °°À» °æ¿ì
			this._selectedTab._setVisible(false, options.changeAction);
		}

		// ¼±ÅÃÅÇ È°¼ºÈ­
		TabItem._setVisible(true, options.changeAction);		
		this._selectedTab = TabItem;
		
		if (options.afterChange != null) 
			options.afterChange(TabItem);
	}
};

/*============================================================================*
 * TabItem
 *============================================================================*/
Empas.UI.TabItem = Class.create();

Empas.UI.TabItem.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * 
	 * @param {String} tab_id ÅÇ°ú ¿¬°áÇÒ ¿¤¸®¸ÕÆ® ¾ÆÀÌµð
	 * @constructor
	 */
	initialize: function(tab_id) {
		this.view = null; // ÅÇ°ú ¿¬°áÇÒ ºä ¾ÆÀÌÅÛ
		
		if ((this.el = $(tab_id)) != null) {			
			this.id = tab_id;
			
			// ¸¶¿ì½º ¿À¹ö½Ã ½ÇÇàÇÒ ¸í·É¿¡ ´ëÇÑ ¼³Á¤°ª ÀúÀå
			if (this.el.tagName=="IMG") { // ÀÌ¹ÌÁöÀÏ °æ¿ì
				this._over = {
					mode: 'img',
					off: this.el.readAttribute('offsrc')!=null ? 
							this.el.readAttribute('offsrc'):this.el.src,
					on: this.el.readAttribute('onsrc')
				};
			} else {
				this._over = {
					mode: 'class',
					off: this.el.readAttribute('offclass')!=null ? 
							this.el.readAttribute('offclass'):$(this.el).className,
					on: this.el.readAttribute('onclass')
				};
			}
		}
	},
	
	/**
	 * ÅÇ°ú ºä ¿¬°á
	 * 
	 * @param {String} view_id ºä ¿¤¸®¸ÕÆ® ¾ÆÀÌµð
	 * @param {Object} request Ajax ¿äÃ» ¿É¼Ç 
	 */
	setView: function(view_id, request) {	
		if ((this.view = new Empas.UI.ViewItem(view_id, request)) != null) {
			this.view.hide();
		}
	},
	
	/**
	 * ºä º¸ÀÓ/¾Èº¸ÀÓ Ã³¸®
	 * 
	 * @param {Boolen} visible º¸ÀÓ/¾Èº¸ÀÓ
	 * @param {Boolen} changeAction »óÅÂ º¯°æ½Ã ¾×¼Ç ¿©ºÎ
	 */	
	_setVisible: function(visible, changeAction) {
		if (!this.view) return;
		
		var tab = this.el;
		if (visible) {
			if (changeAction && this._over.on!=null) {
				if (this._over.mode=='img') {
					tab.src = this._over.on;
				} else if (!tab.hasClassName(this._over.on)){
					tab.removeClassName(this._over.off);
					tab.addClassName(this._over.on);
				}
			}
			this.view.show();
		}
		else {
			if (changeAction && this._over.off!=null) {
				if (this._over.mode=='img') {
					tab.src = this._over.off;
				} else if (!tab.hasClassName(this._over.off)){
					tab.removeClassName(this._over.on);
					tab.addClassName(this._over.off);
				}
			}
			this.view.hide();
		}
	}
};

/*============================================================================*
 * Rotate
 *============================================================================*/
Empas.UI.Rotate = Class.create();

Empas.UI.Rotate.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * 
	 * @param {Object} options ¿É¼Ç
	 * @constructor
	 */
	initialize: function(options) {
		this._options = Object.extend({			
			autoTime: 0,		// Å¸ÀÌ¸Ó (ÀÚµ¿ ·Ñ¸µ). ÃÊ´ÜÀ§
			useHand: true,		// ¸¶¿ì½º ¿À¹ö½Ã ¼Õ¸ð¾ç ¸¶¿ì½º ¿©ºÎ
			afterChange: null	// º¯°æ½Ã ½ÇÇàÇÒ ÇÔ¼ö
		}, options || {});
		
		this._ViewItems = [null];
	},
	
	/**
	 * ºä Ãß°¡
	 * 
	 * @param {String} view_id ºä ¿¤¸®¸ÕÆ® ¾ÆÀÌµð
	 * @param {Object} request Ajax ¿äÃ» ¿É¼Ç
	 */	
	add: function(view_id, request) {
		this._ViewItems.push(new Empas.UI.ViewItem(view_id, request));
	},	
	
	/**
	 * ½ÇÇà
	 * 
	 * @param {Number} initIdx ÃÊ±â ºä ÀÎµ¦½º
	 */
	start: function(initIdx) {
		var options = this._options;

		// ÀÌº¥Æ® ¿¬°á
		Event.observe(options.prev, "click", this._onClick.bindAsEventListener(this, 'prev'));
		Event.observe(options.next, "click", this._onClick.bindAsEventListener(this, 'next'));
		
		// ¸¶¿ì½º Ä¿¼­
		if (options.useHand) {
			$(options.prev).setStyle({ cursor: "pointer" });
			$(options.next).setStyle({ cursor: "pointer" });			
		}

		// ÃÊ±â ºä
		this._endIdx = this._ViewItems.length-1;
		this._savedIdx = this._curIdx = $D(initIdx) ? initIdx:1;
		
		this._show();
	},

	/**
	 * ÀÌÀü ¹öÆ° ¿ÜºÎ ÇÔ¼ö
	 */	
	priv: function() {
		this._onClick(null, "priv");
	},
	
	/**
	 * ´ÙÀ½ ¹öÆ° ¿ÜºÎ ÇÔ¼ö
	 */		
	next: function() {
		this._onClick(null, "next");
	},
	
	/**
	 * ºä ³ëÃâ ¿©ºÎ
	 */
	_show: function() {
		var options = this._options;

		// ÇöÀç ¾ÆÀÌÅÛ
		this._ViewItems[this._curIdx].show();

		// ÀÚµ¿ ·Ñ¸µ Å¸ÀÌ¸Ó ¼³Á¤
		if (options.autoTime != 0) {
			if ($D(this._timer)) this._timer.stop();
						
			this._timer = new PeriodicalExecuter(function () {
				this._onClick('next'); 
			}.bind(this), options.autoTime);
		}

		if (options.afterChange!=null)
			options.afterChange(this._curIdx);		
	},
	
	/**
	 * ÀÌÀü, ´ÙÀ½ Å¬¸¯ ÀÌº¥Æ® ¹ß»ý½Ã ½ÇÇà
	 */	
	_onClick: function(e, mode) {
		Event.stop(e);
		
		this._curIdx += mode=="next" ? 1:-1;
		
		if (this._curIdx <= 0) 
			this._curIdx = this._endIdx;
		else if (this._curIdx > this._endIdx)
			this._curIdx = 1;

		this._ViewItems[this._savedIdx].hide();
		this._savedIdx = this._curIdx;
		
		this._show();
	}
};

/*============================================================================*
 * Toggle
 *============================================================================*/
Empas.UI.Toggle = Class.create();

Empas.UI.Toggle.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * 
	 * @param {String} id Åä±ÛÀ» ¿¬°áÇÒ ¿¤¸®¸ÕÆ® ¾ÆÀÌµð
	 * @param {String} view_id ºä ¿¤¸®¸ÕÆ® ¾ÆÀÌµð
	 * @param {String} options ¿É¼Ç
	 * @constructor
	 */
	initialize: function(id, view_id, options) {
		this._options = Object.extend({
			visible: false,		// ÃÊ±â Ãâ·Â ¿©ºÎ
			afterChange: null,	// ½ÇÇàÈÄ È£ÃâÇÒ ÇÔ¼ö
			useHand:false		// ¸¶¿ì½º ¼Õ¸ð¾ç Ä¿¼­ À¯¹«
		}, options || {});
		
		this._el = $(id);
		if (!this._el) return;
		
		if (this._options.useHand) 
			this._el.setStyle({ cursor: "pointer" });
			
		this._view = new Empas.UI.ViewItem(view_id);
		
		this.toggle(false);
		
		this._el.observe("click", this.toggle.bind(this));
	},
	
	/**
	 * Åä±Û ÇÔ¼ö
	 * 
	 * @param {Boolean} change »óÅÂ°ª º¯°æ ¿©ºÎ (±âº»°ª true)
	 */
	toggle: function(change) {
		var options = this._options;

		if ((change = change || false))
			options.visible = !options.visible;
			
		this._view[options.visible ? 'show':'hide']();
		
		if (options.afterChange!=null)
			options.afterChange(this._el, options.visible);
	}
};

/*============================================================================*
 * Scroller
 *============================================================================*/
Empas.UI.Scroller = Class.create();

Empas.UI.Scroller.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * 
	 * @param {String} id ·çÆ® ¿¤¸®¸ÕÆ® ¾ÆÀÌµð
	 * @param {Object} options ¿É¼Ç 
	 * @constructor
	 */
	initialize: function(id, options) {
		id = $(id);
		if (!id) return;

		this._options = Object.extend({	
			height: 18,			// ³ôÀÌ
			width: "100%",		// ³Êºñ
			width_unit: "px",	// ³Êºñ ´ÜÀ§
			pauseTime: 3,		// ¸ØÃã½Ã°£(ÃÊ)
			speed: 0.02,		// ½ºÅ©·Ñ ÀÌµ¿ È£Ãâ½Ã°£ (³·À»¼ö·Ï ºü¸§)
			step: 1,			// ÀÌµ¿ ÇÈ¼¿ ´ÜÀ§
			overStop: true,		// ¸¶¿ì½º ¿À¹ö½Ã ¸ØÃã ¿©ºÎ
			autoStart: true		// ½ÃÀÛ½Ã ·Ñ¸µ ½ÃÀÛ
		}, options || {});

		options = this._options;

		if (options.width.indexOf("%")!=-1)
		{
			options.width = options.width.replace("%","");
			options.width_unit = "%";
		}

		// ·çÆ® ¿¤¸®¸ÕÆ® ½ºÅ¸ÀÏ ¼³Á¤
		this._el = $C("div");
		$(this._el).setStyle({
			position : "relative",
			overflow : "hidden",
			height : options.height + "px",
			width : options.width + options.width_unit
		});	
		id.appendChild(this._el);

		// ¾ÆÀÌÅÛ ½ÃÀÛ À§Ä¡(y)
		options.readyPos = options.height;
		
		// ¾ÆÀÌÅÛ ÀúÀå ¹è¿­
		this._items = [];
		this._itemCnt = 0;
	},
	
	/**
	 * µ¥ÀÌÅÍ Ãß°¡
	 * 
	 * @param {String} html Ãß°¡ÇÒ div¿¡ ³ÖÀ» ³»¿ë
	 */	
	add: function(html) {
		if (!$D(this._options)) return;
		
		var options = this._options;

		// div °´Ã¼ ¸¸µé±â
		var item = $C("div");
		item.top = (this._itemCnt==0) ? 0:options.readyPos;
		$(item).setStyle( {
			position : "absolute",
			top : item.top + "px",
			height : options.height + "px",
			width : options.width + options.width_unit
		});
		item.innerHTML = html;
		
		// Ãß°¡
		this._el.appendChild(item);
		this._items[this._itemCnt++] = item;
	},
	
	/**
	 * ½ÇÇà
	 */	
	start: function() {	
		if (this._itemCnt>1) {
			// ÃÊ±âÈ­
			this._pause = false;
			this._curIdx = 0;
			this._nextIdx = 1;

			// mouse over ÀÌº¥Æ® µî·Ï
			if (this._options.overStop) {
				this._el.observe("mouseover", this._setPause.bind(this, true));
				this._el.observe("mouseout", this._setPause.bind(this, false));
			}
			
			this._start();
		}
	},
	
	/**
	 * ½ºÅ©·Ñ Á¤Áö º¯¼ö ¼³Á¤
	 * 
	 * @param {Boolean} val Á¤Áö ¿©ºÎ
	 */
	_setPause: function(val) {
		this._pause = val;		
	},
	
	/**
	 * ½ºÅ©·Ñ ÇÔ¼ö ½ÇÇà
	 */	
	_start: function() {
		new PeriodicalExecuter(function (pe) {
			pe.stop();
		
			// ¾ÆÀÌÅÛ ÀÌµ¿ ÇÔ¼ö ½ÇÇà
			if (this._Executer) this._Executer.stop();			
			this._Executer = new PeriodicalExecuter(function () {
				this._moveItem(); 
			}.bind(this), this._options.speed);
						
		}.bind(this), this._options.pauseTime);
	},
	
	/**
	 * ½ºÅ©·Ñ Á¤Áö º¯¼ö ¼³Á¤
	 * 
	 * @param {Boolean} val Á¤Áö ¿©ºÎ
	 */
	_moveItem: function() {
		if (this._pause) return;
		var oerflow = false;
		var items = this._items;
		var options = this._options;
		
		[this._curIdx, this._nextIdx].each(function(idx) {
			// ÇöÀç ¾ÆÀÌÅÛÀ» À§·Î ÀÌµ¿
			items[idx].top -= options.step;
			if (idx==this._nextIdx && items[idx].top <= 0) {
				items[idx].top = 0;
				oerflow = true;
			}
			items[idx].style.top = items[idx].top + "px";
			
			// ´ÙÀ½ ¾ÆÀÌÅÛÀÌ Á¤Áö À§Ä¡¿¡ ¿Ã °æ¿ì
			if (oerflow) {
				if (this._Executer) this._Executer.stop();

				// ÇöÀç ¾ÆÀÌÅÛ(À§·Î »ç¶óÁø)À» ´ë±â À§Ä¡·Î ÀÌµ¿
				items[this._curIdx].top = options.readyPos;
				items[this._curIdx].style.top = items[this._curIdx].top + "px";

				// ÇöÀç, ´ÙÀ½ ¾ÆÀÌÅÛ ÀÎµ¦½º Áõ°¡
				if (++this._curIdx>=this._itemCnt) this._curIdx = 0;
				if (++this._nextIdx >= this._itemCnt) this._nextIdx = 0;
			
				// ½ºÅ©·Ñ ´Ù½Ã ½ÃÀÛ			
				this._start();
			}
		}.bind(this));
	}
};

/*============================================================================*
 * Floating
 *============================================================================*/
Empas.UI.Floating = Class.create();

Empas.UI.Floating.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * 
	 * @param {String} id Àû¿ëÇÒ ¿¤¸®¸ÕÆ® ¾ÆÀÌµð
	 * @param {Object} options ¿É¼Ç
	 * @constructor
	 */
	initialize: function(id, options) {
		this._el = $(id);
		if (!this._el) return;
		
		this._options = Object.extend({
			xMargin: 10,		// X ¸¶Áø 
			yMargin: 10,		// Y ¸¶Áø
			xMode: "left",		// X ¸ðµå : left, right, center, center_add
			yMode: "top",		// Y ¸ðµå : top, middle, bottom
			duration: 0.04,	// ÀÌµ¿ Ã¼Å© ½Ã°£(ÃÊ)
			width: this._el.getWidth(),
			height: this._el.getHeight()
		}, options || {});

		options = this._options;

		// yMode¿¡¼­ »ç¿ëÇÏ±â À§ÇÑ ÃÊ±â yMargin °ª
		options.yOrgMargin = options.yMargin;

		// yMode¿¡ µû¸¥ yMargin°ª º¯°æ
		this._arragePositionY();
		
		// ·çÆ® ¿¤¸®¸ÕÆ® ½ºÅ¸ÀÏ ¼³Á¤
		this._el.setStyle( {
			position : "absolute",
			top : options.yMargin + "px"
		});
		
		// xMode¿¡ µû¸¥ x À§Ä¡ º¯°æ
		this._arragePositionX();
		
		// À©µµ¿ì Å©±â º¯°æ½Ã À§Ä¡ º¸Á¤
		Event.observe(window, "resize", function () {
			this._arragePositionX();
			this._arragePositionY();
		}.bind(this));

		this.start();
	},
	
	/**
	 * xMode¿¡ µû¸¥ x À§Ä¡ º¯°æ
	 */
	_arragePositionX: function() {
		var docWidth = document.body.clientWidth;
		var options = this._options;
		var xPos = options.xMargin;

		// X ÁÂÇ¥ ±¸ÇÏ±â
		switch(this._options.xMode) {
			case "center_add":
				xPos = parseInt(docWidth/2,10) + options.xMargin;
			break;

			case "right":
				xPos = docWidth - options.width - options.xMargin;
			break;

			case "center":
				xPos = parseInt((docWidth - options.width)/2, 10);
			break;
		}

		this._el.style.left = xPos + "px";
	},
	
	/**
	 * yMode¿¡ µû¸¥ yMargin°ª º¯°æ
	 */	
	_arragePositionY: function() {
		var options = this._options;
		if (options.yMode=="middle") {
			options.yMargin = parseInt((document.body.clientHeight - options.height)/2, 10);
		} else if (options.yMode=="bottom") {
			options.yMargin = document.body.clientHeight - options.height - options.yOrgMargin;
		}
	},
	
	/**
	 * ÁÖ±âÀûÀÎ ÀÌµ¿ÇÔ¼ö ½ÇÇà
	 */	
	start: function() {
		this.stop();		
		this._Executer = new PeriodicalExecuter(function () {
			this._move();
		}.bind(this), this._options.duration);
	},
	
	/**
	 * ÀÌµ¿ÇÔ¼ö ½ÇÇà ¸ØÃã
	 */	
	stop: function() {
		if (this._Executer) this._Executer.stop();
	},
	
	/**
	 * ¿¤¸®¸ÕÆ® ÀÌµ¿
	 */	
	_move: function() {
		// ½ÃÀÛ(ÇöÀç) À§Ä¡
		var startPos = parseFloat(this._el.style.top);
		if (!startPos) startPos = 0;
		
		// ¸ñÇ¥ À§Ä¡
		var endPos = document.body.scrollTop + document.documentElement.scrollTop + this._options.yMargin;
		
		// ÀÌµ¿ ¹æÇâ (+, -)
		var dir = (endPos < startPos) ? -1:1;

		// ÀÌµ¿
		if (startPos != endPos) {
			var amount = Math.ceil(Math.abs(endPos-startPos)/5);
			this._el.style.top = (startPos + (dir * amount)) + "px";
		} else {
			this.start();
		}
	}
};