/**
 * interface.js
 *
 * Enthaelt Funktionen, mit denen das Interface an sich gesteuert wird
 * @version 0.5 200400816
 *	@author Andreas Reichert
 * @author (c) Top 21 GmbH
 *
 * TODO: solseitXMLObject.addNewNodeByXPath error-Handling
 *
 */
var fileName = 'solseitLib/editor/interface.js';

/**
 * public void editor.editIn
 *
 * Macht einen Node editierbar
 *
 * @argument xslObj (Object solseitXMLObject) 	enthÃ¤lt das zu verwendende Stylesheet
 * @argument xPath (String) 					xPath zum Objekt, gleichzeitig auch der Name des Input-Feldes
 * @argument w (Integer) 						Breite des verwendeten Input-Feldes
 * @argument h (Integer) 						Hoehe des verwendeten Input-Feldes
 *
 * @author andi r.
 * @version 20040526
 *
 */

editor.prototype.editIn = function(xPath, w, h)
{
   this.xslObj.setXslParameter('editable', 'generate-id(' + xPath + ')');
   editor.renderView('editView');

   var formElement = document.getElementById(xPath);
   formElement.style.height = h - 1 + "px";
   // hoehe des Textfeldes formatieren
   formElement.style.width = w - 1 + "px";
   // breite des Textfeldes formatieren
   formElement.style.border = "0px none";
   formElement.style.backgroundColor = "#F5F5F5";
   formElement.parentNode.style.padding = "0px 0px 0px 0px";
   // margin und padding der umgebenden td auf 0 setzen
   formElement.parentNode.style.margin = "0px 0px 0px 0px";
   formElement.parentNode.style.border = "1px dashed";
   // Textfeld ausw\u00e4hlen
   //formElement.select();
   return false;
}

/**
 * Beendet die Editierung eines editierbaren Nodes
 *
 * @argument xslObj (Object mainObject) 	enth\u00e4lt das zu verwendende Stylesheet
 * @argument xPath 								xPath zum Objekt, gleichzeitig auch der Name des Input-Feldes
 *
 * @author andi r.
 * @version 20040524
 *
 */

editor.prototype.editOut = function(xPath)
{
   var val = document.getElementById(xPath).value;
   try
   {
      var oldVal = this.xmlObj.getValueByXPath(xPath);
   }
   catch(e)
   {
      var oldVal = "";
   }
   if(val != oldVal)
   {
      this.xmlObj.setValueByXPath(xPath, val);
      writeLogLine("editOut", "Wert: '" + val + "' in Element '" + xPath + "' geschrieben.");
      // logfile schreiben
   }
   this.xslObj.setXslParameter("editable", "''");
   this.renderView('editView');
}
/**
 * @return (string) enthaelt namespaces
 * @exeption Keine Namespaces fuer dieses Projekt definiert, Standard-Namespaces gesetzt
 *
 * @author andi r.
 * @version 20031222
 *
 */

function getClientNamespaces()
{
   try
   {
      var l = config.namespaces.length;
      var s = "";
      var f = false;
      for(var i = 0; i < l; i++)
      {
         var act = config.namespaces[i];
         s += 'xmlns:' + act[0] + '="' + act[1] + '" ';
         f = true;
      }
   }
   catch(e)
   {
      new solseitError("editor.getClientNamespaces", 2101, fileName);
      s = "xmlns:xhtml='http://www.w3.org/1999/xhtml' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'";
   }
   return s;
}
/**
 * fÃ¤ngt den return im editformular auf den Eingabefeldern ab,
 * damit hier beim Return nicht das ganze Formular verschickt wird.
 * Stattdessen wird der Edit-Vorgang fÃ¼r diese Feld beendet.
 *
 * @argument xslObj (Object xml) enthÃ¤lt das verwendete xsl-Dokument
 * @argument field (Object html) das Formularfeld
 * @argument event (event)
 *
 * @author andi r.
 * @version 20031222
 *
 */

function handleEnter(xslObj, field, event)
{
   var keyCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
   if(keyCode == 13)
   {
      this.editOut(xslObj, field.name);
   }
}
/**
 * public void solseitXMLObject.blockAction
 * dient der Vereinfachung/Weiterleitung der Editiermoeglichkeiten auf einen Teilbaum
 *
 * @argument xPath (String)
 * @argument action (String) up, down, add, del
 *
 * @author andi r.
 * @version 20040818
 *
 */

