/**
 * editor.js
 *
 * Editor-Objekt
 *
 * ToDo: - Button-Funktionalit\u00e4ten [ok 24.05.2004]
 *			- Div um gesamten Editor als Container [ok 22.05.2004]
 *			- Funktionalit\u00e4ten wieder herstellen [ok 27.05.2004]
 *			- tabActive ins Objekt integrieren  [ok 20.05.2004]
 *			- Klassen/Prototypen dokumentieren [ok 28.05.2004]
 *       - Popup-Window integrieren [ok 27.05.2004]
 *			- Events auf event-handler-object umschreiben [ok 01.06.2004]
 * 		- renderView() ueberarbeiten [ok 01.06.2004]
 *			- htmlarea einbauen [ok 08.07.2004]
 *				- htmlarea-plugin fuer jTidy-Implementation einbauen
 *			- saveDocument-Methode ausarbeiten [ok 18.08.2004]
 *       - css fuer Editor importieren
 *			- IE-css debuggen
 *			- configuration ueber config.js abwickeln (aber auch standard-config)
 *			- i18n mehrsprachigkeit fuer editoroberflaeche aus htmlarea kopieren
 *			- calendar-Object einbauen
 *			- Ausbau der javascript-session
 *			- Preview-Funktion ausarbeiten
 *			- Error-Handling und Logging durchgehend einbauen
 *       ....
 *
 * @author andi r.
 * @version 20040727
 *
 */
/**
 * config-Objekte uebernehmen
 *
 */

var editorViews = config.editorViews;
var debugFunctions = config.debugFunctions;

function createPopup(x, y, h, w, name, src, content, ifrm, isResizeable)
{
   var min = '/_images/min.gif';
   var max = '/_images/max.gif';
   var close = '/_images/close.gif';
   var resize = '/_images/resize.gif';
   return new popUp(x, y, h, w, name, src, "white", "#FFF3B3", "16pt Arial", content, "#00385c", "white", "lightgrey", "#00568c", "black", false, isResizeable, true, true, ifrm, false, min, max, close, resize);
}

/**
 * erzeugt eine editor-instanz und stellt diese dar
 *
 * @argument xmlfile pfad zum xmlFile
 * @argument xslfile pfad zum xslFile
 * @argument previewFile pad zum Preview-xsl-file
 * @author andi r.
 * @version 20040524
 *
 */

function initEditor(xmlFile, xslFile, previewFile, xmlMasterFile, flag)
{
   try{
      editor = new editor('editor');
      editor.config = config;
      editor.xmlDoc = xmlFile;

      if(flag == 'undefined' || flag == undefined)
      {
      	editor.xmlObj = editor.createXMLObjectFromFile(editor.xmlDoc);
      }
      else
      { 
      	var str = parent.document.getElementById('templateXMLString').value;
      	editor.xmlObj = editor.createXMLObjectFromString(str);
      }
      /* Pfad muss allgemein bleiben fuer Festool und Fein Kapiteleditierung sonst nicht abfragbar */
      editor.pathToUserrights = '//userRights';
      editor.hasUserObject = false;

      // Userrechte in eigenes solseitXMLObject verpacken und aus xmlObj entfernen
      if(editor.xmlObj.checkXPath(editor.pathToUserrights))
      {
         editor.userObject = editor.xmlObj.getXMLObjectByXPath(editor.pathToUserrights);
         editor.xmlObj.removeByXPath(editor.pathToUserrights);
         editor.hasUserObject = true;
      }
      // Ausgelagert aus Konstruktor editor()
		editor.createViews();
		
		// wenn es ein Benutzerobjekt gibt 
		if(editor.hasUserObject)
		{
			//alert(editor.userObject.toString());
			// und der Benutzer das Recht f?r debugXML hat, dann einblenden
			if(editor.userObject.checkXPath('/userRights/roleRights/right[@doctype="javaScriptEditor" and @textRef="debugXML"]'))
			{
            editor.createSubTabs();
			}
		}

      editor.xslDoc = xslFile;
      editor.xslObj = editor.createXMLObjectFromFile(editor.xslDoc);
      // Doctype auf den Name des Root-Elementes des XML-files setzen
      //editor.doctype = doctype;

      if(previewFile && previewFile != '')
      {
         editor.preDoc = previewFile;
         editor.preObj = editor.createXMLObjectFromFile(editor.preDoc);
      }
      editor.xmlMasterFile = xmlMasterFile;

      for(view in editorViews)
      {
			if(editor.hasUserObject)
			{
				// und der Benutzer keine Rechte fuer bestimmte Tabs hat
				// dann werden diese ausgeblendet
				if(editor.userObject.checkXPath('/userRights/roleRights/right[@doctype="javaScriptEditor" and @textRef="' + view + '"]'))
				{
					editor.renderView(view);
					break;
				}
			}
			else if(editorViews[view][1])
         {
            editor.renderView(view);
            break;
         }
      }

      createPopup(100, 100, 640, 480, "DivX", "about:blank", "solseit::editor", true, true);
      createPopup(100, 100, 640, 480, "DivSolseitTextEditor", "about:blank", "solseit::editor", true, true);
      createPopup(100, 100, 640, 480, "DivY", "about:blank", "Debug-Out", false, true, true);
      createPopup(100, 100, 320, 240, "DivSave", "about:blank", "Speichern", true, false);
      createPopup(100, 100, 830, 750, "DivEditTemplates", "about:blank", "solseit::editor", true, true); /*f?r Festool*/
   }
   catch(e)
   {
      alert(e);
   };
   return false;
}
/**
 * public Class editor
 * Baut einen editor und stellt die entsprechenden funktionalit\u00e4ten zur verf\u00fcgung
 *
 * @argument instanceName Name der aus der Klasse erzeugten instanz wird nocheinmal \u00fcbergeben
 * @returns boolean
 * @author andi r.
 * @version 20040524
 *
 */

