/*
 * JSON-RPC JavaScript client
 *
 * $Id: jsonrpc.js,v 1.36.2.3 2006/03/08 15:09:37 mclark Exp $
 *
 * Copyright (c) 2003-2004 Jan-Klaas Kollhof
 * Copyright (c) 2005 Michael Clark, Metaparadigm Pte Ltd
 *
 * This code is based on Jan-Klaas' JavaScript o lait library (jsolait).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

/* escape a character */

function escapeJSONChar(c)
{
    if(c == "\"" || c == "\\") return "\\" + c;
    else if (c == "\b") return "\\b";
    else if (c == "\f") return "\\f";
    else if (c == "\n") return "\\n";
    else if (c == "\r") return "\\r";
    else if (c == "\t") return "\\t";
    var hex = c.charCodeAt(0).toString(16);
    if(hex.length == 1) return "\\u000" + hex;
    else if(hex.length == 2) return "\\u00" + hex;
    else if(hex.length == 3) return "\\u0" + hex;
    else return "\\u" + hex;
};


/* encode a string into JSON format */

function escapeJSONString(s)
{
    /* The following should suffice but Safari's regex is b0rken
       (doesn't support callback substitutions)
       return "\"" + s.replace(/([^\u0020-\u007f]|[\\\"])/g,
       escapeJSONChar) + "\"";
    */

    /* Rather inefficient way to do it */
    var parts = s.split("");
    for(var i=0; i < parts.length; i++) {
	var c =parts[i];
	if(c == '"' ||
	   c == '\\' ||
	   c.charCodeAt(0) < 32 ||
	   c.charCodeAt(0) >= 128)
	    parts[i] = escapeJSONChar(parts[i]);
    }
    return "\"" + parts.join("") + "\"";
};


/* Marshall objects to JSON format */

function toJSON(o)
{
    if(o == null) {
	return "null";
    } else if(o.constructor == String) {
	return escapeJSONString(o);
    } else if(o.constructor == Number) {
	return o.toString();
    } else if(o.constructor == Boolean) {
	return o.toString();
    } else if(o.constructor == Date) {
	return '{javaClass: "java.util.Date", time: ' + o.valueOf() +'}';
    } else if(o.constructor == Array) {
	var v = [];
	for(var i = 0; i < o.length; i++) v.push(toJSON(o[i]));
	return "[" + v.join(", ") + "]";
    } else {
	var v = [];
	for(attr in o) {
	    if(o[attr] == null) v.push("\"" + attr + "\": null");
	    else if(typeof o[attr] == "function"); /* skip */
	    else v.push(escapeJSONString(attr) + ": " + toJSON(o[attr]));
	}
	return "{" + v.join(", ") + "}";
    }
};


// JSONRpcClient 'class'

/* JSONRpcClient constructor */

JSONRpcClient = function JSONRpcClient_ctor(serverURL, user, pass, objectID)
{
    this.serverURL = serverURL;
    this.user = user;
    this.pass = pass;
    this.objectID = objectID;

    /* Add standard methods */
    if(this.objectID) {
	this._addMethods(["listMethods"]);
	var req = this._makeRequest("listMethods", []);
    } else {
	this._addMethods(["system.listMethods"]);
	var req = this._makeRequest("system.listMethods", []);
    }
    var m = this._sendRequest(req);
    this._addMethods(m);
};


/* JSONRpcCLient.Exception */

JSONRpcClient.Exception =
function JSONRpcClient_Exception(code, message, javaStack)
{
    this.code = code;
    var name;
    if(javaStack) {
	this.javaStack = javaStack;
	var m = javaStack.match(/^([^:]*)/);
	if(m) name = m[0];
    }
    if(name) this.name = name;
    else this.name = "JSONRpcClientException";
    this.message = message;
};

JSONRpcClient.Exception.CODE_REMOTE_EXCEPTION = 490;
JSONRpcClient.Exception.CODE_ERR_CLIENT = 550;
JSONRpcClient.Exception.CODE_ERR_PARSE = 590;
JSONRpcClient.Exception.CODE_ERR_NOMETHOD = 591;
JSONRpcClient.Exception.CODE_ERR_UNMARSHALL = 592;
JSONRpcClient.Exception.CODE_ERR_MARSHALL = 593;

JSONRpcClient.Exception.prototype = new Error();

