/*
This file is part of pDAF.
Copyright (c) 2005-2008 by Gregorcic & Helger IT systems OEG.
All rights reserved.
http://www.phloc.com
 */

var nPopupCounter = 0;

// jQuery extensions
( function($) {
  // Mark elements as enabled or disabled
  $.fn.setDisabled = function(bDisabled) {
    return this.each( function() {
      if (typeof this.disabled != "undefined")
        this.disabled = bDisabled;
    });
  };
  // Disable an element
  $.fn.disable = function() {
    return this.setDisabled(true);
  };
  // Enable an element
  $.fn.enable = function() {
    return this.setDisabled(false);
  };
  // Replace an element with some code
  $.fn.replaceWith = function(html) {
    return this.after(html).remove();
  };
})(jQuery);

// If DOM tree parsed completely...
$( function() {
  // On form submission, all submit and reset buttons are disabled
  $("form").submit( function() {
    $(":submit", this).attr("disabled", "disabled");
    $(":reset", this).attr("disabled", "disabled");
  });
});

// constructor
function JPhlocClass() {
}
JPhlocClass.prototype = {
  // Shortcut for getElementById
  ge : function(id) {
    return document.getElementById(id);
  },

  // Shortcut for createElement
  ce : function(name) {
    return document.createElement(name);
  },
  
  // Shortcut for createTextNode
  ct : function(text) {
    return document.createTextNode(text);
  },

  // Submit form with the given ID
  submitForm : function(id) {
    this.ge(id).submit();
  },

  // used only from mod-wcms/navigation
  getPrevNode : function(o) {
    if (!o) return o;
    t = o.previousSibling;

    while (t != null && (t.nodeType != 1 || t.nodeName != 'DIV'))
    {
      t = t.previousSibling;
    }
    return t;
  },

  // used only from mod-wcms/navigation
  clearChildNodes : function(o)
  {
    var lContentElems = o.childNodes;
    for (var i = 0; i < lContentElems.length;)
    {
      if (lContentElems[i].nodeType == 1 && lContentElems[i].nodeName == 'DIV')
      {
        o.removeChild(lContentElems[i]);
      }
      else
      {
        i++;
      }
    }
  },
  
  // used only from mod-wcms/navigation
  getNextNode  : function(o)
  {
    if (!o) return o;
    t = o.nextSibling;

    while (t != null && (t.nodeType != 1 || t.nodeName != 'DIV'))
    {
      t = t.nextSibling;
    }
    return t;
  },

  // used only from mod-wcms/navigation
  hasChildNodes : function(o)
  {
    if (!o) return false;
    var oChildren = o.childNodes;

    for (var i = 0; i < oChildren.length; i++)
    {
      if (oChildren[i].nodeType == 1 && oChildren[i].nodeName == 'DIV')
        return true;
    }
    return false;
  },  

  outerHTML : function (aElem, sHTML)
  {
    var lastPastedElem = null;
    if (aElem)
    {
      var aParent = aElem.parentNode;
      var aTmp = document.createElement("span");
      aTmp.innerHTML = sHTML;
      for (var i = 0; i < aTmp.childNodes.length; i++)
      {
        var aChild = aTmp.childNodes[i];
        aParent.insertBefore(aChild, aElem);
        lastPastedElem = aChild;
      }
      aParent.removeChild(aElem);
    }
    return lastPastedElem;
  },
  
  // checks if the passed string starts with the passed pattern
  startsWith : function(sString, sPattern) {
    if (sString && sPattern)
    {
      if (sString.length < sPattern)
        return false
      return (sString.substring(0, sPattern.length) == sPattern)
    }
    return false;
  },

  // checks if the passed string ends with the passed pattern
  endsWith : function(sString, sPattern) {
    if (sString && sPattern)
    {
      if (sString.length < sPattern)
        return false
      return (sString.substr(sString.length - sPattern.length) == sPattern)
    }
    return false;
  },
  
  getChildrenByTagName : function (oNode, sTagName, bRecursive){
    var aChildren = new Array();
    if (oNode)
    {
      for (var i = 0; i < oNode.childNodes.length; i++)
      {
        var a = oNode.childNodes[i];
        if (a.nodeType == 1)
        {
          if (a.nodeName.toLowerCase() == sTagName)
            aChildren.push(a);
          if (bRecursive)
            aChildren = aChildren.concat(this.getChildrenByTagName(a, sTagName, bRecursive));
        }
      }
    }
    return aChildren;
  },
  
  getParentByTagName : function (oNode, sTagName){
    if (oNode)
    {
      var aParent = oNode.parentNode;
      if (aParent.nodeType == 1)
      {
        if (aParent.nodeName.toLowerCase() == sTagName)
          return aParent;
        return this.getParentByTagName(aParent, sTagName);
      }
    }
    return null;
  },
  
  getChildrenByIDPrefix : function (oNode, sIDPrefix, bRecursive){
    var aChildren = new Array();
    if (oNode)
    {
      for (var i = 0; i < oNode.childNodes.length; i++)
      {
        var a = oNode.childNodes[i];
        if (a.nodeType == 1)
        {
          if (jphloc.startsWith(a.id, sIDPrefix))
            aChildren.push(a);
          else if (bRecursive)
            aChildren = aChildren.concat(this.getChildrenByIDPrefix(a, sIDPrefix, bRecursive));
        }
      }
    }
    return aChildren;
  },
  
  getJSCode : function (oNode) {
    if (oNode && oNode.nodeType == 1 && oNode.nodeName.toLowerCase() == "script")
    {
      var sCode = oNode.innerHTML;
      var nStart = sCode.indexOf("<!--"); 
      var nEnd = sCode.indexOf("//-->");
      if (nEnd < 0)
        nEnd = sCode.indexOf("-->");
      if (nStart >= 0 && nEnd >= 0 && nEnd > nStart)
        return sCode.substring(nStart + 4, nEnd);
      return sCode;
    }
    return "";
  },
    
  evalJS : function (oAnyNode) {
    // important for IE, otherwise it does not evaluate/execute the DOMappended JS code!
    var z = this.getChildrenByTagName (oAnyNode, "script", true);
    for (key in z)
      eval(this.getJSCode(z[key]));    
  },
  
  getOffsetTopRecursive : function (oNode){
    var x = 0;
    if (oNode)
    {
      if (oNode.offsetTop  && typeof(oNode.offsetTop) == "number")
        x = oNode.offsetTop;
      if (oNode.offsetParent)
        x += this.getOffsetTopRecursive(oNode.offsetParent);
    }
    return x;
  },
  
  
  // Escape a JS regular expression
  escapeRegex : function(text) {
    if (!arguments.callee.sRE) {
      var specials = [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{',
          '}', '\\' ];
      arguments.callee.sRE = new RegExp('(\\' + specials.join('|\\') + ')', 'g');
    }
    return text.replace(arguments.callee.sRE, '\\$1');
  },

  // Escape a JS literal
  escapeLiteral : function(text) {
    if (!arguments.callee.sRE) {
      var specials = [ '\'', '"', '\\'];
      arguments.callee.sRE = new RegExp('(\\' + specials.join('|\\') + ')', 'g');
    }
    return text.replace(arguments.callee.sRE, '\\$1');
  },
  
  escapeLinebreaks : function(text) {
    if (!arguments.callee.sRE) {
      var specials = [ '\n' ];
      arguments.callee.sRE = new RegExp('(\\' + specials.join('|\\') + ')', 'g');
    }
    return text.replace(arguments.callee.sRE, '\\n');
  },

  // Escape a text as HTML
  escapeHTML : function(text) {
    return text.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/"/g, '&quot;'); // "                                         
  },
  
  appendTextWithBR : function(aParent, sText) {
    if (sText && sText != '')
    {
      var aLines = sText.split('\n');
      var nIndex = 0;
      for (var nLine in aLines)
      {
        if (nIndex > 0)
        {
          aParent.appendChild(document.createElement("br"));          
        }
        aParent.appendChild(document.createTextNode(aLines[nLine]));
        nIndex++;
      }
    }
  },
  
  // Show/hide element
  setVisible : function(element,bVisible) {
    if (element)
      element.style.display = bVisible ? 'block' : 'none';
  },
  
  removeNodeByID : function (sID) {
    this.removeNode(this.ge(sID));    
  },
  
  removeNode : function (aNode) {
    if (aNode && aNode.parentNode)
      aNode.parentNode.removeChild(aNode);    
  },

  /* This is a wrapper around getAttribute() which does not work in IE 
   * (see http://tobielangel.com/2007/1/11/attribute-nightmare-in-ie/) 
   * NOTE: use this whenever getting attributes which might contain JS 
   * code interpreted as function */
  readAttribute : function (aNode, sName) {
    var aAttr = aNode.getAttribute(sName, 0);
    if (typeof(aAttr) == "function")
      aAttr = aNode.getAttributeNode(sName).nodeValue;
    return aAttr;  
  },
  
  updateDisableStateByCheckBox : function (aCheckBox, sCtrlID) {
    if (aCheckBox)
    {
      var bChecked = aCheckBox.checked;
      var aObj = this.ge(sCtrlID);
      if (aObj)
      {
        if (bChecked)
          this.enableCtrl(aObj);
        else
          this.disableCtrl(aObj);
      }
    }
  },
  
  disableButton : function (aButton) {
    if (aButton)
    {
      var aDisabled = aButton.getAttribute("disabled", 0);
      if (!aDisabled || aDisabled != "disabled")
      {
        aButton.setAttribute("disabled", "disabled");
        this.addClass(aButton, "pdaf_button_disabled");
        aButton.onfocus = function() {aButton.blur();};
      }
    }
  },
  
  enableButton : function (aButton) {
    if (aButton && aButton.getAttribute("disabled", 0))
    {
      aButton.removeAttribute("disabled");
      this.removeClass(aButton, "pdaf_button_disabled");
      aButton.removeAttribute("onfocus");
    }
  },
  
  isDisabled : function (aButton) {
      return (aButton && this.readAttribute(aButton, "disabled"));
    },

  disableCtrl : function (oCtrl) 
  {
    if (oCtrl)
    {
      oCtrl.disabled = 'disabled';
      this.addClass(oCtrl, 'disabled');
    }
  },

  enableCtrl : function (oCtrl) 
  {
    if (oCtrl)
    {
      oCtrl.disabled = false;
      this.removeClass(oCtrl, 'disabled');
    }
  },
    
  focusControl  : function (oCtrl, sClass){
      if (!this.hasClass(oCtrl, 'readonly'))
        this.addClass(oCtrl, sClass);
  },

  blurControl  : function (oCtrl, sClass){
    if (!this.hasClass(oCtrl, 'readonly'))
      this.removeClass(oCtrl, sClass);
  },

  isSubmitKey  : function (evt) {
      evt = (evt) ? evt : ((event) ? event : null);
      if (evt) 
      {
        var nKey = evt.keyCode;
        if (nKey == 13)
          return true;
      }
      return false;      
    },
    
  href : function (sURL) {
     try { window.location.href = sURL; }
     catch (e) { 
       // editor intercepter causes error in IE   
       }
    },  

  hidden : function (aE) {
    if (aE)
      aE.style.visibility = 'hidden';
  },

  disable : function(aE) {
    if (aE)
      aE.disabled = 'disabled';
  },

  enable : function (aE) {
    if (aE)
      aE.disabled = false;
  },

  visible : function (aE) {
    if (aE)
      aE.style.visibility = 'visible';
  },    
    
  disableButtonByID  : function (sID) {
      this.disableButton(this.ge(sID));
  },
  
  enableButtonByID  : function (sID) {
    this.enableButton(this.ge(sID));
  },
  
  getJSButtonCode : function (sID, sLabel, sJS, bDisabled)
  {
    var sIDCode = "";
    var sDisableCode = "";
    var sDisabledState = "";
    var sDisabledClass = " ";
    var sJSLink = "";
    if (sJS)
      sJSLink = sJS;
    
    if (sID)
      sIDCode = " id=\"" + sID + "\"";
    if (bDisabled)
    {
      sDisableCode = " onfocus=\"javacript:blur();\"";
      sDisabledState = " disabled=\"disabled\"";
      sDisabledClass = " pdaf_button_disabled";
    }
    return "<a " + sIDCode + " onmouseup=\"javascript:jphloc.removeClass(this, 'pdaf_button_down');\"" + 
    " onclick=\"javascript:if (jphloc.isDisabled(this)) return false; " + sJSLink + "; return false;\"" + 
    sDisableCode + 
    " href=\"#\" class=\"pdaf_button" + sDisabledClass + "\"" + sDisabledState + "><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"pdaf_button_tl\"/><td class=\"pdaf_button_tc\"/><td class=\"pdaf_button_tr\"/></tr><tr><td class=\"pdaf_button_ml\"/><td class=\"pdaf_button_mc\"><table cellspacing=\"0\" cellpadding=\"0\"><colgroup><col width=\"10\"/><col width=\"*\"/><col width=\"10\"/></colgroup><tbody><tr><td class=\"pdaf_button_icon\"><span/></td><td class=\"pdaf_button_label\"><span class=\"pdaf_button_label\">" + 
    sLabel + 
    "</span></td><td/></tr></tbody></table></td><td class=\"pdaf_button_mr\"/></tr><tr><td class=\"pdaf_button_bl\"/><td class=\"pdaf_button_bc\"/><td class=\"pdaf_button_br\"/></tr></tbody></table></a>"   
  },
  
  /* takes a DOM node and evaluates any JS code contained in any SCRIPT block 
   * this is necessary since IE does not execute JS code on DOM appending */
  evalScrpttCode : function (oNode){
    if (oNode)
    {
    }
  },

  hasClass : function (oE, sClass) 
  {
    if (oE && sClass)
    {
      if (true)
      {        
        var sClasses = oE.className;
        if (sClasses)
        {
          if (sClasses == sClass)
            return true;
          if (this.startsWith(sClasses, sClass + " "))
            return true;
          if (this.endsWith(sClasses, " " + sClass))
            return true;
          return (sClasses.search(" " + sClass + " ") >= 0);
        }
        else
          return false;
      }
      else
      {
        return this.getClassIndex(oE, sClass) >= 0;
      }
    }
    return false;
  },
  
  getClassIndex : function (oE, sClass) {
    var aClasses = oE.className.split(" ");
    for ( var i in aClasses)
      if (aClasses[i] == sClass)
        return i;
    return -1;
  },
  
  addClass : function (oE, sClass) 
  {
    if (oE && !this.hasClass(oE, sClass)) 
    {
      var sClasses = oE.className;
      if (!sClasses || sClasses.length == 0)
        sClasses = sClass;
      else
        sClasses += (' ' + sClass);
      oE.className = sClasses;
      oE.setAttribute('class', sClasses);
    }
  },

  removeClass : function (oE, sClass) 
  {
    if (true)
    {
      this.removeClassQuickly(oE, sClass);
    }
    else
    {  
      if (oE && sClass)
      {
        var iClassIndex = this.getClassIndex(oE, sClass);
        if (iClassIndex >= 0)
        {
          var aClasses = oE.className.split(" ");
          aClasses.splice(iClassIndex, 1);
          var sNewClasses = aClasses.join(" ");
          oE.className = sNewClasses;
          oE.setAttribute('class', sNewClasses);
        }
      }
    }
  },
  
  // seems to be much faster as the split/splice/join alternative
  removeClassQuickly : function (oE, sClass) 
  {
    if (oE && sClass)
    {
      var sClasses = oE.className;
      
      // trivial case
      if (sClasses == sClass)
      {
        sClasses = "";
      }
      else if (sClasses.search(sClass)  >= 0)
      {
        // kick at start
        if (this.startsWith(sClasses, sClass + " "))
        {
          sClasses = sClasses.substr(sClass.length + 1);
        }
        
        // kick at end
        if (this.endsWith(sClasses, " " + sClass))
        {
          sClasses = sClasses.substring(0, sClasses.length - (1 + sClass.length));
        }
        
        // kick in the middle
        {
          sClasses = sClasses.replace(" " + sClass + " ", " ");          
        }
      }
      oE.className = sClasses;
      oE.setAttribute('class', sClasses);
    }
  },
  
  toggleClassByFlag : function (aElem, sClass1, sClass2, bFirst) 
  {
    var aClasses = aElem.className.split(" ");
    var sNewClasses = "";
    var bContained = false;
    for (var i in aClasses) 
    {
      var bTake = false;
      if ((aClasses[i] == sClass1 && bFirst) ||
          (aClasses[i] == sClass2 && !bFirst))
      {
        bContained = true;
        bTake = true;
      }
      else if (aClasses[i] != sClass1 && aClasses[i] != sClass2) 
        bTake = true;
      if (bTake)
      {
        if (sNewClasses != "")
          sNewClasses += " ";
        sNewClasses += aClasses[i];
      }
    }
    if (!bContained)
    {
      if (sNewClasses != "")
        sNewClasses += " ";
      sNewClasses += bFirst ? sClass1 : sClass2;      
    }
    aElem.className = sNewClasses;
    aElem.setAttribute('class', sNewClasses);
  },
  
  hide : function(oE) {
    if (oE)
      oE.style.display = 'none';
  },

  show : function (oE) {
    if (oE)
      oE.style.display = 'block';
  },

  showInline : function (oE) {
    if (oE)
      oE.style.display = 'inline-block';
  },
  
  hideByID : function (sID) {
    this.hide (this.ge(sID));
  },
  
  showByID : function (sID) {
    this.show(this.ge(sID));
  },
  
  showInlineByID : function (sID) {
    this.showInline(this.ge(sID));
  },
  
  appendHiddenField : function(aNode, sName, sValue) 
  {
    // alert("appendHiddenField: " + aNode + "\n" + sName + "\n" + sValue);
    var aField = this.ce('input');
    aField.setAttribute('type',  'hidden');
    aField.setAttribute('name',  sName);
    aField.setAttribute('value', sValue);
    var aForm = this.getParentByTagName(aNode, "form");
    //alert(aForm);
    if (aForm)
      aForm.appendChild(aField);
  },
  
  go :function (sURL)
  {
    if (sURL && sURL.length > 0)
    {
      window.location.href = sURL;
    }
  }
}

var jphloc = window.jphloc = new JPhlocClass();

//========================================================
function pDAFAjaxClass() 
//========================================================
{
}

//========================================================
pDAFAjaxClass.prototype = 
//========================================================
{
  /** function to trigger an AJAX call for keeping the session alive */
  pdafSessionStartKeepAlive : function()
  {  
    sajax_do_call(null,
                  "keepSessionAlive",
                  pDAFAjax.pdafCallbackSessionKeepAlive);  
  },


  pdafCallbackSessionKeepAlive : function(sResultXHTMLSniplet)
  {
    window.setTimeout("pDAFAjax.pdafSessionStartKeepAlive()", 60000);
  }
}

var pDAFAjax = window.pDAFAjax = new pDAFAjaxClass();



function pdaf_display_element(oE, bShow) {
  if (bShow)
    jphloc.show(oE);
  else
    jphloc.hide(oE);
}

function pdaf_jump_on_select(o) {
  if (o)
    self.location = o.options[o.selectedIndex].value;
}

var g_bAnyModifications = false;
var g_sRequestedHref = false;

/**
 * Show the help window
 */
function pdaf_show_help(sURL) {
  window.open(sURL,
              '',
              'dependent=yes,location=no,menubar=no,resizable=yes,scrollbars=yes,status=no,toolbars=no,width=600,height=400');
}

// Use for opening the file browser
function pdaf_default_popup(sURL, sTitle, nWidth, nHeight, bResizable, bStatus) {
  var oNewWin = window.open(sURL, 
                            sTitle + nPopupCounter, 
                            "width=" + nWidth + 
                              ",height=" + nHeight + 
                              ",resizable=" + (bResizable ? "yes" : "no") + 
                              ",status=" + (bStatus ? "yes" : "no"));
  oNewWin.focus();
  nPopupCounter++;
}

function pDAF_formSubmitWithHiddenField  (sFormID, sFieldName, sValue)
{
  var aForm = jphloc.ge(sFormID);
  if (aForm) {
    var aHidden = jphloc.ce("input");
    aHidden.setAttribute("type", "hidden");
    aHidden.setAttribute("name", sFieldName);
    aHidden.setAttribute("value", sValue);
    aForm.appendChild(aHidden);
    aForm.submit();
  }
}

// this cache can be used to store values between windows
// (must always be executed in the parent window to work in IE
// is currently used by the file browser...

var oPDAFPropertyCache = new Object();

oPDAFPropertyCache.setProperty = function(key, value) {
  if (!this.props)
    this.props = new Array();
  this.props[key] = value;
}

oPDAFPropertyCache.getProperty = function(key) {
  if (!this.props)
    this.props = new Array();
  return this.props[key];
}

function pdaf_submit_form(aElem)
{
  //alert("submitting form..");
  var bForm = false;
  var aParent = aElem;
  if (aElem && aElem.nodeType == 1 && aElem.nodeName.toLowerCase() == 'form')
    bForm = true;
  while (!bForm && aParent)
  {
    aParent = aParent.parentNode;
    if (aParent && aParent.nodeType == 1 && aParent.nodeName.toLowerCase() == 'form')
      bForm = true;
  }
  if (aParent)
    aParent.submit();
}

function pDAF_ToolTipInit()
{
  $(".pdaf_tooltip").tipTip({maxWidth: "auto", edgeOffset: 10});
}