//http://www.maconstateit.net/tutorials/JSDHTML/JSDHTML12/jsdhtml12-02.htm

function xbDesignMode(aIFrame){
  this.mEditorDocument = null;
  this.mIFrameElement = null;
  // argument is a string, therefore an ID
  if ( (typeof(aIFrame) == "string") && (document.getElementById(aIFrame).tagName.toLowerCase()=="iframe") ){
	this.mIFrameElement = document.getElementById(aIFrame);
  } else if( (typeof(aIFrame)=="object") && (aIFrame.tagName.toLowerCase() == "iframe") ){
	this.mIFrameElement = aIFrame;   
  } else {
	throw "Argument isn't an id of an iframe or an iframe reference";
  }

  if (this.mIFrameElement.contentDocument){  
	// Gecko
	this.mEditorDocument = this.mIFrameElement.contentDocument;
	this.mEditorDocument.designMode = "On";    
  } else {
	// IE
	this.mEditorDocument = this.mIFrameElement.contentWindow.document;
	this.mEditorDocument.designMode = "On";   
	// IE needs to reget the document element after designMode was set 
	this.mEditorDocument = this.mIFrameElement.contentWindow.document;
  }
}

xbDesignMode.prototype.execCommand = function (aCommandName, aParam){
  if (this.mEditorDocument)
	this.mEditorDocument.execCommand(aCommandName, false, aParam);
  else 
	throw "no mEditorDocument found";
}

xbDesignMode.prototype.getSel = function()
{
	var fA = null;
	var fB = null;
	try { fA = (this.mIFrameElement.contentWindow) ? this.mIFrameElement.contentWindow.getSelection() : this.mIFrameElement.contentWindow.selection; } catch (ex) {}
	try { fB = (window.getSelection) ? window.getSelection() : this.mIFrameElement.contentWindow.document.selection } catch (ex) {}
	return fA ? fA : fB;
}

xbDesignMode.prototype.getIESelPosition = function(textRange)
{
	var element = textRange.parentElement();
	var range = element.ownerDocument.body.createTextRange();
	range.moveToElementText(element);
	range.setEndPoint("EndToStart", textRange);
	var rangeLength = range.text.length;
	// Choose Direction
	if(rangeLength < element.innerText.length / 2) {
		var direction = 1;
		var node = element.firstChild;
	}
	else {
		direction = -1;
		node = element.lastChild;
		range.moveToElementText(element);
		range.setEndPoint("StartToStart", textRange);
		rangeLength = range.text.length;
	}
	// Loop through child nodes
	while(node) {
		switch(node.nodeType) {
			case 3:
				nodeLength = node.data.length;
				if(nodeLength < rangeLength) {
					var difference = rangeLength - nodeLength;
					if(direction == 1) range.moveStart("character", difference);
					else range.moveEnd("character", -difference);
					rangeLength = difference;
				}
				else {
					if(direction == 1) return {node: node, offset: rangeLength};
					else return {node: node, offset: nodeLength - rangeLength};
				}
				break;

			case 1:
				nodeLength = node.innerText.length;
				if(direction == 1) range.moveStart("character", nodeLength);
				else range.moveEnd("character", -nodeLength);
				rangeLength = rangeLength - nodeLength;
				break;
		}
		if(direction == 1) node = node.nextSibling;
		else node = node.previousSibling;
	}

	return {node: element, offset: 0};
}

xbDesignMode.prototype.getDoc = function()
{
	return this.mEditorDocument;
}