JSONRpcClient.Exception.prototype.toString =
function JSONRpcClient_Exception_toString(code, msg)
{
    return this.name + ": " + this.message;
};


/* Default top level exception handler */

JSONRpcClient.default_ex_handler =
function JSONRpcClient_default_ex_handler(e) { alert(e); };


/* Client settable variables */

JSONRpcClient.toplevel_ex_handler = JSONRpcClient.default_ex_handler;
JSONRpcClient.profile_async = false;
JSONRpcClient.max_req_active = 1;
JSONRpcClient.requestId = 1;


/* JSONRpcClient implementation */

JSONRpcClient.prototype._createMethod =
function JSONRpcClient_createMethod(methodName)
{
    var fn=function()
    {
	var args = [];
	var callback = null;
	for(var i=0;i<arguments.length;i++) args.push(arguments[i]);
	if(typeof args[0] == "function") callback = args.shift();
	var req = fn.client._makeRequest.call(fn.client, fn.methodName,
					      args, callback);
	if(callback == null) {
	    return fn.client._sendRequest.call(fn.client, req);
	} else {
	    JSONRpcClient.async_requests.push(req);
	    JSONRpcClient.kick_async();
	    return req.requestId;
	}
    };
    fn.client = this;
    fn.methodName = methodName;
    return fn;
};

JSONRpcClient.prototype._addMethods =
function JSONRpcClient_addMethods(methodNames)
{
    for(var i=0; i<methodNames.length; i++) {
	var obj = this;
	var names = methodNames[i].split(".");
	for(var n=0; n<names.length-1; n++) {
	    var name = names[n];
	    if(obj[name]) {
		obj = obj[name];
	    } else {
		obj[name]  = new Object();
		obj = obj[name];
	    }
	}
	var name = names[names.length-1];
	if(!obj[name]) {
	    var method = this._createMethod(methodNames[i]);
	    obj[name] = method;
	}
    }
};

JSONRpcClient._getCharsetFromHeaders =
function JSONRpcClient_getCharsetFromHeaders(http)
{
    try {
	var contentType = http.getResponseHeader("Content-type");
	var parts = contentType.split(/\s*;\s*/);
	for(var i =0; i < parts.length; i++) {
	    if(parts[i].substring(0, 8) == "charset=")
		return parts[i].substring(8, parts[i].length);
	}
    } catch (e) {}
    return "UTF-8"; /* default */
};

/* Async queue globals */
JSONRpcClient.async_requests = [];
JSONRpcClient.async_inflight = {};
JSONRpcClient.async_responses = [];
JSONRpcClient.async_timeout = null;
JSONRpcClient.num_req_active = 0;

JSONRpcClient._async_handler =
function JSONRpcClient_async_handler()
{
    JSONRpcClient.async_timeout = null;

    while(JSONRpcClient.async_responses.length > 0) {
	var res = JSONRpcClient.async_responses.shift();
	if(res.canceled) continue;
	if(res.profile) res.profile.dispatch = new Date();
	try {
	    res.cb(res.result, res.ex, res.profile);
	} catch(e) {
	    JSONRpcClient.toplevel_ex_handler(e);
	}
    }

    while(JSONRpcClient.async_requests.length > 0 &&
	  JSONRpcClient.num_req_active < JSONRpcClient.max_req_active) {
	var req = JSONRpcClient.async_requests.shift();
	if(req.canceled) continue;
	req.client._sendRequest.call(req.client, req);
    }
};

JSONRpcClient.kick_async =
function JSONRpcClient_kick_async()
{
    if(JSONRpcClient.async_timeout == null)
	JSONRpcClient.async_timeout =
	    setTimeout(JSONRpcClient._async_handler, 0);
};

JSONRpcClient.cancelRequest =
function JSONRpcClient_cancelRequest(requestId)
{
    /* If it is in flight then mark it as canceled in the inflight map
       and the XMLHttpRequest callback will discard the reply. */
    if(JSONRpcClient.async_inflight[requestId]) {
	JSONRpcClient.async_inflight[requestId].canceled = true;
	return true;
    }

    /* If its not in flight yet then we can just mark it as canceled in
       the the request queue and it will get discarded before being sent. */
    for(var i in JSONRpcClient.async_requests) {
	if(JSONRpcClient.async_requests[i].requestId == requestId) {
	    JSONRpcClient.async_requests[i].canceled = true;
	    return true;
	}
    }

    /* It may have returned from the network and be waiting for its callback
       to be dispatched, so mark it as canceled in the response queue
       and the response will get discarded before calling the callback. */
    for(var i in JSONRpcClient.async_responses) {
	if(JSONRpcClient.async_responses[i].requestId == requestId) {
	    JSONRpcClient.async_responses[i].canceled = true;
	    return true;
	}
    }

    return false;
};

