/**
 * @projectDescription Empas Prototye & UI
 * @copyright Empas Corp. <http://www.empas.com>
 * @author ifsnow ifsnow@empascorp.com
 * @version 1.0
 * 
 * Empas > UI > Form > CheckBox, Radio
 */

if(typeof Prototype == "undefined")
	throw("empas.ui.form.js requires including Prototype library");

if (!$D(Empas)) var Empas = {};
if (!$D(Empas.UI)) Empas.UI = {};

/*============================================================================*
 * CheckBox
 *============================================================================*/
Empas.UI.Checkbox = Class.create();

Object.extend(Empas.UI.Checkbox,{
	_groups: {},		// ±×·ì
	
	/**
	 * ±×·ì µ¥ÀÌÅÍ »ý¼º
	 * @param {String} group ±×·ì¸í
	 */
	create: function(group) {
		if (!$D(this._groups[group])) 
			this._groups[group] = { els : [], checked : false};
	},

	/**
	 * ±×·ìº° Ã¼Å©¹Ú½º ¿¤¸®¸ÕÆ® Ãß°¡
	 * 
	 * @param {Object} instance Empas.UI.Checkbox Å¬·¡½º
	 * @param {Object} el Ã¼Å©¹Ú½º ¿¤¸®¸ÕÆ®
	 */	
	add: function(instance, el) {
		this._groups[instance.options.group].els.push(el);
	},
	
	/**
	 * ±×·ì¸íÀ¸·Î µ¥ÀÌÅÍ ±¸ÇÏ±â
	 * 
	 * @param {String} group ±×·ì¸í
	 * @return {Object} ±×·ì µ¥ÀÌÅÍ
	 */	
	_getGroup: function(group) {
		group = group || "default";		
		if (!$D(this._groups[group])) return null;
		
		return this._groups[group];
	},
	
	/**
	 * µî·ÏµÈ Ã¼Å©¹Ú½ºÁß ¼±ÅÃµÈ °ª ±¸ÇÏ±â
	 * 
	 * @param {String} group ±×·ì¸í
	 * @return {Object} ¼±ÅÃµÈ °ªÀ» ¹è¿­ ÇüÅÂ·Î ¹ÝÈ¯
	 */	
	values: function(group) {
		var groups = this._getGroup(group);
		if (!groups) return [];

		var result = [];
		groups.els.each(function (el) { 
			if (el.checked)
			{
				result.push(el.value);
			}
		});

		return result;
	},

	/**
	 * ±×·ìº° Åä±Û ÇÔ¼ö
	 * 
	 * @param {String} group ±×·ì¸í
	 * @param {Boolean} val »ç¿ëÀÚ ÁöÁ¤°ª.
	 */		
	toggle: function(group, val) {
		 var groups = this._getGroup(group);
		if (!groups) return;

		groups.checked = val || !groups.checked;

		groups.els.each(function (el) { el.checkAll(groups.checked) }); 
	},
	
	/**
	 * °ªÀ¸·Î Ã¼Å©
	 * 
	 * @param {String} val °ª
	 * @param {String} group ±×·ì¸í
	 */		
	checkByValue: function(val, group) {
		group = group || "default";
		
		if (!$D(this._groups[group])) return;
		
		var groups = this._groups[group];		
				
		groups.els.each(function (el) {
			if (el.value==val) el.checkAll(true);
		}); 
	},
	
	/**
	 * ´Ù½Ã ±×¸®±â
	 * 
	 * @param {String} group ±×·ì¸í
	 */
	redraw: function(group) {
		group = group || "default";
		
		if (!$D(this._groups[group])) return;
		
		var groups = this._groups[group];		

		groups.els.each(function (el) {
			el.redraw();
		}); 
	}
});