xbDesignMode.prototype.getNodeAtSelection = function() {
	var sel = this.getSel();
	var position;
	var container;
	var pos;
	var range;
	

	
	var selectedObject = null;
	
	if ((navigator.userAgent.indexOf("Firefox") == -1) && (!!window.opera) && (navigator.userAgent.indexOf("Chrome") == -1))
	{
		var iesel = sel.createRange();
		try {
		//iesel.pasteHTML('');//This is incorrect, it might also delete the container		
		iesel.collapse(true);
		position = this.getIESelPosition(iesel);
		container = position.node;
		selectedNode = container;
		pos = position.offset;
		sel.empty();
		} catch (ex) {}
	}
	else
	{
		var range = sel.getRangeAt(0);
		
		//sel.removeAllRanges();
		//range.deleteContents();
		container = range.startContainer;
		
		if (range.collapsed||range.startContainer.childNodes.length==0) {
			selectedObject=sel.focusNode
		}
		else
		{
			selectedObject=range.startContainer.childNodes[range.startOffset]
		}
		
		var pos = range.startOffset;
		range=document.createRange();
		
	}
	
	//alert(selectedObject);
	return selectedObject;
}

xbDesignMode.prototype.getSelection = function() {
var sel = this.getSel();
	var position;
	var container;
	var pos;
	var range;



	var selectedObject = null;

	if ((navigator.userAgent.indexOf("Firefox") == -1) && (!!window.opera) && (navigator.userAgent.indexOf("Chrome") == -1))
	{
		var iesel = sel.createRange();
		try {
		//iesel.pasteHTML('');//This is incorrect, it might also delete the container		
		iesel.collapse(true);
		position = this.getIESelPosition(iesel);
		container = position.node;
		selectedNode = container;
		pos = position.offset;
		sel.empty();
		} catch (ex) {}
	}
	else
	{
		var range = sel.getRangeAt(0);

		//sel.removeAllRanges();
		//range.deleteContents();
		container = range.startContainer;

		if (range.collapsed||range.startContainer.childNodes.length==0) {
			selectedObject=sel.focusNode
		}
		else
		{
			selectedObject=range.startContainer.childNodes[range.startOffset]
		}

		//var pos = range.startOffset;
		//range=document.createRange();

	}

	//alert(selectedObject);
	return range;
}

xbDesignMode.prototype.insertNodeAtSelection = function(insertNode) {
		// get current selection
		//myDesignMode.mIFrameElement.contentWindow
		var sel = this.getSel();
		var position;
		var container;
		var pos;
		var range;

		if ((navigator.userAgent.indexOf("Firefox") == -1) || (!!window.opera))
		{
			var iesel = sel.createRange();
			try {
			iesel.pasteHTML('');//This is incorrect, it might also delete the container		
			iesel.collapse(true);
			position = this.getIESelPosition(iesel);
			container = position.node;
			pos = position.offset;
			sel.empty();
			} catch (ex) {}
		}
		else
		{
			var range = sel.getRangeAt(0);
			sel.removeAllRanges();
			range.deleteContents();
			container = range.startContainer;
			var pos = range.startOffset;
			range=document.createRange();
		}

		if (!container) return false;

		if (container.nodeType==3 && insertNode.nodeType==3) {

			// if we insert text in a textnode, do optimized insertion
			container.insertData(pos, insertNode.nodeValue);

			// put cursor after inserted text
			//range.setEnd(container, pos+insertNode.length);
			//range.setStart(container, pos+insertNode.length);

		}
		else
		{
			var afterNode;

			if (container.nodeType==3) {

			  // when inserting into a textnode
			  // we create 2 new textnodes
			  // and put the insertNode in between

			  var textNode = container;
			  container = textNode.parentNode;
			  var text = textNode.nodeValue;

			  // text before the split
			  var textBefore = text.substr(0,pos);
			  // text after the split
			  var textAfter = text.substr(pos);

			  var beforeNode = this.getDoc().createTextNode(textBefore);
			  afterNode = this.getDoc().createTextNode(textAfter);

			  // insert the 3 new nodes before the old one
			  container.insertBefore(afterNode, textNode);
			  container.insertBefore(insertNode, afterNode);
			  container.insertBefore(beforeNode, insertNode);

			  // remove the old node
			  container.removeChild(textNode);

			} else {
			  afterNode = container.childNodes[pos];
			  container.insertBefore(insertNode, afterNode);
			}

			//range.setEnd(afterNode, 0);
			//range.setStart(afterNode, 0);
		}

		//sel.addRange(iesel);

	////update properties
	//this.endContainer = this.startContainer;
	//this.endOffset = this.startOffset;
	//this._commonAncestorContainer();
	//this._collapsed();

	return;
}