function editor(instanceName)
{
   this.instanceName = instanceName;
   this.actView = new String();
   /*UI bauen*/
   this.editorContainer = createDiv('editorMainDiv');
   this.tabBar = createDiv('tabs');
   this.editorArea = this.createEditorArea();
   this.editorContainer.appendChild(this.tabBar);
   this.editorContainer.appendChild(this.editorArea);
   this.editorContainer.appendChild(this.createBottomButtons());
   if(document.getElementById('main') != 'undefined')
   {
      document.getElementById('main').appendChild(this.editorContainer)
   }
   else
   {
      document.body.appendChild(this.editorContainer);
   }
   
   this.logObj = this.createLogObj();
   return true;
}
/**
 * private boolean editor.loadDocument
 * laedt ein Dokument vom Server in den Editor
 *
 * @argument path (string) xPath
 * @argument objName (string) Name des Objektes, das im Editor erzeugt werden soll
 * @extends editor
 * @author andi r.
 * @version 20040525
 *
 */
editor.prototype.loadDocument = function(path, objName)
{
   eval("this." + objName + "Doc = '" + path + "';");
   eval("this." + objName + "Obj = this.createXMLObjectFromFile(this." + objName + "Doc)");
   return false;
}
/**
 * package boolean editor.renderView
 * rendert in Abhaengigkeit von dem Namen der View den Output
 *
 * @argument view (string) id der View
 * @extends andi r.
 * @version 20040524
 *
 */
editor.prototype.renderView = function(view)
{
   var t = document.getElementById(view);
   switch(view)
   {
      case 'editView' :
         {
            t.innerHTML = this.xmlObj.xslTransform(this.xslObj);
            break;
         }
      case 'preView' :
         {
            t.innerHTML = this.xmlObj.xslTransform(this.preObj);
            break;
         }
      case 'xmlView' :
         {
            t.innerHTML = this.xmlObj.showInlineTree();
            break;
         }
      case 'xslView' :
         {
            t.innerHTML = this.xslObj.showInlineTree();
            break;
         }
      case 'htmlView' :
         {
            t.innerHTML = this.xmlObj.showInlineHtml(this.xslObj);
            break;
         }
      case 'logView' :
         {
            t.innerHTML = this.logObj.showInlineTree();
         }
      default :
         {
         }
   }
   document.getElementById(view).style.display = 'block';
   return false;
}
/**
 * private htmlElement editor.createEditorArea
 * mittels dom-methoden wird die Editor-Oberflaeche erzeugt
 *
 * @returns (htmlElement) div
 * @version 20040524
 * @author andi r.
 *
 */
editor.prototype.createEditorArea = function()
{
   var Div = createDiv('editorArea');
   return Div;
}
/**
 * private htmlElement editor.createTB
 * Erzeugt das Div, in dem sich die Tabs befinden
 *
 * @returns (HTML-ELEMENT) div
 * @version 20040524
 * @author andi r.
 *
 */
