

// TVG - SCRIPTICIAN - EVENT




// devnote: check trees combined with mouse position: when the mouse is over an absolutely positioned element that is a child of an element which is tracked, thecursor can be in a totally different position than the tracked element, but will not register as outside the element...
// possible solutions: 
// - make a config option to have the check tree ignore abolutely positioned elements (only return true when the mouse is in a normally positioned child element)
// - make an option to have cursor operations behave coordinate-based instead of element based (checking if the coordinates of the elements rendered offsets contain the cursor coordinates), this would probably be problematic in some browsers, but also do away with the need for a number of other sketchy fixes

// devnote: when an element moves from under the mouse when the cursor is not moving (so an event is not triggered to evaluate cursor position) this new cursor status is not evaluated
// possible solution:
// - have chron periodically simulate a mousemove (evaluate the cursor position in every frame) and trigger the event handler (this would also be good when for instance the mouse moves out of a class-based mouseleave into the shadow of an element and is then over an adjacent menu item, which does not trigger because the cursor is not moving, same scenario)
// - see if this event can be triggered easily using standard methods

	
if (TVGS) TVGS.event_bridge = function (anything)
{

	// this is the scriptician event bridge!
	// note: this is where you leave scriptician, and activate your own code
	// note: following an event, the variable or value you specified for bridging will be passed into this function
	// note: you can pas anything in here, and take care of further handling
	// note: good luck!
	
	// example
	alert('Scriptician event bridge activated: ' + anything);

}


