var KEditor = Class.create( KUtil, {
	initialize: function( textareaElement ) {
		//¿¡·¯ Ã³¸®
		if (typeof(document.execCommand) == 'undefined') { alert("not Used execCommand"); return; }
		if( textareaElement == "" || !document.getElementById(textareaElement) ) { alert( "Textarea does not exist."); return; }

		this.baseURL = this.getScriptPath('KEditor');
		this.imageURL = this.baseURL+"/images/editor";
		this.cssURL = "css";
	
		ua = navigator.userAgent;
		this.isMSIE = (navigator.appName == "Microsoft Internet Explorer");
		this.isMSIE5 = this.isMSIE && (ua.indexOf('MSIE 5') != -1);
		this.isMSIE5_0 = this.isMSIE && (ua.indexOf('MSIE 5.0') != -1);
		this.isMSIE7 = this.isMSIE && (ua.indexOf('MSIE 7') != -1);
		this.isGecko = ua.indexOf('Gecko') != -1; // Will also be true on Safari
		this.isSafari = ua.indexOf('Safari') != -1;
		this.isOpera = window['opera'] && opera.buildNumber ? true : false;
		this.isMac = ua.indexOf('Mac') != -1;
		this.isNS7 = ua.indexOf('Netscape/7') != -1;
		this.isNS71 = ua.indexOf('Netscape/7.1') != -1;

		// Fake MSIE on Opera and if Opera fakes IE, Gecko or Safari cancel those
		if (this.isOpera) {
			this.isMSIE = true;
			this.isGecko = false;
			this.isSafari =  false;
		}

		this.isIE = this.isMSIE;
		this.isRealIE = this.isMSIE && !this.isOpera;

		this.textareaElement = $(textareaElement);
		this.textareaElementCopy = null;	//FullÈ­¸éÀ» À§ÇÑ textarea º¹»ç
		this.editorPos = [];			//¿¡µðÅÍ À§Ä¡
		this.editorDim = [];			//¿¡µðÅÍ ³ÐÀÌ
		this.editorFrame = null;		//ÇÁ·¡ÀÓ
		this.parentObj = null;			//ºÎ¸ðÅÂ±×
		this.frameObj = null;			//¿¡µðÅÍ IFRAME
		this.cw = null;
		this.doc = null;				//¿¡µðÅÍ IFRAME TEXTAREA
		this.fontname = null;			//±Û¾¾Ã¼
		this.fontsize = null;			//»çÀÌÁî
		this.selectionPos = null;		//Ä¿¼­ÀÇ À§Ä¡
		this.fullscreenMode = false;
		this.designMode = "on";

		this.lastWindow = null;			//¸ðÁú¶ó °è¿­ ÆË¾÷ ¿¡¼­ ¸¶Áö¸·¿¡ ¿ÀÇÂµÈ À©µµ¿ì °´Ã¼

		this.options = Object.extend({
			topMenus: new Array(),
			dialogType: "modal",
			fontfases: [ "±¼¸²", "µ¸¿ò", "Arial", "Tahoma", "Verdana", "Time" ],
			fontsizes: [ 1, 2, 3, 4, 5, 6 ]
		}, arguments[1] || {});

		var this_s = this;
		Event.observe(window, "load", function() { this_s.initEditor() } );

	},

	initEditor: function() {

		this.parentObj = this.textareaElement.up(0);
		this.editorPos = this.textareaElement.positionedOffset();
		this.editorDim = this.textareaElement.getDimensions();
		this.initFrame();
	},

	/**
	/* EditorÀ» »ý¼ºÇÏ±âÀ§ÇÑ layer »ý¼º
	**/
	initFrame: function() {
		var this_s = this;
		//·¹ÀÌ¾î »ý¼º
		this.topObj = Builder.node('DIV',
						{ style: "position:relative;" },
						[this.frameSet()]);
		//ºÙÀÌ±â
		new Insertion.Top(this.parentObj, this.topObj);

		//¿¡µðÅÍ ¿ÀÇÂ
		this.cw = $(this.frameObj).contentWindow;
		this.doc = this.cw.document;
		this.doc.open();
		this.doc.write("<html><head>");
		this.doc.write("<style type='text/css'>");
		this.doc.write("p{ margin:0px; }");
		this.doc.write("ul,ol{ margin-top:0; margin-bottom:0; }");	
		this.doc.write("body, table, td{");
		this.doc.write("scrollbar-3dlight-color:#E0E0E0;");
		this.doc.write("scrollbar-arrow-color:#E0E0E0;"); 
		this.doc.write("scrollbar-base-color:#E0E0E0;"); 
		this.doc.write("scrollbar-darkshadow-color:#FFFFFF;"); 
		this.doc.write("scrollbar-face-color:#FFFFFF;"); 
		this.doc.write("scrollbar-highlight-color:#FFFFFF;"); 
		this.doc.write("scrollbar-shadow-color:#E0E0E0;");
		this.doc.write("font-family:'Arial'; font-size:9pt; line-height:140%;}");
		this.doc.write("</style>");
		this.doc.write("</head><body bgcolor='#FFFFFF'></body></html>"); 
		this.doc.close();
		this.doc.designMode = this.designMode;
		//Å©¸¯ ¶Ç´Â Å°º¸µå¸¦ ¿ñÁ÷¿´À»°æ¿ì
		Event.observe($(this.doc), "mousedown", this.eventListener.bindAsEventListener(this));
		Event.observe($(this.doc), "mouseup", this.eventListener.bindAsEventListener(this));
		Event.observe($(this.doc), "keydown", this.eventListener.bindAsEventListener(this));
		Event.observe($(this.doc), "keyup", this.eventListener.bindAsEventListener(this));

		setTimeout(function () { this_s.html2edit(); }, 100);
	},
	
	/**
	/* IFRAME SET
	**/
	frameSet: function() {
		var headerTr = Builder.node('TR');
		headerTr.appendChild(this.frameHeader());
		
		var bodyTd = Builder.node("TD");
		bodyTd.appendChild(this.frameBody());
		bodyTd.appendChild(this.textareaBody());

		var bodyTr = Builder.node('TR');
		bodyTr.appendChild(bodyTd);

		var tbody = Builder.node('TBODY');
		tbody.appendChild(headerTr);
		tbody.appendChild(bodyTr);

		return Builder.node('TABLE', { width:this.editorDim.width, height:"100%", style: "background-color:#FFFFFF;", border:"0px" }, [tbody]);
	},

	/**
	/* ¸Þ´º(¾ÆÀÌÄÜ) »ý¼º
	**/
	frameHeader: function() {
		var item, node;
		var tds = new Array();
		var trs = new Array();
		var this_s = this;

		for( var i=0; i<this.options.topMenus.length;i++) {
			this.options.topMenus[i].each( 
				function(item) { 
					node = this_s.setItem(item);
					tds.push( Builder.node( "DIV", { style: "float:left;" }, [node] ) );
				} 
			);

			trs.push(Builder.node("DIV", { style: "width:" + this.editorDim.width + ";"}, tds));
			tds = new Array();
		}
		return Builder.node("TD", { height:(20*i) }, trs);
	},

	/**
	/* IFRAME »ý¼º
	**/
	frameBody: function() {

		//»ý¼ºÇÏ°íÀÚ ÇÏ´Â Å×ÀÌºí¼ö ¸¸Å­ IFRAME¸¦ »ý¼ºÇÑ´Ù.
		var width = this.editorDim.width;
		var height =  this.editorDim.height;

		this.frameObj = Builder.node(
				"IFRAME", 
				{ 
					scrolling:"yes", 
					frameborder:"no", 
					wrap:"virtual", 
					frameborder:"0px",
					marginwidth:"0",
					marginheight:"0",
					style:"border:1px solid #D0D0D0" 
				} 
			);
		this.frameObj.style.width = width;
		this.frameObj.style.height = height;

		return this.frameObj;
	},

	/**
	/* textarea¸¦ ±×´ë·Î º¹»çÇÏ¿© ·¹ÀÌ¾î ¾È¿¡ ³Ö´Â´Ù.
	**/
	textareaBody: function() {

		//»ý¼ºÇÏ°íÀÚ ÇÏ´Â Å×ÀÌºí¼ö ¸¸Å­ IFRAME¸¦ »ý¼ºÇÑ´Ù.
		var width = this.editorDim.width;
		var height =  this.editorDim.height;
		var name= this.textareaElement.name;
		var id = this.textareaElement.id;
		var className = this.textareaElement.className;
		var value = this.textareaElement.value;

		this.textareaElement.hide();

		this.textareaElementCopy = Builder.node("TEXTAREA", { id: id, name: name, className: className, style:"width:"+width+"px; height:"+height+"px" } );
		this.textareaElementCopy.value = value;

		return Builder.node( "TD", [this.textareaElementCopy] );
	},

	setItem: function(item) {
		
		switch( item ) {
			case "fontface" :
				return Builder.node( "DIV", [this._fontface()] );
			case "fontsize" :
				return Builder.node( "DIV", [this._fontsize()] );
		}

		return Builder.node( "DIV", { id: item + "_item" }, [this._defaultItems( item )]);
	},

	/**
	/* ¾ÆÀÌÄÜ ¼ÂÆÃ
	**/	
	_defaultItems: function( item ) {

		var node, src;
		item = item=="|"?"separator":item;
		src = this.imageURL + "/"+item+".gif";
		node = Builder.node('IMG', {id: item+"_icon", src: src, alt: item, style: 'cursor:pointer'});

		switch ( item ) {
		case "fontcolor" :
			Event.observe( node, "click", this._color.bindAsEventListener(this, item) );
			break;
		case "bgcolor" :
			Event.observe( node, "click", this._color.bindAsEventListener(this, item) );
			break;
		case "insertdate" :
			Event.observe( node, "click", this._insertdate.bindAsEventListener(this, item) );
			break;
		case "inserttime" :
			Event.observe( node, "click", this._inserttime.bindAsEventListener(this, item) );
			break;
		case "table" :
			Event.observe( node, "click", this._table.bindAsEventListener(this, item) );
			break;
		case "charmap" :
			Event.observe( node, "click", this._charmap.bindAsEventListener(this, item) );
			break;
		case "link" :
			Event.observe( node, "click", this._link.bindAsEventListener(this, item) );
			break;
		case "image" :
			Event.observe( node, "click", this._image.bindAsEventListener(this, item) );
			break;
		case "fullscreen" :
			Event.observe( node, "click", this._fullscreen.bindAsEventListener(this, item) );
			break;
		case "code" :
			Event.observe( node, "click", this.changeMode.bindAsEventListener(this, item) );
			break;
		default :
			Event.observe( node, "click", this._mouseEvent.bindAsEventListener(this, item, false, null) );
			break;		
		}

		return node;
	},

	/**
	/* ÆùÆ® Å©±â
	**/
	_fontface: function() {
		//ÇöÀçÀÇ ½ºÅ©¸³Æ® Ç×¸ñ 
		this.fontname = Builder.node("SELECT", { id: "fontname", className: "select",  style: "margin-left:2px; margin-right:2px" } );
		this.fontname.options[0] = new Option("-Font face-","");
		for( var i=0;i<this.options.fontfases.length;i++ ) {
			this.fontname.options[(i+1)] = new Option(this.options.fontfases[i],this.options.fontfases[i]);
		}
		Event.observe(this.fontname,"change", this._mouseEvent.bindAsEventListener(this, "fontname", false, this.fontname ) );
		return this.fontname;
	},

	/**
	/* ÆùÆ®»çÀÌÁî
	**/
	_fontsize: function() {
		//ÇöÀçÀÇ ½ºÅ©¸³Æ® Ç×¸ñ 
		this.fontsize = Builder.node("SELECT", { className: "select", style: "margin-left:2px; margin-right:2px" } );
		this.fontsize.options[0] = new Option("-Font size-","");
		for( var i=0;i<this.options.fontsizes.length;i++ ) {
			this.fontsize.options[(i+1)] = new Option(this.options.fontsizes[i],this.options.fontsizes[i]);
		}
		
		Event.observe(this.fontsize,"change", this._mouseEvent.bindAsEventListener(this, "fontsize", false, this.fontsize ) );

		return this.fontsize;
	},

	/**
	/* »ö»ó¼±ÅÃ ·¹ÀÌ¾î
	**/
	_color: function(evt) {

		this.colorDistory();

		var colors = [
			"#FE1100","#FE4C24","#FE875A","#FECDA7","#040967","#2D328D","#44499A","#686EB8","#669900","#66CC00","#99FF00","#FF99FF",
			"#6E0017","#7B243D","#834C6B","#66FFFF","#006BD4","#0087E1","#37B7FE","#A7DEFE","#FFCC00","#FFFF00","#FEFE9F","#FEFED0",
			"#4E003D","#6D2262","#926594","#C2A9C5","#005557","#03747B","#579D9F","#A2C6CC","#FF6600","#FF9933","#FECD8A","#FEE2B0",
			"#1B0B73","#4C379D","#876EBA","#BBBAEF","#008E37","#26B168","#47BE80","#76D3A2","#B31C00","#B03F21","#AE623A","#AC6E54",
			"#FEFEFE","#E6E6E6","#CDCDCD","#B4B4B4","#A8A8A8","#8D8D8D","#747474","#595959","#4B4B4B","#303030","#0A0A0A","#000000"
		];

		var tds = new Array();
		var trs = new Array();
		var _td, _tr, _btn, execute, item = arguments[1];
		var pos = Position.cumulativeOffset(Event.element(evt));

		//»ö»óÀÇ ÁÖ¸¸Å­ ·çÇÁ µ¹¸°´Ù.
		for( var i=0; i<colors.length;i++ ) {

			_td = Builder.node("TD");
			Element.setStyle( _td, {
				backgroundColor: colors[i],
				width: '11px',
				cursor: 'pointer'
			} );

			if( item == "fontcolor" ) execute = "forecolor";
			else if( item == "bgcolor" ) {
				if(navigator.appName != "Microsoft Internet Explorer") execute = "hilitecolor";
				else execute = "backcolor";
			}

			Event.observe( _td, "mousedown", this._mouseEvent.bindAsEventListener(this, execute, false, colors[i]) );
			tds.push( _td );

			if( i%12 == 11 ) {
				//tds µî·Ï
				trs.push( Builder.node("TR", { height:"11px" }, tds ) );
				//tds ÃÊ±âÈ­
				tds = new Array();
			}
		}

		var tbody = Builder.node('TBODY', trs);
		var table = Builder.node( 'TABLE', { style: "cellPadding: 0px; margin:7px", cellspacing:"0px" }, [tbody]);
		var div = Builder.node( 'DIV', { className:"colorDiv", style: "position:absolute; left:"+pos[0]+"px; top:"+(pos[1]+20)+"px; border:1px solid #999999;" }, [table] );
		this.parentObj.appendChild(div);
	},

	/**
	/* ÇöÀç½Ã°£ µî·Ï
	**/
	_insertdate: function() {
		var t = new Date();
		var d = t.getFullYear() + "-" + (t.getMonth()+1) + "-" + t.getDate();
		this._insertHTML( d );
	},

	/**
	/* ÇöÀç ½Ã°£ ÀÔ·Â
	**/
	_inserttime: function() {
		var t = new Date();
		var d = t.getHours() + ":" + t.getMinutes() + ":" + t.getSeconds();
		this._insertHTML( d );
	},

	/**
	/* Å×ÀÌºí ÆË¾÷
	**/
	_table: function() {
		var url = this.baseURL+"theme/table.html";
		var args = { 'width':'320', 'height':'170', 'resizable':'no', 'scrollbars':'no' };
		this.popWin(url, args);
	},

	/**
	/* Æ¯¼ö¹®ÀÚ ÆË¾÷
	**/
	_charmap: function() {
		var url = this.baseURL+"theme/charmap.html";
		var args = { 'width':'550', 'height':'270', 'resizable':'no', 'scrollbars':'no' };
		this.popWin(url, args);
	},

	/**
	/* ¸µÅ© ÆË¾÷
	**/
	_link: function() {
		var url = this.baseURL+"theme/link.html";
		var args = { 'width':'400', 'height':'150', 'resizable':'no', 'scrollbars':'no' };
		this.popWin(url, args);
	},
	
	/**
	/* ¸µÅ© µî·Ï
	**/
	_linkAction: function( param ) {
		
		var text="";
		if( this.isRealIE ) text = this.doc.selection.createRange().text;
		else text = this.cw.getSelection();

		alert( typeof(text) );

		var href = param.href.replace("http://","");
		var target = param.target? " target='"+param.target+"'":"";
		var title = param.title? " title='"+param.title+"'":"";
		//this.doc.execCommand("delete", false, null);

		var url = "<a href='http://"+param.href+"'"+target+""+title+">"+text+"</a>";
		alert( url );
		this._insertHTML( url );

	},
	
	/**
	/* ÀÌ¹ÌÁö µî·Ï
	**/
	_image: function() {
		var url = this.baseURL+"theme/image.html";
		var args = { 'width':'500', 'height':'70', 'resizable':'no', 'scrollbars':'no' };
		this.popWin(url, args);
	},

	/**
	/* ÀüÃ¼È­¸é ¸ðµå
	**/
	_fullscreen: function() {

		if( this.fullscreenMode )this.fullscreenMode = false;
		else this.fullscreenMode = true;
		if( this.designMode == "on" ) this.html2edit();
		else this.edit2html();
	},

	/**
	/* ¿¡µðÅÍ¿¡ text »ðÀÔ
	**/
	_insertHTML: function( t ) {

		$(this.frameObj).contentWindow.focus();
		this.doc.execCommand("delete", false, null);
		if ( navigator.appName=="Microsoft Internet Explorer" ) {
			this.doc.selection.createRange().pasteHTML(t);
		} else {
			this.doc.execCommand("inserthtml", false, t);
		}

		this.textareaSynch();
	},
	
	/**
	/* ±âº»ÀûÀÎ ¿¡µðÅÍ ¾ÆÀÌÄÜ
	**/
	_mouseEvent: function() {
		this.colorDistory();
		var execute = arguments[1];
		var bool = arguments[2];
		var value = arguments[3];

		if( execute == "fontsize" || execute == "fontname" ) {
			value = value.value;
		}

		this.doc.execCommand(execute, bool, value);
		this.textareaSynch();
		this.doc.focus();
	},

	/**
	/* ¿¡µðÅÍ Ã¢¿¡ ¸¶¿ì½º·Î ¶Ç´Â Å°º¸µå Å¬¸¯½Ã »ý¼ºµÇ´Â ÀÌº¥Æ®
	/* ±¸Áö ÇÊ¿äÇÑÁö´Â ¸ð¸£°Ú´ç...¤Ñ¤Ñ;;
	**/
	eventListener: function() {
		this.colorDistory();
		this.textareaSynch();
		this.fontsize.value="";
		this.fontname.value="";
	},

	/**
	/* ¸ðµåº¯°æ
	**/
	changeMode: function() {
		
		this.colorDistory(); 
		if( this.designMode == "on" ) this.edit2html();
		else this.html2edit();

	},
	
	textareaSynch: function() {
		if( this.designMode == "on" ) {
			this.textareaElementCopy.value = this.textareaElement.value = this.doc.body.innerHTML;
		}else {
			this.doc.body.innerHTML = this.textareaElement.value = this.textareaElementCopy.value;
		}
	},

	/**
	/* ¼Ò½º¿¡¼­ ¿¡µðÆ®·Î
	**/
	html2edit: function() {

		this.designMode = "on";

		this.textareaElementCopy.style.display = "none";	//°¡¸®±â
		this.frameObj.style.display = "";

		if( this.fullscreenMode ) {
			this.topObj.style.position = "absolute";
			this.topObj.style.top = "0px";
			this.topObj.style.left = "0px";
			this.frameObj.style.width = screen.availWidth-28;
			this.frameObj.style.height = screen.availHeight;
		}else {
			this.topObj.style.position = "relative";
			this.topObj.style.width = "100%";
			this.topObj.style.height = "20px";
			this.frameObj.style.width = this.editorDim.width;
			this.frameObj.style.height = this.editorDim.height;
		}

		$("code_icon").src = this.imageURL+"/html.gif";
		this.doc.body.innerHTML = this.textareaElement.value = this.textareaElementCopy.value;

	},
	
	/**
	/* ¿¡µðÆ®¿¡¼­ ¼Ò½º·Î
	**/
	edit2html: function() {

		this.designMode = "off";
		this.textareaElementCopy.style.display = "";
		this.frameObj.style.display = "none";

		if( this.fullscreenMode ) {
			this.topObj.style.position = "absolute";
			this.topObj.style.top = "0px";
			this.topObj.style.left = "0px";
			this.textareaElementCopy.style.width = screen.availWidth-28;
			this.textareaElementCopy.style.height = screen.availHeight;
		}else {
			this.topObj.style.position = "relative";
			this.topObj.style.width = "100%";
			this.topObj.style.height = "20px";
			this.textareaElementCopy.style.width = this.editorDim.width;
			this.textareaElementCopy.style.height = this.editorDim.height;
		}


		$("code_icon").src = this.imageURL+"/code.gif";
		this.textareaElementCopy.value = this.textareaElement.value = this.doc.body.innerHTML;
	},

	//¸ðµç ¾ÆÀÌÅÛ ·¹ÀÌ¾î ÃÊ±âÈ­
	//»ö»ó
	colorDistory: function() {
		$$('DIV.colorDiv').each( function(e) { e.remove() });
	},
	
	/**
	/* ÆË¾÷ ¶ç¿ì±â
	**/
	popWin: function(url, args) {
		var width, height, x, y, scrollbars, resizable, modal;

		if( url == "" ) { alert("URL does not exist."); return; }
		width = (args && args.width) ? parseInt(args.width):320;
		height = (args && args.height) ? parseInt(args.height):320;
		x=(screen.availWidth-width)/2;
		y=(screen.availHeight-height)/2;
		resizable = (args && args.resizable) ? args.resizable : "no";
		scrollbars = (args && args.scrollbars) ? args.scrollbars : "no";

		// Add to height in M$ due to SP2 WHY DON'T YOU GUYS IMPLEMENT innerWidth of windows!!
		if (this.isIE) height += 40;
		else height += 25;

		//IEÀÏ °æ¿ì ¸ð´ÞÃ¢ ¶Ù¿î´Ù
		if( this.isRealIE ) {
			features = "resizable:" + resizable + ";scroll:" + scrollbars + ";status:yes;center:yes;help:no;dialogWidth:" + width + "px;dialogHeight:" + height + "px;";
			window.showModalDialog(url, window, features);
		}else {

			modal = (resizable == "yes") ? "no" : "yes";

			if (this.isGecko && this.isMac)
				modal = "no";

			if( this.lastWindow != null ) {
				try { this.lastWindow.close(); this.lastWindow=null; } catch (e){}
			}

			win = window.open(url, "mcePopup" + new Date().getTime(), "top=" + y + ",left=" + x + ",scrollbars=" + scrollbars + ",dialog=" + modal + ",minimizable=" + resizable + ",modal=" + modal + ",width=" + width + ",height=" + height + ",resizable=" + resizable);
			if (win == null) {
				alert("ÆË¾÷»ý¼º¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù.");
				return;
			}

			if( this.lastWindow == null ) {
				try { this.lastWindow = win; } catch (e) {}
			}
		}

	}
});