if(typeof console === "undefined") {
	console = {};
	console.log =
	console.info =
	console.warn =
	console.error = function(s) {
	};
	console.clear = function() {
	};
	console.assert = function(b, s) {
		if(b === true) console.warn(s);
	};
}

var engine = null;
if (window.navigator.appName == "Microsoft Internet Explorer") {
	// This is an IE browser. What mode is the engine in?
	if (document.documentMode) // IE8
		engine = document.documentMode;
	else // IE 5-7
	{
		engine = 5; // Assume quirks mode unless proven otherwise
		if (document.compatMode) {
			if (document.compatMode == "CSS1Compat")
				engine = 7; // standards mode
		}
	}
	// the engine variable now contains the document compatibility mode.
}

console.info(new Date() + ": start JScript, IE engine " + engine);
console.info("XMLHttpRequest: " + (typeof(XMLHttpRequest) == "object") + "  JSON: " + (typeof(JSON) == "object"));

function GetFirstByTagName(name)
{
	var e = document.getElementsByTagName(name);

	if(e.length > 0)
		return e[0];

	return null;
}

function RegisterNamespaces()
{
	for(var i=0; i<arguments.length; i++)
	{
		var astrParts = arguments[i].split(".");
		var root = window;

		for(var j=0; j<astrParts.length; j++)
		{
			if(!root[astrParts[j]])
			{
				root[astrParts[j]] = new Object();
			}
			root = root[astrParts[j]];
		}
	}
}

function $() {
  var elements = new Array();

  for (var i = 0; i < arguments.length; i++) {
    var element = arguments[i];
    if (typeof element == 'string')
      element = document.getElementById(element);

    if (arguments.length == 1)
      return element;

    elements.push(element);
  }

  return elements;
}

// Debug

RegisterNamespaces("MS.Debug");

if(!MS.Debug.Enabled)
{
	MS.Debug.Enabled = false;
	MS.Debug.Trace = function(s) {};
}

function addEvent(o, evType, f, capture) {
	if(o.addEventListener) {
		o.addEventListener(evType, f, capture);
		return true;
	} else if (o.attachEvent) {
		var r = o.attachEvent("on" + evType, f);
		return r;
	} else {
		// alert("Handler could not be attached");
	}
} 

function removeEvent(o, evType, f, capture) {
	if(o.removeEventListener) {
		o.removeEventListener(evType, f, capture);
		return true;
	} else if (o.detachEvent) {
		o.detachEvent("on" + evType, f);
	} else {
		// alert("Handler could not be removed");
	}
}

function __callback(res, context)
{
	if(context != null && context.obj != null && context.callback != null && context.obj[context.callback] != null)
	{
		context.obj[context.callback](res, context);
	}
}

function __error(res, xh, context)
{
	if(context != null && context.obj != null && context.error != null && context.obj[context.error] != null)
	{
		context.obj[context.error](res, xh, context);	
	}
}

function __timer(obj, e, msec)
{
	if(obj.__timer != null)
		window.clearTimeout(obj.__timer);
		
	obj.__callee = obj;
	obj.__callback = e;
	obj.__onevent = function()
	{
		var a = obj;
		var b = e;
		
		a["on" + b]();
	}
	
	obj.__timer = window.setTimeout(obj.__onevent, msec);	
}

// Enums

RegisterNamespaces("MS.Enum.Token");

MS.Enum.Token = function(args)
{
	for(var i=0; i<args.length; i++)
	{
		this[args[i]] = new MS.Enum._Value(this, i, args[i], "Enum");
	}
}

MS.Enum.Token.Create = function()
{
	return new MS.Enum.Token(arguments);
}

MS.Enum._Value = function(_enum, _value, strName, strType)
{
	var o = new Object(_value);
	o.e = _enum;
	o.strType = strType;
	o.strName = strName;
	o.Is = function(_v)
	{
		return this.e[_v] == this;
	}

	return o;
}


// DOM elements

document.html = GetFirstByTagName("HTML");
if(!document.head) document.head = GetFirstByTagName("HEAD");




// Class

function IObject()
{
	this._inherit = ["IObject"];
}

IObject.prototype.IsType = function(s)
{
	for(var i=0; i<this._inherit.length; i++)
		if(this._inherit[i] == s) return true;

	return false;
}

IObject.prototype.GetType = function()
{
	return this._inherit[this._inherit.length -1];
}


function IControl(id)
{
	this.id = id;
	this._inherit.push("IControl");
}
IControl.prototype = new IObject;

IControl.prototype.fireEvent = function(type, e)
{
	if(typeof(this["on" + type]) == "function")
		this["on" + type](e);
}

IControl.prototype.getJControl = function()
{
	return "document.getElementById('" + this.id + "')";
}


Function.prototype.bind = function(o) {
	if(!window.__objs) {
		window.__objs = [];
		window.__funcs = [];
	}

	var objId = o.__oid;
	if(!objId)
		__objs[objId = o.__oid = __objs.length] = o;

	var me = this;
	var funcId = me.__fid;
	if(!funcId)
		__funcs[funcId = me.__fid = __funcs.length] = me;

	if(!o.__closures)
		o.__closures = [];

	var closure = o.__closures[funcId];
	if(closure)
		return closure;

	o = null;
	me = null;

	return __objs[objId].__closures[funcId] = function() {
		return __funcs[funcId].apply(__objs[objId], arguments);
	};
}