JSONRpcClient.prototype._makeRequest =
function JSONRpcClient_makeRequest(methodName, args, cb)
{
    var req = {};
    req.client = this;
    req.requestId = JSONRpcClient.requestId++;

    var obj = {};
    obj.id = req.requestId;
    if (this.objectID)
	obj.method = ".obj#" + this.objectID + "." + methodName;
    else
	obj.method = methodName;
    obj.params = args;

    if (cb) req.cb = cb;
    if (JSONRpcClient.profile_async)
	req.profile = { "submit": new Date() };
    req.data = toJSON(obj);

    return req;
};

JSONRpcClient.prototype._sendRequest =
function JSONRpcClient_sendRequest(req)
{
    if(req.profile) req.profile.start = new Date();

    /* Get free http object from the pool */
    var http = JSONRpcClient.poolGetHTTPRequest();
    JSONRpcClient.num_req_active++;

    /* Send the request */
    if (typeof(this.user) == "undefined") {
	http.open("POST", this.serverURL, (req.cb != null));
    } else {
	http.open("POST", this.serverURL, (req.cb != null), this.user, this.pass);
    }

    /* setRequestHeader is missing in Opera 8 Beta */
    //    try { http.setRequestHeader("Content-type", "text/plain"); } catch(e) {}
    try { http.setRequestHeader("Content-type", "text/json"); } catch(e) {}

    /* Construct call back if we have one */
    if(req.cb) {
	var self = this;
	http.onreadystatechange = function() {
	    if(http.readyState == 4) {
		http.onreadystatechange = function () {};
		var res = { "cb": req.cb, "result": null, "ex": null};
		if (req.profile) {
		    res.profile = req.profile;
		    res.profile.end = new Date();
		}
		try { res.result = self._handleResponse(http); }
		catch(e) { res.ex = e; }
		if(!JSONRpcClient.async_inflight[req.requestId].canceled)
		    JSONRpcClient.async_responses.push(res);
		delete JSONRpcClient.async_inflight[req.requestId];
		JSONRpcClient.kick_async();
	    }
	};
    } else {
	http.onreadystatechange = function() {};
    }

    JSONRpcClient.async_inflight[req.requestId] = req;

    try {
	http.send(req.data);
    } catch(e) {
	JSONRpcClient.poolReturnHTTPRequest(http);
	JSONRpcClient.num_req_active--;
	throw new JSONRpcClient.Exception
	    (JSONRpcClient.Exception.CODE_ERR_CLIENT, "Connection failed");
    }

    if(!req.cb) return this._handleResponse(http);
};

JSONRpcClient.prototype._handleResponse =
function JSONRpcClient_handleResponse(http)
{
    /* Get the charset */
    if(!this.charset) {
	this.charset = JSONRpcClient._getCharsetFromHeaders(http);
    }

    /* Get request results */
    var status, statusText, data;
    try {
	status = http.status;
	statusText = http.statusText;
	data = http.responseText;
    } catch(e) {
	JSONRpcClient.poolReturnHTTPRequest(http);
	JSONRpcClient.num_req_active--;
	JSONRpcClient.kick_async();
	throw new JSONRpcClient.Exception
	    (JSONRpcClient.Exception.CODE_ERR_CLIENT, "Connection failed");
    }

    /* Return http object to the pool; */
    JSONRpcClient.poolReturnHTTPRequest(http);
    JSONRpcClient.num_req_active--;

    /* Unmarshall the response */
    if(status != 200) {
	throw new JSONRpcClient.Exception(status, statusText);
    }
    var obj;
    try {
	eval("obj = " + data);
    } catch(e) {
	throw new JSONRpcClient.Exception(550, "error parsing result");
    }
    if(obj.error)
	throw new JSONRpcClient.Exception(obj.error.code, obj.error.msg,
					  obj.error.trace);
    var res = obj.result;

    /* Handle CallableProxy */
    if(res && res.objectID && res.JSONRPCType == "CallableReference")
	return new JSONRpcClient(this.serverURL, this.user,
				 this.pass, res.objectID);

    return res;
};