/*

*/

function lwie( tag_id )
{
	lwie.prototype.HasClassName = function(objElement, strClass) {
		if ( objElement == null ) return false;
		if ( objElement.className ) {
			var arrList = objElement.className.split(' ');
			var strClassUpper = strClass.toUpperCase();
			for ( var i = 0; i < arrList.length; i++ ) if ( arrList[i].toUpperCase() == strClassUpper ) return true;
		}
		return false;
	}

	lwie.prototype.AddClassName = function (objElement, strClass, blnMayAlreadyExist) {
		if ( objElement.className ) {
			var arrList = objElement.className.split(' ');
			if ( blnMayAlreadyExist ) {
				var strClassUpper = strClass.toUpperCase();
				for ( var i = 0; i < arrList.length; i++ ) {
					if ( arrList[i].toUpperCase() == strClassUpper ) {
						arrList.splice(i, 1);
						i--;
					}
				}
			}
			arrList[arrList.length] = strClass;
			objElement.className = arrList.join(' ');
		}
		else
		{
			objElement.className = strClass;
		}
	}

	lwie.prototype.RemoveClassName = function(objElement, strClass) {
		if ( objElement.className ) {
			var arrList = objElement.className.split(' ');
			var strClassUpper = strClass.toUpperCase();
			for ( var i = 0; i < arrList.length; i++ ) {
				if ( arrList[i].toUpperCase() == strClassUpper ) {
					arrList.splice(i, 1);
					i--;
				}
			}
			objElement.className = arrList.join(' ');
		}
	}

	var myD = document.getElementById( tag_id );
	
	if (myD)
	{
		var myDP = myD.parentNode;
		if (this.HasClassName( myD, 'edit_class' ) == true) return false;
	
		this.inline_editor = null;
		this.tag_id = tag_id;
	
		lwie.instances[tag_id] = this;
	}
}

lwie.instances = Array();
lwie.current_instance = null;

lwie.getInstance = function( tag_id ) {
	if (lwie.instances[tag_id] != undefined)
	{
		return lwie.instances[tag_id];
	}
	return new lwie( tag_id );
}

lwie.getCurrentInstance = function() {
	if (lwie.current_instance == null) return false;
	return lwie.current_instance;
}

lwie.execCommand = function (aCommandName, aParam)
{
	var active_editor = lwie.getCurrentInstance();
	if (active_editor) {
		var design_editor = active_editor.designEditor();
		if (design_editor != false) {
			design_editor.execCommand(aCommandName, aParam);
		}
	}
}

lwie.getSelectedNode = function() {
	var active_editor = lwie.getCurrentInstance();
	if (active_editor) {
		var design_editor = active_editor.designEditor();
		if (design_editor != false) {
			return design_editor.getNodeAtSelection();
		}
	}
	return null;
}

lwie.updateHeight = function (aCommandName, aParam)
{
	var active_editor = lwie.getCurrentInstance();
	if (active_editor) {
		active_editor.updateHeight();
	}
}

lwie.destroyInstance = function( tag_id ) {
	// will destroy and clear everything
}

lwie.prototype.getContent = function() {
	var inner_html_code = this.inline_editor.mEditorDocument.getElementById( this.tag_id ).innerHTML;
	var html_code = new String(inner_html_code);
	html_code = html_code.replace(/<br>/g,"<br />");
	return html_code;
}

lwie.prototype.setContent = function(sSTR_html) {
	this.inline_editor.mEditorDocument.getElementById( this.tag_id ).innerHTML = sSTR_html;	
	//this.inline_editor.mEditorDocument.body.innerHTML = sSTR_html;
	//alert(this.inline_editor.mEditorDocument.body.innerHTML);
	//lwie_content
}

lwie.prototype.getInstance = function() {
	return this.inline_editor;
}

