/* mini library - default */

var isEnter = 0; // opera, safari 용 enter 방지 변수
window.safari = (window.webkit == true || window.webkit419 == true || window.webkit420 == true) ? true : false;

Element.extend({
	/** 레이어 토글
	 * @class Element
	 * @param
			$mode: [!|show|hide]
	 */
	toggle: function (mode) {
		$(this);
		if((this.getStyle('display') == 'none' && mode != 'hide') || mode == 'show')
			this.setStyle('display','');
		else
			this.setStyle('display','none');
	},


	/** 레이어 가운데로 놓기
	 * @class Element
	 * @param
			$target: Element. 값이 있을 경우 이 Element의 중앙으로 위치시킨다
			$top: 중앙에서의 top 보정치(더한다)
			$left: 중앙에서의 left 보정치(더한다)
	 */
	center: function (target, top, left) {
		var size = this.getSize();
		var ws = getWindowSize();
		var setLeft = 0;
		var setTop = 0;

		this.setStyle('position', 'absolute');

		if ($chk(target)) {
			var coordinates = target.getCoordinates();
			
			setTop = coordinates.top + Math.round(coordinates.height / 2) - Math.round(size.size.y / 2);
			setLeft = coordinates.left + Math.round(coordinates.width / 2) - Math.round(size.size.x / 2);
		}
		else {
			setTop = window.getScrollTop() + Math.round(ws.size.y / 2) - Math.round(size.size.y / 2);
			setLeft = window.getScrollLeft() + Math.round(ws.size.x / 2) - Math.round(size.size.x / 2);
		}		
		
		if (top) setTop += top;
		if (left) setLeft += left;		
		if (setLeft > ws.scrollSize.x || setLeft < 0) setLeft = 0;
		if (setTop > ws.scrollSize.y || setTop < 0) setTop = 0;
	
		this.setStyles({
			top: setTop,
			left: setLeft
		});
	},
	

	/** 레이어 위치 고정
	 * @class Element 
	 */
	fix: function () {
		this.setStyle('position', 'absolute');

		var tmp_top = '';
		var tmp_left = '';
		
		tmp_top = window.gecko ? this.style.top : this.getStyle('top');
		tmp_left = window.gecko ? this.style.left: this.getStyle('left');
		
		if (!tmp_top) tmp_top = 0;
		if (!tmp_left) tmp_left = 0;

		var targetTop = parseInt(tmp_top.toString().replace(/px/, '')) - parseInt(window.getScrollTop().toString().replace(/px/, ''));
		var targetLeft = parseInt(tmp_left.toString().replace(/px/, '')) - parseInt(window.getScrollLeft().toString().replace(/px/, ''));
		
		if (targetTop < 0) targetTop = 0;

		// 오페라일 경우 뭔가를 넣어줘야 작동 함
		if (window.opera || window.safari) {
			this.setStyle('position', 'absolute');
		}

		var size = this.getSize();
		
		(function (targetTop, targetLeft) {
			if ($chk(this)) {

				var top = window.gecko ? parseInt(this.style.top) : parseInt(this.getStyle('top'));
				var left = window.gecko ? parseInt(this.style.left) : parseInt(this.getStyle('left'));
				var scrollTop = parseInt(window.getScrollTop());
				var scrollLeft = parseInt(window.getScrollLeft());
				var ws = getWindowSize();
		
				if (!top) top = 0;
				if (!left) left = 0;

				if (ws.size.y >= size.size.y && ws.size.x >= size.size.x) {					
					if (top != targetTop + scrollTop && targetTop + scrollTop >= 0) {
						new Fx.Style(this,'top', {
							duration: 100,
							wait: false
						}).start(top, targetTop + scrollTop);
					}
					
					if (left != targetLeft + scrollLeft && targetLeft + scrollLeft >= 0) {
						new Fx.Style(this,'left', {
							duration: 100,
							wait: false
						}).start(left, targetLeft + scrollLeft);
					}
				}
			}
			else {
				$clear();
			}
		}).periodical(500, this, [targetTop, targetLeft]);
	},
	

	/** ajax 펼침목록
	 * @class Element
	 * @param
			-url: ajax URL
			-width: width
			-height: height
			-funcList: function. 목록 출력시 사용될 함수. 반환된 ajax 의 Object 값을 하나씩 순서대로 받는다
			-funcClick: function. 항목을 클릭시 사용될 함수. 반환된 ajax 의 Object 값을 하나씩 순서대로 받는다
	 * @css
			-iiAjaxDiv: div
			-iiAjaxDivRows: 열
	 */
	ajax: function (setting) {
		if ($chk(setting) && $type(setting) == 'object') {
			if (!$chk(setting['url'])) error('ajax 함수의 URL 인수가 없습니다');
			var Obj = this;
			var size = '';
			var selected = '';
			var i = 0;
			var now = '';
			var max = '';
			var selectObj = {};
			var macArrow = 0;
			var data;
			var charFF = '';
			var eventFF = '';
			var selectObj = $$('select');	
			var isClick = 0;
			
			// div 생성
			var thisDiv = new Element('DIV', {
				styles: {
					display: 'none',
					overflow: 'auto',
					position: 'absolute',
					width: setting['width'].px(),
					height: setting['height'].px()
				}
			}).inject(document.body);			
			thisDiv.addClass('iiAjaxDiv');
			
			// 보이기
			function show () {
				if (Obj.getValue()) {
					// 자식이 있을 땐 자식을 끊는다
					if ($chk(thisDiv.hasChildNodes())) {
						for (i=0; i<thisDiv.length; i++) {
							thisDiv[i].remove();
						}
					}
				
					// 초기화
					thisDiv.innerHTML = '';
					size = Obj.getCoordinates();
					
					// 위치 조정
					thisDiv.setStyles({
						left: size.left,
						top: size.bottom 
					});
					
					// 레이어 토글
					thisDiv.toggle('show');
					
					// SELECTBOX 토글
					$$('select').each(function (item) { item.setStyle('visibility', 'hidden'); });
					
					isClick = 1;
					
					// Ajax 정의
					new Ajax(setting['url'], {
						onComplete: function (item) {
							thisDiv.innerHTML = '';							
							max = '';
							
							if ($chk(item)) {
								data = setJSON(item);

								if ($chk(data['error']) && data['error'] == 1) {
									thisDiv.innerHTML = '<div class="iiAjaxDivRows">' + data['msg'] + '</div>';
								}
								else {
									// 자식이 있을 땐 자식을 끊는다
									if ($chk(thisDiv.hasChildNodes())) {
										for (i=0; i<thisDiv.length; i++) {
											thisDiv[i].remove();
										}
									}

									// 추가
									for (i in data['data']) {
										thisDiv.innerHTML += '<div id="ajaxDiv' + i + '" class="iiAjaxDivRows">' + setting['funcList'](data['data'][i]) + '</div>';
									}
									
									max = i; // 마지막 포인터 저장
									
									// 이벤트 추가
									$$('div[id^=ajaxDiv]').each(function (a){									
										var isNull = '';
										
										a.addEvent('mouseover', function () { select(this); });
										a.addEvent('mouseout', function () { unselect(); });
										
										try {										
											isNull = data['data'][a.id.toString().replace(/[^0-9]/ig, '')]['isNull'];
										} catch (e){}
										
										if (!isNull) {
											a.addEvent('click', function () { 
												select(this);
												var bindFunction = setting['funcClick'].bind(Obj);
												bindFunction(data['data'][selected]);
												kill();
											});
										}
									});
								}
							}							
						},
						
						onFailure: function () {
							thisDiv.innerHTML = '<div class="iiAjaxDivRows">폼 전송에 실패했습니다.</div>';
						}
					}).send(setting['url'], Object.toQueryString({
						mode: setting['mode'], 
						value: Obj.getValue()
					}));
				}
				else {
					kill();
				}
			};
			
			// 없애기
			function kill() {
				// 자식이 있을 땐 자식을 끊는다
				if ($chk(thisDiv.hasChildNodes())) {
					for (i=0; i<thisDiv.length; i++) {
						thisDiv[i].remove();
					}
				}
				
				// SELECTBOX 토글
				$$('select').each(function (item) { item.setStyle('visibility', ''); });
			
				thisDiv.innerHTML = '';
				thisDiv.toggle('hide');
				selected = '';
			};
			
			// 선택
			function select(target) {
				if ($chk(target)) {
					target.removeClass('iiFjaxDivRows');
					target.addClass('iiAjaxDivRowsOver');
					selected = target.id.toString().replace(/[^0-9]/g, '');
				}
				else {
					selected = '';
				}
			};
			
			// 해제			
			function unselect() {
				if (selected !== '') {
					target = $('ajaxDiv' + selected);
					if ($chk(target)) {
						target.removeClass('iiAjaxDivRowsOver');
						target.addClass('iiAjaxDivRows');
					}
					selected = '';
				}
			};
			
			// 이벤트 추가
			this.addEvent('focus', function () {
				// FF 의 아시아권 문자 이벤트 핸들러 정지 기능 방지
				if (window.gecko || window.safari) {
					eventFF = (function () {
						if (Obj.value != charFF) {
							charFF = Obj.value;
							show();
						}
					}).periodical(10);
				}
			});
			
			this.addEvent('click', function () {
				show();
			});			
			
			if (window.gecko || window.safari) {
				this.addEvent('blur', function () {
					if ($chk(eventFF)) $clear(eventFF);
				});
			}
			
			document.addEvent('click', function (e) {
				var event = setEvent(e);

				if (
					(event.page.x < size.left ||
					event.page.x > size.right ||
					event.page.y < size.bottom ||
					event.page.y > size.bottom + parseInt(setting['height'])) &&
					(event.target != Obj) && !isEnter && $chk(event.page)
				)
					kill();
			});
			
			this.addEvent('keydown', function (e) {
				var event = setEvent(e);
				
				if ($chk(event.key)) {
					if (event.key.toString().match(/[^0-9a-z ]/i)) {
						event.key = 'not';
					}
					
					switch (event.key) {
						case 'down':
							// 맥 두번 눌리는 것 처리
							if (window.safari && !macArrow) { 
								macArrow = 1;
								return false;
							}
							
							now = selected !== '' ? parseInt(selected) + 1 : 0;
							
							if (now > max) now = 0;
							if (selected !== '') unselect($('ajaxDiv' + selected));
							selectObj = $('ajaxDiv' + now);

							if ($chk(selectObj)) {
								select(selectObj);
								if (size.bottom + thisDiv.scrollTop + parseInt(setting['height']) < selectObj.getTop() + selectObj.getSize().size.y) {
									thisDiv.scrollTo(0, thisDiv.scrollTop + selectObj.getSize().size.y);
								}
								if (now === 0) {
									thisDiv.scrollTo(0, 0);
								}							
							}
							
							macArrow = 0;
							break;
							
						case 'up':
							// 맥 두번 눌리는 것 처리
							if (window.safari && !macArrow) { 
								macArrow = 1;
								return false;
							}
												
							now = selected !== '' ? parseInt(selected) - 1 : max;
							if (now < 0) now = max;
							if (selected !== '') unselect($('ajaxDiv'+selected));
							selectObj = $('ajaxDiv' + now);
							if ($chk(selectObj)) {
								select(selectObj);
								if (size.bottom + thisDiv.scrollTop > selectObj.getTop()) {
									thisDiv.scrollTo(0, thisDiv.scrollTop - selectObj.getSize().size.y);
								}
								if (now === max) {
									thisDiv.scrollTo(0, thisDiv.scrollHeight);
								}
							}
	
							macArrow = 0;						
							break;
							
						case 'tab':
							if (selected !== '') {
								$('ajaxDiv' + selected).fireEvent('click');
							}
							kill();
							break;
						
						case 'enter':
							new Event(e).stop();
							isEnter = 1;
							break;
							
						default :
							if (event.key.length <= 1) show();
								
					}
				}
			});
			
			this.addEvent('keyup', function (e) {
				var event = setEvent(e);
				
				if ($chk(event.key)) {
					if (event.key.toString().match(/[^0-9a-z ]/i)) {
						event.key = 'not';
					}
					switch (event.key) {
						case 'down':
						case 'up':
							break;
							
						case 'enter':
							if (selected !== '') {
								$('ajaxDiv' + selected).fireEvent('click');
							}
							kill();
							isEnter = 0;
							break;
							
						case 'backspace':
							show();
							break;
							
						default :
							if (event.key.length <= 1) show();
					}
				}
			});
		}
	},

	
	/** 제목줄 꾸미기
	 * @class Element
	 * @param
			$title: 제목
			-id:
			-styles:
			-class:
	 */
	addTitle: function (title, setting) {
		if (!$chk(setting)) var setting = {};

		setting['id'] = this.id.toString() + '_title';

		if (!setting['styles'] && !setting['class']) setting['styles'] = {
			width: 'auto',
			backgroundColor: '#f0f0f0',
			borderBottom: '1px solid #ddd',
			font: '11px dotum',
			color: '#545454',
			padding: '5px',
			overflow: 'hidden'
		};

		new Element('div', setting)
			.setHTML(title)
			.injectTop(this);
	},

	
	/** 해당 태그가 맞는지 확인
	 * @class Element
	 * @param
			$name: 태그명(복수개 입력시 (asd|qwe) 으로 입력)
	 * @return boolean
	 */
	isTag: function (name) {
		if (!$chk(this.nodeName)) return false;
		return this.nodeName.toString().match(new RegExp('^' + name + '$', 'i'));
	},

	/** swf 삽입
	 * @class Element
	 * @param
			-id:
			-url: swf주소
			-width:
			-height:
			-param: FlashVars
	 */
	setFlash: function (setting) {
		var param = '';
		if (!$chk(setting)) var setting = {};
		if (!setting.width) setting.width = 0;
		if (!setting.height) setting.height = 0;

		if (setting.param) param = Object.toQueryString(setting.param);

		var output = "<object id='" + setting.id + "' type='application/x-shockwave-flash' "
					+ "width='" + setting.width + "px' height='" + setting.height + "px' "
					+ "classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' style='vertical-align:middle;'>"
					+ "<param name='movie' value='" + setting.url + "' />"
					+ "<param name='allowScriptAccess' value='always' />"
					+ (setting.bgcolor ? "<param name='bgcolor' value='" + setting.bgcolor + "' />" : "<param name='wmode' value='transparent' />")
					+ (param ? "<param name='FlashVars' value=\"" + param + "\" />" : "")
					+ "<param name='allowFullScreen' value='true' />"
					+ "<embed src='" + setting.url + "' width='" + setting.width + "px' height='" + setting.height + "px' "
					+ (setting.bgcolor ? "bgcolor='" + setting.bgcolor + "'" : "wmode='transparent'")
					+ (param ? "FlashVars=\"" + param + "\"" : "")
					+ " allowScriptAccess='always' allowFullScreen='true' type='application/x-shockwave-flash' style='vertical-align:middle;'></embed>"
					+ "</object>";

		this.innerHTML = output;
	}
});