solseitXMLObject.prototype.blockAction = function(xPath, action)
{
   switch(action)
   {
      case 'down' :
         {
            editor.xmlObj.moveByXPath(xPath, action);
            break;
         }
      case 'up' :
         {
            editor.xmlObj.moveByXPath(xPath, action);
            break;
         }
      case 'add' :
         {
            editor.xmlObj.appendCleanCopyNode(xPath, true);
            break;
         }
      case 'del' :
         {
            editor.xmlObj.removeByXPath(xPath, false);
            break;
         }
      default :
         {
            break;
         }
   }
   editor.renderView('editView');
}
/**
 * public void solseitXMLObject.appendNewChildByXPath
 *
 * l\u00e4dt einen Teilbaum aus einem wertelosen Vorlagen-Dokument.
 * Dieses Dokument soll nur einmal geladen werden, dann kann es
 * beliebig oft verwendet werden. Bedingungen werden aus dem xPath
 * entfernt, da diese ja im Vorlagendokument in der Regel nicht zutreffend
 * sind.
 *
 * @argument xPath (String)
 * @argument nn (string nodeName)
 * @argument search (boolean) default: false
 * @argument clean (string all||position) default: all
 *
 * @author andi r.
 * @version 20040928
 *
 */

solseitXMLObject.prototype.appendNewChildByXPath = function(xPath, nn, search, clean)
{
   var search = new String(search) || 'false';
   var clean = new String(clean) || 'all';
   pathToClean = xPath + '/' + nn;
   cleanXPath = cleanXPathString(pathToClean, search, clean);
   // node aus dem Vorlagendokument clonen
   var node = editor.masterXMLCollection.getCollectionXMLObject().getElementByXPath(cleanXPath);
   var copied = node.cloneNode(true);
   // im eigentlichen Object das Element auf den der XPath zeigt holen
   var pointer = this.internalDomObject.selectNodes(xPath).item(0);
   // neues Element einhaengen
   pointer.appendChild(copied);
   return false;
}

/**
 * public boolean solseitXMLObject.appendNewNodeByXPath
 *
 * @arugment xPath (string xPath)
 * @argument nn (string nodeName)
 * @argument search (boolean)
 * @argument clean (string all||position) default: all
 *
 * @author andi r.
 * @version 20040928
 *
 */
solseitXMLObject.prototype.appendNewNodeByXPath = function(xPath, nn, search, clean)
{
   var search = new String(search) || 'false';
   var clean = new String(clean) || 'all';
   cleanXPath = cleanXPathString(xPath, search, clean);
   // node aus dem Vorlagendokument clonen
   var node = editor.masterXMLCollection.getCollectionXMLObject().getElementByXPath(cleanXPath);
   var copied = node.cloneNode(true);
   // im eigentlichen Object das Element auf den der XPath zeigt holen
   var pointer = this.internalDomObject.selectNodes(xPath).item(0);
   // neues Element einhaengen
   if(node_after(pointer))
   {
      pointer.parentNode.insertBefore(copied, node_after(pointer));
   }
   else
   {
      pointer.parentNode.appendChild(copied);
   }
   return false;
}

function cleanXPathString(xPath, search, clean)
{
   var clean = new String(clean) || 'all';
   // Bedingungen aus XPath entfernen
   var cleanXPath = new String();
   if(clean == 'all')
   {
      cleanXPath = xPath.replace(/\[.*?\]/gi, "");
   }
   else if(clean == 'position')
   {
      cleanXPath = xPath.replace(/\[\d*?\]/gi, "");
   }
   // abschliessenden Slash entfernen
   cleanXPath = cleanXPath.replace(/\/$/gi, "");
   // kein MasterObject vorhanden - nachladen
   if(editor.masterXMLCollection == 'undefined' || editor.masterXMLCollection != 'object')
   {
      editor.createMasterXMLCollectionFromFile();
   }
   // stufenweise Suche ueber ancestor-nodes
   while(cleanXPath.length)
   {
      var testXPath;
      if(cleanXPath.indexOf('/')!=0)
      {
         testXPath = "//" + cleanXPath;
      }
       else if(cleanXPath.indexOf('/') == 0)
       {
         testXPath = "/" + cleanXPath;
       }
       else
       {
          testXPath = cleanXPath;
      }
      if(editor.masterXMLCollection.getCollectionXMLObject().checkXPath(testXPath))
      {
          break;
      }
      else
      {
         // wenn search = false keine recursion
         if(search == 'false')
         {
            break;
         }
          if(cleanXPath.indexOf('/') != -1)
         {
            cleanXPath = cleanXPath.substring(cleanXPath.indexOf('/')+1, cleanXPath.length);
         }
         else
         {
            break; // Notbremse am Ende
         }
      }
   }
   return testXPath;
}

/**
 * Erzeugt den verschiebbaren Frame f\u00f6r den Text-Editor
 * oder zerstört ihn, sofern er vorhanden ist
 *
 * @argument fName (string) name des zu erzeugenden Frames
 * @argument w (integer) breite des zu erzeugenden Frames
 * @argument h (integer) höhe des zu erzeugenden Frames
 *
 * @author andi r.
 * @version 20040312
 *
 */