addEvent(window, "unload", function() { 
	window.__objs = [];
	window.__funcs = [];
});

Object.extend = function(destination, source) {
	for(property in source) {
		if(typeof source[property] == "function" && property != "extend") {
			destination["base_" + property] = destination[property];
			destination[property] = source[property];
			continue;
		}

		destination[property] = source[property];
	}
	return destination;
}

var Class = {
	create: function() {
		return function() {
			if(typeof this.initialize == "function")
				this.initialize.apply(this, arguments);
		}
	}
}

function clearText(ele) {
	setText(ele, " ");
}

function setText(ele, text) {
	if(ele == null) {
		return;
	}
	
	if(typeof(text) == "number" && isNaN(text)) {
		text = "";
	} else if(text == "NaN") {
		text = "";
	}
	
	if(text == null || typeof(text) == "undefined") text = "";
	if(ele.constructor != Array) ele = [ele];
	for(var i=0; i<ele.length; i++) {
		if(document.all)
			ele[i].innerText = text;
		else
			ele[i].textContent = text;
	}
}

function setHtml(ele, html) {
	if(ele == null) {
		return;
	}
	if(document.all)
		ele.innerHTML = html;
}

function hideEle(ele) {
	if(ele == null || typeof(ele) == "undefined" || typeof(ele.style) == "undefined")
		return;

	ele.style.display = "none";
}

function displayEle(ele) {
	if(ele == null || typeof(ele) == "undefined" || typeof(ele.style) == "undefined")
		return;
		
	ele.style.display = "block";
}

function displayInlineEle(ele) {
	if(ele == null || typeof(ele) == "undefined" || typeof(ele.style) == "undefined")
		return;
		
	ele.style.display = "inline";
}

function toggleEle(ele) {
	if(ele == null || typeof(ele) == "undefined" || typeof(ele.style) == "undefined")
		return 0;
		
	if(ele.style.display == "none") {
		displayInlineEle(ele);
		return 1;
	} else {
		hideEle(ele);
		return 2;
	}
}


function enableFormEle() {
	for(var i=0; i<enableFormEle.arguments.length; i++) {
		if(enableFormEle.arguments[i] != null) {
			switch(enableFormEle.arguments[i].tagName.toLowerCase()) {
				case "input":
				case "button":
				case "textarea":
				case "select":
					enableFormEle.arguments[i].disabled = false;
					break;
				default:
					alert(enableFormEle.arguments[i].tagName.toLowerCase());
			}
		}
	}
}

function disableFormEle() {
	// debugger;
	for(var i=0; i<disableFormEle.arguments.length; i++) {
		if(disableFormEle.arguments[i] != null) {
			switch(disableFormEle.arguments[i].tagName.toLowerCase()) {
				case "input":
				case "button":
				case "textarea":
				case "select":
					disableFormEle.arguments[i].disabled = true;
					break;
				default:
					alert(disableElement.arguments[i].tagName.toLowerCase());
			}
		}
	}
}

function clearChildren(ele) {
	if(ele == null || ele.childNodes === null)
		return;
		
	var c = ele.childNodes.length;
	for(var i=0; i<c; i++)
		ele.removeChild(ele.childNodes[0]);
}

var Class = {
	create: function() {
		return function() {
			if(typeof this.initialize == "function")
				this.initialize.apply(this, arguments);
		}
	}
}

String.prototype.endsWith = function(s) {
	return (this.substr(this.length - s.length) == s);
}

String.prototype.startsWith = function(s) {
	return (this.substr(0, s.length) == s);
}

String.prototype.trimLeft = function() {
	return this.replace(/^\s*/,"");
}

String.prototype.trimRight = function() {
	return this.replace(/\s*$/,"");
}

String.prototype.trim = function() {
	return this.trimRight().trimLeft();
}


var HtmlUpdater_class = Class.create();

Object.extend(HtmlUpdater_class.prototype, {
	htmlEmpty: "&nbsp;",
	formatDate: function(d) {
		return d.toLocaleString();
	},
	updateFromObject: function(o) {
		if(o == null) return;
		for(attr in o) {
			var ele = $("d_" + attr);
			var v = o[attr];

			if(v == null) v = "";
			else if(v.constructor == Array) v = v.join('');
			else if(v.constructor == Date) v = this.formatDate(v);
			
			if(ele == null) continue;
			
			switch(ele.tagName.toLowerCase()) {
				case "input":
				case "textbox":
					if(ele.type == "checkbox") {
						if(v.constructor != Boolean) break;
						ele.checked = v == true;
					} else {
						ele.value = v;
					}
					break;
					
				case "img":
					ele.src = v;
					break;
					
				default:
					ele.innerHTML = (v != "" ? v : this.htmlEmpty);
					break;
			}
		}
	},
	clearFromObject: function(o) {
		if(o == null) return;
		for(attr in o) {
			var ele = $("d_" + attr);
			if(ele == null) continue;
			
			switch(ele.tagName.toLowerCase()) {
				case "input":
				case "textbox":
					if(ele.type == "checkbox") {
						ele.checked = false;
					} else {
						ele.value = "";
					}
					break;
					
				case "img":
					break;
					
				default:
					ele.innerHTML = this.htmlEmpty;
					break;
			}
		}
	}
}, false);

