/**
 * EditorManager.preview() 는 작성한 내용을 미리보기 할 수 있는 팝업을 띄웁니다.
 */
EditorManager.prototype.preview = function(){
	var pw=window.open("","preview","width=800,height=600,status=1,scrollbars=1,resizable=1");
	pw.document.open();	
	pw.document.write('<html><head>');
	pw.document.write('<title>EditOn Preview</title>');
	pw.document.write('<link href="'+EditOn.path+'/css/editon_io.css" rel="stylesheet" type="text/css" />');
	pw.document.write("<style type='text/css'>body {font-family:"+(this.editOnFontFamily)+";font-size:"+(this.editOnFontSize)+";}</style>");
	pw.document.write("<style type='text/css'>P {line-height:1.8; font-family:"+(this.editOnFontFamily)+";font-size:"+(this.editOnFontSize)+";margin-top:3px;margin-bottom:3px;margin-left:3;margin-right:3;white-space: -moz-pre-wrap;word-break:break-all;}</style>");	
	pw.document.write('</head><body>'+this.getContent()+'</body></html>');
	pw.document.close();	
}
EditorManager.prototype.lineHeight = function(value){
	if(EditorUtil.agent().IE){
		this.getParagraphIE();
		this.lineTestIE(value);
	}else{
		this.getParagraph();
		this.lineTest(value);
	}	
}
EditorManager.prototype.lineTest = function(value){
	var oAllNodes = this.getAllNodes();
    var oNode;
    for(var i=0; i<oAllNodes.length; i++){
    	oNode = oAllNodes[i];
        if(!oNode)continue;
        //if(oNode.nodeType!=3)continue;
        if(oNode.nodeValue=="")continue;
        
        if(oNode.nodeType==1){
        	if(oNode.tagName.toUpperCase()=="P") {
        		this.log("lineTest() 1-1 ");
        		oNode.style.lineHeight = value;	
        	}else{
        		this.log("lineTest() 1-2 ");
        	}
        }else if(oNode.nodeType == 3){
        	this.log("lineTest() 3 ");
        	this.setLine(this.getFirstNode(oNode), this.getLastNode(oNode), value);
        }

    }			
}
EditorManager.prototype.lineTestIE = function(value){
	this.getsOffset();
	this.geteOffset();
	var allNodes = this.oRange.parentElement().childNodes;
	this.log("=========>>1");
	
//	this.getParentElement(this.oRange.parentElement());
//	
//	var allNodes = null;
//	if(this.startFlag && this.endFlag){
//		this.startFlag = false;
//		this.endFlag = false;		
//		allNodes = this.oRange.parentElement().childNodes;
//	}else{
//		this.startFlag = false;
//		this.endFlag = false;
//		allNodes = this.oRange.parentElement().parentElement().childNodes;
//	}	
	
	
	this.log("=========>>2");
	var flag = false;
	this.log("시작:"+this.sContainer.nodeName +","+this.sContainer.nodeValue+","+this.sContainer.nodeType);
    var oNode;
	for(var i = 0; i < allNodes.length; i++){
    	oNode = allNodes[i];
        if(!oNode)continue;    	
		if(oNode == this.sContainer) flag = true;
		if(!flag) continue;
		
		if(oNode.nodeType == 1){
			if(oNode.nodeName == 'P') {
				this.log("lineTestIE() 1-1 ");
				oNode.style.lineHeight = value;	
			}else if(oNode.childNodes) {
				this.log("lineTestIE() 1-2 ");
				this.setLine(this.getFirstNode(oNode), this.getLastNode(oNode));
				oNode.parentNode.style.lineHeight = "2.0";
				if(this.getFirstNode(this.sContainer)){	//SCPE가 p태그일 경우에는 null을 반환 그렇지 않을 경우 노드를 반환
					this.setLine(this.getFirstNode(this.sContainer), this.getLastNode(this.sContainer));	//시작 컨테이너가 있는 라인을 p태그로 감싼다
					this.sContainer = this.sContainer.parentNode;	// 시작 컨테이너를 감싼 p태그를 변수 SCPE에 대입
				}
			}
		}else if(oNode.nodeType == 3){
			this.log("lineTestIE() 3 ");
			this.setLine(this.getFirstNode(oNode), this.getLastNode(oNode), value);
		}
		if(oNode == this.eContainer) {
			this.log("lineTestIE() 4 ");
			break;
		}
	}	
}

