/*----------------------------------------------------------------------------\
|                                JSVM 2.0                                     |
|-----------------------------------------------------------------------------|
|                         Created by Wan.Changhua                             |
|                      (Email,MSN: wch3116@hotmail.com)                       |
|                      For Homolo (http://jsvm.homolo.com/)                   |
|-----------------------------------------------------------------------------|
| An object based javascript framework, targeted at rich web applications,    |
| JSVM (JavaScript Virtual Machine) is implemented in JavaScript. Currently   |
| only internet explorer 5.5 and later and firefox and opera are supported.   |
|-----------------------------------------------------------------------------|
|                   Copyright (c) 2004 - 2005 Homolo JSVM Team                |
|-----------------------------------------------------------------------------|
|                                                                             |
| BSD - FreeBSD Copyright Information License                                 |
|                                                                             |
| Permission is hereby granted, free of charge, to any person obtaining a     |
| copy of this software and associated documentation files (the "Software"),  |
| to deal in the Software without restriction, including without limitation   |
| the rights to use, copy, modify, merge, publish, distribute, sublicense,    |
| and/or sell copies of the Software, and to permit persons to whom the       |
| Software is furnished to do so, subject to the following conditions:        |
|                                                                             |
| The above copyright notice and this permission notice shall be included     |
| in all copies or substantial portions of the Software.                      |
|                                                                             |
| This software is provided "as is", without warranty of any kind, express or |
| implied, including  but not limited  to the warranties of  merchantability, |
| fitness for a particular purpose and noninfringement. In no event shall the |
| authors or  copyright  holders be  liable for any claim,  damages or  other |
| liability, whether  in an  action of  contract, tort  or otherwise, arising |
| from,  out of  or in  connection with  the software or  the  use  or  other |
| dealings in the software.                                                   |
|                                                                             |
|-----------------------------------------------------------------------------|
| Dependencies: ./rtenv.conf, ./bin/*.js                                      |
|-----------------------------------------------------------------------------|
| 2005-01-02 | Renamed filename to jsre.js and updated the version to 2.01.   |
| 2005-11-08 | Ignored error when Userdata is invalid.                        |
| 2005-11-16 | Updated the currentVersion property to "2.01.051116".          |
| 2005-12-06 | Updated the currentVersion property to "2.02.051206".          |
| 2006-01-07 | Updated the currentVersion property to "2.02.060107".          |
| 2006-01-27 | Updated the currentVersion property to "2.02.060127".          |
| 2006-02-08 | Updated the currentVersion property to "2.02.060208".          |
| 2006-02-09 | Updated the currentVersion property to "2.02.060209".          |
|-----------------------------------------------------------------------------|
| Created 2005-01-02 | All changes are in the log above. | Updated 2006-02-09 |
\----------------------------------------------------------------------------*/

/**
 * Define JSVM Namespace and
 * JSVM Runtime Environment Variable
 * @file:	jsre.js
 * @author:	Wan Changhua
 * @date:	2005.01.02
 */

/*@cc_on @*/
/*@if (!@_jsvm_loaded) @*/

/* JSVM Namespace Object */

window._JSVM_Namespace = new function ()
{
	/* Device Number */
	this.deviceNumber = 0x3116;

	/* JSVM Runtime Environment Object */
	this.runtimeEnvironment = new function ()
	{
		this.currentVersion = "2.02.060209";
		this.navigator = "unknow";
		this.jsvmHome = ".";
		this.mode = "standalone";
		this.classpath = "";
		this.debug = false;

		this.window = window;
		this.element = null;
		this.parent = null;
		this.JSVM = null;
		this.resources = {};
		this.extModules = [];
		this.logs = [];
		this.state = 1;

		/* define interface */

		this.config = {
			getParameter : function(){}
		};
		this.live = function()
		{
			return (this.window.closed == false);
		}
		this.log = function (log)
		{
			this.logs[this.logs.length] = log;
		}
		this.getParent = function ()
		{
			if (this.parent != null)
			{
				try
				{
					this.parent.live();
				}
				catch(ex)
				{
					this.parent = null;
				}
			}
			return this.parent;
		}
		this.getResource = function (name)
		{
			return ((res = this.resources[name]) != null) ?
				res : _JSVM_Namespace.plugIn.localCache.get(name);
		}
		this.setResource = function (name, obj)
		{
			_JSVM_Namespace.plugIn.localCache.put(name,
				(this.resources[name] = String(obj)));
		}
	}

	/* Kernel Component */
	this.kernel = {};

	/* Development Kit */
	this.developmentKit = {};

	/* Plug-In */
	this.plugIn = {
		localCache : {
			get : function(){},
			put : function(){} },
		systemResloader : {}
	};

};