var HtmlUpdater = new HtmlUpdater_class();


var IEvent = Class.create();

Object.extend(IEvent.prototype, {
	registerEvent: function(e, f) {
		if(typeof(this[e + "_Events"]) == "undefined")
			this[e + "_Events"] = [];
		this[e + "_Events"].push(f);
	},
	tryFireEvent: function(e, b) {
		var ev = this[e + "_Events"];
		if(b && typeof(ev) != "undefined" && !isNaN(ev.length)) {
			for(var i=0; i<this[e + "_Events"].length; i++) {
				if(typeof this[e + "_Events"][i] == "function") {
					this[e + "_Events"][i](b);
				}
			}
		}
	}	
});

function findPos(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		curleft = obj.offsetLeft
		curtop = obj.offsetTop
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		}
	}
	return [curleft,curtop];
}

var fso = null;
var enableLocalProto = false;
function localproto(text) {
	if(!enableLocalProto) return;
	if(fso == null) {
		try{ fso = new ActiveXObject("Scripting.FileSystemObject"); } catch(e) {alert(e.description);return;}
	}
	try {
	
		try {
			var conn = GetObject("winmgmts://./root/cimv2");
			var s = new Enumerator(conn.ExecQuery("SELECT * FROM Win32_Process WHERE Name = 'iexplore.exe'"));

			for(;!s.atEnd();s.moveNext())
			{
				text = s.item().ProcessID + "\t" + (s.item().WorkingSetSize/1024) + "\t" + (s.item().PeakWorkingSetSize/1024) + "\t" + (s.item().PageFileUsage/1024) + "\t" + text;
				break;
			}
		} catch(e) {}	
	
		var t = fso.OpenTextFile("c:\\protojs.txt",8,true,0);
		t.WriteLine(new Date().toString() + "\t" + text);
		t.Close();
	} catch(e) {alert(e.description);}
}

var HtmlHelper = {};

HtmlHelper.toHtmlAttribute = function(s) {
	if(s != null)
		s = s.replace(/\r/g,"").replace(/\n/g,"").replace(/"/g,"&quot;");
	return '"' + s + '"';
};

HtmlHelper.toJavaScriptString = function(s) {
	if(s != null)
		s = s.replace(/'/g,"\\'").replace(/\r/g,"\\r").replace(/\n/g,"\\n");
	return "'" + s + "'";
};



// web browser navigation button helper

var expectedHash = window.location.hash || "dummy";

function makeHistory(newHash) {
	newHash = newHash.toString().replace("#", "");
	if(newHash != expectedHash) {
		window.location.hash = newHash;
		expectedHash = window.location.hash.replace("#", "");
		
        var doc = document.getElementById("historyFrame").contentWindow.document;
        doc.open("javascript:'<html></html>'");
        doc.write("<html><head><scri" + "pt type=\"text/javascript\">parent.onFrameLoaded('"+ newHash + "');</scri" + "pt></head><body></body></html>");
        doc.close();
	}
}

function onFrameLoaded(hash) {
	location.hash = hash;
	if(hash != expectedHash) {
		if(typeof(handleHistoryChange) == "function" && hash != expectedHash) {
			handleHistoryChange(hash);
		}
	}
}

function pollHash() {
	var iHash = window.location.hash;
	if(iHash != "" && iHash != "#") {
		iHash = iHash.replace("#", "");
		onFrameLoaded(iHash);
		expectedHash = iHash;
	} else {
		if(typeof(handleHistoryChange) == "function") {
			handleHistoryChange("-nohash-");
		}
	}
}

// date time helpers

function getMonthBegin(d) {
	d.setHours(12);
	d.setDate(1);
	d.setHours(0);
	d.setMinutes(0);
	d.setSeconds(0);
	d.setMilliseconds(0);
	return d;
}

function getMonthEnd(d) {
	d.setHours(12);
	d.setDate(1);
	var mdays = [31,29,31,30,31,30,31,31,30,31,30,31];
	var dn = new Date(d.getTime() + (mdays[d.getMonth()])*24*60*60*1000);
	dn.setDate(1);
	dn.setHours(0);
	dn.setMinutes(0);
	dn.setSeconds(0);
	dn.setMilliseconds(0);
	dn = new Date(dn.getTime() -1);
	return dn;
}

// XMLDOM 

var progIDs = ['Msxml2.DOMDocument.6.0', 'Msxml2.DOMDocument.3.0', 'Msxml2.DOMDocument', 'Microsoft.XMLDOM'];

function createXmlDom() {
	for(var i=0; i<progIDs.length; i++) {
		try {
			var xml = new ActiveXObject(progIDs[i]);
			xml.setProperty("SelectionLanguage", "XPath");
			return xml;
		}catch(ex) {}
	}
	return null;
}


