  var AjaxLib_Browser;

  if (navigator.appName.indexOf("Microsoft") > -1) {
    AjaxLib_Browser = 'IE';
  } else {
    AjaxLib_Browser = 'FF';
  }

 function AjaxLib_ElementText(XMLElement) {
    if (AjaxLib_Browser == 'IE') {
      return XMLElement.text;
    } else {
      return XMLElement.textContent;
    }
  }


  function AjaxLib_CallResult(XMLDoc) {
    var Result = null;
    var Elements = XMLDoc.getElementsByTagName('result');
    if (Elements.length == 1) {
      var Attribs = Elements[0].attributes;
      var S = Attribs.getNamedItem('return').value;
      Result = window.top.php_unserialize(S);
    }
    return Result;
  }


  function AjaxLib_TFormDetails() {
    // returns
    var Value;
    if (Value = ejc_GetValueByID('UID')) {
      this.UID = Value;
    } else {
      this.UID = null;
    }
    if (Value = ejc_GetValueByID('PID')) {
      this.PID = Value;
    }
    // add a "string" of properties methods have ()
    var Inputs = document.getElementsByTagName("input");
//    alert(Inputs.length);
    var A = new Array();
    var J = 0;
    var id = '';
    for (var I=0; I < Inputs.length; I++) {
      id = Inputs[I].id;
      if (id) {
        if (id.indexOf('(') < 0 && id.indexOf('[') >= 0) {
          A[J] = id;
          J++;
        }
      }
    }
    var Inputs = document.getElementsByTagName("textarea");
    for (var I=0; I < Inputs.length; I++) {
      id = Inputs[I].id;
      if (id) {
        if (id.indexOf('(') < 0 && id.indexOf('[') >= 0) {
          A[J] = id;
          J++;
        }
      }
    }
    this.Properties = A.join(';');
  }


  function AjaxLib_MergeObjects(Obj1, Obj2) {
    var Prop;
    for (Prop in Obj2) {
      Obj1[Prop] = Obj2[Prop];
    }
    return Obj1;
  }

  function AjaxLib_TInputDetail(Input) {
    // id is Class[OID].Property or
    //       Class[OID].Method(Param1,..) or
    var ParamName;
    var S = new String(Input.id);
    var I = S.indexOf(':'); // for multiple properties
    if (I > 0) {S = S.substring(0,I);}
    I = S.indexOf('[');
    var J = S.indexOf(']');
    var K = S.indexOf('(');
    var L = S.indexOf(')');
    var Method = K > J;
    if (!Method) {K = S.length;}
    this.Class = S.substring(0,I);
    this.OID = S.substring(I+1,J);
    var PropMethod = S.substring(J+2,K);
    if (Method) {
      this.Method = PropMethod;
      var Params = S.substring(K+1,L).replace(' ','');
      if (Params.length > 0) {
        var Params = Params.split(',');
        for (I = 0; I<Params.length; I++) {
          ParamName = 'Parameter'+String(I);
          this[ParamName] = Params[I];
          if (I == 0) { // special case first parameter is the name the value is passed as
            ParamName = Params[I];
             this[ParamName] = escape(Input.value);
          }
        }
      } else {
        I = 0;
      }
    } else {
      this.Property = PropMethod;
    }
    this.Value = escape(Input.value);
//    this.Value = Input.value;
    ParamName = 'Parameter'+String(I);
    this[ParamName] = this.Value;
    // add the value as the last paramert
//    alert(Input.id);
//    alert(this.Class);
  }


  function AjaxLib_DisplayResult(XMLDoc) { // returns true if an error occured
    if (!XMLDoc) {return false}

    var Attr;
    var error;
    var property;
    var message = null;
    var i;
    var s;
    var Elements = XMLDoc.getElementsByTagName('result');
    // can only be one
    if (Elements.length == 1) {
      s = AjaxLib_ElementText(Elements[0]);
      if (s != '') {
       window.top.eJIF_ModalMessage('Alert', s, null);
      }
    }
    Elements = XMLDoc.getElementsByTagName('error');
    message = null;
    for (i = 0; i < Elements.length; i++) {
      s = AjaxLib_ElementText(Elements[i]);
      if (message) {
        message = message+'<br>'+s;
      } else {
        message = s;
        }
    }
    if (message != null) {
      window.top.eJIF_ModalMessage('Error', message, null);
    }
    return (i > 0);
  }

  function AjaxLib_UpdateForm(Input, XMLDoc) {
    // get the update values
    if (!XMLDoc) {return;}
    if (Input && Input.style.backgroundColor == clProcessingColour) {
      Input.style.backgroundColor = clOKColour;
    }
    var Attr;
    var id;
    var value;
    var Elements = XMLDoc.getElementsByTagName('update');
    for (var i=0; i<Elements.length; i++) {
      try {
        Attr = Elements[i].attributes;
        var classname = Attr.getNamedItem('class').value;
        var oid = Attr.getNamedItem('oid').value;
        var property = Attr.getNamedItem('property').value;
        var value = Attr.getNamedItem('value').value;
        id = classname+'['+oid+'].'+property;
        ejc_SetValueByID(id, value);
      } catch(Error) {
        // add debug code here
      }
    }
  }


  function AjaxLib_TagValue(XMLDom, TagName) {
    if (XMLDom != null)  {
      var Elements = XMLDom.getElementsByTagName(TagName);
      if (Elements.length > 0) {
        if (Elements[0].firstChild != null) {
          try {
            return (Elements[0].firstChild.nodeValue);
          } catch (err) {
            alert('error extracting ['+TagName+'] from \n'+XMLDom.text);
          }
        }
      }
    }
    return null;
  }

  function AjaxLib_HTMLPropertySave(TinyMCEEditor, HTML, Body) {
    var Input = TinyMCEEditor.formElement;
    AjaxLib_SetProperty(Input);
    return HTML;
  }


  function AjaxLib_SetProperty(Input, OnSucess, Parameters) {
    if (Input) {
      Details = new AjaxLib_TInputDetail(Input);
      Parameters = AjaxLib_MergeObjects(Details, Parameters);
      FormDetails = new AjaxLib_TFormDetails();
      Details = AjaxLib_MergeObjects(Details, FormDetails);
    }
//    alert(Details.Class);
//    var savebackgroundcolour = Input.style.background;
    window.top.eJIF_UserEvent();
    window.top.AjaxRequest.post(
      {
        'url':'eJIFCont.php',
        'parameters':Parameters,
          'onSuccess':function(Req) {
             AjaxLib_UpdateForm(Input, Req.responseXML);
             if (OnSucess) {
               if (!AjaxLib_DisplayResult(Req.responseXML)) {
                 if (isString(OnSucess)) {
                   eval(OnSucess);
                 } else {
                   OnSucess(Input, Req.responseXML);
                 }
               }
             } else {
               AjaxLib_DisplayResult(Req.responseXML);
               Input.style.backgroundColor = clOKColour;
             }
          },
          'onLoading':function(Req) {
             Input.style.backgroundColor = clProcessingColour;
          },
          'onTimeout':function(Req) {
             window.top.eJIF_SetProcessingDlg(false);
             alert('Server cannot update at this time - try later');
             Input.value = Value;
             Input.style.backgroundColor = savebackgroundcolour;
          }
        }
      );
    }

  function AjaxLib_CallMethod(Input, Parameters, OnSucess, OnTimeout, Caption) {
    var InputType = '';
    if (Input) {
      InputType = Input.type;
      // If the input type is not a button should we only call if green!
      Details = new AjaxLib_TInputDetail(Input);
      Details = AjaxLib_MergeObjects(Details, Parameters);
    } else {
      Details = Parameters;
    }
    FormDetails = new AjaxLib_TFormDetails();
    Details = AjaxLib_MergeObjects(Details, FormDetails);
    if (Caption) {
      window.top.eJIF_SetProcessingDlg(true, Caption);
    }
    window.top.eJIF_UserEvent();
    window.top.AjaxRequest.post(
      {
        'url':'eJIFCont.php',
        'timeout': 30000,
        'parameters':Details,
          'onSuccess':function(Req) {
             if (Input && InputType != 'button') {Input.style.backgroundColor = clOKColour;}
             window.top.eJIF_SetProcessingDlg(false);
             AjaxLib_UpdateForm(Input, Req.responseXML);
             if (!AjaxLib_DisplayResult(Req.responseXML)) {
               if (OnSucess != null) {
                 // if OnSucess is a string with () then execute it
                 if (isString(OnSucess)) {
                   eval(OnSucess);
                 } else {
                   OnSucess(Input, Req.responseXML);
                 }
               }
             }
          },
          'onTimeout':function(Req) {
             window.top.eJIF_SetProcessingDlg(false);
             if (OnTimeout) {OnTimeout(Input, Req.responseXML);}
          },
          'onLoading':function(Req) {
             if (Input && InputType != 'button') {Input.style.backgroundColor = clProcessingColour;}
          }
        }
      );
  }

  function isString() {
    if (typeof arguments[0] == 'string') return true;
    if (typeof arguments[0] == 'object') {
      var criterion = arguments[0].constructor.toString().match(/string/i);
      return (criterion != null);
    }
    return false;
  }