_JSVM_Namespace.initialize = function (element)
{

// begin of function

try
{

/* Define JSVM Runtime Environment Variable */
var jsre = this.runtimeEnvironment;
jsre.element = element;

jsre.log("JSVM_Namespace.rtenv: Initialize...");

var ua, jh, src, mode;

/* jsre.navigator */
jsre.navigator = (/opera/i.test(ua = navigator.userAgent)) ?
	"opera" : ((/gecko/i.test(ua)) ? "moz" :
	((/msie/i.test(ua)) ? "ie" : "other"));

var isIE = jsre.navigator == "ie";
var isMOZ = jsre.navigator == "moz";
var isOPERA = jsre.navigator == "opera";

var getOwnerElementAttribute = function (name)
{
	var v = jsre.element.getAttribute(name);
	return (isOPERA && v == "")	? null : v;
}

/* jsre.mode [standalone|application|module|auto]*/

jsre.log("JSVM_Namespace.rtenv: Get system properties...");

jsre.jsvmHome = ((jh = getOwnerElementAttribute("jsvm_home")) != null) ?
	jh : ((index = (src =getOwnerElementAttribute("src")).replace(/\\/g,"/").lastIndexOf(
		"/")) == -1) ? "." : src.substring(0, index);

jsre.mode = ((mode = getOwnerElementAttribute("mode")) == null) ?
	jsre.mode : (",standalone,application,module,auto,".indexOf(
		mode = mode.toLowerCase()) == -1) ?	jsre.mode : mode;

/* Search _JSVM_Namespace for parent */
if (jsre.mode == "module" || jsre.mode == "auto")
{
	var winHDL = window, pJsvmNs;
	while (true)
	{
		if (((winHDL.opener != null && winHDL.opener.closed == false
			&& (pJsvmNs = winHDL.opener._JSVM_Namespace) != null) ||
			(typeof(dialogArguments) != "undefined" &&
				(pJsvmNs = (dialogArguments._JSVM_Namespace != null) ?
				dialogArguments._JSVM_Namespace : ((dialogArguments.window != null
				&& dialogArguments.window._JSVM_Namespace != null) ?
				dialogArguments.window._JSVM_Namespace : null)) != null))
			&& pJsvmNs.runtimeEnvironment.mode == "application")
		{
			jsre.parent =	pJsvmNs.runtimeEnvironment;
			jsre.mode = "module";
			break;
		}
		if (winHDL == winHDL.parent &&
			winHDL.opener == null &&
				winHDL.dialogArguments == null)
		{
			if (jsre.mode == "auto")
			{
				jsre.mode = "standalone";
			}
			break;
		}
		if (winHDL.parent.closed == false &&
			(pJsvmNs = winHDL.parent._JSVM_Namespace) != null &&
			pJsvmNs.runtimeEnvironment.mode == "application")
		{
			jsre.parent =	pJsvmNs.runtimeEnvironment;
			jsre.mode = "module";
			break;
		}
		winHDL = (((winHDL.parent != winHDL) ? winHDL.parent : null)
			|| winHDL.opener || (winHDL.dialogArguments
				&& winHDL.dialogArguments.window));
	}
}

if (jsre.mode != "module")
{
	/* jsre.classpath */
	jsre.classpath = ((cp = getOwnerElementAttribute(
		"classpath"))	!= null) ? cp : "";

	/* jsre.debug */
	jsre.debug = ((debug = getOwnerElementAttribute("debug")) != null
		&& (debug.toLowerCase()	== "true")) ? true : false;

	var rtInf = "";
	if (/ jsvm2Config=([^;]*)/.test(" " + document.cookie))
	{
		rtInf = unescape(RegExp.$1);
	}
	else
	{
		var xmlHttp = (!isIE) ? (new XMLHttpRequest())
			: (new ActiveXObject("Microsoft.XMLHTTP"));
		xmlHttp.open("GET", jsre.jsvmHome + "/rtenv.conf", false);
		try
		{
			xmlHttp.send(null);
		}
		catch (ex)
		{
			throw "JSVM_Namespace.rtenv: " + ex;
		}
		if (xmlHttp.status == 0 || xmlHttp.status == 200)
		{
			rtInf = xmlHttp.responseText.replace(/#([^"\n\r]*)((\r\n)|$)/g, "")
				.replace(/\[([^"\n\r]*)\]/g, "").replace(/\r\n(\s)*\r\n/g, "\r\n");
			document.cookie = "jsvm2Config=" + escape(rtInf);
		}
		else
		{
			throw "JSVM_Namespace.rtenv: can't find rtenv.conf.";
		}
	}

	var cfg = jsre.config = new function ()
	{
		var content = rtInf, params = {};
		var parseParam = function (name)
		{
			var re = new RegExp("(\\^|\\r\\n)( |\\t)*("
				+ name + ")( |\\t)*=( |\\t)*(.*)($|\\r\\n)");
			return re.test(content) ? RegExp.$6.replace(/\s+$/g, "") : null;
		}
		this.getParameter = function(name)
		{
			return ((p = params[name]) != null ||	(p = params[name]
				= getOwnerElementAttribute(name)) != null) ?
				p :	(params[name] = parseParam(name));
		}
	}

	jsre.extModules = jsre.extModules.concat(
		((tmp = cfg.getParameter("ExtModules")) == null ||
			tmp == "") ? [] : tmp.replace(/,$/, "").split(","));
	jsre.classpath = ((tmp = cfg.getParameter("classpath"))
		== null) ? "" : tmp;

	if (!jsre.debug)
	{
		// implement localCache
		if (isIE)
		{
			_JSVM_Namespace.plugIn.localCache = new function()
			{
				var preName = "jsvm_cache_CoreFuncs"
					+ jsre.currentVersion.replace(/\./g, "_");
				var elmt = document.createElement("meta");
				elmt.addBehavior("#default#userdata");
				document.getElementsByTagName("head")[0].appendChild(elmt);
				var udIsOk = true;
				/* public interface */
				this.get = function(name)
				{
					// Returns null when userdata is invalid
					if (!udIsOk)
					{
						return null;
					}
					try
					{
						elmt.load(preName + "_"	+ name.replace(/\$|\{|\}/g, "_"));
						return elmt.getAttribute("code");
					}
					catch (ex)
					{
						udIsOk = false;
						return null;
					}
				}
				this.put = function(name, value)
				{
					// Do noting then userdata is invalid
					if (!udIsOk)
					{
						return;
					}
					try
					{
						name = preName + "_"
							+ name.replace(/\$|\{|\}/g, "_");
						elmt.load(name);
						elmt.setAttribute("code", value);
						elmt.save(name);
					}
					catch (ex)
					{
						udIsOk = false;
					}
				}
			}
		}
		else
		{
			/** for other platforms
			 *  (not implemented)
			 */
		}
	}
}
else
{
	var rjsre = jsre.getParent();
	if (rjsre == null)
	{
		throw "JSVM_Namespace.rtenv: 'Module' must work under a "
			+ "appliction, System can't find anyone";
	}
	jsre.navigator = rjsre.navigator;
	jsre.classpath = rjsre.classpath;
	jsre.debug = rjsre.debug;
	jsre.config = new function ()
	{
		var config = rjsre.config;
		this.getParameter = function(name)
		{
			return config.getParameter(name);
		}
	}
	jsre.getResource = function (name)
	{
		return this.getParent().getResource(name);
	}
	jsre.setResource = function (name, obj)
	{
		this.getParent().setResource(name, obj);
	}
}

/* Function: load system resource */
var cacheIsOk = true;
var loadModule = function (name)
{
	var code = cacheIsOk ? jsre.getResource("$code{" + name + "}") : null;
	if (code != null && jsre.state == 1)
	{
		try
		{
			eval("(" + code	+ ")();");
			jsre.log("JSVM_Namespace.rtenv: "
				+ "Load core function '" + name + "' succ.");
		}
		catch (ex)
		{
			jsre.state = 0;
			jsre.log(ex);
			jsre.log("JSVM_Namespace.rtenv: "
				+ "Load core function '" + name + "' fail.");
		}
	}
	else
	{
		cacheIsOk = false;
		document.write("<script src='"
			+ jsre.jsvmHome	+ "/bin/"
			+ (((tmpRes = jsre.config.getParameter(name))
				== null) ? (name + ".js") : tmpRes)
			+ "'></script>");
	}
}

jsre.log("JSVM_Namespace.rtenv: Load core functions...");

loadModule("kernel");
if (jsre.mode == "module")
{
	loadModule("runtime.module");
	loadModule("module");
}
else
{
	loadModule(jsre.navigator);
	loadModule("runtime");
	if (jsre.mode == "application")
	{
		loadModule("application");
	}
}

for (var i = 0; i < jsre.extModules.length; i++)
{
	var m = jsre.extModules[i].replace(/\.[j|J][s|S]$/g ,"");
	loadModule((/[\\|\/]/.test(m))? m : ("extends/" + m));
}


}
catch(ex)
{
	jsre.log((!ex.description) ? ex.toString()
		: ("Error: " + ex.description));
	jsre.log("JSVM_Namespace.rtenv: load jsre.js error!");
	if (jsre.dubug)
	{
		alert("JSVM Load Error , logs: \r\n ---------\r\n"
			+ "URL: " + document.URL + "\r\n ---------\r\n"
			+ jsre.logs.join("\r\n"));
	}
}
finally
{
	if (isIE)
	{
		setTimeout("CollectGarbage();", 1);
	}
}

// end of function

};

/* Get self element */
var scripts = document.getElementsByTagName("SCRIPT");
var element = scripts[scripts.length - 1];

/* Initialize JSVM Runtime Environment */
_JSVM_Namespace.initialize(element);
scripts = element = void(0);

/*@set @_jsvm_loaded = true; @*/
/*@else @*/
/*@end @*/