//$Id: Browser.js,v 1.6.2.1 2006/02/09 22:16:26 spyle Exp $
/*
DOCUMENTATION
This class is responsible for making IE Javascript DOM more W3C compatible.
Other functions exist to facilitate the differences in Javascript implementations.

This does not solve all the javascript DOM problems. Add to this class when needed.

DEPENDENCY
browser_sniffer.js
Window.js
*/
function Browser()
{
	var application_name = navigator.appName.toLowerCase();
	var application_version = parseInt(navigator.appVersion); 
	
	this.window = new Window(); //window manager
	
	//Returns the type of browser that the current browser is
	this.getType = function()
	{
		return application_name;
	}
	
	this.getVersion = function()
	{
		return application_version;
	}

	//gets an event object with corrected additional properties
	this.getEvent = function(e)
	{
		if(is_ie)
		{
			e = window.event;
			e.target = e.srcElement;
		}
		
		return e;
	}

	//Calculates the sizes of the items in the browser.
	//If an event object is given, it will attempt to find the mouse location.
	this.getSizes = function(e)
	{

/*
Mozilla Firefox 1.5+
---------------
document.body.scrollLeft position of the horizontal scroll bar
document.body.scrollTop  position of the vertical scroll bar
document.documentElement.scrollLeft  0
document.documentElement.scrollTop  0
window.pageXOffset same as document.body.scrollLeft
window.pageYOffset same as document.body.scrollTop
event.clientX horizontal position of mouse in the browser window from left
event.clientY vertical position of mouse in the browser window from top
event.pageX  horizontal position of mouse on page from left
event.pageY  vertical position of mouse on page from top
event.screenX horizontal position of mouse on the user's screen from left
event.screenY vertiacal position of mouse on the user's screen from top

IE 6 SP2
---------------
document.body.scrollLeft position of the horizontal scroll bar
document.body.scrollTop  position of the vertical scroll bar
document.documentElement.scrollLeft  0
document.documentElement.scrollTop  0
window.pageXOffset undefined
window.pageYOffset undefined
event.clientX horizontal position of mouse in the browser window from left
event.clientY vertical position of mouse in the browser window from top
event.pageX  undefined
event.pageY  undefined
event.screenX horizontal position of mouse on the user's screen from left
event.screenY vertiacal position of mouse on the user's screen from top

   1. clientX,clientY
   2. layerX,layerY
   3. offsetX,offsetY
   4. pageX,pageY
   5. screenX,screenY
   6. x,y

   mouse position
     window
     screen
   scroll position
 
   page width/height
   document width/height
   element width/height
 */
		var root = document.documentElement;
		var body = document.body;

		var sizes = [];
		//mouse location
		
		//dimensions
//		sizes.window_width = parseInt(root.clientWidth);
//		sizes.window_height = parseInt(root.clientHeight);
//		sizes.root_width = parseInt(root.style.width);
//		sizes.root_height = parseInt(root.style.height);
//		sizes.body_width = parseInt(body.clientWidth);
//		sizes.body_height = parseInt(body.clientHeight);
//		sizes.body_width = parseInt(body.style.width);
//		sizes.body_height = parseInt(body.style.height);
	
/*
		var _root = document.documentElement;
		var _body = document.body;
		
//		if(is_ie)
//		{
//			_root = _body; //This takes care of the problem that IE doesn't set the documentElement items correctly for width, height, scrollLeft, scrollTop
//		}

		//window dimensions
		sizes.window = []; 
		sizes.window.width = parseInt(_root.clientWidth);
		sizes.window.height = parseInt(_root.clientHeight);

		//body dimension //TODO: ensure this is correct
		sizes.body = [];
		sizes.body.width = parseInt(_body.clientWidth);
		sizes.body.height = parseInt(_body.clientHeight);
		
		sizes.scroll = [];
		//find scroll coordinates in document
		sizes.scroll.document = [];
		sizes.scroll.document.left = parseInt(_root.scrollLeft);
		sizes.scroll.document.top = parseInt(_root.scrollTop);

		//find scroll coordinates in body
		sizes.scroll.body = []
		sizes.scroll.body.left = parseInt(_body.scrollLeft);
		sizes.scroll.body.top = parseInt(_body.scrollTop);

		//find screen sizes
		//sizes.screen.mouse = [];
		
		if(e)
		{
			sizes.mouse = [];
			
			//find mouse position in client
			sizes.mouse.window = [];
			if(is_nav4)
			{
				sizes.mouse.window.left = parseInt(e.pageX);
				sizes.mouse.window.top = parseInt(e.pageY);
			}
			else //IE & FireFox
			{
				sizes.mouse.window.left = parseInt(e.clientX);
				sizes.mouse.window.top = parseInt(e.clientY);
			}
			
			//find mouse position in document
			if(!is_ie)
			{
				sizes.mouse.document = [];
				sizes.mouse.document.left = parseInt(e.pageX);
				sizes.mouse.document.top = parseInt(e.pageY);
			}
			
			//find mouse position on screen
			sizes.mouse.screen = [];
			sizes.mouse.screen.left = parseInt(e.screenX);
			sizes.mouse.screen.top = parseInt(e.screenY);
		}
*/
		
		return sizes;
	}
	
	//add calls to functions to patch up non W3C browsers
	this.makeW3C = function()
	{
		createIEaddEventListeners();  
		//TODO: create congruent all vs. layers ?
	}
}