/* XMLHttpRequest wrapper code */

/* XMLHttpRequest pool globals */
JSONRpcClient.http_spare = [];
JSONRpcClient.http_max_spare = 8;

JSONRpcClient.poolGetHTTPRequest =
function JSONRpcClient_pool_getHTTPRequest()
{
    if(JSONRpcClient.http_spare.length > 0) {
	return JSONRpcClient.http_spare.pop();
    }
    return JSONRpcClient.getHTTPRequest();
};

JSONRpcClient.poolReturnHTTPRequest =
function JSONRpcClient_poolReturnHTTPRequest(http)
{
    if(JSONRpcClient.http_spare.length >= JSONRpcClient.http_max_spare)
	delete http;
    else
	JSONRpcClient.http_spare.push(http);
};

JSONRpcClient.msxmlNames = [ "MSXML2.XMLHTTP.5.0",
			     "MSXML2.XMLHTTP.4.0",
			     "MSXML2.XMLHTTP.3.0",
			     "MSXML2.XMLHTTP",
			     "Microsoft.XMLHTTP" ];

JSONRpcClient.getHTTPRequest =
function JSONRpcClient_getHTTPRequest()
{
    /* Mozilla XMLHttpRequest */
    try {
	JSONRpcClient.httpObjectName = "XMLHttpRequest";
	return new XMLHttpRequest();
    } catch(e) {}

    /* Microsoft MSXML ActiveX */
    for (var i=0;i < JSONRpcClient.msxmlNames.length; i++) {
	try {
	    JSONRpcClient.httpObjectName = JSONRpcClient.msxmlNames[i];
	    return new ActiveXObject(JSONRpcClient.msxmlNames[i]);
	} catch (e) {}
    }

    /* None found */
    JSONRpcClient.httpObjectName = null;
    throw new JSONRpcClient.Exception(0, "Can't create XMLHttpRequest object");
};



//require("jsonrpc.js");

curry = function(fn, args) {
  return function() {
    fn.apply(window, args);
  };
};

function loadScript(path) {
    e = document.createElement("script");
    e.setAttribute("language", "javascript");
    e.setAttribute("src", path);
    document.getElementsById("body")[0].appendChild(e);
};