String.extend({
	/** 태그를 없앤다
	 * @class String
	 */
	stripTag: function(){
		return this.toString().replace(/\<([^\>]+)\>/ig,'');
	},
	

	/** HTML문자를 escape한다. _inc.php 의 str()과 비슷한 효과
	 * @class String
	 */
	escapeHTML: function(){
		return this.toString().replace(/\&/ig,'&amp;').replace(/\'/ig,'&#039;').replace(/\"/ig,'&quot;').replace(/\</ig,'&lt;').replace(/\>/ig,'&gt;');
	},
	

	/** php의 explode
	 * @class String
	 * @return Array
	 */
	explode: function(splitChar){

		var tmp = new Array();
		
		// 기본 자름 기준 문자열 지정
		if(!splitChar) splitChar = ',';

		var tmp = this.trim().split(splitChar);
		
		// 없을때 제거
		for(var i=0;i<tmp.length;i++){
			if(!$chk(tmp[i].trim())){
				tmp.remove(tmp[i]);
			}			
		}
		
		return tmp;
	},
	

	/** 글자수 체크(바이트 기준으로 산정
	 * @class String
	 */
	getLength: function () {		
		var size = 0;		
		for (var i=0; i<this.length; i++) {
			size += (escape(this.charAt(i)).length > 4) ? 2 : 1; 
		}		
		return size;
	},


	/** px를 붙여준다
	 * @class String
	 */
	px: function () {
		if (!this.toString().match(/px/i))
			return this.toString() + 'px';
		else
			return this.toString();
	},
	

	/** php의 nl2br()
	 * @class String
	 */
	nl2br: function () {
		var tmp;
		tmp = this.replace(/\r\n/g, '<br />');
		tmp = tmp.replace(/\n/g, '<br />');
		
		return tmp;
	},


	/** ajax로 넘어온 PHP nl2br2() 처리
	 * @class String
	 * @param
			$mode: write 모드면 \n 처리한다
	 */
	nl2br2: function (mode) {
		var tmp = this.toString();
		tmp = tmp.replace(/\<\!\-\-nl2br\-\-\>/g, (mode == 'write' ? "\n" : "<br />"));
		tmp = tmp.replace(/&lt;(\/)?script/g, "<$1script");
		return tmp;
	}
});
Number.prototype.getLength = String.prototype.getLength;
Number.prototype.px = String.prototype.px;



var error_previous = {};

/** 에러 표시
 * @class mini
 * @param
		$msg: 에러메세지
		-opacity: 투명도. 1.0이 100%
		-className: css명
		-styles: 별도의 style Object
		-target: Element. 설정되어 있으면 해당 Element 상단에 표시된다
		-center: 화면의 중앙으로 표시한다 [0!|1]
 */
function error(msg, setting) {
	if (!$chk(setting)) var setting = {};
	if (error_previous.innerHTML != msg) {
		// 엘레멘트 생성
		var errorOutput = new Element('div',{
			id: 'errorDiv' + $time() + $random(0,999),
			styles: {
				border: '3px solid #efefef',
				backgroundColor: '#CD5C5C',
				color: '#ffffff',
				fontSize: '9pt',
				fontFamily: '돋움',
				fontWeight: 'bold',
				padding: '7px',
				display: '',
				zIndex: '0',
				lineHeight: '150%',
				position: 'absolute'
			},
			'events': {
				'dblclick': function () {
					if (error_previous.id == this.id) error_previous = {};
					this.remove();
				}
			}
		}).setHTML(msg).inject(document.body);
		errorOutput.addClass('iiError');
		error_previous = errorOutput;

		if ($chk(setting['styles'])) {
			errorOutput.setStyles(setting['styles']);		
		}
		
		setting['opacity'] = 1;
		if ($chk(setting['opacity'])) {
			errorOutput.setStyle('opacity', setting['opacity']);
		}
		else setting['opacity'] = 1;
		
		if ($chk(setting['className'])) {
			errorOutput.addClass(setting['className']);
		}
		var posLeft = 0, posTop = 0;
		
		// Obj가 설정되어 있으면 그 Obj 의 위쪽으로 나타난다
		if ($chk(setting['target'])) {	
			var coordinates = setting['target'].getCoordinates();
			posTop = coordinates.top - errorOutput.getSize().size.y;
			posLeft = coordinates.left;
		}	
		// 에러 개수를 참조해서 상단 위치를 설정	
		else {
			var errorTop = $$('div[id^=errorDiv]').length * (errorOutput.getSize().size.y + 3);
			if (!errorTop) errorTop = 1;

			if (window.opera) {
				posTop = window.innerHeight - errorTop;
				posLeft = (window.innerWidth / 2) - errorOutput.getSize().size.x / 2;
			}
			else {
				posTop = (window.getHeight()) - errorTop;
				posLeft = (window.getWidth() / 2) - errorOutput.getSize().size.x / 2;
			}
			
			// 스크롤 적용
			posTop += window.getScrollTop();
			posLeft += window.getScrollLeft();
		}
		
		// 위치 지정
		// center 설정이 되어 있으면 화면 중단으로 옮긴다
		if (setting['center']) {
			errorOutput.center();
		}	

		else {
			errorOutput.setStyles({
				left: posLeft,
				top: posTop
			});
		}
		
		(function(){
			new Fx.Style(errorOutput,'opacity', {
				duration: 1000,
				wait: true,
				onComplete: function(){ 
					if (error_previous.id == errorOutput.id) error_previous = {};
					errorOutput.remove();
				}
			}).start(setting['opacity'], 0);
		}).delay(3000);
	}
}; // END function


/** 이벤트 정의(mootools 버그)
 * @class mini
 * @param
		$event: event
 * @return Event
 */
function setEvent(event) {
	var e = { page:{}, client:{} };
	
	if (window.ie) {
		$extend(e,event);
		e.code = event.keyCode;
		e.shift = event.shiftKey;
		e.control = event.ctrlKey;
		e.alt = event.altKey;
	
		e.wheel = (window.ie6 || window.ie7) ? event.wheelData : false;
		e.page.x = event.screenX;
		e.page.y = event.screenY;
		e.client.x = event.clientX;
		e.client.y = event.clientY;
		if($chk(event.srcElement)) e.target = event.srcElement;
		if($chk(event.fromElement)) e.relatedTarget = event.fromElement;
		
		switch (e.code) {			
			case 13: e.key = 'enter'; break;
			case 38: e.key = 'up'; break;
			case 40: e.key = 'down'; break;
			case 37: e.key = 'left'; break;
			case 39: e.key = 'right'; break;
			case 32: e.key = 'space'; break;
			case 8: e.key = 'backspace'; break;
			case 46: e.key = 'delete'; break;
			case 27: e.key = 'esc'; break;
			case 9: e.key = 'tab'; break;
			case 16: e.key = 'shift'; break;
			case 17: e.key = 'ctrl'; break;
			case 18: e.key = 'alt'; break;
			case 20: e.key = 'capslock'; break;
			case 229: e.key = 'hangle'; break;
			default: e.key = String.fromCharCode(e.code).toLowerCase(); 
		}	
	}
	else e = new Event(event);
	
	return e;
}; // END function

//// 팝업
var iiPopup = {	
	thisDiv: {},
	thisDivClose: {},
	thisDivBackground: {},
	thisClose: '',
	confirmClose: false,
	
	/**
	 * 레이어 팝업
	 * @class iiPopup
	 * @param
			-mode: 실행모드[!iframe|div|func]
			-width: 창폭
			-height: 창높이
			-border: iframe border
			-backgroundColor: 바탕색
			-url: 대상URL(iframe 모드일 때)
			-target: 대상Object(div 모드일 때)
			-funcL 대상function(func 모드일 때)
			-close: 창을 닫을 때 확인을 받는다 [0!|1]
	 * @css
			-iiPopupDivClose: 창닫기 레이어
	 */
	init: function(setting){
		this.confirmClose = false;	
		if (!setting['mode']) setting['mode'] = 'iframe';
		if (!setting['width']) setting['width'] = 600;
		if (!setting['height']) setting['height'] = 480;
		if (!setting['border']) setting['border'] = '';
		if (!setting['backgroundColor']) setting['backgroundColor'] = '#ffffff';
		if (setting['close']) this.confirmClose = true;

		var ws = getWindowSize();

		// 배경 생성
		var wcWidth = window.getScrollWidth();
		var wcHeight = window.getScrollHeight();
		
		// ie6 보정
		if (window.ie6) {
			wcWidth -= 20;
			wcHeight -= 4;
		}
		
		var popupDivBackground = new Element('div', {
			styles: {
				width: wcWidth.px(),
				height: wcHeight.px(),
				position: 'absolute',
				top: 0,
				left: 0,
				opacity: 0,
				backgroundColor: '#000000'
			},			
			events: {
				click: function() {
					iiPopup.close();
				}
			}
		}).inject(document.body);
		this.thisDivBackground = popupDivBackground;
		
		// 효과		
		new Fx.Style(popupDivBackground, 'opacity', {
			duration: 300
		}).start(0,0.25);
		
		// 내용레이어 생성
		var popupDiv = new Element('div', {
			id: 'popupDiv',
			styles: {
				width: setting['width'].px(),
				height: setting['height'].px(),
				position: 'absolute',
				backgroundColor: setting['backgroundColor'],
				border: setting['border']
			}
		}).inject(document.body);
		
		popupDiv.addClass('iiPopupDiv');
		popupDiv.center();
//		popupDiv.fix();
		
		// close 이벤트 적용
		if ($type(setting['onClose']) == 'function') {
			this.thisClose = setting['onClose'];
		}
		
		// 창닫기 레이어
		var popupDivClose = new Element('div', {
			id: 'popupDivClose',
			styles: {
				width: '31px',
				height: '26px',
				background: 'url("' + miniDir + 'admin/image/button_close.gif")',
				position: 'absolute',
				cursor: 'pointer',
				zIndex: '100'
			},
			events: {
				click: function () { 
					iiPopup.close();
				}
			}
		}).inject(document.body);
		popupDivClose.addClass('iiPopupDivClose');

		var size = popupDivClose.getSize();
		var coordinates = popupDiv.getCoordinates();

		// Close 위치지정
		popupDivClose.setStyles({
			top: coordinates.top - size.size.y,
			left: coordinates.right - size.size.x
		});
		this.thisDivClose = popupDivClose;

//		popupDivClose.fix();
		this.thisDiv = popupDiv;
		
		// select 숨기기
		$$('select').each(function (item) {
			item.setStyle('visibility', 'hidden');
		});
		
		//// 로딩 레이어 추가
		if (!$chk(loading)) {
			var loading = new Element('DIV', {
				styles: {
					display: 'none',
					position: 'absolute'
				}
			}).inject(document.body);
			loading.addClass('iiFormLoading');
		}

		// 단축키 삽입
		this.evt = function (e) {
			var event = setEvent(e);
			if ($chk(event.key) && event.key == 'esc') {
				new Event(e).stop();
				iiPopup.close();
			}
		};
		
		window.document.addEvent('keydown', this.evt);

		// 내용 삽입
		switch (setting['mode']) {			
			// iframe 삽입
			case 'iframe':
				var popupIframe = new Element('iframe',{
					id: 'iiPopupIframe',
					name: 'iiPopupIframeName',
					src: setting['url'],
					frameborder: 0,
					styles: {
						width: setting['width'].px(),
						height: setting['height'].px(),
						backgroundColor: '#fff',
						overflow: 'auto'
					}					
				}).inject(popupDiv);
				
				loading.toggle('show');
				loading.center(popupIframe);
				
				popupIframe.addEvent('load', function () {
					loading.toggle('hide');
				});
				break;

			// 내용넣기
			case 'div':
				popupDiv.setStyle('overflow', 'auto');
				setting['target'].setStyle('display', '').inject(popupDiv);
				break;
			
			// 함수실행
			case 'func':
				var myFunc = setting['func'].bind(popupDiv);
				myFunc(e);
				break;
		}
	},
	
	/** 레이어 창 닫기
	 * @class iiPopup
	 */
	close: function () {
		if (this.confirmClose) {
			if (!confirm('입력한 정보가 저장되지 않아 손실됩니다. 계속하시겠습니까?')) {
				return false;
			}
		}
		// select 보이기
		$$('select').each(function (item) {
			item.setStyle('visibility', 'visible');
		});

		if (this.thisClose) {
			this.thisClose.attempt(false, this.thisDiv);
		}

		if (this.evt) {
			window.document.removeEvent('keydown', this.evt);
			this.evt = null;
		}
		
		$$('.iiFormLoading').each(function (item) { item.toggle('hide'); });

		if ($chk(this.thisDiv.remove)) this.thisDiv.remove();
		if ($chk(this.thisDivBackground.remove)) this.thisDivBackground.remove();
		if ($chk(this.thisDivClose.remove)) this.thisDivClose.remove();
	},

	isOpen: function () {
		return $chk(this.evt);
	}
}

//// 캘린더
var iiCal = new Class({
	thisDiv: null,
	onComplete: null,
	target: null,
	evt: null,
	evt2: null,
	evt3: null,
	pos: null,
	m: 0,
	y: 0,
	insertMode: false,
	setting: {},

	/** 캘린더 생성
	 * @class iiCal
	 * @param
			$target: Element, form이 아닐경우 해당 Element에 달력을 삽입한다
			-name: 해당 클랙스 객체 이름
			-year: 연 선택
			-month: 월 선택
			-onComplete: function. 선택 후 실행될 함수. this.year, this.month, this.day, this.target을 인자로 받는다
			-head: 스킨 - 처음
			-loop_line: 스킨 - 날짜 라인 출력시 처음과 7번반복 후 나옴(tr 같은 태그)
	 */
	initialize: function (target, setting) {
		// 기본 값
		Today = new Date();
		this.m = Today.getUTCMonth() + 1;
		this.y = Today.getUTCFullYear();
		this.name = 'myCal';
		
		if (!$chk(setting)) setting = {};
		if (setting['name']) this.name = setting['name'];
		if (setting['year']) this.y = setting['year'];
		if (setting['month']) this.m = setting['month'];
		if (setting['onComplete']) this.onComplete = setting['onComplete'];
		this.setting = setting;

		if ($chk(target)) {
			this.target = target; 

			// 입력모드
			if (this.target.isTag('input|select|textarea')) {
				// 기존 것 제거
				if ($chk(this.thisDiv)) {
					this.close();
				}
				
				// select 가리기
				$$('select').each(function (item) {
					item.setStyle('visibility', 'hidden');
				});
			
				// 레이어 생성
				this.thisDiv = new Element('DIV', {
					styles: {
						position: 'absolute',
						border: '3px solid #545454',
						backgroundColor: '#ffffff',
						padding: '5px'
					}
				}).inject(document.body);
				
				// 단축키 지정
				this.evt = (function (e) {
					var event = setEvent(e);
					if ($chk(event.key) && event.key == 'esc') {
						new Event(e).stop();
						this.close();
					}
				}).bind(this);

				this.evt2 = (function (e) {
					var event = setEvent(e);
					if (!checkMouseIn(window.ie ? event.client : event.page, this.pos)) {
						this.close();
					}
				}).bind(this);

				window.document.addEvent('keydown', this.evt);
				this.thisDiv.center(target);
				window.document.addEvent('mousedown', this.evt2);
			}

			// 삽입모드
			else {
				this.insertMode = true;
			}

			// 열기
			this.open(this.y, this.m);

			// 휠 이벤트
			this.evt3 = (function(event) {
				event = new Event(event).stop();

				if (event.wheel > 0) {
					if (event.alt || event.shift || event.ctrl) 
						this.open(this.y - 1, this.m);
					else
						this.open((this.m == 1 ? this.y - 1 : this.y), (this.m == 1 ? 12 : this.m - 1));
				} 
				else if (event.wheel < 0) {
					if (event.alt || event.shift || event.ctrl)
						this.open(this.y + 1, this.m);
					else
						this.open((this.m == 12 ? this.y + 1 : this.y), (this.m == 12 ? 1 : this.m + 1));
				}
			}).bind(this);

			if (this.insertMode)
				this.target.addEvent('mousewheel', this.evt3);
			else
				this.thisDiv.addEvent('mousewheel', this.evt3);
		}
	},
	
	/** 열기
	 * @class iiCal 
	 * @param
			$y: 연
			$m: 월
			$isFunc: 값이 있으면 onOpen이 실행되지 않는다
	 */
	open: function (y, m, isFunc) {
		Today = new Date();
		var todayMonth = Today.getUTCMonth() + 1;
		var todayYear = Today.getUTCFullYear();
		var today = Today.getUTCDate();
		var text = '';
		var tmp = '';
		var day = 0;

		if (y) this.y = y;
		if (m) this.m = m;

		if (!$chk(this.setting.head)) this.setting.head = '';
		if (!$chk(this.setting.foot)) this.setting.foot = '';
		if (!$chk(this.setting.loop_line)) this.setting.loop_line = '';
		if (!$chk(this.setting.ment)) this.setting.ment = '';
		if (!$chk(this.setting.ment_data)) this.setting.ment_data = '';
		if (!$chk(this.setting.ment_not)) this.setting.ment_not = '';
		if (!$chk(this.setting.sun)) this.setting.sun = '';
		if (!$chk(this.setting.not_today)) this.setting.not_today = '';
		if (!$chk(this.setting.today)) this.setting.today = '';
		if (!$chk(this.setting.day)) this.setting.day = '';

		if (!isFunc && $chk(this.setting.onOpen)) {
			this.setting.onOpen.attempt([this.y, this.m], this);
		}

		// 삽입모드가 아니면 정해진 디자인 사용
	    if (!this.insertMode) {
			this.setting.head = 
				"<table cellpadding='0' cellspacing='0'>" +
				"<tr>" +
					"<td colspan='7' style='background-color:#545454; padding:3px; font:11px dotum;color:#e1e1e1;'>" +
						"<b>훨</b>:월, <b>alt+휠</b>:연" +
					"</td>" +
				"</tr>" +
				"<tr>" + 
					"<td colspan='7' style='text-align:center;background-color:#545454;'>" + 
						"<span onclick='[linkPrevYear]' style='cursor:pointer; font:7pt verdana; background-color:#545454; padding:3px; color:#e1e1e1;' title='1년 전'> &lt;&lt; </span>" + 
						"<span onclick='[linkPrevMonth]' style='cursor:pointer; font:7pt verdana; background-color:#545454; padding:3px; color:#e1e1e1;' title='1달 전'> &lt; </span>" + 
						"<span style='color:#fff; font:bold 8pt Calibri, verdana, tahoma'>[year]/[month]</span>" + 
						"<span onclick='[linkNextMonth]' style='cursor:pointer; font:7pt verdana; background-color:#545454; padding:3px; color:#e1e1e1;' title='1달 후'> &gt; </span>" + 
						"<span onclick='[linkNextYear]' style='cursor:pointer; font:7pt verdana; background-color:#545454; padding:3px; color:#e1e1e1;' title='1년 후'> &gt;&gt; </span>" + 
					"</td>";

			this.setting.loop_line = "</tr>\n<tr>";
			this.setting.ment_not = "<td style='cursor:pointer; padding:3px; font:8pt Calibri, verdana, tahoma; text-align:center;'> </td>";
			this.setting.sun = "color:red;";
			this.setting.not_today = "onmouseover='$(this).setStyle(\"backgroundColor\",\"#e1e1e1\");' onmouseout='$(this).setStyle(\"backgroundColor\",\"#ffffff\");'";
			this.setting.today = "font-weight:bold; color:blue; background-color:#e1e1e1;";
			this.setting.ment = "<td style='cursor:pointer; padding:3px; font:8pt Calibri, verdana, tahoma; text-align:center; [sun][today]' [not_today] onclick='[linkSelect]'>[day]</td>";
			this.setting.foot = "</tr>\n</table>";
		}
		
		text = this.setting.head;

	    var d1 = (this.y+(this.y-this.y%4)/4-(this.y-this.y%100)/100+(this.y-this.y%400)/400 
	          +this.m*2+(this.m*5-this.m*5%9)/9-(this.m<3?this.y%4||this.y%100==0&&this.y%400?2:3:4))%7;
			   
	    for (i = 0; i < 42; i++) { 
	        if (i%7==0 && $chk(this.setting.loop_line)) text += this.setting.loop_line;
	        if (i < d1 || i >= d1+(this.m*9-this.m*9%8)/8%2+(this.m==2?this.y%4||this.y%100==0&&this.y%400?28:29:30)) {
				text += this.setting.ment_not; 
			}
	        else {
				day = i+1-d1;
	            tmp = this.setting.ment;

				if ($chk(this.data) && $chk(this.data[y + '_' + m + '_' + day])) {
					tmp = this.setting.ment_data;
					tmp = tmp.toString().replace(/\[data\]/g, this.data[y + '_' + m + '_' + day]);
				}

				// 날짜별 스킨처리
				tmp = tmp.toString().replace(/\[sun\]/g, (i%7 == 6 ? this.setting.sun : ''));
				tmp = tmp.toString().replace(/\[today\]/g, (day == today && y == todayYear && m == todayMonth ? this.setting.today : ''));
				tmp = tmp.toString().replace(/\[not_today\]/g, (day == today && y == todayYear && m == todayMonth ? '' : this.setting.not_today));
				tmp = tmp.toString().replace(/\[linkSelect\]/g, this.name + '.select(' + this.y + ',' + this.m + ',' + day + ');');
				tmp = tmp.toString().replace(/\[day\]/g, day);
				tmp = tmp.toString().replace(/\[day2\]/g, (day.toString().length > 1 ? day : '0'+day));

	            text += tmp;
			}
	    }
		
		text += this.setting.foot;

		// 스킨 전체 처리
		text = text.toString().replace(/\[linkPrevYear\]/g, this.name + '.open(' + (this.y-1) + ',' + this.m + ');');
		text = text.toString().replace(/\[linkPrevMonth\]/g, this.name + '.open(' + (this.m==1?(this.y-1)+','+12:this.y+','+(this.m-1)) + ');');
		text = text.toString().replace(/\[linkNextYear\]/g, this.name + '.open(' + (this.y+1) + ',' + this.m + ');');
		text = text.toString().replace(/\[linkNextMonth\]/g, this.name + '.open(' + (this.m==12?(this.y+1)+','+1:this.y+','+(this.m+1)) + ');');
		text = text.toString().replace(/\[year\]/g, this.y);
		text = text.toString().replace(/\[month\]/g, this.m);
		text = text.toString().replace(/\[month2\]/g, (this.m.toString().length > 1 ? this.m : '0'+this.m));

		// 처리
		if (this.insertMode) {
			this.target.innerHTML = text;
		}
		else {
			this.thisDiv.innerHTML = text;
			this.pos = this.thisDiv.getCoordinates();
		}
	},

	/** 날짜 선택
	 * @class iiCal
	 * @param
			$y: 연
			$m: 월
			$d: 일
	 */
	select: function (y, m, d) {
		var m2 = (m.toString().length > 1 ? m : '0'+m);
		var d2 = (d.toString().length > 1 ? d : '0'+d);

		if ($chk(this.onComplete)) {
			this.onComplete.attempt(false, {
				year: y,
				month: m,
				day: d,
				month2: m2,
				day2: d2,
				target: this.target
			});
		}
		
		if (!this.insertMode) this.target.value = y + '-' + m2 + '-' + d2;
		this.close();
	},

	close: function () {
		if (!this.insertMode) {
			// select 보이기
			$$('select').each(function (item) {
				item.setStyle('visibility', 'visible');
			});

			// 이벤트 초기화
			if (this.evt) window.document.removeEvent('keydown', this.evt);
			if (this.evt2) window.document.removeEvent('click', this.evt2);
			if ($chk(this.thisDiv)) this.thisDiv.remove();
			this.thisDiv = null;
			this.target = null;
			this.onComplete = null;
		}
	}
});
var myCal = new iiCal();


/** 레이어 메뉴 토글(자신의 ID에서 숫자를 뺀 것이나 _뒤의 것을 뺀 것으로 시작하는 ID의 레이어들을 닫고 자신을 연다.)
 * @class mini
 * @param
		$objName: 자신의 Element 이름
		$nodeName: 대상이 되는 nodeName. 기본값은 자신의 nodeName
		$menuObj: 같이 토글될 메뉴 Obj. 있을 경우 해당 메뉴 Obj는 class명이 해당 id 에서 마지막 _ 앞까지를 토대로 _on, _off class로 토글된다
 */
function toggleMenu(objName, nodeName, menuObj) {
	var Obj = $(objName);
	if ($chk(Obj)) {
		var asd = Obj.id.toString().replace(/[0-9]/ig, '');
		var asd = asd.replace(/_.+/ig, '_');
		var id = Obj.id;
		if (!nodeName) nodeName = Obj.nodeName.toLowerCase();

		$$(nodeName+'[id^='+asd+']').each(function (item){
			if (item.id != id) {
				item.toggle('hide');
			}
		});

		Obj.toggle('show');

		// 메뉴 토글
		if ($chk(menuObj)) {
			var asd2 = menuObj.id.toString().replace(/[0-9]/ig, '');
			var asd2 = asd2.replace(/_.+/ig, '_');

			$$(menuObj.nodeName.toString().toLowerCase()+'[id^='+asd2+']').each(function (item) {
				if (item.id != id) {
					item.removeClass(asd2 + 'on');
					item.addClass(asd2 + 'off');
				}
			});

			menuObj.toggleClass(asd2 + 'on');
		}
	}
}; // END function


/** 좌표 안의 영역인지 확인
 * @class mini
 * @param
		pos: 현재 position
		coordinates: 대상이 되는 Element의 position
 * @return Boolean
 */
function checkMouseIn(pos, coordinates) {
	if (
		pos.x >= coordinates.left &&
		pos.x <= coordinates.right &&
		pos.y >= coordinates.top &&
		pos.y <= coordinates.bottom
	)
		return true;
	else
		return false;	
}; // END function


/** JSON 데이터인지 확인해서 맞다면 JSON처리, 틀리다면 error()
 * @class mini
 * @param
		$data: String
 * @return Object
 */
function setJSON (data) {
	if (!data.toString().match(/^\{/i)) {
		error(data);
		return false;
	}
	else {
		return Json.evaluate(data);
	}
}; // END function


//// 회원 팝업
var Member = new Class({
	obj: {},

	/** 회원 팝업
	 * @class member
	 * @param
			$e: event
			-target_member: 대상회원번호
			-id: 게시판아이디 혹은 번호
			-post_no: 게시물번호
			-memo_no: 쪽지번호
			-new: 새창
			-is_memo: 쪽지창에서
	 * @css
			-tool_on: 행에 마우스를 올렸을 때
			-tool_off: 행에 마우스를 올리지 않았을 떄
			-tool_close: 닫기 행
	 */
	initialize: function (tmp) {
		this.obj = $('tool_member');
		if (!$chk(this.obj)) {
			this.obj = new Element('div', { 
				id: 'tool_member', 
				styles: {
					'position': 'absolute',
					'display': 'none'
				}
			});
			
			window.addEvent('load', (function () {
				this.obj.inject(document.body);
			}).bind(this));
		}
	},

	open: function (e, setting) {
		this.event = new Event(e).stop();
		if (!$chk(setting)) setting = {};
		this.setting = setting;

		this.obj.innerHTML = '<ul></ul>'; //<div class="tool_close" onclick="view_member.close();"></div>
		this.obj.toggle('show');

		var ul = this.obj.getChildren()[0];
		var is_target_member = ($chk(setting['target_member']) && parseInt(setting['target_member']));
		var is_memo = $chk(setting['is_memo']);
		
		if (is_target_member) ul.innerHTML += '<li id="tool_member_myinfo" class="tool_off">회원정보</li>';
		if (is_target_member) ul.innerHTML += '<li id="tool_member_mymenu" class="tool_off">회원통계</li>';
		if (is_target_member && !is_memo) ul.innerHTML += '<li id="tool_member_memo" class="tool_off">쪽지보내기</li>';
		if (is_target_member) ul.innerHTML += '<li id="tool_member_friend" class="tool_off">친구추가/삭제</li>';
		if (is_target_member) ul.innerHTML += '<li id="tool_member_memo_block" class="tool_off">차단/해제</li>';
		if (is_target_member && $chk(setting['id'])) ul.innerHTML += '<li id="tool_member_search" class="tool_off">다른글보기</li>';

		if (ul.innerHTML) {
			// 위치
			this.obj.setStyles({
				'left': this.event.page.x,
				'top': this.event.page.y
			});

			this.pos = this.obj.getCoordinates();
		
			$$('li[id^=tool_member_]').each((function (item) {
				item.addEvents({
					'mouseover': function () {
						this.addClass('tool_on');
						this.removeClass('tool_off');
					},					
					'mouseout': function () {				
						this.addClass('tool_off');
						this.removeClass('tool_on');
					},					
					'click': (function () {
						var name = item.id.toString().replace(/^tool_member_/, '');		
						this.action(name);
						this.close();
					}).bind(this)
				});
			}).bind(this));

			this.evt = (function (e) {
				var event = setEvent(e);
				if (!checkMouseIn(window.ie ? event.client : event.page, this.pos)) {
					this.close();
				}
			}).bind(this)

			window.addEvent('click', this.evt);
		}
		else {
			this.close();
		}
	}, 

	/** 회원 팝업 행동
	 * @class mini
	 * @param
			$name: 모드
	 * @description
			ii.form.js와 같이 써야 함
	 */
	action: function (name, setting) {
		if (!$defined(id)) var id = '';
		if (!$chk(setting)) setting = this.setting;

		switch (name) {
			case 'mymenu':
			case 'myinfo':
				if (setting['new'])
					window.open(miniDir + 'mymenu.php?mode=' + name + '&id=' + id + '&no=' + setting['target_member'], 'm_mymenu', 'width='+iiSize['mymenu'][0]+', height='+iiSize['mymenu'][1]);
				else
					iiPopup.init({ url:miniDir + 'mymenu.php?mode=' + name + '&id=' + id + '&no=' + setting['target_member'], 'width': iiSize['mymenu'][0], 'height': iiSize['mymenu'][1] });
				break;

			case 'memo':
				if (!setting['is_memo']) sendMemo(setting['target_member']);
				break;
				
			case 'friend':
			case 'memo_block':
				ajaxForm({
					'url': miniDir + 'ajax.php',
					'values': {
						'mode': name,
						'no': setting['target_member']	
					}
				});
				break;
				
			case 'memo_del':
			case 'memo_save':
				ajaxForm({
					'url': miniDir + 'mymenu.x.php',
					'values': {
						'mode': name,
						'no': setting['memo_no']
					}
				});
				break;
				
			case 'search':
				document.location.href = miniDir + 'mini.php?id=' + setting['id'] + '&s[target_member]=' + setting['target_member'];
				break;
		}
	},

	close: function () {
		if (!$chk(this.evt)) {
			window.document.removeEvent('click', this.evt);
		}

		this.obj.innerHTML = '';
		this.obj.toggle('hide');
	}
});
var view_member = new Member({});


/** 쪽지쓰기 새창 열기
 * @class mini
 * @param
		$no: 회원번호
 */
function sendMemo(no, mode) {
	var url = (mode == 'view') ? miniDir + 'memo.view.php?no=' + no : miniDir + 'memo.write.php?no=' + no;
	var name = (mode == 'view') ? 'memo_view_' + no : 'memo_' + no;
	window.open(url, name, 'width=' + iiSize['memo'][0] + ',height=' + iiSize['memo'][1] + ',resizable=no');
}; // END function



/** 단축키 설정
 * @class mini
 * @description use_key와 key_map, key_func 변수들이 정의되어 있으면 단축키 지정을 한다
 * @require use_key, key_map, key_func
 */
function setKey () {
//	if (!$defined(use_key)) var use_key = null;
	if ($chk(use_key) && $chk(key_map)) {
		window.document.addEvent('keydown', function (e) {
			var event = setEvent(e);

			if (!$chk(event.control) && !$chk(event.alt) && !$chk(event.shift) && $chk(event.code)) {
				if (!$chk(event.target) || !event.target.nodeName.toString().match(/(textarea|input|checkbox|label|iframe)/i))
				for(var item in key_map) {
					if ($chk(key_func) && $chk(key_func[item])) {
						if (event.code == key_map[item].charCodeAt(0) || ($chk(event.key) && event.key == key_map[item])) {
							key_func[item]();
						}
					}
				}
			}
		});
	}
}; // END function


/** TR Object를 넣으면 툴을 가장자리에 위치시켜준다
 * @class mini
 * @param
		$Obj: TR Element
		$tool: tool Element
		$event: event
 */
function showTool(Obj, tool, event, x) {
	var pos = Obj.getCoordinates();
	var ws = getWindowSize();

	// 사파리는 TR right 가 안맞는다
	if (window.safari) {
		var pos2 = Obj.getParent().getParent().getCoordinates();
		pos.right = pos2.right;
		pos.bottom = event.page.y;
	}		
	tool.toggle('show');
	
	var size = tool.getSize();
	var t = parseInt(pos.bottom - size.size.y);
	var l = ws.scroll.x + ws.size.x - size.size.x;

	// ie relative bug fix
	if (window.ie) {
		try {
			var mode;
		} catch (e) {}

		if ($chk(mode)) {
			if (mode.toString().match(/^(mail|trash)$/)) {
				l -= 250;
			}
		}
	}

	tool.setStyles({
		left: l + 'px',
		top: t + 'px'
	});

	new Fx.Style(tool, 'opacity', {
		duration: 300,
		wait: false
	}).start(0.7);
}; // END function


/** 윈도우 크기를 불러온다. opera 버그 수정
 * @class mini
 * @return Object
 */
function getWindowSize() {
	var size = window.getSize();
	
	if (window.opera) {
		size.size.x = window.innerWidth;
		size.size.y = window.innerHeight;
	}

	return size;
}; // END function


/** TR, LI, DIV Element에서 자식노드들 중 첫번째에 오는 checkbox를 찾는다
 * @class mini
 * @param
		$Obj: TR Element, LI Element
 * @return Checkbox Element
 */
function findCheckbox(Obj) {
	var asd = Obj.getElementsByTagName('input');
	if ($chk(asd)) {
		var target = window.ie ? asd[0] : $(asd[0]);
		if ($chk(target) && $chk(target.type) && target.type == 'checkbox') {
			return target;
		}
		else {
			return false;
		}
	}
}; // END function


/** ajax 전송 후 리턴값을 토대로 실행하는 함수 
 * @class mini
 * @param
		-mode: move, html, reload
		-url: 이동할 url
		-html: document.body에 넣을 내용
		-func: function. 실행할 함수 (function 이 있을경우 alert과 자동실행이 무시되고 function에 의존한다)
 */
 //+ 삭제해야함
function script(setting) {
	if ($chk(setting)) {
		// 실행
		function execScript() {
			switch (setting['mode']) {
				case "goto":
				case "move":
					if ($chk(setting['url'])) {
						document.location.replace(setting['url']);
					}
					else {
						document.location.reload();
					}
					break;
					
				case 'close':
					self.close();
					break;
					
				case 'close2':
					opener.document.location.reload();					
					self.close();
					break;
				
				case 'back':
					history.back();
					break;

				case "html":
					if ($chk(setting['html'])) {
						document.body.innerHTML += setting['html'];
						if ($chk(setting['func'])) {
							setting['func'](setting['msg']);
						}
					}
					else {
						error('결과는 성공했지만 script 함수의 html 값이 정의되어 있지 않습니다');
					}
					break;

				case "reload":				
					document.location.reload();
					break;
			}
		}

		// 함수모드 일 때
		if (setting['mode'] == 'func' && $chk(setting['func'])) {
			eval('(' + setting['func'] + ').attempt(setting["msg"]);');
		}

		else {
			if ($chk(setting['msg'])) {
				if (setting['mode'] == 'nothing')
					error(setting['msg']);
				else
					alert(setting['msg']);
			}
				
			execScript();
		}
	}
}; // END function


/** ajax 전송 후 script체계 실행
 * @class mini
 * @param
		-error
		-mode: [move(.target)|goto(.target)|back(.-2)|alert|reload(.target)|close]
			#error parent가 아니라 현재 프레임의 error를 사용
		-msg
		-script
		-data
		-url
 * @description
		param은 _inc.php의 script함수 참조
		html은 적용 안됨
		기본 msg 표현 방식은 error일땐 error, complete일땐 alert임
 */
 //+ __ 없애야함
 //+ script의 적용여부를 판단해야 함
function __script(data) {
	if ($chk(data)) {
		var mode = $chk(data['mode']) ? data['mode'].toString() : '';
		var mat = null;
		var i = 0;
		var target = '';

		// script
		if ($chk(data['script'])) {
			switch (data['script']) {
				case 'login_autosave': // 글쓰기에서 로그인시 글내용자동저장
					if ($defined(parent.autosave)) { 
						parent.autosave();
					}
					break;

				case 'admin_board': // 게시판관리
					parent.document.getElementById('main_2_leftFrame').src = parent.document.getElementById('main_2_leftFrame').src;
					break;

				case 'admin_member': // 회원관리
					parent.document.getElementById('main_1_leftFrame').src = parent.document.getElementById('main_1_leftFrame').src;
					break;

				case 'admin_site': // 그룹관리
					parent.document.getElementById('main_3_leftFrame').src = parent.document.getElementById('main_3_leftFrame').src;
					break;

				case 'file': // iframe 파일업로드
					
					break;

				default:
					error('script에러: 정의되지 않은 script 입니다');
			}
//			eval('(function () {' + data['script'] + '}).attempt([], data);');
		}
		else if ($chk(data['msg']) && data['msg'] !== '') {
			if (mode.match(/error/i) || (!mode.match(/alert/i) && $chk(data['error']) && data['error'])) {
				if (mode.match(/error\.parent/i)) parent.error(data['msg']); else error(data['msg']);
			}
			else {
				alert(data['msg']);
			}
		}

		// reload
		if (mode.match(/reload/i)) {
			mat = mode.match(/reload\.([^\,\s]+)/i);
			target = $chk(mat) && $chk(mat[1]) ? mat[1] + '.' : '';
			eval(target + 'document.location.reload();');
		}

		// move|goto
		if (mode.match(/(move|goto)/i) && $chk(data['url'])) {
			mat = mode.match(/(move|goto)\.([^\,\s]+)/i);
			target = $chk(mat) && $chk(mat[2]) ? mat[2] + '.' : '';
			eval(target + 'document.location.replace("' + data['url'] + '");');
		}

		// back
		if (mode.match(/back/i)) {
			mat = mode.match(/back\.([0-9]+)/i);
			target = $chk(mat) && $chk(mat[1]) ? 'go(-' + mat[1] + ')' : 'back()';
			if (history.length) eval('history.' + target);
		}

		// close
		if (mode.match(/close/i)) {
			mat = mode.match(/close\.([^\,\s]+)/i);
			target = $chk(mat) && $chk(mat[1]) ? mat[1] : 'self';
			eval(target + '.close();');
		}
	}
}; // END function


//// sortables 수정본
var Sortables = new Class({
	options: {
		handles: false,
		onStart: Class.empty,
		onComplete: Class.empty,
		ghost: true,
		snap: 3,
		onDragStart: function(element, ghost){
			ghost.setStyle('opacity', 0.7);
			element.setStyle('opacity', 0.7);
		},
		onDragComplete: function(element, ghost){
			element.setStyle('opacity', 1);
			ghost.remove();
			this.trash.remove();
		}
	},

	initialize: function(list, options){
		this.setOptions(options);
		this.list = $(list);
		this.listPos = this.list.getCoordinates();
		this.elements = this.list.getChildren();
		this.handles = (this.options.handles) ? $$(this.options.handles) : this.elements;
		this.bound = {
			'start': [],
			'moveGhost': this.moveGhost.bindWithEvent(this)
		};
		for (var i = 0, l = this.handles.length; i < l; i++){
			this.bound.start[i] = this.start.bindWithEvent(this, this.elements[i]);
		}
		this.attach();
		if (this.options.initialize) this.options.initialize.call(this);
		this.bound.move = this.move.bindWithEvent(this);
		this.bound.end = this.end.bind(this);
		this.bound.scrollDown = this.scrollDown.bind(this);
		this.bound.scrollUp = this.scrollUp.bind(this);
	},

	attach: function(){
		this.handles.each(function(handle, i){
			handle.addEvent('mousedown', this.bound.start[i]);
		}, this);
	},

	detach: function(){
		this.handles.each(function(handle, i){
			handle.removeEvent('mousedown', this.bound.start[i]);
		}, this);
	},

	start: function(event, el){
		this.active = el;
		this.coordinates = this.list.getCoordinates();
		if (this.options.ghost){
			var position = el.getPosition();
			this.offset = this.list.getSize().scroll.y;
			this.trash = new Element('div').inject(document.body);
			this.ghost = el.clone().inject(this.trash).setStyles({
				'position': 'absolute',
				'left': position.x,
				'top': event.page.y
			});
			document.addListener('mousemove', this.bound.moveGhost);
			this.fireEvent('onDragStart', [el, this.ghost]);
		}
		document.addListener('mousemove', this.bound.move);
		document.addListener('mouseup', this.bound.end);
		this.fireEvent('onStart', el);
		event.stop();
	},

	moveGhost: function(event){
		// scroll
		if (event.page.y > this.listPos.bottom && !this.checkDown) {
			this.eventDown = this.bound.scrollDown.periodical(50);
			this.checkDown = 1;
		}		
		if (event.page.y <= this.listPos.bottom && this.checkDown) {
			$clear(this.eventDown);
			this.checkDown = null;
		}
		if (event.page.y < this.listPos.top && !this.checkUp) {
			this.eventUp = this.bound.scrollUp.periodical(50);
			this.checkUp = 1;
		}		
		if (event.page.y >= this.listPos.top && this.checkUp) {
			$clear(this.eventUp);
			this.checkUp = null;
		}
		
		var value = event.page.y;
		value = value.limit(this.coordinates.top, this.coordinates.bottom - this.ghost.offsetHeight);
		this.ghost.setStyle('top', value);
		event.stop();
	},

	move: function(event){
		var now = event.page.y;
		this.previous = this.previous || now;
		var up = ((this.previous - now) > 0);
		var prev = this.active.getPrevious();
		var next = this.active.getNext();
		if (prev && up && now < prev.getCoordinates().bottom - this.list.getSize().scroll.y) this.active.injectBefore(prev);
		if (next && !up && now > next.getCoordinates().top - this.list.getSize().scroll.y) this.active.injectAfter(next);
		this.previous = now;
	},
	
	scrollUp: function(){
		this.list.scrollTo(0, this.list.getSize().scroll.y - 15);
	},
	
	scrollDown: function(){
		this.list.scrollTo(0, this.list.getSize().scroll.y + 15);
	},	

	serialize: function(converter){
		return this.list.getChildren().map(converter || function(el){
			return this.elements.indexOf(el);
		}, this);
	},

	end: function(){
		this.previous = null;
		document.removeListener('mousemove', this.bound.move);
		document.removeListener('mouseup', this.bound.end);
		if (this.options.ghost){
			document.removeListener('mousemove', this.bound.moveGhost);
			this.fireEvent('onDragComplete', [this.active, this.ghost]);
		}
		
		if (this.checkDown) {
			$clear(this.eventDown);
			this.checkDown = null;
		}
		if (this.checkUp) {
			$clear(this.eventUp);
			this.checkUp = null;
		}		
		
		this.fireEvent('onComplete', this.active);
	}

});

Sortables.implement(new Events, new Options);