lwie.prototype.updateHeight = function ( ) {
	var ie = this.inline_editor;
	var updateHeight = ie.mEditorDocument.body.offsetHeight;
	ie.mIFrameElement.style.height = updateHeight + 'px';
}

lwie.prototype.enableEditor = function ( ) {
	var myD = document.getElementById( this.tag_id );
	var myDP = null;
	var myDPP = null;
	if (myD)
	{
		myDP = myD.parentNode;
	}
	
	var myDP_Display = '';
	if (myDP != null)
	{
		myDP_Display = myDP.style.display;
		myDP.style.display = 'block';
		myDPP = myDP.parentNode;
	}
	
	var myDPP_Display = '';
	if (myDPP != null)
	{
		myDPP_Display = myDPP.style.display;
		myDPP.style.display = 'block';
	}

	if (this.inline_editor != null) return false;
	if (this.HasClassName( myD, 'edit_class' ) == true) return false;

	// Como verificar se já possue editor? hmm
	this.AddClassName( myD, 'edit_class' );

	//'marginTop': 'margin-top', 'marginBottom' : 'margin-bottom', 'marginLeft': 'margin-left', 'marginRight': 'margin-right', 'paddingTop': 'padding-top', 'paddingBottom': 'padding-bottom', 'paddingLeft': 'padding-left', 'paddingRight': 'padding-right', 'float':'float', 'clear':'clear'

	var styleList = {'fontSize' : 'font-size', 'fontFamily' : 'font-family', 'fontWeight' : 'font-weight', 'color' : 'color', 'lineHeight': 'line-height', 'textAlign' : 'text-align', 'background':'background', 'backgroundImage':'background-image', 'backgroundColor':'background-color' };
	var savedStyles = Array();
	for(itm in styleList) savedStyles[itm] = this.getStyle(myD,styleList[itm]);
	
	//var styleList_iFrame = { 'marginTop': 'margin-top', 'marginBottom' : 'margin-bottom', 'marginLeft': 'margin-left', 'marginRight': 'margin-right', 'paddingTop': 'padding-top', 'paddingBottom': 'padding-bottom', 'paddingLeft': 'padding-left', 'paddingRight': 'padding-right', 'float':'float', 'clear':'clear'  };

	var myDHei = myD.offsetHeight;

	var elmFrame = document.createElement("iframe");
	elmFrame.frameBorder = '0';
	elmFrame.allowTransparency = true;
	elmFrame.scrolling = 'no';
	elmFrame.style.height = myDHei + 'px';
	elmFrame.style.width = '100%';

	var initialContent = myD.innerHTML;
	myD.innerHTML = '';
	myD.appendChild(elmFrame);

	this.inline_editor = new xbDesignMode(elmFrame);
	var ie = this.inline_editor;
	try { ie.execCommand("styleWithCSS", true) } catch (ex) {}
	try { ie.execCommand("useCSS", true) } catch (ex) {}

	ie.mEditorDocument.open();
	ie.mEditorDocument.write('<html><head></head><body class="cbf" id="' + myD.id + '" style="margin: 0 !important; background-color: transparent !important;">'+initialContent+'</body></html>');
	ie.mEditorDocument.close();
	
	var this_object = this;
	
	// TODO (STYLE IMPORT)
	var oS=null;

	if (ie.mEditorDocument.createStyleSheet) {
		oS=ie.mEditorDocument.createStyleSheet('/layout/estilo.css');
	}
	else
	{
		oS=ie.mEditorDocument.createElement("STYLE");
		oS.type="text/css";
		txt=ie.mEditorDocument.createTextNode( "@import url(/layout/estilo.css);" );
		oS.appendChild(txt);
		ie.mEditorDocument.getElementsByTagName("head")[0].appendChild(oS);
	}
	
	for(var itm in savedStyles) ie.mEditorDocument.body.style[itm] = savedStyles[itm];

	if (ie.mEditorDocument.addEventListener)
	{
		ie.mEditorDocument.addEventListener('keyup', function() {
			var updateHeight = ie.mEditorDocument.body.offsetHeight;
			elmFrame.style.height = updateHeight + 'px';
		},true);

		ie.mEditorDocument.addEventListener('focus', function() {
			if (lwie.current_instance != this_object) lwie.current_instance = this_object;
		},true);
		
		ie.mEditorDocument.addEventListener('mousemove', function() {
			var updateHeight = ie.mEditorDocument.body.offsetHeight;
			elmFrame.style.height = updateHeight + 'px';
		},true);
	}
	else
	{
		ie.mEditorDocument.attachEvent('onkeyup', function()
		{
			//var updateHeight = myDesignMode.mEditorDocument.body.offsetHeight;
			//elmFrame.style.height = updateHeight + 'px';
		});

		ie.mEditorDocument.attachEvent('onclick', function()
		{
			var updateHeight = ie.mEditorDocument.body.offsetHeight;
			elmFrame.style.height = updateHeight + 'px';
			if (lwie.current_instance != this_object) lwie.current_instance = this_object;
			return false;
		});
	}
	
	if (myDP != null)
	{
		myDP.style.display = myDP_Display;
	}
	if (myDPP != null)
	{
		myDPP.style.display = myDPP_Display;
	}
}

