var EditOn = {
		version:"1.42",
		lastupdated:"2009.05.11",
		prefix :"EditOn",
		imagePath :"img",
		hostPath : ""
}

/**
 *	EditorManager는 에디터 객체를 생성하고 관리하는 Class 입니다.
 *
 *	textareaID : 에디터 생성의 기준이 될 <textarea> 의 ID
 *	editonID : 툴바를 포함한 에디터의 ID
 *	wysiwygID : WYSIWYG MODE로 사용 되어지는 <iframe>의 ID
 *	textID : TEXT MODE로 사용 되어지는 <textarea> 의 ID
 *	oTextarea : 에디터 생성의 기준이 될 <textarea> 의 Object
 *	oEditon : 툴바를 포함한 에디터의 Object
 *	oWysiwyg : WYSIWYG MODE로 사용 되어지는 <iframe>의 Object
 *	oText : TEXT MODE로 사용 되어지는 <textarea> 의 Object
 *	editOnMode : 현재 에디팅 모드 - 'wysiwyg' or 'text'
 *	editOnWidth : WIDTH
 *	editOnHeight : HEIGHT
 *	editOnFontSize : FONT-SIZE
 *	editOnFontFamily : FONT-FAMILY
 *	editOnFontColor : COLOR
 *
 * @param id 에디터 생성의 기준이 되는 <textarea> 의 ID
 * @param type 에디터의 타입. 타입에 따라 툴바가 변경될 수 있음. 타입은 에디터를 사용하는 jsp페이지에서 정의함. 
 * @return EditorManager()의 Object를 반환합니다.
 */
function EditorManager(id, type) {
	this.textareaID = id;
	this.editonID = EditOn.prefix + "_" + id + "_editon";
	this.wysiwygID = EditOn.prefix + "_" + id + "_wysiwyg";
	this.textID = EditOn.prefix + "_" + id + "_text";
	this.oTextarea = document.getElementById(id);
	if(this.oTextarea.tagName.toLowerCase() != "textarea") return false;
	// 에디터 타입을 지정해 준다.
	this.adjacentHtml(this.oTextarea, this.createHtml(type));
	this.oTextarea.style.display = "none";
	this.oEditon = document.getElementById(this.editonID);
	this.oWysiwyg = document.getElementById(this.wysiwygID);
	this.oText = document.getElementById(this.textID);
	this.editOnMode = "wysiwyg";
	this.editOnWidth = EditorUtil.pureNumber(this.oTextarea.style.width) || "600";
	this.editOnHeight = EditorUtil.pureNumber(this.oTextarea.style.height) || "400";
	this.editOnFontSize = this.oTextarea.style.fontSize || "13px";
	this.editOnFontFamily = this.oTextarea.style.fontFamily || "고딕";
	this.editOnFontColor =  this.oTextarea.style.fontColor || "#444444";
	EF.put(id, this);
}
/**
 *	EditorManager.create() 는(은) 에디터를 초기화하고 designMode를 On 상태로 변경합니다.
 *
 * 	oCW : WYSIWYG MODE로 사용 되어지는 <iframe>의 ContentWindow Object
 *	oDoc : WYSIWYG MODE로 사용 되어지는 <iframe>의 Document Object
 *	popupWrap :
 *	popupID : 
 *	size : 
 */