// events make the world go round
if (TVGS) TVGS.event_switcher = function()
{
	
	// fix scope
	var here = this;
	
	
	this.alert_some = function ()
	{
		alert('some');
	}

	function alert_some_more()
	{
		here.alert_some();
	}

	//alert_some_more();
	
	
	
	
			
	
	// get element coordinates
	here.element_get_offset = function(element_id)
	{
		var element = document.getElementById(element_id);
		
		if (element != null && element.offsetParent)
		{
		
			// set element coordinates
			offset_x = 0;
			offset_y = 0;
		
			do
			{
				offset_x += element.offsetLeft;
				offset_y += element.offsetTop;
			}
			while (element = element.offsetParent);
		
			return {offset_x: offset_x, offset_y: offset_y}

		}
		else return false;
		
	}
	
	

	// all trackers respond globally to the "HTML" node
	var event_root = document.getElementsByTagName("HTML")[0];
	
	
	// start event watchers
	// note: contains a code branch for event listeners on different browsers
	function start_event_watcher(event_name, watched_element, switch_function)
	{
		// for standard browsers
		if (watched_element.addEventListener)
		{
			watched_element.addEventListener(event_name, switch_function, false);
		}
		// for internet explorer
		else if (watched_element.attachEvent)
		{
			var r = watched_element.attachEvent('on' + event_name, switch_function);
			return r;
		}
		// else browser does not support event listening		
	}
	
	
	
	// note: these are tracked events according to browsers, some of them are evaluated as more than one tvgs event in the event handler 
	
	// mousemove watcher
	start_event_watcher('mousemove', event_root, switch_mousemove);
	
	// mouseup watcher
	start_event_watcher('mouseup', event_root, switch_mouseup);
	
	// mousedown watcher
	start_event_watcher('mousedown', event_root, switch_mousedown);
	
	// keyup watcher
	start_event_watcher('keyup', event_root, switch_keyup);

	// resize watcher
	start_event_watcher('resize', window, switch_resize);
	
	
	
	
	// mousemove switch
	// note: may trigger the tvgs events mouseinside, mouseoutside, mouseenter, mouseleave
	function switch_mousemove(event)
	{
		event_handler(event, 'mousemove');
	}
	
	// mouseup switch
	// note: may trigger the tvgs events mouseclick, mousedoubleclick
	function switch_mouseup(event)
	{
		event_handler(event, 'mouseup');
	}
	
	// mousedown switch
	function switch_mousedown(event)
	{
		event_handler(event, 'mousedown');
	}
	
	// keyup switch
	function switch_keyup(event)
	{
		event_handler(event, 'keyup');
	}
	
	// resize switch
	function switch_resize(event)
	{
		event_handler(event, 'resize');
	}
	
	
	
	// set switched element
	this.switched_element = null;
	
	// set list of all elements from the current element up to and including the root element
	this.element_list = [];
	
	// set mousepresent flag tracker for mouseenter and mouseleave
	// note: the arrays are filled with properties that have the class or id string as name
	// devnote:  check oficcial rules for html class and id names, see if this will ever conflict with javascript property naming
	//this.mousepresent = {element_id: [], element_class: []};


	// PUBLIC FUNCTIONS
	
	// make a list of all elements from the current element up to and including the root element
	function make_element_list(element)
	{
		
		// clear list
		this.element_list = [];
		
		// set start element
		var check_element = element;
		
		while (check_element != event_root)
		{
			// add to list
			this.element_list[this.element_list.length] = check_element;
			
			// set check element to parent element
			check_element = check_element.parentNode;
		}
		
		// add event root as last element
		this.element_list[this.element_list.length] = event_root;
	}
	
	
	// check if an element with the given attribute value exists in the element tree, when found it means that the element is or is a parent of the switched element, the switched element is "inside of" the attribute value
	// note: attribute can be "id" or "class"
	// note: value can be a string or an array
	function check_element_list(attribute, value)
	{
		
		// convert string input to a single array element
		if (typeof value == 'string') value = [value];

		// check element list from switched element to event root
		for (var i in this.element_list){ if (TVGS.key(i)){
		
			// check id
			if (attribute == 'id')
			{
				// step through id list
				for (var j in value){ if (TVGS.key(j)){
				
					if (this.element_list[i].id == value[j]) return true;
					
				}}
			}
			
			// check class
			if (attribute == 'class')
			{
			
				// get classnames from list element
				var classnames = this.element_list[i].className.split(' ');
				
				// step through class list
				for (var j in value){ if (TVGS.key(j)){
				
					// crosscheck class names
					for (var k in classnames){ if (TVGS.key(k)){
					
						if (classnames[k] == value[j]) return true;
						
					}}
					
				}}
			}
			
		}}
		
		// no match found
		return false;
		
	}
	
	
	
	function event_handler(event, type)
	{
		
		if (type != 'resize')
		{
			
			// internet explorer
			if (event.srcElement)
			{
				this.switched_element = event.srcElement;
			}
			// standard browsers
			else if (event.target)
			{	
				this.switched_element = event.target;
			}
			
			// make switched element to event root list
			make_element_list(this.switched_element);
		
		}
		
		
		
		// RESIZE HANDLERS
		if (type == 'resize')
		{
			//alert('resize!');
			
			//var viewport = document.getElementsByTagName("HTML")[0];
			
			//alert('viewport is ' + viewport.offsetWidth + 'pixels high x ' + viewport.offsetHeight + 'pixels wide');
			
			
			TVGS.stretch_main_bg_image('main_bg_image');
			
			
		}
	
	
	
		// MOUSEMOVE HANDLERS
		if (type == 'mousemove')
		{
			
			
			//document.getElementById('output_id').innerHTML = this.switched_element.id;
			
			

			// get mouse position relative to document
			here.mouse_x_document = 0;
			here.mouse_y_document = 0;
		
			if (event.pageX || event.pageY)
			{
				here.mouse_x_document = event.pageX;
				here.mouse_y_document = event.pageY;
			}
			else if (event.clientX || event.clientY)
			{
				here.mouse_x_document = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
				here.mouse_y_document = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
			}
			
			//document.getElementById('output').innerHTML = here.mouse_x_document + ' ' + here.mouse_y_document;
			
			
			
			
			
			// MOUSEMOVE
			if (TVGS.config.event.mousemove)
			{
			
				// check config items
				for (var i in TVGS.config.event.mousemove){ if (TVGS.key(i)){
				
					// when element id is found launch action
					if (check_element_list('id', TVGS.config.event.mousemove[i].element_id) == true)
					{
		
						// execute action by means of eval
						eval(TVGS.config.event.mousemove[i].script);
					
					}
				
				}}
		
			}
			
			
			
			
			// MOUSEINSIDE
			if (TVGS.config.event.mouseinside)
			{
			
				// check config items
				for (var i in TVGS.config.event.mouseinside){ if (TVGS.key(i)){
				
					// when element id is found launch action
					if (check_element_list('id', TVGS.config.event.mouseinside[i].element_id) == true)
					{
		
						// execute action by means of eval
						eval(TVGS.config.event.mouseinside[i].script);
					
					}
				
				}}
		
			}
			
			
			
			
			// MOUSEOUTSIDE
			if (TVGS.config.event.mouseoutside)
			{
			
				// check config items
				for (var i in TVGS.config.event.mouseoutside){ if (TVGS.key(i)){
				
					// when element id is found launch action
					if (check_element_list('id', TVGS.config.event.mouseoutside[i].element_id) == false)
					{
					
						// execute action by means of eval
						eval(TVGS.config.event.mouseoutside[i].script);
					
					}
				
				}}
		
			}
		
		
			
			
			// MOUSEENTER / MOUSELEAVE
			// note: these are checked in tandem and the mousepresent flag is is updated after both checks are complete
			
			// setup array of new mousepresent flag values
			var new_mousepresent_flag = [];
			
			// check for mouseenter
			if (TVGS.val(TVGS.config.event.mouseenter))
			{
	
				for (var i in TVGS.config.event.mouseenter){ if (TVGS.key(i)){

					// when trigger id or class is found check state
					if ((TVGS.val(TVGS.config.event.mouseenter[i].element_id) && check_element_list('id', TVGS.config.event.mouseenter[i].element_id) == true) || (TVGS.val(TVGS.config.event.mouseenter[i].element_class) && check_element_list('class', TVGS.config.event.mouseenter[i].element_class) == true))					
					{

						
						// check if the config item has the mousepresent flag set
						if (TVGS.nil(TVGS.config.event.mouseenter[i].mousepresent))
						{
							// no information is available, add flag to config item and do nothing
							new_mousepresent_flag[new_mousepresent_flag.length] = {config_item_to_flag: TVGS.config.event.mouseenter[i], flag: true};
							continue;
						}
						else if (TVGS.config.event.mouseenter[i].mousepresent == true)
						{
							// the mouse was already inside the trigger id or class, do nothing
							continue;
						}
						else
						{
							// the mouse has just entered the trigger id or class, execute action
							
							// execute action relay
							if (TVGS.val(TVGS.config.event.mouseenter[i].relay))
							{
								TVGS.chron_chain_instigate_relay(TVGS.config.event.mouseenter[i].relay);
							}
							
							// execute action script
							if (TVGS.val(TVGS.config.event.mouseenter[i].script))
							{
								// execute action by means of eval
								eval(TVGS.config.event.mouseenter[i].script);
							}

							// mark flag for updating
							new_mousepresent_flag[new_mousepresent_flag.length] = {config_item_to_flag: TVGS.config.event.mouseenter[i], flag: true};
						}
	
					}
					else if (TVGS.config.event.mouseenter[i].mousepresent != false)
					{
						// mouse is outside trigger, mark flag for updating
						new_mousepresent_flag[new_mousepresent_flag.length] = {config_item_to_flag: TVGS.config.event.mouseenter[i], flag: false};
					}
				
				}}
			
			}
			
			// check for mouseleave
			if (TVGS.val(TVGS.config.event.mouseleave))
			{
	
				for (var i in TVGS.config.event.mouseleave){ if (TVGS.key(i)){
					
					// when trigger id and class are not given or false check state
					if (((TVGS.val(TVGS.config.event.mouseleave[i].element_id) && check_element_list('id', TVGS.config.event.mouseleave[i].element_id) == false) || TVGS.nil(TVGS.config.event.mouseleave[i].element_id)) && ((TVGS.val(TVGS.config.event.mouseleave[i].element_class) && check_element_list('class', TVGS.config.event.mouseleave[i].element_class) == false) || TVGS.nil(TVGS.config.event.mouseleave[i].element_class)))
					{
						
						// check if the config item has the mousepresent flag set
						if (TVGS.nil(TVGS.config.event.mouseleave[i].mousepresent))
						{
							// no information is available, add flag to config item and do nothing
							new_mousepresent_flag[new_mousepresent_flag.length] = {config_item_to_flag: TVGS.config.event.mouseleave[i], flag: false};
							continue;
						}
						else if (TVGS.config.event.mouseleave[i].mousepresent == false)
						{
							// the mouse was already outside the trigger id or class, do nothing
							continue;
						}
						else
						{
							// the mouse has just left the trigger id or class, execute action
							
							// execute action relay
							if (TVGS.val(TVGS.config.event.mouseleave[i].relay))
							{
								TVGS.chron_chain_instigate_relay(TVGS.config.event.mouseleave[i].relay);
							}
							
							// execute action script
							if (TVGS.val(TVGS.config.event.mouseleave[i].script))
							{
								// execute action by means of eval
								eval(TVGS.config.event.mouseleave[i].script);
							}
							
							// mark flag for updating
							new_mousepresent_flag[new_mousepresent_flag.length] = {config_item_to_flag: TVGS.config.event.mouseleave[i], flag: false};
						}
	
					}
					else if (TVGS.config.event.mouseleave[i].mousepresent != true)
					{
						// mouse is inside trigger, mark flag for updating
						new_mousepresent_flag[new_mousepresent_flag.length] = {config_item_to_flag: TVGS.config.event.mouseleave[i], flag: true};
					}

				}}
				
			}
			
			// update mousepresent flag values
		   //TVGS.print('', 'replace');
			for (var i in new_mousepresent_flag){ if (TVGS.key(i)){
			
				//TVGS.print(' SET ' + new_mousepresent_flag[i].config_item_to_flag.mousepresent + ' => ', 'append');

				new_mousepresent_flag[i].config_item_to_flag.mousepresent = new_mousepresent_flag[i].flag;

				//TVGS.print(new_mousepresent_flag[i].config_item_to_flag.mousepresent);
				
			}}

		} // end mousemove handlers
	
	
	
		// MOUSEUP HANDLERS	
		if (type == 'mouseup')
		{
			//document.getElementById('output').innerHTML += ' => mouseup ';

			// MOUSECLICK
			// note: uses mouseup so users can rethink their click, move the cursor and "mouseup" somewhere else to cancel their click action
			if (TVGS.config.event.mouseclick)
			{
			
				// check config items
				for (var i in TVGS.config.event.mouseclick){ if (TVGS.key(i)){
					//document.getElementById('output').innerHTML += ' => check ';
					// when element id or class is found launch action
					if ((TVGS.config.event.mouseclick[i].element_id && check_element_list('id', TVGS.config.event.mouseclick[i].element_id) == true) || (TVGS.config.event.mouseclick[i].element_class && check_element_list('class', TVGS.config.event.mouseclick[i].element_class) == true))
					{
						
						// execute action relay
						if (TVGS.config.event.mouseclick[i].relay)
						{
							TVGS.chron_chain_instigate_relay(TVGS.config.event.mouseclick[i].relay);
						}
						
						// execute action script
						if (TVGS.config.event.mouseclick[i].script)
						{
							// execute action by means of eval
							eval(TVGS.config.event.mouseclick[i].script);
						}
						
						// execute action bridge
						if (TVGS.config.event.mouseclick[i].bridge)
						{
							// send to event bridge
							TVGS.event_bridge(TVGS.config.event.mouseclick[i].bridge);
						}
					
					}
				
				}}
			
			}
		
		
		
			// MOUSEDOUBLECLICK
			// not active
			
		}
		
		
		
	}
	
	
	

}