EditorManager.prototype.getParagraph = function(){
	this.getSelection();
	this.getRangeProperties();
	var oCommonAncestorContainer = this.oRange.commonAncestorContainer;
	var parentContainer = oCommonAncestorContainer;
	while(parentContainer.nodeName!='BODY' && parentContainer.parentNode && parentContainer.parentNode.nodeName!='BODY'){
		parentContainer = parentContainer.parentNode;
		if(parentContainer.nodeName=='P') break;
	}
	
	var fNode = null;
	var lNode = null;
	
	if(parentContainer.nodeName == 'P'){
		this.oSelection.selectAllChildren(parentContainer);
	}else if(parentContainer.nodeName == 'BODY'){
		var sNode = this.getStartNode();
		var eNode = this.getEndNode();

		while(sNode.nodeName!='BODY' && sNode.parentNode && sNode.parentNode.nodeName!='BODY'){
			sNode = sNode.parentNode;
			if(sNode.nodeName=='P') break;
		}
		while(eNode.nodeName!='BODY' && eNode.parentNode && eNode.parentNode.nodeName!='BODY'){
			eNode = eNode.parentNode;
			if(eNode.nodeName=='P') break;
		}		
		
		fNode = this.getFirstNode(sNode);
		lNode = this.getLastNode(eNode);
		
		if(fNode==null) fNode = sNode;
		if(lNode==null) lNode = eNode;		
		
		this.getParagraphExpand(fNode, lNode);
	}else{
		fNode = this.getFirstNode(parentContainer);
		lNode = this.getLastNode(parentContainer);
		
		this.getParagraphExpand(fNode, lNode);		
	}
}

EditorManager.prototype.getParagraphIE = function(){
	this.getSelection();
	var commonContainer = this.oRange.parentElement();
	var parentContainer = commonContainer;
	while(parentContainer.nodeName!='BODY' && parentContainer.parentNode && parentContainer.parentNode.nodeName!='BODY'){
		parentContainer = parentContainer.parentNode;
		if(parentContainer.nodeName=='P') break;
	}
	
	var fNode = null;
	var lNode = null;
	
	if(parentContainer.nodeName == 'P'){
		this.oRange.moveToElementText(parentContainer);
		this.oRange.select();
	}else if(parentContainer.nodeName == 'BODY'){
		this.getsOffset();
		this.geteOffset();
		var sNode = this.sContainer;
		var eNode = this.eContainer;
		
		if(this.oRange.text.length==0) sNode = eNode;

		while(sNode.nodeName!='BODY' && sNode.parentNode && sNode.parentNode.nodeName!='BODY'){
			sNode = sNode.parentNode;
			if(sNode.nodeName=='P') break;
		}
		while(eNode.nodeName!='BODY' && eNode.parentNode && eNode.parentNode.nodeName!='BODY'){
			eNode = eNode.parentNode;
			if(eNode.nodeName=='P') break;
		}
		
		fNode = this.getFirstNode(sNode);
		lNode = this.getLastNode(eNode);

		if(fNode==null) fNode = sNode;
		if(lNode==null) lNode = eNode;

		this.getParagraphExpandIE(fNode, lNode);
	}else{
		fNode = this.getFirstNode(parentContainer);
		lNode = this.getLastNode(parentContainer);
		
		this.getParagraphExpandIE(fNode, lNode);
	}
}

EditorManager.prototype.getParagraphExpand = function(fNode, lNode){
	this.log("fNode : "+fNode.nodeName + ", "+fNode.nodeValue+", "+fNode.nodeType);
	this.log("lNode : "+lNode.nodeName + ", "+lNode.nodeValue+", "+lNode.nodeType);
	
	var beforeNode = null;
	var afterNode = null;
	if(fNode && fNode.nodeType==3){
		beforeNode = this.oDoc.createElement("<span>");
		fNode.parentNode.insertBefore(beforeNode,fNode);
	}
	if(lNode && lNode.nodeType==3){
		afterNode = this.oDoc.createElement("<span>");
		lNode.parentNode.insertBefore(afterNode,lNode.nextSibling);
	}

	if(fNode && fNode.nodeType==3)this.oRange.setStartBefore(beforeNode);
	else this.oRange.setStartBefore(fNode);
	if(lNode && lNode.nodeType==3) this.oRange.setEndAfter(afterNode);
	else this.oRange.setEndAfter(lNode);
	
	this.log(this.getHTML());
	this.log(this.getHTML());
	
	if(fNode && fNode.nodeType==3) fNode.parentNode.removeChild(beforeNode);
	if(lNode && lNode.nodeType==3) lNode.parentNode.removeChild(afterNode);	
}