EditorManager.prototype.create = function() {
	this.oEditon.style.width = this.editOnWidth+"px"; 
	this.oWysiwyg.style.width = "100%";
	this.oWysiwyg.style.height = this.editOnHeight+"px";
	this.oText.style.width = "100%";
	this.oText.style.height = this.editOnHeight+"px";	
	
	this.oText.style.border = "none";
	this.oText.style.fontSize = this.editOnFontSize;
	this.oText.style.fontColor = this.editOnFontColor;
	this.oText.style.fontFamily = this.editOnFontFamily;
	this.oText.style.backgroundColor = "#fff";
	this.oCW = this.oWysiwyg.contentWindow;
	this.oDoc = this.oCW.document;
	this.oDoc.designMode = "on";
	this.oDoc.open();	
	this.oDoc.write('<html><head>');
	this.oDoc.write('<link href="/editor/css/editon_io.css" rel="stylesheet" type="text/css" />');
	this.oDoc.write("<style type='text/css'>body {font-family:"+(this.editOnFontFamily)+";font-size:"+(this.editOnFontSize)+"; line-height:150%; margin:5px;}</style>");
	this.oDoc.write("<style type='text/css'>P {line-height:1.5; font-family:"+(this.editOnFontFamily)+";font-size:"+(this.editOnFontSize)+";margin:0px ;white-space: -moz-pre-wrap;word-break:break-all;}</style>");	
	this.oDoc.write('</head><body>'+this.oTextarea.value+'</body></html>');
	this.oDoc.close();
	//this.focus();
	EditorEvent.addEvent(this.oDoc, "click", EditorEvent.bindEvent(this.hidePopup, this));
	this.popupWrap = [this.textareaID+'_fontName',this.textareaID+'_fontSize',this.textareaID+'_foreColor',this.textareaID+'_backColor',this.textareaID+'_quote',
	                  this.textareaID+'_lineHeight',this.textareaID+'_createLink',this.textareaID+'_createTable'];
	this.popupID = null;
	this.size = "DEFAULT";
}
/**
 *	EditorManager.hidePopup() TOOLBAR의 모든 팝업을 닫습니다.
 *
 * @param event - event Object
 */
EditorManager.prototype.hidePopup = function(event) {
	target = EditorEvent.target(event);
	if(target!=null && (target.tagName == 'HTML' || target.tagName == 'BODY' || target.tagName == 'P')){ this.popupID = null;}
	for(var i = 0; i < this.popupWrap.length; i++){
		var tempPop = document.getElementById(this.popupWrap[i]);
		if(tempPop) tempPop.style.display = 'none';
	}
}
/**
 *	EditorManager.showPopup() 선택한 팝업을 띄웁니다.
 *
 * @param name 팝업의 이름
 */
EditorManager.prototype.showPopup = function(name) {
	if(this.editOnMode=='text') return;
	this.hidePopup();
	clickID = this.textareaID+"_"+name;
	this.log("[POPUP_ID : "+this.popupID+" ], [CLICK_ID : "+clickID+"]","info");
	if( this.popupID == clickID){	
		this.popupID = null;
		return;
	}else{
		this.getSelection();
		this.setRange();
		popup = document.getElementById(this.textareaID+"_"+name);
		popup.style.display = '';
		this.popupID = clickID;		
	}
}
EditorManager.prototype.setRange = function(){
	if(this.oRange.duplicate){
		this.oRangeClone = this.oRange.duplicate();
	}else{
		this.oRangeClone = this.oRange.cloneRange();
	}
}
EditorManager.prototype.adjacentHtml = function(target, html) {
	if (target.insertAdjacentHTML) { // IE6, OPERA 9
		target.insertAdjacentHTML('BeforeBegin', html);
	} else { // FF3, Chrome
		var oRange = document.createRange();
		oRange.setStartBefore(target);
		var oFragment = oRange.createContextualFragment(html);
		target.parentNode.insertBefore(oFragment, target);
	}
}
/**
 *	커서 위치를 에디터창으로 이동합니다.
 */
EditorManager.prototype.focus = function() {
	if (this.editOnMode.toLowerCase() == "text") {
		this.oText.focus();
	} else {
		this.oWysiwyg.contentWindow.focus();
	}
}
/**
 *	에디팅 모드를 전환합니다 (wysiwyg ↔ text) 
 */