if (TVGS) TVGS.event_info_cursor_tracker = function()
{
	
	// define template
	if (document.getElementById('tvgs_event_info_cursor_tracker_template'))
	{	
		// get template from document
		var template = document.getElementById('tvgs_event_info_cursor_tracker_template').innerHTML;
	}
	else
	{
		// use default template
		var template = '<div style="border: 1px solid black; background-color: #666666; padding: 5px; font-size: 8px; font-family: sans-serif;">###mouse_coordinates###<br></div>';
	}



	// setup tracker box
	var tracker_box = document.createElement('span');
	
	// set attributes
	tracker_box.setAttribute('id', 'tvgs_event_info_cursor_tracker_box');
	
	// place in body
	document.getElementsByTagName('body')[0].appendChild(tracker_box);
	
	
	
	// retrieve by id
	tracker_box = document.getElementById('tvgs_event_info_cursor_tracker_box');
	
	// assign styles
	tracker_box.style.position = 'absolute';
	tracker_box.style.zIndex = '200';
	
	
	// set info into template
	
	
	
	
	
	// insert template
	tracker_box.innerHTML = template;
	



}














// ============================ //
// PRE/NON-TVGS STUFF //



	/*
	// start event trackers
	// note: initiates standard listeners on root node
			
	// all trackers respond globally to the "HTML" node
	TVGS.EVENT.root = document.getElementsByTagName("HTML")[0];
	
	// mousemove tracker
	addListeners('mousemove', TVGS.EVENT.root, tvgs_pass_mousemove);
	
	// mouseup tracker (used as onclick so users can rethink their click, move the cursor and "mouseup" somewhere else, like outside the menu they were in, to cancel their action)
	addListeners('mouseup', TVGS.EVENT.root, tvgs_pass_mouseup);
	
	// mousedown tracker
	addListeners('mousedown', TVGS.EVENT.root, tvgs_pass_mousedown);
	
	// typing tracker, responds only to key up
	addListeners('keyup', TVGS.EVENT.root, tvgs_pass_keyup);

	// resize tracker
	addListeners('resize', window, tvgs_pass_resize);
	
	//if (document.getElementById('sm_js_console')) document.getElementById('sm_js_console').innerHTML = 'Javascript readout console: tvg_suite handlers running.<br><br>';
	*/


		// Cross-browser implementation of element.addEventListener()

		// Use: listen("event name", elem, func);
		// addListenersThree('mousemove', elem, func)
		function addListeners(evnt, elem, func)
		{
		
		
			if (elem.addEventListener)  // W3C DOM
				elem.addEventListener(evnt,func,false);
			else if (elem.attachEvent)
			{ // IE DOM
				var r = elem.attachEvent("on"+evnt, func);
				return r;
			}
			else window.alert('I\'m sorry Dave, I\'m afraid I can\'t do that.');
			
			
		}



		
// EVENT RELAY
// relay browser events to handler with extra info


// mousemove
function tvgs_pass_mousemove(event)
{
	
	tvg_target_element_watcher(event, 'mousemove');
	
}

// mouseup
function tvgs_pass_mouseup(event)
{
	
	tvg_target_element_watcher(event, 'mouseup');
	
}