function editorFrame(fName, w, h)
{
   var frame = document.getElementById(fName);
   if(frame)
   {
      var jn = confirm("soll der Texteditor wirklich ohne evtl. Änderungen zu speichern geschlossen werden?");
      if(jn)
      {
         document.body.removeChild(frame);
      }
   }
   else
   {
      document.createElement()
      var ifr = document.createElement('iframe');
      ifr.name = 'iframe2';
      ifr.id = 'iframe2';
      ifr.src = '_js/htmlarea/htmlArea.cfm';
      ifr.style.position = 'absolute';
      ifr.style.width = w.toString() + 'px';
      ifr.style.height = h.toString() + 'px';
      ifr.style.zIndex = '1';
      document.body.insertBefore(ifr, document.body.firstChild);
   }
}

function editNormal(t)
{
   var txt = t.firstChild.nodeValue;
   var pNode = t.parentNode;
   var inp = document.createElement('input');
   inp.setAttribute('class', 'val');
   inp.value = txt;
   inp.name = "edit";
   pNode.replaceChild(inp, t);
}
/**
 * Ändert die Höhe eines Textareas wenn der Content grö\u00dfer wird und eigentlich scrollen w\u00f6rde
 * bug in Mozilla: overflow: visible scrollt anstatt das Textarea zu vergrö\u00dfern
 * Aufruf erfolgt in einem Intervall. Bsp.:
 * <textarea class="val" name="{$Pfad}" id="{$Pfad}" rows="1" onBlur="{$xmlObject}.editOut({$xslObject}, this.name);window.clearInterval(myInterval);" onFocus="myInterval=window.setInterval('changeTextAreaHeight(document.getElementById(\'{$Pfad}\'))', 100)">
 *
 * @argument e (html-element) textarea
 *
 * @author andi r.
 * @version 20040323
 *
 */

function changeTextAreaHeight(e)
{
   var h = e.scrollHeight;
   var v = e.offsetHeight;
   if(v != h)
   {
      e.style.height = h + "px";
   }
}
if( typeof HTMLElement != "undefined" && !HTMLElement.prototype.insertAdjacentElement)
{
   HTMLElement.prototype.__defineGetter__("isContentEditable",

   function()
   {
      if(this.hasAttribute('contenteditable') && this.getAttribute('contenteditable') == 'true')
      {
         return true;
      }
      else
      {
         return false;
      }
   }
   );
   HTMLElement.prototype.__defineSetter__("contentEditable",

   function()
   {
      if(this.hasAttribute('contenteditable') && this.getAttribute('contenteditable') == 'true')
      {
         this.designMode = "on";
      }
   }
   );
}
/**
 * ersetzt die Pseudo-Klasse :hover im Stylesheet, die im Internet-Explorer leider nur
 * bei a funktioniert
 *
 * @argument t (HTML-ELEMENT) welches den Event auslöst
 * @argument io (string) in oder out
 * @author andi r.
 * @version 20040604
 *
 */

function hoverMe(t, io)
{
   switch(io)
   {
      case 'in' :
         {
            t.className = t.className + 'Hover';
            break;
         }
      case 'out' :
         {
            t.className = t.className.substring(0, t.className.indexOf('Hover'));
            break;
         }
      default :
         {
            break;
         }
   }
}
/**
 * setzt medienverwendungshaken im medium Attribut eines Nodes
 *
 * @argument ck (boolean) checked der checkbox
 * @argument val (string) value der Checkbox
 * @argument xPath (string xPath) pfad zum element, in dem der mvh gesetzt werden soll
 * @author andi r.
 * @version 20040607
 *
 */

//function setMVH(ck, val, xPath)
solseitXMLObject.prototype.setMVH = function(ck, val, xPath)
{
   //var xPath = xPath + "/@medium";
   var medium = this.getValueByXPath(xPath);
   var medArray = medium.split(',').removeEmpty();
   if(ck)
   {
      medArray.push(val);
   }
   else
   {
      medArray.remove(val);
   }
   this.setValueByXPath(xPath, medArray.join(','));
   editor.renderView('editView');
}
/**
 * \u00d6ffnet einen Teilbaum im Texteditor
 *
 * @argument xPath (string xPath)
 *
 * @author andi r.
 * @version 20040706
 *
 */