EditorManager.prototype.changeMode = function() {
	if (this.editOnMode.toLowerCase() == 'wysiwyg') {
		this.oText.value = this.getContent();
		this.oWysiwyg.style.display = "none";
		this.oText.style.display = "";
		this.editOnMode = "text";
		this.hidePopup();
		this.disable();
		this.focus();
	} else {
		this.oDoc.body.innerHTML = this.getContent();
		this.oText.style.display = "none";
		this.oWysiwyg.style.display = "";
		this.editOnMode = "wysiwyg";
		this.enable();
	}
}
/**
 * execCommand 명령을 수행합니다.
 * 
 * @param cmd	실행할 커맨드 
 * @param value	
 * @return
 */
EditorManager.prototype.command = function(cmd, value) {
	if(this.editOnMode=='text') return;
	this.getSelection();
	if(!value) value = null;
	this.log("[COMMAND : "+cmd+" ], [VALUE : "+value+"]","info");
	
	switch(cmd)
	{
	case "fontName": case "fontSize":
		if(this.font) this.font(cmd, value);
		else this.oDoc.execCommand(cmd, false, value);
		break;
	case "backColor": case "hiliteColor":
		if(EditorUtil.agent().IE) cmd = "backColor";
		else cmd = "hiliteColor";
		this.oDoc.execCommand(cmd, false, value);
		break;
	case "lineHeight":
		if(this.lineHeight) this.lineHeight(value);
		break;
	case "createTable":
		break;
	case "createQuote":
		if(this.quote) this.quote(value);	
		break;
	default:
		this.oDoc.execCommand(cmd, false, value);
		break;
	}
	this.popupID = null;
	this.hidePopup();
}
/**
 *  selection 객체를 유지합니다.
 */
EditorManager.prototype.getSelection = function(){
	this.focus();
	if(this.oCW.getSelection){	// FF, Chrome, Opera
		this.oSelection = this.oCW.getSelection();
		this.oRange = this.oSelection.getRangeAt(0);
	}else if(this.oDoc.selection){	// IE 
		this.oSelection = this.oDoc.selection;
		this.oRange = this.oSelection.createRange();
		this.oRange.select();
	}
}
/**
 * 컨텐트 내용을 가져옵니다.
 * 
 * @return 
 */
EditorManager.prototype.getContent = function() {
	var html = '';
	if(this.editOnMode=='wysiwyg'){
		html = this.oDoc.body.innerHTML;
	}else{
		html = this.oText.value;
	}
	return html;
}
/**
 *	컨텐트에 내용을 입력합니다.
 */
EditorManager.prototype.setContent = function(html) {
	if(this.editOnMode=='wysiwyg'){
		this.oDoc.body.innerHTML = html;
	}else{
		this.oText.value = html;
	}
}
/**
 * 컨텐트에 HTML을 추가합니다.(Opera 미지원)
 * @return
 */
EditorManager.prototype.pasteHTML = function(html) {
	if(this.editOnMode=='wysiwyg'){
		this.getSelection();
		if (this.oRange.pasteHTML) {	// IE
			this.oRange.pasteHTML(html);	
		}else{	// FF, Chrome, Opera
			this.command("insertHTML",html);
//			this.oRange.deleteContents();	
//			this.oRange.insertNode(this.oRange.createContextualFragment(html));		
		}
	}else{
		this.oText.value += html;
	}
}
/**
 * 컨텐트에서 선택된 HTML을 가져옵니다.(Opera 미지원)
 * @return
 */
EditorManager.prototype.getHTML = function() {
	var html = '';
	this.getSelection();
	if(!this.oRange) return html;
	if(this.oRange.cloneContents){	// FF, Chrome, Opera
		/*if(this.oSelection.rangeCount > 0 && window.XMLSerializer){	
			html=new XMLSerializer().serializeToString(this.oRange.cloneContents());
		}*/
		var div = document.createElement('div');
		div.appendChild(this.oRange.cloneContents());
		html = div.innerHTML;
	}else if(this.oRange.htmlText){	//  IE, Opera
		html = this.oRange.htmlText;
	}
	return html;
}
/**
 *	에디터를 활성화 합니다.
 */