EditorManager.prototype.getParagraphExpandIE = function(fNode, lNode){
	this.log("fNode : "+fNode.nodeName + ", "+fNode.nodeValue+", "+fNode.nodeType);
	this.log("lNode : "+lNode.nodeName + ", "+lNode.nodeValue+", "+lNode.nodeType);	
	var beforeNodeRange = this.oDoc.body.createTextRange();
	var afterNodeRange = this.oDoc.body.createTextRange();
	var beforeNode = null;
	var afterNode = null;
	if(fNode && fNode!=null && fNode.nodeType==3){
		beforeNode = this.oDoc.createElement("<span>");
		fNode.parentNode.insertBefore(beforeNode,fNode);
	}
	if(lNode && lNode!=null && lNode.nodeType==3){
		afterNode = this.oDoc.createElement("<span>");
		lNode.parentNode.insertBefore(afterNode,lNode.nextSibling);
	}
	if(fNode && fNode.nodeType==3) beforeNodeRange.moveToElementText(beforeNode); 
	else beforeNodeRange.moveToElementText(fNode);
	if(lNode && lNode!=null && lNode.nodeType==3) afterNodeRange.moveToElementText(afterNode);
	else afterNodeRange.moveToElementText(lNode);
	this.oRange.setEndPoint('StartToStart', beforeNodeRange);
	this.oRange.setEndPoint('EndToEnd', afterNodeRange);
	if(fNode && fNode!=null && fNode.nodeType==3) fNode.parentNode.removeChild(beforeNode);
	if(lNode && lNode!=null && lNode.nodeType==3) lNode.parentNode.removeChild(afterNode);
	this.oRange.select();
}


/**
 * 파라미터 값으로 받은 노드가 있는 문단에서 제일 앞쪽에 있는 노드를 구합니다.
 * 
 * @param node : 형제 노드 - object
 * @return 입력 받은 노드가 p태그일 경우 null을 반환, 그렇지 않을 경우 문단에 제일 앞쪽 노드를 반환 합니다.
 */
EditorManager.prototype.getFirstNode = function(node) {
	var sibling = node;
	if(sibling.nodeName != 'P'){
		while(sibling.previousSibling != null){	//가장 첫번째 노드의 이전 노드를 구하면 null을 반환 한다.
			if(sibling.previousSibling.nodeName == 'P'){
				break;
			}
			sibling = sibling.previousSibling;
		}
		return sibling;
	}else{
		return null;
	}
}
/**
 * 파라미터 값으로 받은 노드가 있는 문단에서 제일 뒤쪽에 있는 노드를 구합니다.
 * 
 * @param node : 형제 노드 - object
 * @return 입력 받은 노드가 p태그일 경우 null을 반환, 그렇지 않을 경우 문단에 제일 뒤쪽 노드를 반환 합니다.
 */
EditorManager.prototype.getLastNode = function(node) {
	var sibling = node;
	if(sibling.nodeName != 'P'){
		while(sibling.nextSibling){
			if(sibling.nextSibling.nodeName == 'P'){
				break;
			}
			sibling = sibling.nextSibling;
		}
		return sibling;
	}else{
		return null;
	}
}
/**
 * firstNode와 lastNode가 있는 문단에 줄 간격을 변경 합니다.
 * @param firstNode : 문단에 첫번째 노드 - object or null
 * @param lastNode : 문단에 마지막 노드 - object or null
 */
EditorManager.prototype.setLine = function(firstNode, lastNode, value) {
	this.log("setLine");
	if(firstNode && firstNode.parentNode.nodeName == 'BODY'){
		this.log("setLine1");	
		var newNode = this.oDoc.createElement('P');
		newNode.style.cssText = 'line-height:2.0;';
		var sibling = firstNode;
		this.oDoc.body.insertBefore(newNode, firstNode);
		newNode.appendChild(sibling);
		
		while(sibling != lastNode){						
			sibling = newNode.nextSibling;
			newNode.appendChild(sibling);
		}
	}else{
		this.log("setLine2");
		var sibling = firstNode.parentNode;
		var newNode = this.oDoc.createElement('DIV');
		this.oDoc.body.insertBefore(newNode, sibling);
		newNode.appendChild(sibling);
		
		while(sibling != lastNode){						
			sibling = newNode.nextSibling;
			newNode.appendChild(sibling);
		}
		var childes = newNode.getElementsByTagName("P");
		//var childes = newNode.all.tags('P')
		for(var i=0; i<childes.length; i++){
			childes[i].removeAttribute('style');
		}
	}
}
/**
 * 선택된 문자열의 첫번째 노드가 포함 되어 있는 문단 부터 마지막 노드가 포함 되어 있는 문단까지 줄 간격을 변경 합니다.
 * @param SCPE : 첫번째 노드에 부모 노드 - object
 * @param ECPE : 마지막 노드에 부모 노드 - object
 * @param height : 줄 간격 설정 값
 */
