 // !Document Information::TMCore
/**
 *	TMCore
 *	TheoreticalMedia
 *	@author Nate Schulz
 *	@version 0.5.1
 */

String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ''); };
/*
Object.prototype.extend = function() {
	// copy reference to target object
	var target = arguments[0], a = 1;

	// extend jQuery itself if only one argument is passed
	if ( arguments.length == 1 ) {
		target = this;
		a = 0;
	}
	var prop;
	while ( (prop = arguments[a++]) != null )
		// Extend the base object
		for ( var i in prop ) {
			target[i] = prop[i];
		}
	// Return the modified object
	return target;
};
*/

var FOCUSED_OBJECT = null;

var TMCore = function(a,c) {
	//if (typeof a == "string" || typeof a == "object") 
	if ( window == this || !this.init )
		return new TMCore(a,c);

	return this.init(a,c);
};

var $TM = TMCore;
TMCore.fn = TMCore.prototype = {
	init: function(a,c) {
		// Make sure that a selection was provided
		a = a || document;
	
		// HANDLE: $TM(function)
		// Shortcut for document ready
		if ( TMCore.fn.isFunction(a) )
			return new TMCore(document)[ a ]( c );
	
		// Handle HTML strings
		if ( typeof a  == "string" ) {
				return new TMCore( c ).find( a );
		}
	},
	find: function(s) {
		if (typeof s == "object") return new TMCore(s);
		var selector = s.substr(0,1);
		switch (selector) {
			case "#": return document.getElementById(s.split("#")[1]); break;
			case ".": return document.getElementById(s.substr(1,s.length-2)); break;
			default: return document.getElementById(s); break;
		}
/*
			case "#": return new TMCore(document.getElementById(s.split("#")[1])); break;
			case ".": return new TMCore(document.getElementById(s.substr(1,s.length-2))); break;
			default: return new TMCore(document.getElementById(s)); break;

*/

	},
	// This may seem like some crazy code, but trust me when I say that this
	// is the only cross-browser way to do this. --John
	// From jQuery -- Nate
	isFunction: function( fn ) {
		return !!fn && typeof fn != "string" && !fn.nodeName && 
			fn.constructor != Array && /function/i.test( fn + "" );
	},
	load: function(u, cb) {
		if (this.innerHTML != undefined) {
			var target = this;
			cb = function(data) {
				target.innerHTML = data;
			};
		}
		TMCore.fn.ajax(u, "GET", "", cb);
	},
	ajax: function (u, t, p, c) {
		var d = null;
		if (t.toLowerCase() == "get" && (p != undefined && p != ""))
			u = u+"?"+p;
		else d = p;

		var _TMXHR_ = __CreateRequest();
		_TMXHR_._cb = c;
		TMCore.fn._TMXHR_ = _TMXHR_;
		_TMXHR_.open(t, u, true);
	    _TMXHR_.onreadystatechange = function () {
			if (_TMXHR_.readyState == 4){
				if (_TMXHR_._cb != undefined){
					_TMXHR_._cb(_TMXHR_.responseText);
				}
			}
	    };
	    _TMXHR_.setRequestHeader("X-Requested-With", "XMLHttpRequest");
	    if (d != null)
		_TMXHR_.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

	    _TMXHR_.send(d);
	},
	html: function(h) {
		this.innerHTML = h;
	},
	create: function(t, c) {
		var nE = document.createElement(t);
		switch (t.toLowerCase()) {
			case "div": nE.innerHTML = c; break;
			case "img": nE.src = c;
			default: break;
		}
	},
	destroy: function(E) {
	},
	clone: function(E) {
		var n = $TM.create("div", E.innerHTML);
		E.parentNode.removeChild(E);
		return n;
	},
	widget: function (t, p) {
		new Widget(this,t,p);
	},
	click: function(a) {
		this.setAttribute("onclick",a);
	},
	addClass: function(div, className) {
		var _c = div.className;
		if (_c.indexOf(className) == -1) {
			div.className = _c+" "+className;
			div.setAttribute("class", _c+" "+className);
			div.setAttribute("className", _c+" "+className);
		}
	},
	removeClass: function(div, className) {
		var _c  = div.className;
		var _cn = className;
		var _cs = _c.split(" ");
		var _i  = -1;
		var _nc = "";
		if (_c.indexOf(_cn) >= 0) {
			for (var i = 0; i<_cs.length; i++) {
				if (_cs[i] != _cn) {
					//_cs.splice(i,1);
					_nc += _cs[i];
					if (i < _cs.length-1) _nc += " ";
				}
			}
			div.className = _nc;
			div.setAttribute("class", _nc);
			div.setAttribute("className", _nc);
		}
	},
	dblclick: function(a) {
		
	},
	mouseover: function(a) {
	
	},
	mouseout: function(a) {
	
	},
	mousedown: function(a) {
	
	},
	mouseup: function(a) {
	
	},
	keydown: function(a) {
		this.setAttribute("onkeydown",a);
	},
	keyup: function(a) {
		this.setAttribute("onkeyup",a);
	},
	focusAction: function(a) {
		this.setAttribute("onfocus",a);
	},
	releasefocus: function(a) {
		this.setAttribute("onblur",a);
	},
	focusdown: function(a) {
		WIDGETS[this.id].focusDownAction = a;
	},
	focusup: function(a) {
		WIDGETS[this.id].focusUpAction = a;
	},
	simulateClick: function(a) {
		WIDGETS[this.id].action = a;
	},
	encodeJSON: function(o) {
	
	},
	decodeJSON: function(j) {
	
	},
	focusObj: function(obj,defaultType) {
		if (typeof obj == "string") obj = $Obj(obj);

		var defaultValue = obj.getAttribute("value");
		if (defaultType == "password") obj.setAttribute("type", "password");
		
		if (obj.value == defaultValue || obj.value == ""){
			obj.value = "";
			obj.style.color = "#000";
		}
	},
	blurObj: function(obj,defaultType) {
		if (typeof obj == "string") obj = $Obj(obj);

		var defaultValue = obj.getAttribute("value");
		
		if (defaultType == "password") obj.setAttribute("type", "password");
		
		if (obj.value == defaultValue || obj.value == ""){
			obj.style.color = "#999";
			obj.value= defaultValue;
			obj.setAttribute("type", "text");
		}
	},
	checkLeadingZero: function(value){
		if (value < 10) {
			value = "0"+ value;
			return value;
		} else {
			return value;
		}
	},
	enableFocusLabeling: function(a)
	{
		var o = a;
		if (typeof a == "string") o = $Obj(a);
		var t = o.getAttribute('type');
		if (t == undefined) t = "textarea";
		o.setAttribute("defaultType", t);
		o.setAttribute("onfocus", "$TM.fn.focusObj(this,'"+t+"')");
		o.setAttribute("onblur", "$TM.fn.blurObj(this,'"+t+"')");
		delete o;
		delete a;
		delete f;
		delete b;
		delete t;
	},
	addClass: function(div, className) {
		var _c = div.className;
		if (_c.indexOf(className) == -1) {
			if (_c.trim() != "") div.className = _c+" "+className;
			else div.className = className;
			div.setAttribute("class", _c+" "+className);
			div.setAttribute("className", _c+" "+className);
		}
	},
	removeClass: function(div, className) {
		var _c  = div.className;
		var _cn = className;
		var _cs = _c.split(" ");
		var _i  = -1;
		var _nc = "";
		if (_c.indexOf(_cn) >= 0) {
			for (var i = 0; i<_cs.length; i++) {
				if (_cs[i] != _cn) {
					//_cs.splice(i,1);
					_nc += _cs[i];
					if (i < _cs.length-2) _nc += " ";
				}
			}
			div.className = _nc;
			div.setAttribute("class", _nc);
			div.setAttribute("className", _nc);
		}
	}
};
TMCore.extend = TMCore.fn.extend = function() {
	// copy reference to target object
	var target = arguments[0], a = 1;

	// extend jQuery itself if only one argument is passed
	if ( arguments.length == 1 ) {
		target = this;
		a = 0;
	}
	var prop;
	while ( (prop = arguments[a++]) != null )
		// Extend the base object
		for ( var i in prop ) target[i] = prop[i];

	// Return the modified object
	return target;
};