lwie.prototype.disableEditor = function () {
	if (this.inline_editor == null) return;
	var myD = document.getElementById( this.tag_id );
	this.RemoveClassName( myD, 'edit_class' );
	myD.innerHTML = this.getContent();
	this.inline_editor = null;
}

lwie.prototype.getStyle = function(oElm, strCssRule) {
	var strValue = "";
	if(document.defaultView && document.defaultView.getComputedStyle){
		strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
	}
	else if(oElm.currentStyle){
		strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1) { return p1.toUpperCase(); });
		strValue = oElm.currentStyle[strCssRule];
	}
	return strValue;
}

lwie.prototype.designEditor = function() {
	return this.inline_editor;
}

lwie.getDocument = function() {
	var active_editor = lwie.getCurrentInstance();
	if (active_editor) {
		var design_editor = active_editor.designEditor();
		if (design_editor != false) {
			return design_editor.getDoc();
		}
	}
	return document;
}

lwie.insertAtSelection = function( obj ) {
	var active_editor = lwie.getCurrentInstance();
	if (active_editor) {
		var design_editor = active_editor.designEditor();
		if (design_editor != false) {
			design_editor.insertNodeAtSelection( obj );
		}
	}
	lwie.updateHeight();
	return obj;
}

lwie.getSelection = function( obj ) {
	var active_editor = lwie.getCurrentInstance();
	if (active_editor) {
		var design_editor = active_editor.designEditor();
		if (design_editor != false) {
			return design_editor.getSelection( obj );
		}
	}
	
}

lwie.doBold = function() {
	lwie.execCommand('bold');
	return false;
}

lwie.doItalic = function() {
	lwie.execCommand('italic');
	return false;
}

lwie.doUnderline = function() {
	lwie.execCommand('underline');
	return false;
}

lwie.doStrikethrough = function() {
	lwie.execCommand('strikethrough');
	return false;
}

lwie.justifyLeft = function() {
		var selectedNode = lwie.getSelectedNode();

		if (selectedNode.tagName == 'IMG') {
			//AddClassName = function (objElement, strClass, blnMayAlreadyExist)
			//alert('img');
			//HasClassName
			var lwie_obj = lwie.getCurrentInstance();
			if (lwie_obj) {
				if (lwie_obj.HasClassName(selectedNode,'left')) {
					lwie_obj.RemoveClassName(selectedNode,'left');
				}
				else {
					lwie_obj.RemoveClassName(selectedNode,'right');
					lwie_obj.AddClassName(selectedNode,'left');
				}
			}
		}
		else
		{
			lwie.execCommand('justifyleft');
		}
	lwie.updateHeight();
	return false;
}