function openInEditorByXPath(xPath)
{
   var nodeToEdit = editor.xmlObj.getXMLObjectByXPath(xPath);
   var x = (document.body.offsetWidth - 640)/2;
   var y = scrollTop() + 30;
   movePopup('DivSolseitTextEditor', x , y);
   showbox('DivSolseitTextEditor');
   changecontent('DivSolseitTextEditor', 'htmlarea.cfm?display=none&xPath=' + xPath);
   //changecontent('DivSolseitTextEditor', '/htmlarea/examples/fully-loaded.html');
   return false;
}
/**
 * Schreibt den editierten Teilbaum aus dem Texteditor zur\u00f6ck ins XML
 *
 * @argument xPath (string xPath)
 * @argument str (string) Inhalt des Texteditors
 * @argument nName (string optional) Name des Rootnodes, der den Inhalt des Editors einschlie\u00dfen soll
 *
 * @author andi r.
 * @version 20040708
 *
 */

function writeBackValueByXPath(xPath, str, nName)
{
   if(nName && nName.length)
   {
      str = "<" + nName + ">" + str + "</" + nName + ">";
   }
   retElement = editor.createXMLObjectFromString(str);
   editor.xmlObj.replaceElementByXPath(xPath, retElement);
   writeLogLine("writeBackValueByXPath", "Wert: '" + str.trim() + "' in Element '" + xPath + "' geschrieben.");
   editor.renderView('editView');
   hidebox('DivSolseitTextEditor');
   changecontent('DivSolseitTextEditor', 'about:blank');
   return false;
}
/**
 * Schreibt den inhalt des zu editierenden Nodes in die Entsprechende Textarea
 *
 * @argument textArea (Object HTML-Object)
 * @argument xPath (string xPath)
 * @returns (string) Name des Root-Elements
 *
 * @author andi r.
 * @version 20040709
 *
 * ToDo: Error-Handling
 *			Leere nodes besser behandeln
 *
 *
 */

function transformNodeToHTMLArea(textArea, xPath)
{
   var editStr = new String();
   var nName = new String();
   var nodeToEdit = editor.xmlObj.getXMLObjectByXPath(xPath);
   if(nodeToEdit.internalDomObject.documentElement.childNodes.length > 0)
   {
      nodeToEditStr = nodeToEdit.toString();
      var regEx = /^<(\w*)?>([\w\W]*)<\/\1>/;
      var e = regEx.exec(nodeToEditStr);
      editStr = e[2];
      nName = e[1];
   }
   else
   {
      nName = nodeToEdit.internalDomObject.documentElement.nodeName;
   }
   textArea.value = editStr;
   return nName;
}
// prototype für date Klasse schreiben
function transformDateFormat(s)
{
   try
   {
   d = s.getDateFromFormat('dd.MM.yyyy');
   s = d.formatDate('yyyy-MM-ddThh:mm:ss') + '.000000';
   return s;
   }
   catch(e)
   {
      return '';
   }
}

function loadImageByXPath(xPath)
{
   var image = editor.xmlObj.getValueByXPath(xPath);


   var x = (document.body.offsetWidth - 640)/2;
   var y = scrollTop() + 30;
   movePopup('DivSolseitTextEditor', x , y);
   showbox('DivSolseitTextEditor');
   changecontent('DivSolseitTextEditor', 'loadImage.cfm?display=popup&xPath=' + xPath + "&image=" + image);
}

/**
 * Beendet die Editierung eines editierbaren Nodes
 *
 * @argument xslObj (Object mainObject) 	enth\u00e4lt das zu verwendende Stylesheet
 * @argument xPath 								xPath zum Objekt, gleichzeitig auch der Name des Input-Feldes
 *
 * @author andi r.
 * @version 20040524
 *
 */

editor.prototype.editOutDate = function(xPath)
{
   var val = document.getElementById(xPath).value;
   var d = val.getDateFromFormat('dd.MM.yyyy');
   var tVal = d.formatDate('yyyy-MM-ddThh:mm:ss') + '.000000';
   try
   {
      var oldVal = this.xmlObj.getValueByXPath(xPath);
   }
   catch(e)
   {
      var oldVal = "";
   }
   if(tVal != oldVal)
   {
      this.xmlObj.setValueByXPath(xPath, tVal);
      writeLogLine("editOut", "Wert: '" + val + "' in Element '" + xPath + "' geschrieben.");
      // logfile schreiben
   }
   this.xslObj.setXslParameter("editable", "''");
   this.renderView('editView');
}

/**
 * startet ein Interval, das überprüft, ob sich der wert des
 * Datumsfeldes verändert hat
 *
 * @argument xPath (string)
 * @author andi r.
 * @version 20040923
 *
 */

function startDateInterval(xPath)
{
   var oldValName = new String("oldval_" + xPath);
   var oldVal = document.getElementById(oldValName).value;
   myDateInterval=window.setInterval(function() {
      var theInput = document.getElementById(xPath).value;
      if(oldVal != theInput)
      {
         editor.editOutDate(xPath);
         window.clearInterval(myDateInterval);
      }
   }, 50)
}