//http://www.codingforums.com/showthread.php?t=68681
//More information: http://www.quirksmode.org/js/events_advanced.html
//TODO:refactor and document
function createIEaddEventListeners()
{
	if (document.addEventListener || !document.attachEvent) //browser doesn't need addEventListener
		return;

	//attaches event to an element
	function ieAddEventListener(eventName, handler, capture)
	{
		if (this.attachEvent)
			this.attachEvent('on' + eventName, handler);
	}

	//adds a addEventListener function to all elements in the body.
	function attachToAll()
	{
		var i, l = document.all.length;

		for (i = 0; i < l; i++)
			if (document.all[i].attachEvent)
				document.all[i].addEventListener = ieAddEventListener;
	}

	//define a new createElement function that includes the addEventListener function
	var originalCreateElement = document.createElement;
	document.createElement = function(tagName)
	{
		var element = originalCreateElement(tagName);

		if (element.attachEvent)
			element.addEventListener = ieAddEventListener;

		return element;
	}

	
	window.addEventListener = ieAddEventListener;
	document.addEventListener = ieAddEventListener;

	var body = document.body;

	//modify the body so that on loading of the page, all elements get an addEventListener function
	if (body)
	{
		if (body.onload)
		{
			var originalBodyOnload = body.onload;

			body.onload = function()
			{
				attachToAll();
				originalBodyOnload();
			};
		}
		else
			body.onload = attachToAll;
	}
	else
	window.addEventListener('load', attachToAll);
}	

//MAIN CODE
var browser = new Browser();
browser.makeW3C();

/*
//http://ejohn.org/projects/flexible-javascript-events/
//http://www.quirksmode.org/blog/archives/2005/09/addevent_recodi.html
//EXAMPLES
addEvent( document.getElementById('foo'), 'click', doSomething );
addEvent( obj, 'mouseover', function(){ alert('hello!'); } );
removeEvent( object, eventType, function );

function addEvent( obj, type, fn ) {
	if ( obj.attachEvent ) {
		obj['e'+type+fn] = fn;
		obj[type+fn] = function(){obj['e'+type+fn]( window.event );}
		obj.attachEvent( 'on'+type, obj[type+fn] );
	} else
	obj.addEventListener( type, fn, false );
}
function removeEvent( obj, type, fn ) {
	if ( obj.detachEvent ) {
		obj.detachEvent( 'on'+type, obj[type+fn] );
		obj[type+fn] = null;
	} else
	obj.removeEventListener( type, fn, false );
}


*/


function Window()
{
	//view
	this.width = '350';	// = number 	the width of the window, in pixels. Min. value is 100
	this.height = '250';	// = number 	the height of the window, in pixels. Min. value is 100
	this.top = '0';		// = number 	the top position, in pixels
	this.left = '0';		// = number 	the left position, in pixels
	this.fullscreen = 'no';	// = yes | no | 1 | 0 	whether to display the browser in full-screen mode. Default is no. A window in full-screen mode must also be in theater mode
	this.channelmode = 'no';// = yes | no | 1 | 0  	whether to display the window in theater mode. Default is no

	//bars
	this.location = 'no';	// = yes | no | 1 | 0 	whether to display the address field. Default is yes
	this.menubar = 'no';		// = yes | no | 1 | 0 	whether to display the menu bar. Default is yes
	this.scrollbars = 'yes';	// = yes | no | 1 | 0 	whether to display scroll bars. Default is yes
	this.titlebar = 'yes';	// = yes | no | 1 | 0 	whether to display the title bar. Ignored unless the calling application is an HTML Application or a trusted dialog box. Default is yes
	this.toolbar = 'no';		// = yes | no | 1 | 0 	whether to display the browser toolbar. Default is yes

	//misc
	this.status = 'yes';		// = yes | no | 1 | 0 	whether to add a status bar. Default is yes
	this.resizable = 'yes';	// = yes | no | 1 | 0 	whether the window is resizable. Default is yes
	this.directories = 'no';// = yes | no | 1 | 0 	whether to add directory buttons. Default is yes

	var windows = []; //array of windows that have been opened from this instance
	
	//returns the string of options for all options that are set
	this.getOptions = function()
	{

		var options_s = ""
		for (x in this)
		{
			if (this[x] != null && typeof(this[x]) == "string")
			{
				options_s += x+"="+this[x]+", ";
			}
		}
		return options_s;
	}

	this.open = function(url,name)
	{
		windows[name] = window.open(url,name,this.getOptions(),false);
		windows[name].focus();
	}
	
	this.close = function(name)
	{
		windows[name].close();
		//windows[name] = '';
	}
	
	this.focus = function(name)
	{
		windows[name].focus();
	}
}