EditorManager.prototype.enable = function() {
	var tools = document.getElementById(this.textareaID+"_toolbar");
	var buttons = tools.getElementsByTagName("BUTTON");

	for(i=0; i<buttons.length; i++){
		EditorUtil.opacity(buttons[i], 1.00);
	}
}
/**
 *	에디터를 비활성화 합니다.
 */
EditorManager.prototype.disable = function() {
	var tools = document.getElementById(this.textareaID+"_toolbar");
	var buttons = tools.getElementsByTagName("BUTTON");

	for(i=0; i<buttons.length; i++){
		EditorUtil.opacity(buttons[i], 0.50);
	}
}
/**
 * EditorFactory 는 EditorManager 에서 생성한 에디터 객체를 
 * KEY,VALUE 형태로 담아두는 일종의 MAP 과 같은 역할을 하는 Class입니다.
 */
var EF = new EditorFactory();
function EditorFactory(){
	this.oMap = new Array();
}
EditorFactory.prototype.containsKey = function(key){
	var keyIndex = -1;
	for(var i=0; i<this.oMap.length; i++){
		if(key == this.oMap[i][0]) {
			keyIndex = i;
			break;
		}
	}
	return keyIndex;
}
EditorFactory.prototype.put = function(key, value){
	var keyIndex = this.containsKey(key);
	if(keyIndex == -1){
		var temp = new Array();
		temp[0] = key;
		temp[1] = value;
		this.oMap[this.oMap.length] = temp;
	}else{
		this.oMap[keyIndex][1] = value;
	}
}
EditorFactory.prototype.get = function(key){
	var obj = null;
	for(var i=0; i<this.oMap.length; i++){
		if(this.oMap[i][0] == key){
			obj = this.oMap[i][1];
			break;
		}
	}
	return obj;
}
EditorFactory.prototype.size = function(){
	return this.oMap.length;
}
/**
 *	EditorEvent 는 event를 Listener 방식으로 등록할 경우
 *  브라우저의   
 */
var EditorEvent = {
		addEvent : function(element, event, callback, useCapture){
			useCapture = useCapture || false;
			if (element.addEventListener) {
				element.addEventListener(event, callback, useCapture);
			} else if (element.attachEvent) {
				element.attachEvent('on' + event, callback);
			}		
		},
		removeEvent : function(element, event, callback, useCapture){
			useCapture = useCapture || false;
			if (element.removeEventListener) {
				element.removeEventListener(event, callback, useCapture);
			} else if (element.detachEvent) {
				element.detachEvent('on' + event, callback);
			}		
		},
		bindEvent : function(func, obj){
			return function(){
				return func.apply(obj, arguments);	
			}
		},
		target : function(event) {
			if (event == null) return null;
			if (event.target) return event.target;
			else if (event.srcElement) return event.srcElement;
			return null;		
		}
	}
var EditorUtil = {
		pureNumber : function(wh){
			wh = wh.toString();
			wh = wh.replace(/px/g,'');
			wh = wh.replace(/%/g,'');
			return wh;
		},
		opacity : function(element, opacity){
			if (element.filters) {
				element.style.filter = 'alpha(opacity=' + opacity * 100 + ')';
			} else {
				element.style.opacity = opacity;
			}		
		},
		agent : function(){
			var nu = navigator.userAgent;
			var np = navigator.platform;
			
			return {
				IE : /MSIE/.test(nu),
				IE6 : /MSIE 6/.test(nu),
				IE7 : /MSIE 7/.test(nu),
				IE8 : /MSIE 8/.test(nu),
				FF : /Firefox/.test(nu),
				Chrome : /Chrome/.test(nu),
				//Safari : /Safari/.test(nu),//Chrome의 agent에도 Safari가 들어있음.
				Opera : /Opera/.test(nu),
				Windows : /Win/.test(np),
				Linux : /Linux/.test(np),
				Mac : /Mac/.test(np)		
			}
		}
	}