editor.prototype.createTB = function()
{
   var Div = createDiv('tabs');
   return Div;
}
/**
 * private void editor.createViews
 * Erzeugt buttons, mit denen die Ansichten umgeschaltet werden.
 * Gleichzeitig werden die Div-Container f\u00fcr den Content erzeugt.
 *
 * @version 20040601
 * @author andi r.
 *
 */
editor.prototype.createViews = function()
{
   for(var view in editorViews)
   {
	  // Buttons bauen
	  var aHref = document.createElement('a');
	  if(editorViews[view][1])
	  {
	     aHref.className = 'active';
	  }
	  new CJL_RegisterEvent(aHref, "click", function(){showView(event.srcElement.id);});
	
	  aHrefText = document.createTextNode(editorViews[view][0]);
	  aHref.appendChild(aHrefText);
	  aHref.id = view + 'Button';
	  aHref.name = view;
	  aHref.href = 'javascript:void(0);';
	  aHref.title = view;

		// wenn es ein Benutzerobjekt gibt 
		if(editor.hasUserObject)
		{
			// und der Benutzer keine Rechte fuer bestimmte Tabs hat
			// dann werden diese ausgeblendet
			if(!editor.userObject.checkXPath('/userRights/roleRights/right[@doctype="javaScriptEditor" and @textRef="' + view + '"]'))
			{
				aHref.style.display = 'none';
			}
		}

	  this.tabBar.appendChild(aHref);

	  // View-Divs bauen
	  var editDiv = createDiv(view, 'content');
	  var editDivTxt = document.createTextNode(view);
	  editDiv.appendChild(editDivTxt);
	  editDiv.style.display = 'none';
	  this.editorArea.appendChild(editDiv);
   }
}

/**
 * private htmlElement editor.createBottomButtons
 * Erzeugt untere Buttonleiste
 *
 * @returns (HTML-ELEMENT) div
 * @version 20040601
 * @author andi r.
 *
 */
editor.prototype.createBottomButtons = function()
{
   var bT = createDiv('bottomtabs');
   for(button in config.bottomButtons)
   {
   	var aHref = document.createElement('a');
      var aHrefTxt = document.createTextNode(button);
      aHref.appendChild(aHrefTxt);
      aHref.href = 'javascript:void(0);';
      bT.appendChild(aHref);
      new CJL_RegisterEvent(aHref, "click", config.bottomButtons[button][0]);
   }
   return bT;
}
/**
 * private htmlElement editor.createSubTabs
 * Erzeugt testoberflaeche fuer entwickler
 *
 * @returns (HTML-ELEMENT) div
 * @version 20040522
 * @author andi r.
 *
 */
editor.prototype.createSubTabs = function()
{
   var Div = createDiv('subtabs');
   var frm = document.createElement('form');
   frm.name = 'xPathForm';
   frm.id = 'xPathForm';
   var xpi = document.createElement('input');
   xpi.type = 'text';
   xpi.id = 'xPathing';
   xpi.name = 'xPathing';
   xpi.value = '/';
   frm.appendChild(xpi);
   frm.appendChild(this.createDebugSelect());
   frm.appendChild(this.createDebugButton());
   Div.appendChild(frm);
   ea = document.getElementById('editorArea')
   ea.insertBefore(Div, ea.firstChild);
   return true;
}
/**
 * private htmlElement editor.createDebugSelect
 * erzeugt eine Select-Box aus dem Object debugFunctions
 *
 * @returns select (html-element)
 * @author andi r.
 * @version 20040522
 *
 */
editor.prototype.createDebugSelect = function()
{
   var sel = document.createElement('select');
   sel.id = 'xPathCommand';
   sel.name = 'xPathCommand';
   for(var fkt in debugFunctions)
   {
      var opt = document.createElement('option');
      opt.setAttribute('value', fkt);
      var optTxt = document.createTextNode(debugFunctions[fkt][0]);
      opt.appendChild(optTxt);
      sel.appendChild(opt);
   }
   return sel;
}
/**
 * private htmlElement editor.createDebugButton
 * Button, mit dem der XPath-test abgeschickt wird
 *
 * @extends editor
 * @returns input (html-element)
 * @author andi r.
 * @version 20050601
 */
editor.prototype.createDebugButton = function()
{
   var xpb = document.createElement('input');
   xpb.type = 'button';
   xpb.id = 'xPathGo';
   xpb.name = 'xPathGo';
   xpb.value = 'go';
   new CJL_RegisterEvent(xpb, "click", function(){editor.xPathTest(event.srcElement.form);});
   return xpb;
}
/**
 * public void editor.getSelectionPopup
 * Oeffnen eines "Popups" zur auswahl von Textbausteinen etc.
 *
 * @argument ev (html-event) event, der die Funktion ausl\u00f6st
 * @argument xPath (string xPath)
 *
 * @author andi r.
 * @version 20040527
 *
 */