Empas.UI.Checkbox.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * 
	 * @param {Object} options ¿É¼Ç
	 * @constructor
	 */
	initialize: function(options) {
		this.savedImg = {};	// »ý¼ºµÈ ÀÌ¹ÌÁö °´Ã¼ ÀúÀå (Å° : Ã¼Å©¹Ú½º ¾ÆÀÌµð)
	
		this.options = Object.extend({
			group: "default",								// ±×·ì¸í
			checkbox: null,									// °³º° Ã¼Å©¹Ú½º ¾ÆÀÌµð·Î Àû¿ë½Ã (,·Î º¹¼ö ±¸ºÐ)			
			imgOn: 'http://img.nate.com/kwshop/renewal/eprototypeui/check_on.gif',				// Ã¼Å©»óÅÂ ÀÌ¹ÌÁö
			imgOff: 'http://img.nate.com/kwshop/renewal/eprototypeui/check_off.gif',				// ÀÏ¹Ý»óÅÂ ÀÌ¹ÌÁö
			imgOnOver: 'http://img.nate.com/kwshop/renewal/eprototypeui/check_on_over.gif',		// Ã¼Å©»óÅÂ ¸¶¿ì½º¿À¹ö ÀÌ¹ÌÁö
			imgOffOver: 'http://img.nate.com/kwshop/renewal/eprototypeui/check_off_over.gif',	// ÀÏ¹Ý»óÅÂ ¸¶¿ì½º¿À¹ö ÀÌ¹ÌÁö			
			overMode: true,									// ¸¶¿ì½º¿À¹ö ¸ðµå
			useHand: true,									// ¸¶¿ì½º ¿À¹ö½Ã ¼Õ¸ð¾ç Ä¿¼­ À¯¹«
			classApply: true								// Å¬·¡½º(EUICheckbox) ÀÏ°ý Àû¿ë À¯¹«
		}, options || {});
		
		options = this.options;
		
		// ±×·ì µ¥ÀÌÅÍ »ý¼º
		Empas.UI.Checkbox.create(options.group);
		
		// Å¬·¡½º ÀÏ°ý Àû¿ë
		if (options.checkbox==null && options.classApply) {
			document.getElementsByClassName("EUICheckbox").each(this._bindCheckbox.bind(this));
		} else {
			options.checkbox.split(",").each(function (elm) {
				this._bindCheckbox($(elm));
			}.bind(this));
		}

		// ¶óº§ ¹ÙÀÎµù 
		document.getElementsByClassName("EUICheckLabel").each(this._bindLabel.bind(this));

		// clear memory leak
		Event.observe(window, 'unload', this._cleanup.bind(this));
	},

	/**
	 * Ã¼Å©¹Ú½º °´Ã¼ ¹ÙÀÎµù
	 * 
	 * @param {Object} element ¹ÙÀÎµùÇÒ °´Ã¼
	 */	
	_bindCheckbox: function(element) {
		// Áßº¹ ¹ÙÀÎµù Ã¼Å©
		if ($D(element._created)) return;
		element._created = true;
		
		// ÀÌ¹ÌÁö »ý¼º
		var img = $C("img").setStyle( { "vertical-align":"top" });
		if (this.options.useHand) {
			img.setStyle({ "cursor": "pointer" });
		}

		// Ã¼Å©ÇÔ¼ö ¿¬°á
		element.parent = this;
		Object.extend(element, {
			check: function(val) {
				this.checked = val;
				this.parent._clickImg(img, true);
			},
			checkAll: function(val) {
				this.checked = val;
				this.parent._clickImg(img, true, false);
			},
			setDisable: function(val) {
				this.parent._setDisable(img, val);
			},
			redraw: function() {
				this.parent._draw(img);
			}
		});
		
		// ÀÌ¹ÌÁö onclick ÀÌº¥Æ® ¼³Á¤
		img.observe('click', this._clickImg.bind(this, img));

		// ÀÌ¹ÌÁö mouseover, mouseout ÀÌº¥Æ® ¼³Á¤
		if (this.options.overMode) {
			img.observe('mouseover', this._mouseImg.bind(this, img, 'over'));
			img.observe('mouseout', this._mouseImg.bind(this, img, 'out'));
		}
		
		// Ã¼Å©¹Ú½º °´Ã¼ ¿¬°á
		img.checkbox = element;
		
		// on,off »óÅÂ¿¡ µû¶ó ±×¸®±â 
		this._draw(img);

		if ($ATTR(element, "disabled")) {
			this._setDisable(img, true);
		}
			
		// ¶óº§°ú ¿¬°áÀ» À§ÇØ ÀúÀå 					
		if (element.id)
			this.savedImg[element.id] = img;

		// ÀÌ¹ÌÁö »ðÀÔÇÏ°í ±âÁ¸ Ã¼Å©¹Ú½º ¼û±â±â
		element.parentNode.insertBefore(img, element);
		element.hide();
		
		// ±×·ìº° Ã¼Å©¹Ú½º ¿¤¸®¸ÕÆ® Ãß°¡
		Empas.UI.Checkbox.add(this, element);
	},

	/**
	 * ºñÈ°¼³È­ ¿©ºÎ ¼³Á¤
	 * 
	 * @param {Object} img ÀÌ¹ÌÁö °´Ã¼
	 * @param {Boolean} disable ¼³Á¤°ª
	 */
	_setDisable: function(img, disable) {
		img.setOpacity(disable ? 0.5:1.0);
		img.checkbox.disabled = disable;
	},
	
	/**
	 * ¶óº§ ¹ÙÀÎµù
	 * 
	 * @param {Object} element ¹ÙÀÎµùÇÒ ¶óº§ °´Ã¼
	 */
	_bindLabel: function(element)
	{
		element = $(element);
		
		// Ã¼Å©¹Ú½º ¹ÙÀÎµùÀÌ µÈ ¶óº§¸¸ ¹ÙÀÎµù
		var img = this.savedImg[element.readAttribute("for")];
		if (!img) return;
		
		// Áßº¹ ¹ÙÀÎµù Ã¼Å©
		if ($D(element._created)) return;
		element._created = true;
		
		if (this.options.useHand) 
			element.setStyle({ "cursor": "pointer" });
		
		element.observe('click', this._clickLabel.bindAsEventListener(this));
		
		// ¶óº§ mouseover, mouseout ÀÌº¥Æ® ¼³Á¤
		if (this.options.overMode) {
			element.observe('mouseover', this._mouseImg.bind(this, img, 'over'));
			element.observe('mouseout', this._mouseImg.bind(this, img, 'out'));
		}
		
	},

	/**
	 * ÀÌ¹ÌÁö click ÀÌº¥Æ® Ã³¸®
	 * 
	 * @param {Object} img ÀÌº¥Æ® ¹ß»ýÇÑ ÀÌ¹ÌÁö °´Ã¼ 
	 * @param {Object} notupdate Ã¼Å©°ª º¯°æÇÏÁö ¾ÊÀ»Áö À¯¹«. ±âº»°ª false
	 */
	_clickImg: function(img, notupdate) {
		if (img.checkbox.disabled) return;
		
		notupdate = $T(notupdate)=='boolean' ? notupdate:false;
		
		if (!$ATTR(img.checkbox, "disabled")) {
			if (!notupdate) img.checkbox.checked = !img.checkbox.checked;
			this._draw(img);

			// toggleÀÏ °æ¿ì onclick ÀÌº¥Æ® »ç¿ë ¾ÈÇÔ
			if (!$D(arguments[2]) && img.checkbox.onclick) img.checkbox.onclick();
		}
	},
	
	/**
	 * ÀÌ¹ÌÁö mouseover, mouseout ÀÌº¥Æ® Ã³¸®
	 * 
	 * @param {Object} img ÀÌº¥Æ® ¹ß»ýÇÑ ÀÌ¹ÌÁö °´Ã¼ 
	 * @param {String} kind ÀÌº¥Æ® Á¾·ù. (over|out)
	 */
	_mouseImg: function(img, kind) {
		if (img.checkbox.disabled) return;
		
		if (kind=="over")
			img.src = img.checkbox.checked ? this.options.imgOnOver:this.options.imgOffOver;
		else
			this._draw(img);
	},
	
	/**
	 * ¶óº§ click ÀÌº¥Æ® Ã³¸®
	 * 
	 * @param {Object} e ÀÌº¥Æ® ¹ß»ý °´Ã¼
	 */
	_clickLabel: function(e) {
		Event.stop(e);
		this._clickImg(this.savedImg[Event.element(e).readAttribute("for")]);
	},	
	
	_draw: function(img) {
		img.src = img.checkbox.checked ? this.options.imgOn:this.options.imgOff;
	},

	/**
	 * ¸Þ¸ð¸®¸¯ Á¦°Å¸¦ À§ÇÑ Ã³¸® 
	 */
	_cleanup: function() {
		for (var elm_id in this.savedImg) {
			this.savedImg[elm_id].checkbox = null;
			this.savedImg[elm_id].options = null;
			this.savedImg[elm_id] = null;
		}
		this.savedImg = null;		
	}
};