// mousedown
function tvgs_pass_mousedown(event)
{
	//if (document.getElementById('sm_js_console')) document.getElementById('sm_js_console').innerHTML += 'Passing mousedown.<br>';	
	tvg_target_element_watcher(event, 'mousedown');
	
}

// keyup
function tvgs_pass_keyup(event)
{
	
	tvg_target_element_watcher(event, 'keyup');
	
}

// resize
function tvgs_pass_resize(event)
{

	tvg_target_element_watcher(event, 'resize');
	
}
		
	


		// THESE GLOBALS NEED TO BE REVISED
		// move into global vars array, do away with all other window.something vars for "tvg_" stuff
		var popup_active_id = '';
		var rollover_active_id = '';
		var content_active_id = '';
		var mousemoved = 0;
		var mousedown_time = null;
		var show_info_tracker = false;
		
		if (document.getElementById('sm_js_console')) document.getElementById('sm_js_console').innerHTML += 'Globals: initialized some nasty globals.<br>';
		
		// show/hide menu based on continuous onmousemove tracking
		// ISSUE: browsers may interpret only part of the window as body, and the event will not fire when the mouse is not in it.
		// fix: set the width and height of the body tag to 100% to make sure the entire window is interpreted as body
		
		// todo: make script realize when the mouse is not in the browser window at all, treat as mouseout closing active elements
		