lwie.justifyCenter = function() {
		var selectedNode = lwie.getSelectedNode();

		if (selectedNode.tagName == 'IMG') {
			//AddClassName = function (objElement, strClass, blnMayAlreadyExist)
			//alert('img');
			//HasClassName
			var lwie_obj = lwie.getCurrentInstance();
			if (lwie_obj) {
				lwie_obj.RemoveClassName(selectedNode,'right');
				lwie_obj.RemoveClassName(selectedNode,'left');
			}
		}
		else
		{
			lwie.execCommand('justifycenter');
		}
	lwie.updateHeight();
	return false;
}

lwie.justifyRight = function() {

	var selectedNode = lwie.getSelectedNode();

	if (selectedNode.tagName == 'IMG') {
		//AddClassName = function (objElement, strClass, blnMayAlreadyExist)
		//alert('img');
		//HasClassName
		var lwie_obj = lwie.getCurrentInstance();
		if (lwie_obj) {
			if (lwie_obj.HasClassName(selectedNode,'right')) {
				lwie_obj.RemoveClassName(selectedNode,'right');
			}
			else {
				lwie_obj.RemoveClassName(selectedNode,'left');
				lwie_obj.AddClassName(selectedNode,'right');
			}
		}
	}
	else
	{
		lwie.execCommand('justifyright');
	}
	lwie.updateHeight();
	return false;
}

lwie.justifyFull = function() {
	var selectedNode = lwie.getSelectedNode();

	if (selectedNode.tagName != 'IMG') {
		lwie.execCommand('justifyfull');
	}
	return false;
}

lwie.indentText = function() {
	lwie.execCommand('indent');
	return false;
}

lwie.outdentText = function() {
	lwie.execCommand('outdent');
	return false;
}

lwie.orderedList = function() {
	lwie.execCommand('insertorderedlist');
	return false;
}

lwie.unorderedList = function() {
	lwie.execCommand('insertunorderedlist');
	return false;
}

lwie.removeFormat = function() {
	lwie.execCommand('removeformat');
	var obj = lwie.getSelectedNode();
	if (obj.nodeType == 3) obj = obj.parentNode;
	if (obj.nodeType == 3) obj = obj.parentNode;
	
	var styleList = {'fontSize' : 'font-size', 'fontFamily' : 'font-family', 'fontWeight' : 'font-weight', 'color' : 'color', 'lineHeight': 'line-height', 'textAlign' : 'text-align', 'background':'background', 'backgroundImage':'background-image', 'backgroundColor':'background-color' };
	for(itm in styleList) obj.style[itm] = '';
	
	//obj.className = '';
	
	return false;
}

lwie.doSuperscript = function() {
	lwie.execCommand('superscript');
	return false;
}

lwie.doSubscript = function() {
	lwie.execCommand('subscript');
	return false;
}

lwie.doLink = function(href) {
	var tmp_href = 'javascript:lwie_temporary_href();';
	lwie.execCommand('createlink',tmp_href);
	var list = lwie.getDocument().getElementsByTagName('A');
	for(var i=0;i<list.length;i++) {
		if(list[i].getAttribute('href') == tmp_href) {
			var link_obj = list[i];
			link_obj.href = href;
			return link_obj;
			break;
		}
	}
	return false;
}

lwie.formatStyle = function(tag,style) {
	lwie.removeFormat();
	lwie.execCommand('formatBlock',tag);
	var obj = lwie.getSelectedNode();
	
	if (obj.nodeType == 3)
	{
		obj = obj.parentNode;
	}
	if ((style != '') && (style != undefined))
	{
		obj.className = style;
	}
	return obj;
}

lwie.createTable = function() {
	//lwie.execCommand('insertunorderedlist');
	
	
	var img_obj = lwie.insertAtSelection( lwie.getDocument().createElement('img') );
	img_obj.src = 'http://localhost:8080/layout/imagens/agron-agronegocios-online.jpg';
	
	return false;
}

lwie.insertHR = function() {
	var hr_obj = lwie.insertAtSelection( lwie.getDocument().createElement('div') );
	hr_obj.className = 'hr';
	hr_obj.innerHTML = '<hr />';
	lwie.updateHeight();
	return false;
}