editor.prototype.getSelectionPopup = function(ev, xPath, type)
{
   var pyo;
   var url;
   var myTarget = ev.srcElement;
   var top = 0;
   var left = 0;
   // ermittlung der Position des Eventausl\u00f6senden Elements
   while(myTarget != document.body)
   {
      try
      {
         top += myTarget.offsetTop;
         left += myTarget.offsetLeft;
         myTarget = myTarget.offsetParent;
      }
      catch(e) //Notbremse: bei Volldarstellung im Framework wird der Body nicht gefunden (IE)
      {
         break;
      }
   }
   if((parseInt(document.getElementById('DivX_t').style.width) + left) < document.body.offsetWidth)
   {
      left += ev.srcElement.offsetWidth;
   }
   else
   {
      left -= ev.srcElement.offsetWidth - parseInt(document.getElementById('DivX_t').style.width);
   }
   movePopup('DivX', left, top);
   url = 'auswahl.cfm?xPath='+xPath;
   if(type && type.length)
   {
      url += "&type=" + type;
   }
   changecontent('DivX', url);
   showbox('DivX');
   window.scrollTo(0, top);
   return false;
}
/**
 * public boolean editor.writeBackSelection
 * Uebernimmt einen Wert aus einem Popup und schreibt ihn in das XML-Object
 *
 * @argument xPath (string xPath)
 * @argument val (string) Wert, der zur\u00fcckggeschrieben werden soll
 *
 * @author andi r.
 * @version 20040527
 *
 */
editor.prototype.writeBackSelection = function(xPath, val)
{
   this.xmlObj.setValueByXPath(xPath, val);
   this.renderView('editView');
   hidebox('DivX');
   changecontent('DivX', 'about:blank');
   return false;
}
/**
 * public boolean showView
 * Schaltet die verschiedenen Ansichten des Editors um
 *
 * @argument viewButton (string) id des Buttons, auf den geklickt wurde
 *
 * @author andi r.
 * @version 20040528
 *
 */

function showView(viewButton)
{
   var clickedView = viewButton.substring(0, viewButton.indexOf('Button'));
   editor.renderView(clickedView);
   for(view in editorViews)
   {
      var actButton = document.getElementById(view + 'Button');
      var actView = document.getElementById(view);
      if(view == clickedView)
      {
         actButton.className = 'active';
         actView.style.display = 'block';
      }
      else
      {
         actButton.className = '';
         actView.style.display = 'none';
      }
   }
   return false;
}
/**
 *
 * Schreibt ein Dokument zurueck in die DB
 *
 * @author andi r.
 * @version 20040805
 *
 */

function saveDocument()
{
   var formField = document.getElementById('xmlString');
   formField.value = editor.xmlObj.toString();
   formField.form.submit();
   showbox('DivSave');
   return false;
}
/**
 * Laedt das  XML-Dokument neu vom Server
 *
 * @author: andi r.
 * @version: 20040528
 *
 */

function resetDocument()
{
   var bFrage = confirm('Sollen wirklich alle \u00c4nderungen verworfen werden?');
   if(bFrage)
   {
      editor.loadDocument(editor.xmlDoc, 'xml');
      editor.renderView('editView');
   }
   writeLogLine("resetDocument", "User hat \u00c4nderungen verworfen und daten zur\u00fcckgesetzt.");
   return false;
}
/**
 * Erzeugt ein Div-HTML-ELEMENT
 *
 * @argument id (string) id des zu erzeugenden Containers
 * @argument classname (string) name der Stylsheet-Klasse, die dem div zugewiesen wird (optional)
 * @returns theDiv (HTML-ELEMENT)
 *
 * @author andi r.
 * @version 20040522
 *
 */

function createDiv(id, classname)
{
   var theDiv = document.createElement('div');
   theDiv.id = id;
   theDiv.name = id;
   if(classname)
   {
      theDiv.className = classname;
   }
   return theDiv;
}
/**
 * public solseitXmlObject editor.createXMLObjectFromFile
 *
 * erzeugt ein solseitXMLObject aus einem XML-File
 *
 * @argument file (string uri)
 * @return (object solseitXmlObject)
 * @author andi r.
 * @version 20040902
 *
 */


