
/** Page Tricks (for HTML, recently) **/

var pi__init = false; 
var pi_tracers = new Array(); 
var pi__evt_handled = new Array(50); 
function pi_resetIf(index, st) {
	// reset if not handled
	if (pi__evt_handled[index] == false) {
		var i; 
		for (i = 0; i < pi_tracers.length; i++) {
			pi_tracers[i].enterEvent(st); 
		}
	}
	// !! the out-most document handler must be actived at last !!
	pi__evt_handled[index] = false; 
}
function pi_handled(index) {
	pi__evt_handled[index] = true; 
}

function pi_init_bodies() {
	if (!pi__init) {
		pi__init = true; 
		var i; 
		for (i = 0; i < 50; i++) pi__evt_handled[i] = "unused"; 
		var initBodies = 
			"Sub document_onClick()		:pi_resetIf 1,\"c_doc_\":End Sub\n" + 
			"Sub document_onMouseDown()	:                       :End Sub\n" + 
			"Sub document_onMouseUp()	:                       :End Sub\n" + 
			"Sub document_onMouseOver()	:                       :End Sub\n" + 
			"Sub document_onMouseOut()	:                       :End Sub\n" + 
			"Sub document_onKeyPress()	\n" + 
			"	dim k\n" + 
			"	k = window.event.keyCode\n" + 
			"	for each tr in pi_tracers\n" + 
			"		tr.enterEvent(\"k\" + chr(k))\n" + 
			"	next\n" + 
			"End Sub\n"
			; 
		window.execScript(initBodies, "VBScript"); 
	}
}


/**
	prefix code: 
		c		click
		d		mousedown
		u		mouseup
		k<x>	keypress x
		e		enter
		x		leave
		
	examples: 
		"cObject1-dObject2-kA-eImage1-xImage2"
**/
function pi_eetr(tr,text) { return tr._name_ + ".enterEvent(\"" + text + "\")"; }

function piGetVbsImpl(events, tr) {
	if (tr == null) tr = this.tracer; 
	if (events == null) events = tr.cmptarget; 
	
	var vbstext = "\n"; 
	var iEvent; 
	for (iEvent = 0; iEvent < events.length; iEvent++) {
		var evText = events[iEvent]; 
		var evCode = evText.charAt(0); 
		var evObj = evText.substring(1); 
		switch (evCode) {
		case 'c': 
			vbstext += 
				"Sub " + evObj + "_onClick()\n" + 
				"	" + pi_eetr(tr, evText) + "\n" + 
				"pi_handled(1): End Sub\n"; 
			break; 
		case 'd': 
			vbstext += 
				"Sub " + evObj + "_onMouseDown()\n" + 
				"	" + pi_eetr(tr, evText) + "\n" + 
				"pi_handled(2): End Sub\n"; 
			break; 
		case 'u': 
			vbstext += 
				"Sub " + evObj + "_onMouseUp()\n" + 
				"	" + pi_eetr(tr, evText) + "\n" + 
				"pi_handled(3): End Sub\n"; 
			break; 
		case 'e': 
			vbstext += 
				"Sub " + evObj + "_onMouseOver()\n" + 
				"	" + pi_eetr(tr, evText) + "\n" + 
				"pi_handled(4): End Sub\n"; 
			break; 
		case 'x': 
			vbstext += 
				"Sub " + evObj + "_onMouseOut()\n" + 
				"	" + pi_eetr(tr, evText) + "\n" + 
				"pi_handled(5): End Sub\n"; 
			break; 
		}
	}
	vbstext += "\n"; 
	pi_init_bodies(); 
	window.execScript(vbstext, "VBScript"); 
	return vbstext; 
}
function piGetJsImpl(events, tr) {
	//var jstext = piGetVbsImpl(events, tr); 
	var jstext = "<SCRIPT LANGUAGE=JScript>\n"; 
	var iEvent; 
	for (iEvent = 0; iEvent < events.length; iEvent++) {
		var evText = events[iEvent]; 
		var evCode = evText.charAt(0); 
		var evObj = evText.substring(1); 
	}
	jstext += "</SCRIPT>\n"; 
	return jstext; 
}

function piEnterEvent(newEvent, tracer) {
	if (tracer == null) tracer = this; 
	
	var i; 
	for (i = 1; i < tracer.size; i++) {
		tracer.elems[i - 1] = tracer.elems[i]; 
	}
	tracer.elems[tracer.size - 1] = newEvent; 

	if (tracer.traceDetails != null) 
		tracer.traceDetails(this.detail()); 

	for (i = 0; i < tracer.size; i++)
		if (tracer.elems[i] != tracer.cmptarget[i])
			return false; 
	if (tracer.triggerFilter != null)
		if (!tracer.triggerFilter())
			return false; 
	if (tracer.trigger != null) 
		return tracer.trigger(tracer); 
	return true; 
}

function piTracerDetails() {
	var details = "Details of " + this._name_ + "\n"; 
	details += this.elems.join("-"); 
	details += "\n---- the target ---\n"; 
	details += this.cmptarget.join("-") + "\n"; 
	details += "\ntriggerFilter: " + this.triggerFilter; 
	details += "\ntrigger: " + this.trigger; 
	details += "\ntraceDetails: " + this.traceDetails; 
	return details; 
}

/**
 * Object wrappers
 */
function EventTracer(target, trigger) {
	this._name_ = "??"; 
	this.size = target.length; 
	this.elems = new Array(target.length); 
	this.cmptarget = target; 
	this.enterEvent = piEnterEvent; 
	this.triggerFilter = null; 
	this.trigger = trigger; 
	this.detail = piTracerDetails; 
	this.traceDetails = null; 
	pi_tracers.push(this); 
}

function EventTricks(name, evtstr, trigger) {
	if (name == null) name = "EventTricks"; 
	this._name_ = name; 
	this.tracer = new EventTracer(evtstr.split("-"), trigger); 
	this.tracer._name_ = name + ".tracer"; 
	this.implVBS = piGetVbsImpl; 
	this.implJS = piGetJsImpl; 
	
	this.implVBS(); 
}