/*============================================================================*
 * Radio
 *============================================================================*/
Empas.UI.Radio = Class.create();

Empas.UI.Radio.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * 
	 * @param {String} group Àû¿ëÇÒ radio °´Ã¼ÀÇ name°ª
	 * @param {Object} options ¼³Á¤°ª
	 * @constructor
	 */
	initialize: function(group, options) {
		// ³»ºÎº¯¼ö ÃÊ±âÈ­
		this._init();
		
		// ¿É¼Ç
		this._options = Object.extend({
			imgOn: 'http://img.nate.com/kwshop/renewal/eprototypeui/radio_on.gif',
			imgOff: 'http://img.nate.com/kwshop/renewal/eprototypeui/radio_off.gif',
			imgOnOver: 'http://img.nate.com/kwshop/renewal/eprototypeui/radio_on_over.gif',
			imgOffOver: 'http://img.nate.com/kwshop/renewal/eprototypeui/radio_off_over.gif',
			overMode: true,
			useHand: true
		}, options || {});
		
		// ÁöÁ¤µÈ ±×·ì ÀÌ¸§À¸·Î ¹ÙÀÎµù
		$A(document.getElementsByName(group)).each(this._bindRadio.bind(this));
		
		// ¶óº§ ¹ÙÀÎµù
		document.getElementsByClassName("EUIRadioLabel").each(this._bindLabel.bind(this));

		// for memory leak
		Event.observe(window, 'unload', this._cleanup.bind(this), false);
	},

	/**
	 * ºñÈ°¼³È­ ¿©ºÎ ¼³Á¤
	 * 
	 * @param {Object} img ÀÌ¹ÌÁö °´Ã¼
	 * @param {Boolean} disable ¼³Á¤°ª
	 */
	_setDisable: function(img, disable) {
		img.setOpacity(disable ? 0.5:1.0);
		img.radio.disabled = disable;
	},
	
	/**
	 * ³»ºÎ º¯¼ö ÃÊ±âÈ­
	 */
	_init: function() {
		this.savedImg =  {};
		this.savedElement = [];
		this.selectedImg = null;
		this._disabled = false;
	},
	
	/**
	 * ¶óµð¿À °´Ã¼ ¹ÙÀÎµù
	 * 
	 * @param {Object} element ¹ÙÀÎµùÇÒ °´Ã¼
	 */
	_bindRadio: function(element) {
		// Áßº¹ Ã¼Å©
		if ($D(element._created)) {
			return;
		} else {
			element._created = true;
		}
		
		// ¶óµð¿À °´Ã¼ ÀúÀå
		this.savedElement.push(element);

		// ÀÌ¹ÌÁö »ý¼º	
		var img = $C("img").setStyle({ "vertical-align":"top" });
		if (this._options.useHand) {
			img.setStyle({ "cursor": "pointer" });
		}
		
		// Ã¼Å© ÇÔ¼ö ¿¬°á		
		element.parent = this;
		Object.extend(element, {
			check: function() {
				this.parent._clickImg(img);
			},			
			setDisable: function(val) {
				this.parent._setDisable(img, val);
			}
		});
		
		// ¼±ÅÃµÈ ÀÌ¹ÌÁö °´Ã¼
		if (element.checked) {
			this.selectedImg = img;
		}
		
		img.radio = element;
		
		if ($ATTR(element, "disabled")) {
			this._setDisable(img, true);
		}
		
		// ÀÌ¹ÌÁö onclick ÀÌº¥Æ® 
		Event.observe(element, 'click', this._clickImg.bind(this, img));
		
		// ÀÌ¹ÌÁö onclick ÀÌº¥Æ® 
		img.observe('click', this._clickImg.bind(this, img));

		// ÀÌ¹ÌÁö mouseover, mouseout ÀÌº¥Æ® ¼³Á¤
		if (this._options.overMode) {
			img.observe('mouseover', this._mouseImg.bind(this, img, 'over'));
			img.observe('mouseout', this._mouseImg.bind(this, img, 'out'));
		}

		// ÀÌ¹ÌÁö¿¡ ¶óµð¿À °´Ã¼ ¿¬°á
	
		this._draw(img);

		// ¶óº§°ú ¿¬°áÀ» À§ÇØ ÀÌ¹ÌÁö ÀúÀå 					
		if (element.id) {
			this.savedImg[element.id] = img;			
		}

		// ÀÌ¹ÌÁö »ðÀÔ
		element.parentNode.insertBefore(img, element);
		element.hide();
	},

	/**
	 * ¶óº§ ¹ÙÀÎµù
	 * 
	 * @param {Object} element ¹ÙÀÎµùÇÒ °´Ã¼
	 */
	_bindLabel: function(element)
	{
		// Áßº¹ Ã¼Å©
		if ($D(element._created)) {
			return;
		} 
				
		var img = this.savedImg[element.readAttribute("for")];		
		if ($D(img)) {
			if (this._options.useHand) 
				$(element).setStyle({ "cursor": "pointer"});	
			
			// ¶óµð¿À¿¡ ÀÌ¹ÌÁö ÀúÀåÇÏ°í click ÀÌº¥Æ® ¿¬°á
			element._created = true;
			element.img = img;
			
			Event.observe(element, 'click', this._clickLabel.bindAsEventListener(this));
			
			if (this._options.overMode) {
				Event.observe(element, 'mouseover', this._mouseImg.bind(this, img, 'over'));
				Event.observe(element, 'mouseout', this._mouseImg.bind(this, img, 'out'));
			}
		}
	},
	
	/**
	 * ÀÌ¹ÌÁö click ÀÌº¥Æ® Ã³¸®
	 * 
	 * @param {Object} img ¹ß»ýÇÑ ÀÌ¹ÌÁö
	 */
	_clickImg: function(img) {
		if (img.radio.disabled) return;
		
		img.radio.checked = true;
		this._draw(img);

		// ÀÌÀü ¼±ÅÃµÈ ¶óµð¿À ÇØÁ¦
		if (this.selectedImg!=null && this.selectedImg!=img) {
			this._draw(this.selectedImg);
		}
		
		this.selectedImg = img;
		if (img.radio.onclick) img.radio.onclick();
	},
	
	/**
	 * ÀÌ¹ÌÁö mouseover, mouseout ÀÌº¥Æ® Ã³¸®
	 * 
	 * @param {Object} img ÀÌº¥Æ® ¹ß»ýÇÑ ÀÌ¹ÌÁö °´Ã¼ 
	 * @param {String} kind ÀÌº¥Æ® Á¾·ù. (over|out)
	 */
	_mouseImg: function(img, kind) {
		if (this._disabled) return;
		
		if (kind=="over")
			img.src = img.radio.checked ? this._options.imgOnOver:this._options.imgOffOver;
		else
			this._draw(img);
	},	
	
	/**
	 * ¶óº§ click ÀÌº¥Æ® Ã³¸®
	 * 
	 * @param {Object} e ÀÌº¥Æ® ¹ß»ý °´Ã¼
	 */
	_clickLabel: function(e) {
		Event.stop(e);
		this._clickImg(Event.element(e).img);
	},	
	
	_draw: function(img) {		
		img.src = img.radio.checked ? this._options.imgOn:this._options.imgOff;		
	},
	
	/**
	 * °ªÀ¸·Î Ã¼Å©
	 * 
	 * @param {String} val °ª
	 * @param {String} group ±×·ì¸í
	 */		
	checkByValue: function(val) {
		this.savedElement.each(function(el) {
			if (el.value==val) el.check();
		}); 
	},
	
	/**
	 * ¸Þ¸ð¸®¸¯ Á¦°Å¸¦ À§ÇÑ Ã³¸®
	 */
	_cleanup: function() {
		this.selectedImg = null;
		
		for (var elm_id in this.savedImg) {
			this.savedImg[elm_id].radio = null;
			this.savedImg[elm_id].options = null;
			this.savedImg[elm_id] = null;
		}
		this.savedImg = null;
				
		this.savedElement.each(function(obj) {
			obj.parent = null;			
			obj.img = null;			
			obj.check = null;
		});
		
		this.savedElement = null;
	}
};