function tvg_target_element_watcher(event, event_type)
{
	
	
	
	
	// build element id-tree to document HTML root
	function build_element_to_root_id_tree(current_element)
	{
		
		var element_to_root_id_tree = [];
		var element_parent_count = 0;
		var check_element = current_element;
		
		while (check_element.nodeName != 'HTML')
		{
			
			// expand tree
			element_to_root_id_tree[element_parent_count] = check_element.id;
			
			// step up to to parent
			check_element = check_element.parentNode;
			
			// increase parent count
			element_parent_count = element_parent_count + 1;
		
		}
		
		// HTML node parent number
		// used by info tracker, move this global to somewhere else
		window.distance_to_html_node = element_parent_count;
		
		
		
		return element_to_root_id_tree;
		
		
	
	}
	
	
	
	// build element class-tree to document HTML root
	function build_element_to_root_class_tree(current_element)
	{
		
		var element_to_root_class_tree = [];
		var element_parent_count = 0;
		var check_element = current_element;
		
		while (check_element.nodeName != 'HTML')
		{
			
			// expand tree
			element_to_root_class_tree[element_parent_count] = check_element.className.split(' ');
			
			// step up to to parent
			check_element = check_element.parentNode;
			
			// increase parent count
			element_parent_count = element_parent_count + 1;
		
		}
		
		// HTML node parent number
		// used by info tracker, move this global to somewhere else
		window.distance_to_html_node = element_parent_count;
		
		
		
		return element_to_root_class_tree;
		
		
	
	}
	
	
	// build element info-tree to document HTML root
	function build_element_to_root_element_tree(current_element)
	{
		
		var element_to_root_element_tree = [];
		var element_parent_count = 0;
		var check_element = current_element;
		
		
		while (check_element.nodeName != 'HTML')
		{
			
			// expand tree
			element_to_root_element_tree[element_parent_count] = check_element; // element reference
			
			// step up to to parent
			check_element = check_element.parentNode;
			
			// increase parent count
			element_parent_count = element_parent_count + 1;
		
		}
		
		
		// HTML node parent number
		// used by info tracker, move this global to somewhere else
		window.distance_to_html_node = element_parent_count;
		
		
		return element_to_root_element_tree;
		
	}
	
	
	
	// detect if the monitored element is or is a parent of the current element
	function get_monitored_element_status(monitored_element_id, check_tree)
	{
	
		for (var i in check_tree){ if (TVGS.key(i)){
		
			if (check_tree[i] == monitored_element_id)
			{
			
				return true;
			
			}
		
		}}
		
		return false;
		
	}
	
	
	
	
	// detect if the monitored element class or is a current element class
	function check_monitored_element_class(monitored_element_class, check_tree)
	{
	
		for (var i in check_tree){ if (TVGS.key(i)){
		
			for (var j in check_tree[i]){ if (TVGS.key(j)){
			
				if (check_tree[i][j] == monitored_element_class)
				{
				
					return true;
				
				}
			
			}}
		
		}}
		
		return false;
		
	}
	
	
	
	
	// return the first element from the parent tree that has a specific class
	function get_first_parent_element_by_class(parent_element_class, check_tree_element)
	{
	
		for (var i in check_tree_element){ if (TVGS.key(i)){
			
			var classnames = check_tree_element[i].className.split(' ');

			
			for (var j in classnames){ if (TVGS.key(j)){
			
				if (classnames[j] == parent_element_class)
				{
				
					return check_tree_element[i];
				
				}
			
			}}
		
		}}
		
		return false;
		
	}
	
	
	
	
	// GET EVENT
	
	
	if (event_type != 'resize')
	{
		
		// explorer
		if (event.srcElement)
		{
		
			var current_element = event.srcElement;
			
		}
		// standard browsers
		else if (event.target)
		{	
		
			var current_element = event.target;
			
		}
		
	
		// get check trees
		var check_tree_id = build_element_to_root_id_tree(current_element);
		var check_tree_class = build_element_to_root_class_tree(current_element);
		var check_tree_element = build_element_to_root_element_tree(current_element);
	
	}
	
	
	
	
	
	
	
	
	// MOUSEMOVE HANDLERS
	if (event_type == 'mousemove')
	{
		
		
		// we're moving!
		// used by info tracker, move this global to somewhere else
		window.mousemoved++;
		
	
		
		
		
		
		// ======================================= //
		
		// ROLLOVER TYPE 1 CONFIG
		// inline here... needs to be autogenerated/parsed sometime
		
		// check if the config variable exists
		if (window.tvg_rollover_index)
		{
		
			var rollover_index = window.tvg_suite_config[window.tvg_rollover_index][2];
			
	
			// HANDLE ROLLOVER TYPE 1
			
			// experimental: rollovers are based on unique class naming convention (same as id, to keep config simple), appending or removing "_over" to the element's class, paths to images are set in the css
			
		
			// check to deactivate rollover
			// this does not use a config list, but just checks/modifies the classname when a rollover_active_id is set
			
			// when a rollover is active, and thecursor is not in it (a "mouseout", but really a "mousenotin"), switch to passive
			if (window.rollover_active_id != '')
			{
			
				// check if it is really active
				// if "_over" is in the classname, it is assumed to be active
				if (document.getElementById(rollover_active_id).className.indexOf('_over') != -1)
				{
				
					// check if the mouse is in the active rollover, if not switch current active to passive
					if (get_monitored_element_status(rollover_active_id, check_tree_id) != true)
					{
					
						// change status from active to passive
						// the switch is assumed to work by just removing "_over" from the classname
						document.getElementById(rollover_active_id).className = document.getElementById(rollover_active_id).className.replace('_over', '');
						
						// clear active popup
						window.rollover_active_id = '';
						
					}
				
				}
				
			}
			
			// check to activate rollover, do not check anything when a rollover is still active
			// when a rollover from the config is under the cursor (a "mouseover", but really a "mousein"), switch to active
			if (window.rollover_active_id == '')
			{
				
				// check config list
				for (var i in rollover_index){ if (TVGS.key(i)){
					
					// when config id is found and is passive activate rollover
					if (get_monitored_element_status(rollover_index[i], check_tree_id) == true && document.getElementById(rollover_index[i]).className.indexOf('_over') == -1)
					{
						
						// change status from passive to active
						document.getElementById(rollover_index[i]).className = document.getElementById(rollover_index[i]).className.replace(rollover_index[i], rollover_index[i] + '_over');
						
						// set to active rollover
						window.rollover_active_id = rollover_index[i];
						
						break;
					
					}
					
				
				}}
			
			}
			
		
		} // end if rollover_index
		
		
	
		
		
		
		//var popup_index = window.popup_index;
		
		
		// check if the config variable exists
		if (window.tvg_popup_index)
		{
		
			var popup_index = window.tvg_suite_config[window.tvg_popup_index][2];
			
			
			// HANDLE POPUP MENU TYPE 1
			
			
			// check to show popup_passive
			// when a popup_content is visible, and the cursor is not in its content area (a "mouseout", but really a "mousenotin"), switch to popup_passive
		
		
			
			// get associated popup values from popup_index
			for (var i in popup_index){ if (TVGS.key(i)){
					
				// check for correct popup type (1)
				if (is_numeric(i) && popup_index[i][0] == 1)
				{ 	
				
				
					// check active id set
					if (document.getElementById(popup_index[i][2]) && document.getElementById(popup_index[i][2]).style.display != 'none')
					{ 
					
					/*
					 
						// check if the mouse is in the active popup_content, if not switch current active to passive
						if (get_monitored_element_status(popup_index[i][3], check_tree_id) != true)
						{
						
						//	document.getElementById('console').innerHTML += 'setting to passive ' + popup_index[i][1] + ' <br>';
						
							// change status from active to passive
							//switchDisplayFade(popup_index[i][1], popup_index[i][2]);
							
							// fade active portion
							fade_out_element( popup_index[i][2], 10);
							
							// clear active popup
							//window.popup_active_id = '';
							
							//alert('hiding ' + popup_index[i][2]);
							
						}
						*/
						
						
						// check if the mouse is in the active popup_content, if not switch current active to passive
						if (check_monitored_element_class(popup_index[i][3], check_tree_class) != true)
						{
						
						//	document.getElementById('console').innerHTML += 'setting to passive ' + popup_index[i][1] + ' <br>';
						
							// change status from active to passive
							//switchDisplayFade(popup_index[i][1], popup_index[i][2]);
							
							// fade active portion
							fade_out_element(popup_index[i][2], 10);
							
							// clear active popup
							// not essential, just for info tracker
							window.popup_active_id = '';
							
							//alert('hiding ' + popup_index[i][2]);
							
						}
					
					}
				
				}
			
			}}
				
		
		
		
			
			// check to show popup_active
			// when a popup_passive is under the cursor (a "mouseover", but really a "mousein"), switch to popup_active
			for (var i in popup_index){ if (TVGS.key(i)){
			
				//document.getElementById('console').innerHTML += 'CHECK for ' + i + ' = ' + get_monitored_element_status(popup_index[i][1], check_tree_id) + ' <br>';
				
				// check for correct popup type (1) and look for the active id set
				if (is_numeric(i) && popup_index[i][0] == 1 && get_monitored_element_status(popup_index[i][1], check_tree_id) == true)
				{
				
				
					// check active id set
					//if (document.getElementById(popup_index[i][2]) && document.getElementById(popup_index[i][2]).style.display != 'none')
				//	{ 
					
				
					
					// change status from passive to active
					//switchDisplay(popup_index[i][1], popup_index[i][2]);
					
					
					// show active portion
					//if (document.getElementById('sm_js_console')) document.getElementById('sm_js_console').innerHTML += 'Popup type 1: setting to active "' + popup_index[i][2] + '".<br>';
					
				tvg_show_element_by_id(popup_index[i][2]);
				
				
					
					//if (document.getElementById('sm_js_console')) document.getElementById('sm_js_console').innerHTML += 'Popup type 1: setting to active "' + popup_index[i][2] + '".<br>';
					
					// set to active popup
					// not essential, just for info tracker
					window.popup_active_id = popup_index[i][2];
					
					//alert('showing ' + popup_index[i][2]);
					
					break;
				
				}
			
			}}
		
		
		} // end if popup_index
		
		
		if (window.show_info_tracker == true)
		{
			
			showPopup(event, 'linkPopup', current_element);
			
		}
	
	
		
	} // end mousemove handlers
	
	
	
	
		// MOUSEDOWN HANDLERS	
	if (event_type == 'mousedown')
	{
	
	
				// set mousedown time
				window.mousedown_time = get_millitime();
				
				
				//if (document.getElementById('sm_js_console')) document.getElementById('sm_js_console').innerHTML += 'Mousedown tracker: button pressed at ' + window.mousedown_time + '.<br>';
		
	
	
		} // end mousedown handlers
		
		
		
		
		
	// MOUSEUP HANDLERS	
	if (event_type == 'mouseup')
	{
		
		
		
		
		
		// GET CLICK INFO
		
		// get mouseup time and mousepress time
		var mouseup_time = get_millitime();
		var mousepress_time_delta = 0;
		
		//if (document.getElementById('sm_js_console')) document.getElementById('sm_js_console').innerHTML += 'Mouseup tracker: button released at ' + mouseup_time + '.<br>';
		
		
		if (window.mousedown_time != null && window.mousedown_time < mouseup_time)
		{
		
				// see how long user is holding down the button
				var mousepress_time_delta = mouseup_time - mousedown_time;
				
				if (document.getElementById('sm_js_console')) document.getElementById('sm_js_console').innerHTML += 'Mouseup tracker: mousebutton pressed for ' + (mousepress_time_delta / 1000) + ' seconds.<br>';
		
				
				// reset
				window.mousedown_time = null;
				
		}
				
				
				
		
		// HANDLE LINKBLOCK
		
		// see if a linkblock is clicked, get the url and redirect
		// the a-tag with the link is three div's down from the block
		
		// check if this click was in a linkblock and get the block element
		var linkblock = get_first_parent_element_by_class('linkblock', check_tree_element);

		// check for linkblock
		if (linkblock != false)
		{
		
			// set vars
			var depth = 0;
			var progress = true;
			var search_group = linkblock.childNodes;
			

			while (progress == true)
			{
				
				// check all child nodes
				for (var i in search_group){ if (TVGS.key(i)){
					
					// skip properties
					if (is_numeric(i))
					{
					
						// check for link at the right position
						if (search_group[i].nodeName == 'A' && depth == 3)
						{
							
							// set link values
							var url = '';
							var url_target = '';
							
							
							// get url info from a-tag
							if (search_group[i].href) var url = search_group[i].href;
							if (search_group[i].target) var url_target = search_group[i].target;
							
							
							if (url != null && url != '')
							{
								
								//alert (url);
								
								// MAKE FUNCTION add-parameter-to-url
								// set clicktime in get-string, only if parameters are present
								//if (url.indexOf('?') > -1) url = url + '&clicktime=' + mousepress_time_delta;
								

								if (mousepress_time_delta > 750)
								{
								
									tvgs_open_url(url, 'blank');
									
									//alert ('link to blank');
								
								}
								else
								{
								
									//	alert ('link to self');
									if (url_target == '_blank' || url_target == '_top')
									{
										
										// send to correct target, strip underscore
										tvgs_open_url(url, url_target);
										
									}
									else
									{
									
										tvgs_open_url(url);
									
									}
								
								}
								
								
								// stop handling anything and wait for redirect
								return;
							
							}
							else
							{
								
								// invalid link
								progress = false;
								
							}
							
						}
						// advance only on div tag
						else if (search_group[i].nodeName == 'DIV')
						{
							
							// update search group
							search_group = search_group[i].childNodes;
							
							progress = true;
							
							depth++;
							
							break;
							
						}
						else
						{
						
							progress = false;
							
						}
						
					}

				}}
		
			}
			
			
			// stopped searching because of invalid linkblock
			if (document.getElementById('sm_js_console')) document.getElementById('sm_js_console').innerHTML += 'Linkblock mouseup tracker: aborting redirect for inconsistent linkblock.<br>';
		
		}
		
		
		
		// HANDLE SUBMITBLOCK
		
		// see if a submitblock is clicked, get the enclosing form and submit

		// check if this click was in a submitblock and get the block element
		var submitblock = get_first_parent_element_by_class('submitblock', check_tree_element);
		
		// check for linkblock
		if (submitblock != false)
		{

			var active_form = tvgs_get_enclosing_form_element(submitblock);
			
			
			// set clicktime in post-array
			var input_hidden = document.createElement('input');
			
			input_hidden.type = 'hidden';
			input_hidden.name = 'clicktime';
			input_hidden.value = mousepress_time_delta;
			
			active_form.appendChild(input_hidden);
			
		
          
          // if (document.getElementById('sm_js_console')) document.getElementById('sm_js_console').innerHTML += 'Submitblock mouseup tracker: setting clicktime to ' + input_hidden.value + '.<br>';
		
          
          
          
          // set submitblock to inactive
          var submitblock_classnames = submitblock.className.split(' ');
          var new_submitblock_classnames = [];
          
          for (var i in submitblock_classnames){ if (TVGS.key(i)){
          	
          	// rebuild classname, leaving out 'submitblock' so submit will not be triggered again
          	if (submitblock_classnames[i] != 'submitblock')
          	{
          	
          		new_submitblock_classnames[new_submitblock_classnames.length] = submitblock_classnames[i];
          	
          	}
          	
          }}
          
          submitblock.className = new_submitblock_classnames.join(' ');
		
		
			// submit the form
			active_form.submit();
			
		
			// stop handling anything and wait for submit
			return;
								
								
		}
		
		
		
		
		
		
		
		
		
		
		//alert('mouseup on id "' + current_element.id + '"');
		  
	} // end mouseup handlers
	
	
	
	
	
	// KEYUP HANDLERS	
	if (event_type == 'keyup')
	{
		
		//alert('keyup on id "' + current_element.id + '" with value "' + current_element.value + '"');
		

		// HANDLE IEKS LISTS
		
		// check if the config variable exists
		if (window.tvg_ieks_index)
		{
		
			var ieks_index = window.tvg_suite_config[window.tvg_ieks_index][2];
			
			// check if it's an ieks field call
			for (var i in ieks_index){ if (TVGS.key(i)){
			
				if (is_numeric(i) && ieks_index[i][0] == 0 && get_monitored_element_status(ieks_index[i][1], check_tree_id) == true)
				{
	
					// activate list handler
					update_list(ieks_index[i][2], current_element.value);
				
				}
			
			}}
			
		
		} // end if ieks_index
		
		
		// end handle ieks lists
		
	} // end keyup handlers
	
	
	
	

	
	
	// HANDLE COLOR TRANSITION
	// see if the mouse has left an element
	
	/*
	if (window.content_active_id != '')
	{
	
		// check if it is really active
		//if (document.getElementById(content_active_id).style.display != 'none')
		//{
		
			// check if the mouse is in the active popup_content, if not switch current active to passive
			if (current_element.id != window.content_active_id)
			{
				
				
				background_color_transition(document.getElementById(window.content_active_id));
				
				// clear active content
				window.content_active_id = '';
				
			}
		
		//}
		
	}
	// check to show popup_content
	// when a popup_title is under the cursor (a "mouseover", but really a "mousein"), switch to popup_content
	else if (current_element.id.indexOf('popup_content') >= 0)
	{
	
		clearInterval(current_element.name);
		
		current_element.style.backgroundColor='#870082';
	
		window.content_active_id = current_element.id;
		
	}
	*/
	
	

	
	
	
	
	
	
	
}
				
		
		
		
		
		
		
		// IEKS
		
		
		function update_list(option_list, query_string)
		{
			
			
			//var ieks_index = window.tvg_suite_config[window.tvg_ieks_index][2];
			
			
			//alert(output_id);
			
			// set default config vars
			var label_mask = '#label#';
			var match_highlight_mask = '#match#';
			
			// get config vars when specified
			 for (var i in option_list){ if (TVGS.key(i)){
			 	
			 	// see if the query string is contained in the option
			 	if(is_numeric(i) && option_list[i][0] == 0)
			 	{
			 	
			 		if (option_list[i][1] == 'list_output_id')
			 		{
			 			output_id = option_list[i][2];
			 		}
			 		
			 		if (option_list[i][1] == 'label_mask')
			 		{
			 			label_mask = option_list[i][2];
			 		}
			 		
			 		if (option_list[i][1] == 'match_highlight_mask')
			 		{
			 			match_highlight_mask = option_list[i][2];		
			 			
			 		}
			 		
			 	}
			 
			 }}
				
			
			// process options
			var match_query = eval('/' + query_string + '/i');
			
			var option_id = '';
			
			var matching_option = '';
			var matching_option_list = '';
				
			 for (var i in option_list){ if (TVGS.key(i)){
			 	
			 	// use case insensiteve query
			 //	match_query = eval('/' + query_string + '/i');
			 	
			 	
			 	
			
			 	// see if the query string is contained in the option
			 	if(is_numeric(i) && option_list[i][0] == 1)
			 	{
			 		
			 		
			 		if (query_string == '')
			 		{
			 			
			 			// no query, just show all
			 			matching_option = option_list[i][1];
			 		
			 		}
			 		else if (option_list[i][1].match(match_query) != null)
			 		{

			 			// highlight the first occurence op the string in the option label
			 			matching_option = option_list[i][1].replace(match_query, match_highlight_mask.replace('#match#', option_list[i][1].match(match_query)));
			 		
			 		}
			 		else
			 		{
			 			
			 			// no match, leave out
			 			matching_option = '';
			 		
			 		}
			 		
			 		
			 		// construct option code
			 		if (matching_option != '')
			 		{

			 			// wrap label in label mask
			 			matching_option = label_mask.replace('#label#', matching_option);
			 			
			 			// set option_id
			 			option_id = output_id + '_option_' + i;
			 			
			 			matching_option = matching_option.replace('#option_id#', option_id);
			 			
			 		}
			 		
			 		
			 		// add to list
			 		matching_option_list += matching_option;
			 		
			 		//alert(matching_option_list);	 		
			 		
			 		//reset option
			 		matching_option = '';
			 	
			 	}
			 	
			 	// reset match query
			 	//match_query = '';
			 
			 }}
			 
			 
			 // check result
	 		if (matching_option_list == '')
	 		{

	 			// display no results message
	 			matching_option_list = 'No matches!';
	 			
	 		}
			 
			 // write to page
			//document.getElementById(output_id).innerHTML = matching_option_list;
		
		}
		