editor.prototype.createXMLObjectFromFile = function(file)
{
	try
	{
	   var oDomDoc = Sarissa.getDomDocument();
	   oDomDoc.async = false;
	   oDomDoc.validateOnParse = false;  // wichtig - sonst versucht IE das Schema zu validieren
	   oDomDoc.resolveExternals = false; //					-||-
	   oDomDoc.setProperty("SelectionNamespaces", getClientNamespaces());
	   oDomDoc.load(file);
		
	   if(oDomDoc.parseError != 0)
	   {
	      new solseitError("editor.createXMLObjectFromFile", 3001, "solseitLib/editor/editor.js", e);
	   }
	
	   xmlObj = new solseitXMLObject(oDomDoc);
	   return xmlObj;
	}
	catch(e)
	{
		new solseitError("editor.createXMLObjectFromFile", 3002, "solseitLib/editor/editor.js", e);
		return false;
	}
}

/**
 * public solseitXmlObject editor.createXMLObjectFromFile
 *
 * erzeugt ein solseitXMLObject aus einem String
 *
 * @argument str (string)
 * @return (object solseitXmlObject)
 * @author andi r.
 * @version 20040902
 *
 */

editor.prototype.createXMLObjectFromString = function(str)
{
   try
   {
	   var oDomDoc = Sarissa.getDomDocument();
	   oDomDoc.validateOnParse = false;  // wichtig - sonst versucht IE das Schema zu validieren
	   oDomDoc.resolveExternals = false; //					-||-
	   oDomDoc.setProperty("SelectionNamespaces", getClientNamespaces());
	   oDomDoc.loadXML(str);
	   if(oDomDoc.parseError != 0)
	   {
	      new solseitError("editor.createXMLObjectFromString", 3001, "solseitLib/editor/editor.js", e);
	   }
	   xmlObj = new solseitXMLObject(oDomDoc);
	   return xmlObj;
   }
   catch(e)
   {
   	new solseitError("editor.createXMLObjectFromString", 3002, "solseitLib/editor/editor.js", e);
   	return false;
   }
}
/**
 * dient zum Testen von xPath's mit verschiedenen Methoden
 * teilweise wird das Ergebnis als alert-Box ausgegeben, teilweis
 * als xml-(Teil-)Baum im content-Bereich dargestellt.
 *
 * @argument theForm (form-object)
 *
 * @author andi r.
 * @version 20040706
 *
 */

editor.prototype.xPathTest = function(theForm)
{
   var action = theForm.xPathCommand.options[theForm.xPathCommand.selectedIndex].value;
   var xPath = theForm.xPathing.value;
   switch(action)
   {
      case "getXMLObjectByXPath" : // Element
         {
            var elem = this.xmlObj.getXMLObjectByXPath(xPath);
            if(elem)
            {
               showbox('DivY');
               changecontent('DivY', elem.showInlineTree());
            }
            break;
         }
      case "getValueByXPath" : // String
         {
            var elem = this.xmlObj.getValueByXPath(xPath);
            if(elem)
            {
               alert(elem);
            }
            break;
         }
      case "checkXPath" : // Test
         {
            if(this.xmlObj.checkXPath(xPath))
            {
               alert("Der XPath:\n'" + xPath + "'\nliefert ein Ergebnis.");
            }
            else
            {
               alert("Der XPath:\n'" + xPath + "'\nliefert kein Ergebnis.");
            }
            break;
         }
      case "getXMLCollectionByXPath" : // solseit:collection
         {
            var coll = this.xmlObj.getXMLCollectionByXPath(xPath);
            alert(coll.showInlineTree());
            if(coll)
            {
               showbox('DivY');
               changecontent('DivY', coll.showInlineTree());
            }
            break;
         }
      default :
         {
            new solseitError("editor.xPathText", 3101, "solseitLib/editor/editor.js", e);
         }
   }
}

/**
 * package boolean editor.createMasterXMLCollectionFromFile
 *
 * laedt ein Vorlagendokument passend zum doctype
 * @return boolean (boolean)
 *
 * @author andi r
 * @version 20040818
 *
 */

editor.prototype.createMasterXMLCollectionFromFile = function()
{
   try
   {
      var path = this.xmlMasterFile;
      var tmp = this.createXMLObjectFromFile(path);
      this.masterXMLCollection = tmp.getXMLCollectionByXPath('/');
   }
   catch(e)
   {
      new solseitError("editor.createMasterXMLCollectionFromFile", 0, 'solseitLib/editor/editor.js');
      return false;
   }
}