EditorManager.prototype.lineHeightRoop = function(SCPE, ECPE, height) {
	var nodeList = this.oDoc.body.childNodes;
	var startFlag = false;
	var endFlag = true;
	for(var i=0; i<nodeList.length; i++){
		if(nodeList[i] == SCPE){
			nodeList[i].style.lineHeight = height;
			startFlag = true;
			if(SCPE == ECPE){
				endFlag = false;
				break;
			}
		}else if(nodeList[i] == ECPE){
			nodeList[i].style.lineHeight = height;
			endFlag = false;
			break;
		}else if(startFlag){
			if(nodeList[i].nodeName == 'P'){
				nodeList[i].style.lineHeight = height;
			}else{
				this.setLine(this.getFirstNode(nodeList[i]), this.getLastNode(nodeList[i]), height);
				if(SCPE.parentNode.nodeName != 'BODY') SCPE = SCPE.parentNode;
				break;
			}
		}
	}
	if(endFlag)this.lineHeightRoop(SCPE, ECPE, height);
}
/**
 * 에디터 창에 표를 삽입 합니다.
 * @param name : 표를 삽입할 위치를 나타내주는 문자열 - String
 * */
EditorManager.prototype.addTable = function(name) {
	var row = document.getElementById(this.textareaID+'_row');
	var col = document.getElementById(this.textareaID+'_col');
	var border = document.getElementById(this.textareaID+'_border');
	var rows = row.value;
	var cols = col.value;
	var borders = border.value;
	if(!(rows.length > 0) || !(cols.length > 0) || !(borders.length > 0)){
		row.value = 3;
		col.value = 4;
		border.value = 1;
		this.resetTable();
		return;	
	}
	if(isNaN(rows) || isNaN(cols) || isNaN(borders)){
		row.value = 3;
		col.value = 4;
		border.value = 1;
		this.resetTable();
		return;	
	}
	if(parseInt(rows) <= 0 || parseInt(cols) <= 0 || parseInt(borders) <= 0){
		alert('최소 1까지 지정할 수 있습니다.');
		row.value = 3;
		col.value = 4;
		border.value = 1;
		this.resetTable();
		return;	
	}
	if(parseInt(rows)>20 || parseInt(cols) >20){
		alert('행과 열은 최대 20까지 지정할 수 있습니다.');
		row.value = 3;
		col.value = 4;
		border.value = 1;
		this.resetTable();
		return;	
	}
	if(parseInt(borders) >10){
		alert('선 굵기는 10이하만 가능 합니다.');
		border.value = 1;
		this.resetTable();
		return;
	}
	var table = '<table border="0" width="100%"  bgColor="#b7bbb5" style="height:95%;border-collapse:separate;" cellpadding="0" cellspacing="'+parseInt(borders)+'">';
	for(var i=0; i<parseInt(rows); i++){
		table += '<tr bgColor="#ffffff">';
		for(var k = 0; k<parseInt(cols); k++){
			table += ' <td width="'+100/parseInt(cols)+'%"></td>';
		}
		table += '</tr>';
	}
	table += '</table><br>';
	/**
	 *팝업창에 그리는 테이블과 iframe에 그리는 테이블은 같은 메서드를 사용 하기 때문에 테이블을 삽입 할 곳을 나눕니다. 
	 */
	if(name == 'onblur'){
		document.getElementById(this.textareaID+'_tablePreview').innerHTML = table;
		return;
	}else{
		this.pasteHTML(table);
	}
	this.popupID = null;
	this.hidePopup();
	this.resetTable('cancel');
}
/**
 * 테이블 팝업에 그려져 있는 표를 기본 모양으로 변경 하는 역활을 합니다.
 */
EditorManager.prototype.resetTable = function(str) {
	var row = document.getElementById(this.textareaID+'_row').value=3;
	var col = document.getElementById(this.textareaID+'_col').value=4;
	var border = document.getElementById(this.textareaID+'_border').value=1;
	this.addTable('onblur');
	if(str == 'cancel'){
		this.popupID = null;
		this.hidePopup();
	}
}
/**
 * 문자열에 링크를 걸어주는 역활을 합니다.
 * @param id : 주소를 입력한 링크 팝업 textfield에 id - String
 */