function Widget(self, t, p) {
	this._type 		= t;
	this._params	= eval(p);
	this._elem 		= self;
	this._onfocus	= this._elem.getAttribute("onfocus");
	this._onblur 	= this._elem.getAttribute("onblur");
	this._id		= this._elem.id;
	this._effects	= true;
	this.action 	= "";
	this.focusDownAction = "";
	this.focusUpAction	 = "";
	this.focusLeftAction = "";
	this.focusRightAction = "";
	
	if (this._onfocus != undefined) {
		this._elem.setAttribute("onfocus", this._onfocus+";WIDGETS['"+this._elem.id+"'].takeFocus();");	
	} else {
		this._elem.setAttribute("onfocus", "WIDGETS['"+this._elem.id+"'].takeFocus();");	
	}
	if (this._params.action != undefined) this.action = this._params.action;
	this._value = this._elem.value;
	if (this._type == "auto-complete") {
		this._results = [{"symbol":"aapl","name":"Apple, Inc."}, {"symbol":"MSFT","name":"Microsoft"}];
		this._div = new Elem("div");
		this._selector = new Elem("select");
		this._selector.setAttribute("class", "autoComplete");
		//this._elem.setAttribute("onblur", "WIDGETS['"+this._elem.id+"'].releaseFocus()");
		
		this._selector.setAttribute("onclick", "WIDGETS['"+this._elem.id+"']._elem.value = this.value");
		this._selector.setAttribute("ondblclick", "WIDGETS['"+this._elem.id+"'].selectValue(this.value)");
		this._div.style.zIndex = 100;
		this._selector.setAttribute("size", 2);
		for (var i=0; i<this._results.length; i++) {
			var option = new Elem("option");
			option.text = this._results[i].symbol.toUpperCase() + " - " + this._results[i].name;
			option.value = this._results[i].symbol.toUpperCase();
			this._selector.appendChild(option);
			delete option;
		}
		this._div.appendChild(this._selector);
		this._elem.parentNode.insertBefore( this._div, this._div.nextSibling );
		WIDGETS[this._elem.id] = this;
		this._elem.setAttribute("onkeyup", "setTimeout(WIDGETS['"+this._elem.id+"'].ac_field(WIDGETS['"+this._elem.id+"']._elem.value, WIDGETS['"+this._elem.id+"']._params.url), 400)");
	}
};
Widget.prototype = {
	takeFocus: function() {
		try {
			FOCUSED_OBJECT.releaseFocus();
		} catch (E) {}
		FOCUSED_OBJECT = this;
	},
	releaseFocus: function() {
		if (this._type == "auto-complete") this._selector.style.display = "none";		
	},
	focusUp: function() {
		eval(this.focusUpAction);
	},
	focusRight: function() {
		eval(this.focusRightAction);
	},
	focusDown: function() {
		eval(this.focusDownAction);
	},
	focusLeft: function() {
		eval(this.focusLeftAction);
	},
	simulateClick: function() {
		eval(this.action);
	},
	ac_field: function(value, script) {
		var self = this;
		if (value.length > 0 && value != this._value && value.trim() != "")
			TMCore.fn.load("scripts/ac_stocks.php?s="+value, function(data){
				var suggestions = eval(data);
				self._selector.innerHTML = "";
				self._selector.style.display = "block";
				self._div.style.display = "block";
				
				if (suggestions.length > 10) 
					self._selector.setAttribute("size", 10);
				else if (suggestions.length < 2)
					self._selector.setAttribute("size", 2);
				else
					self._selector.setAttribute("size", suggestions.length);
				
				if (suggestions.length == 0){
					var option = new Elem("option");
					option.text = "No suggestions";
					option.value = "";
					self._selector.appendChild(option);
					delete option;
				}
				
				for (var i=0; i<suggestions.length; i++) {
					var option = new Elem("option");
					option.text = suggestions[i].symbol.toUpperCase() + " - " + suggestions[i].name;
					option.value = suggestions[i].symbol.toUpperCase();
					self._selector.appendChild(option);
					delete option;
				}
			});
		this._value = value;

	},
	selectValue: function(v) {
		this._elem.value = v;
		this._selector.style.display = "none";
		while (this.action.indexOf("self.") > -1)
		this.action = this.action.replace("self.", "WIDGETS['"+this._elem.id+"']._elem.");
		
		if (this.action != undefined) eval(this.action);
	}
};