/*		
		
function mouseEventHandler(event)
{
	// Internet Explorer
	if (event.srcElement)
	{
		showPopup(event, 'linkPopup', event.srcElement);
	}
	// Netscape and Firefox
	else if (event.target)
	{
		showPopup(event, 'linkPopup', event.target);
	}
}

function getPopupObject(myId)
{
   if (document.getElementById(myId))
   {
     return document.getElementById(myId);
   }
   else
   {
     return window.document[myId]; 
	}     
}
*/




function toggleInfoTracker()
{
	
	if (window.show_info_tracker == true)
	{
		
		window.show_info_tracker = false;
		
		document.getElementById('linkPopup').style.display = 'none';
		
	//	if (document.getElementById('sm_js_console')) document.getElementById('sm_js_console').innerHTML += 'Info tracker: disabled.<br>';
		
	}
	else
	{
		window.show_info_tracker = true;
		
	//	if (document.getElementById('sm_js_console')) document.getElementById('sm_js_console').innerHTML += 'Info tracker: enabled.<br>';
	}
	
}





function showPopup(event, tracker_id, element)
{
	
	// get position
	var x = parseInt(event.clientX+document.body.scrollLeft);
	var y = parseInt(event.clientY+document.body.scrollTop);


	//var popup=getPopupObject(id);
	
	
	
	if (document.getElementById(tracker_id))
	{	
		
		var tracker = document.getElementById(tracker_id);
		
		
		// show
		if(tracker.style.display == 'none')
		{
			tracker.style.display = '';	
		}
		// update contents
		//var popupText=getPopupObject(id+"Text");
		
		var text = '';
		
		text += 'Node: ' + element.nodeName + '(distance to HTML root: ' + window.distance_to_html_node +  ')<br>';
		
		if (element.id != '')
		{
		
			text += 'Id: "' + element.id + '"<br>';
			
		}
		
		if (element.className != '')
		{
		
			text += 'Class: "' + element.className + '"<br>';
			
		}
			
		//text += element.parentNode.nodeName + ", id '"+element.parentNode.id+"'<br>";
		
		
		
	//	text += 'Distance to HTML node: ' + window.distance_to_html_node + '<br>';
			
	
		text += 'Mouse moves: ' + window.mousemoved + ' (' + x + ', ' + y + ')<br>';
		
		
		if (window.popup_active_id != '')
		{
			
			text += 'Popup type 1 id: ' + window.popup_active_id + '<br>';
			
		}
		
		if (window.rollover_active_id != '')
		{
			
			text += 'Rollover type 1 id: ' + window.rollover_active_id + '<br>';
			
			//text += 'Active rollover class: ' + document.getElementById(rollover_active_id).className + '<br>';
			
		}
		
		// update content
		tracker.innerHTML = text;
		
		// info window offset from cursor
		x = x + 10;
		y = y + 10;
		
		// style string values
		x = x + 'px';
		y = y + 'px';
		
		// update position
		tracker.style.left = x;
		tracker.style.top = y;
		
	}
	
}

		
		