EditorManager.prototype.createLink = function(id) {
	/**
	 * IE에서 팝업창에 포커스가 이동하면 Range를 잊어 버리기 때문에  this.oRangeClone에 저장을 한다 여기서는 저장한 range에 다시 select를 줍니다.
	 */
	if(this.oRangeClone.select){
		this.oRangeClone.select();
	}
	var html = this.getHTML();	
	var obj = document.getElementById(this.textareaID+id);
	var sLink = obj.value;
	if(!(/^(http|https|ftp|mailto):(?:\/\/)?((\w|-)+(?:[\.:@](\w|-))+)(?:\/|@)?([^"\?]*?)(?:\?([^\?"]*?))?$/.test(sLink))){
		alert("입력하신 URL이 올바르지 않습니다.");
		obj.value = 'http://';
		obj.focus();
		return;
	}
	if(html == ''){
		this.pasteHTML('<a href="'+sLink+'">'+sLink+'</a>');	
	}else{	
		this.command("CreateLink",sLink);	
	}	
	obj.value = 'http://';
	this.popupID = null;
	this.hidePopup();
}
/**
 * 에디터 창에 인용구를 삽입 합니다.
 * @param num : 선택한 인용구 번호 - String
 */
EditorManager.prototype.quote = function(num){
	var nu = navigator.userAgent;
	var defaultValue = '<br/>';
	if(/MSIE/.test(nu)) defaultValue = '<p></p>';
	var html = this.getHTML() || defaultValue;
	
	var str = '<p></p><blockquote class="quote0'+num+'">'+html+'</blockquote><p></p>';
	this.pasteHTML(str);
}
/**
 * 에디터 창에 크기를 변경 합니다.
 * 
 */
EditorManager.prototype.expansion = function(){
	if(this.size=="DEFAULT"){
		this.oEditon.style.zIndex = 999;
		this.oEditon.style.position = "absolute";
		this.oEditon.style.top = "0";
		this.oEditon.style.left = "0";
		var curW = document.body.clientWidth || document.documentElement.clientWidth;
		var curH = document.body.clientHeight || document.documentElement.clientHeight;
		this.oEditon.style.width = curW+"px"; 
		this.oWysiwyg.style.width = "100%";
		this.oWysiwyg.style.height = curH+"px";
		this.oText.style.width = "100%";
		this.oText.style.height = curH+"px";		
		this.size = "MAX";
		this.log("[SIZE : MAX], [CLIENT WIDTH : "+curW+"], [CLIENT HEIGHT : "+curH+"]","info");
	}else{
		this.oEditon.style.zIndex = 0;
		this.oEditon.style.position = "";
		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.size = "DEFAULT";
		this.log("[SIZE : DEFAULT], [CLIENT WIDTH : "+this.editOnWidth+"], [CLIENT HEIGHT : "+this.editOnHeight+"]","info");
	}
}
/**
 * 디버그 창을 생성합니다.
 */
EditorManager.prototype.debug = function(){
	var divObj = document.createElement("div");
	divObj.setAttribute('id', this.textareaID+'_DebugDiv');
	divObj.style.cssText = 'border:2px solid #000; width:800px; height:200px; text-align:left; font-size:10pt;';
	divObj.style.overflowY = 'scroll';
	document.body.insertBefore(divObj, document.body.lastChild.nextSibling);
}
/**
 * 디버그 창에 파라미터로 받은 값을 보여 줍니다.
 * @param str : 디버그 창에 찍어 주고 싶은 값 또는 문자열 - String 
 */
EditorManager.prototype.log = function(str, level){
	var debug = document.getElementById(this.textareaID+ '_DebugDiv');
	if(!level) level = "debug";
	var date2 = new Date();
	if(debug){
		switch(level)
		{
		case "debug" :
			debug.innerHTML += "<span style='color:#000;'>[DEBUG]</span> <span style='color:#444;'><"+date2. toLocaleString()+"></span>"+" <span>"+str+"</span>"+"<br>";
			debug.scrollTop = debug.scrollTop +27;
			break;
		case "info" :
			debug.innerHTML += "<span style='color:#3058d2;'>[INFO]</span> <span style='color:#444;'><"+date2. toLocaleString()+"></span>"+" <span>"+str+"</span>"+"<br>";
			debug.scrollTop = debug.scrollTop +27;
			break;
		case "error" :
			debug.innerHTML += "<span style='color:#c84205;'>[ERROR]</span> <span style='color:#444;'><"+date2. toLocaleString()+"></span>"+" <span>"+str+"</span>"+"<br>";
			debug.scrollTop = debug.scrollTop +27;
			break;
		default : 
			break;
		}
	}
}