function __CreateRequest(v) {
	try {
		request = new XMLHttpRequest();
		} catch (trymicrosoft) {
		try {
			request = new ActiveXObject("Msxm12.XMLHTTP");
			} catch (othermicrosoft) {
			try {
				request = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (failed) {
				request = null;
			}
		}
	}
	if (request == null) {
		alert("Error creating request object, please check your browser javascript support.");
	} else {
		return request;
	}
};
function $Obj(id) {
	var _obj = id;
	if (typeof id == "string") _obj = document.getElementById(id);
	if (_obj == undefined) return;
	_obj.append = function(child) {
		if (child.constructor == new Object().constructor){
			this.appendChild(child.getElem());
		} else {
			this.appendChild(child);
		}
	};
	return _obj;
};
function NOW(){
	return new Date().getTime();
};

var TMEventCore = function(delay) {
	if (delay != undefined && typeof delay == "number") this.delay = delay;
	else this.delay = 1000;
	this._events = [];
	if (DEBUG_MODE) console.log("Initializing TMEventCore with delay: "+this.delay);
};
TMEventCore.prototype = {
	pushTimerEvent:function(e){
		var _length = this._events.length;

		this._events[_length] = e;
		e.index = _length;
		return _length;
	},
	removeTimerEvent:function(index) {
		if (index != undefined){
			for (var i = 0; i<this._events.length; i++) {
				if (this._events[i].index == index && index != i) {
					index = i;
					break;
				}
			}
			this._events.splice(index,1);
		}
	},
	createTimedEvent: function(d, r, f) {
		var _event_ = new TimerEvent(d,r,f);
		return this.pushTimerEvent(_event_);
	},
	tick: function() {
		if (this.onDuty) {
			for(var e = 0; e < this._events.length; e++) {
				try {
					this._events[e].fire();
				} catch (E) {
					if (DEBUG_MODE) console.log("TMEventCore had an exception for event "+e+".");
				}
			}
			var _ec_ = this;
		}
	},
	putOnDuty:function() {
		this.onDuty = true;
		this.timeout = setInterval("TMUIServer.eventCore.tick()",this.delay);
		this.tick();
	},
	takeOffDuty: function() {
		this.onDuty = false;
		clearInterval(this.timeout);
	}	
};

var TimerEvent = function(duration, repeat, action) {
	this.duration 	= duration;
	this.repeat		= repeat;
	this.action		= action;
	this.id			= "";
	this.fire = function(){
		this.action();
		if (this.repeat != true) {
			//$T.TMEventCore.removeTimerEvent(this.index);
		}
	};
	this.setID = function(id) {
		this.id = id;
	};
	//this.index 		= $T.TMEventCore.pushTimerEvent(this);
};

// !onkeydown eventHandler
/**
 *	onkeydown eventHandler
 *	Used only in Safari to fire
 *	key methods.
 */

TMCore.fn.keyDown = function(e) {
	var evt = (e) ? e: (window.event) ? window.event: null;
	if (evt) {
		var key = (evt.charCode) ? evt.charCode:
		((evt.keyCode) ? evt.keyCode: ((evt.which) ? evt.which: 0));
		TMCore.fn.KEYSTATES[key] = 1;
		switch (key) {
		case 37:
			TMCore.fn.leftArrow();
			break;
		case 38:
			TMCore.fn.upArrow();
			break;
		case 39:
			TMCore.fn.rightArrow();
			break;
		case 40:
			TMCore.fn.downArrow();
			break;
		case 13:
			TMCore.fn.enterKey();
			break;
		case 27:
			TMCore.fn.escapeKey();
			break;
		case 9:
			//tabKey();
			break;
		case 32:
			TMCore.fn.spaceBar();
			break;
		}
	}
	
	// Key combinations
	if (TMCore.fn.KEYSTATES[91] == 1 && TMCore.fn.KEYSTATES[77] == 1) {
		TMCore.fn.KEYSTATES[91] = 0;
		TMCore.fn.KEYSTATES[77] = 0;
		TMCore.fn.commandM();
	}
};

TMCore.fn.KEYSTATES = [];
TMCore.fn.KEYSTATES[91] = 0; // Command Key
TMCore.fn.KEYSTATES[77] = 0; // m key

TMCore.fn.keyUp = function(e) {
	var evt = (e) ? e: (window.event) ? window.event: null;
	if (evt) {
		var key = (evt.charCode) ? evt.charCode:
		((evt.keyCode) ? evt.keyCode: ((evt.which) ? evt.which: 0));
		TMCore.fn.KEYSTATES[key] = 0;
	}
};
// !Arrow Key Functions
/**
 *	Arrow Key Functions
 *	Nanopoint fires the arrow key
 *	methods directly, as focus events
 */

TMCore.fn.upArrow = function() {
if (FOCUSED_OBJECT != undefined && FOCUSED_OBJECT != null)
	FOCUSED_OBJECT.focusUp();
};
TMCore.fn.rightArrow = function() {
if (FOCUSED_OBJECT != undefined && FOCUSED_OBJECT != null)
	FOCUSED_OBJECT.focusRight();
};
TMCore.fn.downArrow = function() {
if (FOCUSED_OBJECT != undefined && FOCUSED_OBJECT != null)
	FOCUSED_OBJECT.focusDown();
};
TMCore.fn.leftArrow = function() {
if (FOCUSED_OBJECT != undefined && FOCUSED_OBJECT != null)
	FOCUSED_OBJECT.focusLeft();
};
TMCore.fn.spaceBar = function() {
if (FOCUSED_OBJECT != undefined && FOCUSED_OBJECT != null)
	FOCUSED_OBJECT.simulateClick();
};
TMCore.fn.escapeKey = function() {
if (FOCUSED_OBJECT != undefined && FOCUSED_OBJECT != null)
	FOCUSED_OBJECT.releaseFocus();
};
TMCore.fn.enterKey = function() {
	//spaceBar();
};
document.onkeydown = TMCore.fn.keyDown;
document.onkeyup = TMCore.fn.keyUp;