// sends a useless query to server at a set interval to keep session alive
// interval is in seconds
function tvgs_keep_alive(url, interval)
{

	if (document.getElementById('sm_js_console')) document.getElementById('sm_js_console').innerHTML += 'Keep alive counter: initialized.<br>';
	
	
	
	if (document.getElementById('sm_keep_alive_count'))
	{
			
		var counter = document.getElementById('sm_keep_alive_count');
		
		var interval = 1; // tick interval in seconds
		
		var beq_interval = 5; // beq interval in seconds
		
		var tick = 0;
		
		var beq_tick = 0;
		
		var beq_response = null;
		
		var image_link = counter.name;
		
		if (document.getElementById('sm_js_console')) document.getElementById('sm_js_console').innerHTML += 'Keep alive ticker image link: ' + image_link + '.<br>';
			
	}
	else
	{
		
		// no output element
		return;
	
	}
	

	function tvgs_keep_alive_ticker()
	{
	
			// update counter image
			counter.src = image_link + tick + '';


			// refresh session through responder
			if (beq_tick == beq_interval)
			{
				
				beq_tick = 0;
				
				beq_response = initiate_backend_query(url);

		 	}
		 	
		 	
			if (document.getElementById('sm_keep_alive_message'))
			{
				
				// update message
				if (beq_response != null)
				{
					
					if (document.getElementById('sm_js_console')) document.getElementById('sm_js_console').innerHTML += 'Keep alive message sent at: tick ' + tick + '.<br>';
		
					var message = document.getElementById('sm_keep_alive_message');
					
					message.innerHTML = beq_response;
					message.style.display = '';
					
					fade_out_element('sm_keep_alive_message', 20);
					
					
				}
				
				
				
			}
		
		
			beq_response = null;
			
			tick++;
		
			beq_tick++;
		 
	}
	
	setInterval(tvgs_keep_alive_ticker, (interval * 1000));
				
}