myapp = Object({
  onloads: [],

  addonload: function(f) {
      if (f != null)
          myapp.onloads.push(f);
  },

  topMenuColor: "#404040",
  rightColColor: "#00b3af",
  menuActiveColor: "white",

  menus: [
      {label: "Home",
       id: "navHomeTop",
       uri: "/",
       menuId: null,
       entries: null
      },
      {label: "About",
       id: "navAboutTop",
       menuId: "menuAbout",
       entries: [{label: "What is Rebirthing?",
                  id: "menuAboutIntro",
                  uri: "/about/intro"
                  },
                 {label: "Sessions",
                  id: "menuAboutSessions",
                  uri: "/about/sessions"
                  },
                 {label: "History of Rebirthing",
                  id: "menuAboutHistory",
                  uri: "/about/history"
                  },
                 {label: "Safety",
                  id: "menuAboutSafety",
                  uri: "/about/safety"
                  },
                 {label: "Frequently Asked Questions",
                  id: "menuAboutQuestions",
                  uri: "/about/questions"
                  }
                ]
      },
      {label: "Benefits",
       id: "navBenefitsTop",
       menuId: "menuBenefits",
       entries: [{label: "Health",
                  id: "menuBenefitsHealth",
                  uri: "/benefits/health"
                  },
                 {label: "Emotions",
                  id: "menuBenefitsEmotions",
                  uri: "/benefits/emotions"
                  },
                 {label: "Self-Esteem",
                  id: "menuBenefitsSelfesteem",
                  uri: "/benefits/selfesteem"
                  },
                 {label: "Relationships",
                  id: "menuBenefitsRelationships",
                  uri: "/benefits/relationships"
                  }
                 ]
      },
      {label: "Practitioners",
       id: "navPractitionersTop",
       menuId: "menuPractitioners",
       entries: [{label: "Northland",
                  id: "menuPractitionersNorthland",
                  uri: "/practitioners/northland"
                  },
                 {label: "Auckland",
                  id: "menuPractitionersAuckland",
                  uri: "/practitioners/auckland"
                  },
                 {label: "Waikato",
                  id: "menuPractitionersWaikato",
                  uri: "/practitioners/waikato"
                  },
                 {label: "Bay of Plenty",
                  id: "menuPractitionersBop",
                  uri: "/practitioners/bop"
                  },
                 {label: "Wellington",
                  id: "menuPractitionersWellington",
                  uri: "/practitioners/wellington"
                  },
                 {label: "Dunedin",
                  id: "menuPractitionersDunedin",
                  uri: "/practitioners/dunedin"
                  },
                 {label: "West Coast (South Island)",
                  id: "menuPractitionersSouthwest",
                  uri: "/practitioners/southwest"
                  }
                 ]
      },
  /* */
      {label: "Store",
       id: "navStoreTop",
       uri: "/store",
       menuId: null,
       entries: null
      },
  /* */

      {label: "Contact",
       id: "navContactTop",
       uri: "/contact",
       menuId: null,
       entries: null
      }
  ],

  initMenus: function(menus) {

      var i, j;

      // for each main menu heading...
      for (i=0; i<myapp.menus.length; i++) {

          // find menu entry and its dom element
          entry = myapp.menus[i];
          entry.elem = document.getElementById(entry.id);

          if (entry.elem == null) {
              alert("null element: " + entry.label);
              continue;
          }

          // convert from html link to js pseudo-link
          entry.elem.removeAttribute("href");
          entry.elem.style.textDecoration = "none";
          try { entry.elem.style.cursor = "pointer"; } catch (e) {}

          // install handler funcs
          entry.elem.onmouseover = curry(myapp.showMenu, [entry]);

          // bail from here if no menu attached
          if (entry.menuId == null) {
              //alert(entry.uri);
              if (entry.uri)
                  entry.elem.onclick = curry(myapp.rpcGetPages, [entry.uri, entry.elem]);
              continue;
          }

          // now process the menu itself and its entries
          entry.elemMenu = document.getElementById(entry.menuId);

          entry.elemMenu.onclick = myapp.hideAllMenus;
          //entry.elemMenu.onmouseout = myapp.hideAllMenus;

          // now, for each individual menu entry:
          for (j=0; j<entry.entries.length; j++) {

              // get menu entry's dom element
              subentry = entry.entries[j];

              if (!subentry)
                  alert("null subentry:id=" + entry.id + " j=" + j);
              elem = subentry.elem = document.getElementById(subentry.id);
              //myapp.ajaxifyLink(elem);
          }
      }
  },

  ajaxifyPanes: function() {
    return;
  //  console.log("ajaxifyPanes: entered");
    myapp.ajaxifyNode(myapp.elemPageLeft, "#8ff", "#336");
    myapp.ajaxifyNode(myapp.elemPageRight);
  //  console.log("ajaxifyPanes: done");
  },

  ajaxifyNode: function(elem, colorOn, colorOff) {

    links = elem.getElementsByTagName("a");

    for (var i=0, len=links.length; i<len; i++) {
      myapp.ajaxifyLink(links[i], colorOn, colorOff);
    }
  },

  ajaxifyLink: function(elem, colorOn, colorOff) {

  //  console.log("ajaxifyLink: href=%s txt=%s", elem.href, elem.innerHTML);
    var h = elem.href;

    // bail if no href
    if (h == null) {
      return;
    }

    // bail if no http:// or https://
    if (h.substr(0, 7) == "http://") {
      h = h.substr(7);
    } else if (h.substr(0, 8) == "https://") {
      h = h.substr(8);
    } else {
      return;
    }

    // bail if link points off-site
    domain = h.split("/", 1)[0];
    if (domain != document.domain) {
      return;
    }

    uri = h.substr(domain.length);
  //  console.log("ajaxifying to %s", uri);

    // convert from html link to js pseudo-link
    elem.removeAttribute("href");
    elem.style.textDecoration = "none";
    try { elem.style.cursor = "pointer"; } catch (e) {}

    myapp.unhighlight(elem, colorOff);

    // add mouse events
    elem.onmouseover = curry(myapp.highlight, [elem, colorOn]);
    elem.onmouseout = curry(myapp.unhighlight, [elem, colorOff]);
    elem.onclick = curry(myapp.rpcGetPagesSubmenu, [uri, elem]);
  },

  highlight: function(elem, color) {
    if (!color) color = "white";
    elem.style.color = color;
  //  elem.style.backgroundColor = "#404040";
  },

  unhighlight: function(elem, color) {
    if (!color) color = "#404040";
    elem.style.color = color;
  //  elem.style.backgroundColor = "#00b3af";
  },

  showMenu: function(menu) {

      myapp.hideAllMenus();
      menu.elem.style.color = myapp.menuActiveColor;
      menu.elem.style.backgroundColor = myapp.rightColColor;
      if (menu.elemMenu)
          menu.elemMenu.style.display = "inline";
      //alert("show menu: " + menu.label);
  },

  hideAllMenus: function() {

      var i;

      for (i=0; i<myapp.menus.length; i++) {

          entry = myapp.menus[i];
          if (!entry.elem) continue;

          // un-highlight the menu label
          entry.elem.style.color = myapp.topMenuColor;
          entry.elem.style.backgroundColor = "";

          // hide the menu
          if (entry.elemMenu) {
              entry.elemMenu.style.display = "none";
          }
      }
  },

  rpcGetPagesSubmenu: function(uri, elem) {
    elem.style.color = "#404040";
    elem.style.backgroundColor = "#00b3af";
    myapp.hideAllMenus();
    myapp.rpcGetPages(uri, elem)
  },

  rpcGetPages: function(uri, elem) {

  //alert("rpc: uri="+uri);

    myapp.elemPageLeft.style.color = "#fff";
    myapp.elemPageLeft.style.backgroundColor = "#cee";

    url = document.documentURI;
    url = "http://" + document.domain + "/RPC2";

    // disabled RPC for now - force whole-page reload
    document.location = "http://" + document.domain + uri;
    return;

    // rpc via vcXMLRPC
  //  XMLRPC.send(url, "getpanes", [uri, {}], myapp.rpcOnResponse);

    // rpc via mimic
    //alert("url=" + url);

    // rpc via json-rpc
    res = myapp.jsonrpc.getpanes(uri, {});
    myapp.rpcOnResponse(res);

    //var request = new XmlRpcRequest(url, "getpanes");  
    //request.addParam(uri);
    //request.addParam({});
    //var response = request.send();  
    //alert("fault: " + response.faultValue);
    //jsresp = response.parseXML();
    //alert("jsresp=" + jsresp);
    //myapp.xmlrpcOnResponse(response.parseXML());
  },

  rpcOnResponse: function(resp) {

  //  alert(resp);

    var pageLeft = resp.left;
    var pageRight = resp.right;

    myapp.elemPageLeft.innerHTML = pageLeft;
    myapp.elemPageRight.innerHTML = pageRight;

    myapp.ajaxifyPanes();

    //alert(pageLeft); alert(pageRight);
    myapp.elemPageLeft.style.backgroundColor = "#cef";
    myapp.elemPageLeft.style.color = "black";
  },

  init: function() {

    // -----------------------------------------
    // find some DOM elements
    myapp.elemPageLeft = document.getElementById("pageLeft");
    myapp.elemPageRight = document.getElementById("pageRight");
    myapp.elemRowMain = document.getElementById("rowMain");
    myapp.elemRowMain.onclick = myapp.hideAllMenus;
    myapp.elemBody = document.getElementsByTagName("body")[0];

    // hide the javascript warning paragraph
    myapp.jWarning = document.getElementById("javascriptWarning");
    if (myapp.jWarning != null) {
      myapp.jWarning.style.display = "none";
    } else {
      //alert("can't find jswarning element");
    }

    // conditionally process the menu - only if using vcXMLRPC
  /*
    if (!isOTHER) {
      myapp.initMenus();
      myapp.ajaxifyPanes();
    }
  */
    try { 
      myapp.initMenus();
      //myapp.ajaxifyPanes();
    } catch (e) {};

    // create the jsonrpc proxy
    myapp.jsonuri = "http://" + document.domain + "/jsonrpc"
    myapp.jsonrpc = new JSONRpcClient(myapp.jsonuri);

    // run the init funcs
    for (i=0; i<myapp.onloads.length; i++) {
      myapp.onloads[i]();
    }

    console.log("initialisation completed ok");
  },

});

try {
  console.log("Console enabled");
} catch (e) {
  //alert("adding fake console.log func");
  var console = Object();
  console.log = function() {};
}

myapp.addonload(window.onload);
window.onload = myapp.init;


//alert("back from initmenus");