// make query to backend script
function initiate_backend_query(url)
{

	// create empty query variable
	var backend_query = null;
	
	
	// setup request, alert on fail
	try
	{
	
		// firefox, opera 8+, safari, ie7
		backend_query = new XMLHttpRequest();
		
	}
	catch(e)
	{
		
		// old ie
		try
		{
		
			backend_query = new ActiveXObject('Microsoft.XMLHTTP');
		
		}
		catch(e)
		{
		
			alert ('This webbrowser does not support XMLHTTP!');
			return;  
		
		}
	
	}
	
	
	// send query, wait for response
	backend_query.open('GET',url,false);
	
	backend_query.send(null);
	
	
	// get result
	return backend_query.responseText;

}


// v1 2009-01-09
// updates an image src with the time like "16:34" every second
// todo: get this to just return the formatted time, and separate the image updater
// note: set show seconds to true to get the time with seconds
function tvgs_clock(img_id, show_seconds)
{

	if (document.getElementById(img_id))
	{
	
		// set vars
		var clock = document.getElementById(img_id);
		var clock_base_img_src = clock.name;
		
		var clock_display = '';
		window.tvgs_clock_display = '';	
		
		var current_date = null;
		var current_hours = null;
		var current_minutes = null;
		var current_seconds = null;
	
		var tick_count = 0;
		
		
		function tvgs_clock_ticker()
		{
			
			// get current date
			current_date = new Date()
			
			// get current hours
			current_hours = current_date.getHours();
			if ((current_hours + '').length == 1) current_hours = '0' + current_hours + '';
			
			// get current minutes
			current_minutes = current_date.getMinutes();
			if ((current_minutes + '').length == 1) current_minutes = '0' + current_minutes + '';
			
		
			// set clock display text				
			clock_display = current_hours + ':' + current_minutes;
			
			
			if (show_seconds == true)
			{
			
				// get current seconds
				current_seconds = current_date.getSeconds();
				if ((current_seconds + '').length == 1) current_seconds = '0' + current_seconds + '';
				
				// set clock display text
				clock_display = clock_display + ':' + current_seconds;
			
			}
			
			
			// check if the displayed time will change
			if (window.tvgs_clock_display != clock_display)
			{
				
				// update current display
				window.tvgs_clock_display = clock_display;	
				
				// update image
				clock.src = clock_base_img_src + clock_display;
				
			}
			
			
			// update ticker
			tick_count++;
		
		}
	
	
		// start ticking
		//tvgs_clock_ticker();
		setInterval(tvgs_clock_ticker, 100); // interval is 0.1 second to provide for smooth seeming display of seconds when the interval is slighty off
		
		
		if (document.getElementById('sm_js_console')) document.getElementById('sm_js_console').innerHTML += 'Clock: initialized.<br>';
			
	}
	else
	{
		
		if (document.getElementById('sm_js_console')) document.getElementById('sm_js_console').innerHTML += 'Clock: output element not found.<br>';
		
		// no output element
		return;
	
	}
	

}

// NOT FUNCTIONAL: BREAKS SCRIPT
// allImagesLoaded()
// Checks if all the images are loaded in the document
// It Does this by looping through all the images and checks the attribute .complete
// If .complete is false then we set the return variable to 0
function allImagesLoaded(document_start_time)
{

 

 	function wait_for_images()
	{
		
								
							
		var all_images = document.images;
		
		// Loop through all the images
		for (var i = 0;i<all_images.length;i++)
		{
			// If the image isnt loaded we set the return varible to 0
			if(all_images[i].complete == false)
			{
				return false;
			}
		}
					
		clearTimeout(timer_intervalset);
							
							
		var document_images_loaded_time = get_millitime();
		
		var document_images_completion_delta = document_images_loaded_time - document_start_time;
		
		window.timer_info_images = document_images_completion_delta;
						
						
		display_timer_result();
						

	}
	
	
	
	var timer_intervalset = setTimeout(wait_for_images, 50);
	
	
	
	
	
	// display report
	function display_timer_result()
	{
		
		if (document.getElementById('sm_js_console')) document.getElementById('sm_js_console').innerHTML += 'Images completion time: ' + window.timer_info_images + 'ms.<br>';
		//document.getElementById('page_info_load_time').innerHTML = 'DOM completion time: ' + 	window.timer_info_dom + 'ms. Images completion time: ' + window.timer_info_images + 'ms.';
		//alert('DOM completion time: ' + 	window.timer_info_dom + 'ms. Images completion time: ' + window.timer_info_images + 'ms.');

	}
				
								
								
								
}





