﻿/**
 * Browser Class - v.1.2
 * Main class for handling HTML Elements
 *
 * Author Cristian Nicolescu
 * Copyright 2006, Gecad Tehnologies
 *
 * Known bugs/issues: 
 *   - new setXY and/or getXY, tested on IE 6, Opera 8, FF 1.0.6, Konqueror 3.4.2
 * 
 * Class Interface:
 *   - getObject(obj)
 *   - getObjectsByTag(tagName, parent)
 *   - getStyle(obj, property)
 *   - getX(obj)
 *   - getY(obj)
 *   - getXY(obj)
 *   - getAttribute(obj, attr)
 * 
 *   - setStyle(obj, property, value)
 *   - setX(obj, newX)
 *   - setY(obj, newY)
 *   - setXY(obj, newX, newY, forceAbsolute)
 *   - moveTo is an alias for setXY
 *   - setAttribute(obj, attr, value)
 *   - removeAttribute(obj, attr)
 *   - addClass(obj, className)
 *   - removeClass(obj, class)
 *
 *   - addInnerText(obj, text)
 *   - createElement(obj, text)
 *   - insertBefore(beforeObj, obj)
 *   - insertAfter(afterObj, obj)
 *   - removeObject(obj)
 *   - replaceObject(obj, newObj)
 *   - resize(obj, width, height) 
 *   - setSize is an alias for resize
 *   - cloneObject(obj, copySubTree)
 *   - appendObject(newObj, toObj)
 *   - getSize(obj)
 *   - getScroll
 *   - getVisibleSize
 *   - getObjectsWithClass(parent, class, tag)
 *   - getFirstChild(obj)
 *
 *   - createTable(params)
 *   - addRow(tblObj, params)
 *   - addCell(tblObj, data, params)
 *   - getTable(tblObj)
 *
 *   - clone()
 */

var Browser = new function () {
	var d = document;
	var dView = d.defaultView;

	//support W3C DOM browsers
	var w3cdom = ( d.createElement && d.getElementById );

	if( w3cdom ) {}
	else if( d.layers ) { alert('Your browser is currently not supported'); return null; }
	else if ( d.all ) { alert('Your browser is currently not supported'); return null; }
	else { alert('Your browser is not supported'); return null; }

	//-----------------------------------------
	this.getObject = function(obj) {
		if( typeof obj == 'string' && d.getElementById(obj) ) { return d.getElementById(obj); }
		else if( typeof obj == 'object' ) { return obj; }
		return false;
	}
	//-----------------------------------------
	
	//-----------------------------------------
	this.getObjectsByTag = function(tagName, parent) {
		pObj = this.getObject(parent);
		pObj = ( pObj ) ? pObj : d;
		
		if( tagName && pObj.getElementsByTagName(tagName) ) { return pObj.getElementsByTagName(tagName); }
		return false;
	}
	//-----------------------------------------
	
	//-----------------------------------------
	this.getStyle = function(obj, property) {
		el = this.getObject(obj);
		if( !el ) { return false; }
		
		if( property == 'opacity' && el.filters ) {
			try {
				return el.filters.item('DXImageTransform.Microsoft.Alpha').opacity;
			} 
			catch(e) {
				try {
					return el.filters.item('alpha').opacity;
				} 
				catch(e) {}
			}
			
			return 100;
		}
		else if( el.style[property] ) {
			return el.style[property];
		}
		else if( el.currentStyle && el.currentStyle[property] ) {
			return el.currentStyle[property];
		}
		else if ( dView && dView.getComputedStyle ) {  //dropped case to hyphen case
			var out = '';
			for(i = 0, len = property.length; i < len; ++i) {
				if( property.charAt(i) == property.charAt(i).toUpperCase() ) {
					out = out + '-' + property.charAt(i).toLowerCase();
				} 
				else {
					out = out + property.charAt(i);
				}
			}

			if( dView.getComputedStyle(el, null) ) {
				return dView.getComputedStyle(el, null).getPropertyValue(out);
			}
		}
		else {
			return false;
		}
	}
	//-----------------------------------------
	
	//-----------------------------------------
	this.getX = function(obj) { return this.getXY(obj)[0]; }
	//-----------------------------------------

	//-----------------------------------------
	this.getY = function(obj) { return this.getXY(obj)[1]; }
	//-----------------------------------------

	//-----------------------------------------
	this.getXY = function(obj) {
		var curTop = 0, curLeft = 0;
		var temp = this.getObject(obj);
		if( !temp ) { return false; }

		if( temp.parentNode != null && temp.offsetParent ) {
			while( temp.offsetParent ) {
				curTop += temp.offsetTop;
				curLeft += temp.offsetLeft;
				temp = temp.offsetParent;
			}
		}
		else if( temp.x && temp.y ) {
			curTop = temp.y;
			curLeft = temp.x;
		}
		else {
			curLeft = parseInt(this.getStyle(temp, 'left'), 10);
			curTop = parseInt(this.getStyle(temp, 'top'), 10);

			if( isNaN(curLeft) ) curLeft = 0;
			if( isNaN(curTop) ) curTop = 0;
		}

		return [curLeft, curTop];
	}
	//-----------------------------------------

	//-----------------------------------------
	this.getAttribute = function(obj, attr) {
		el = this.getObject(obj);
		if( el && el.getAttribute(attr) ) { return el.getAttribute(attr); }
		return false;
	}
	//-----------------------------------------
	
	//-----------------------------------------
	this.setStyle = function(obj, property, val) {
		el = this.getObject(obj);
		if( !el ) { return false; }
		
		if( property == 'opacity' ) {
			if( el.filters ) {
				el.style.filter = 'alpha(opacity=' + val * 100 + ')';
		
				if( !el.currentStyle.hasLayout ) {
					el.style.zoom = 1;
				}
			}
			else {
				el.style.opacity = val;
				el.style['-moz-opacity'] = val;
				el.style['-khtml-opacity'] = val;
			}
		}
		else {
			el.style[property] = val;
		}
		
		return true;
	}
	//-----------------------------------------

	//-----------------------------------------
	this.moveTo = this.setXY = function(obj, newX, newY, forceAbsolute) {
		el = this.getObject(obj);
		if( !el ) { return false; }

		if( isNaN(newX) ) { newX = null; }
		if( isNaN(newY) ) { newY = null; }

		if( this.getStyle(el, 'position') == 'static' ) {
			this.setStyle(el, 'position', 'relative');
		}
		
		if( forceAbsolute == true && newX != null && newY != null ) {
			this.setStyle(el, 'position', 'absolute');
		}

		try {
			if( newX != null ) { this.setStyle(el, 'left', newX + 'px'); }
			if( newY != null ) { this.setStyle(el, 'top', newY + 'px'); }
		}
		catch(e) { return false; }
		
		return true;
	}
	//-----------------------------------------

	//-----------------------------------------
	this.setX = function(obj, newX) { return this.setXY(obj, newX, null); }
	//-----------------------------------------

	//-----------------------------------------
	this.setY = function(obj, newY) { return this.setXY(obj, null, newY); }
	//-----------------------------------------

	//-----------------------------------------
	this.setAttribute = function(obj, attr, value) {
		el = this.getObject(obj);
		if( el && el.setAttribute ) {
			el.setAttribute(attr, value);
			return true;
		}
		
		return false;
	}
	//-----------------------------------------

	//-----------------------------------------
	this.removeAttribute = function(obj, attr) {
		return this.setAttribute(obj, attr, null);
	}
	//-----------------------------------------

	//-----------------------------------------
	this.addClass = function(obj, className) {
		el = this.getObject(obj);
		if( !el ) { return false; }
		this.removeClass(el, className);
		el.className += " " + className;
	}
	//-----------------------------------------

	//-----------------------------------------
	this.removeClass = function(obj, className) {
		el = this.getObject(obj);
		if( el && el.className ) {
			var cls = el.className.split(" ");
			var ar = new Array();
			for (var i = cls.length; i > 0;) {
				if( cls[--i] != className ) {
					ar[ar.length] = cls[i];
				}
			}
			el.className = ar.join(" ");
			return true;
		}
		
		return false;
	}
	//-----------------------------------------
	
	//-----------------------------------------
	this.addInnerText = function (obj, text) {
		el = this.getObject(obj);
		if( !el ) { return false; }
		try {
			return el.appendChild(d.createTextNode(text));
		}
		catch(e) {
			return false;
		}
	}
	//-----------------------------------------

	//-----------------------------------------
	//insert obj before beforeObj
	this.insertBefore = function(beforeObj, obj) {
		if( typeof obj != 'object' ) { return false; }
		el = this.getObject(beforeObj);
		if( !el ) { return false; }
		try {
			elParent = el.parentNode;
			return elParent.insertBefore(obj, el);
		}
		catch(e) {
			return false;
		}
	}	
	//-----------------------------------------

	//-----------------------------------------
	//insert obj after afterObj
	this.insertAfter = function(afterObj, obj) {
		if( typeof obj != 'object' ) { return false; }
		el = this.getObject(afterObj);
		if( !el ) { return false; }

		try {
			elParent = el.parentNode;
			sibling = el.nextSibling;
			return elParent.insertBefore(obj, sibling);
		}
		catch(e) {
			return false;
		}
		
	}	
	//-----------------------------------------

	//-----------------------------------------
	this.createElement = function(elem, text) {
		el = d.createElement(elem);
		if( !el ) { return false; }
		
		if( text ) {
			try {
				el.appendChild(d.createTextNode(text)); 
			} 
			catch(e) { 
				return false; 
			} 
		}

		return el;
	}
	//-----------------------------------------
	
	//-----------------------------------------
	this.removeObject = function(obj) {
		el = this.getObject(obj);
		if( !el ) { return false; }

		try {
			return el.parentNode.removeChild(el);
		}
		catch(e) {
			return false;
		}
	}
	//-----------------------------------------
	
	//-----------------------------------------
	this.replaceObject = function(obj, newObj) {
		el = this.getObject(obj);

		if( typeof newObj == 'object' ) { elNew = newObj; }
		else { elNew = this.getObject(newObj); }

		if( !elNew || !el ) { return false; }
		
		try {
			return el.parentNode.replaceChild(elNew, el);
		}
		catch(e) {
			return false;
		}
	}
	//-----------------------------------------
	
	//-----------------------------------------
	this.setSize = this.resize = function(obj, width, height) {
		el = this.getObject(obj);
		if( !el ) { return false; }
		
		try {
			all = [0, 0, 0, 0];
/*
			margins = [this.getStyle(el, 'marginTop'), this.getStyle(el, 'marginRight'), this.getStyle(el, 'marginBottom'), this.getStyle(el, 'marginLeft')];
			paddings = [this.getStyle(el, 'paddingTop'), this.getStyle(el, 'paddingRight'), this.getStyle(el, 'paddingBottom'), this.getStyle(el, 'paddingLeft')];
			borders = [this.getStyle(el, 'borderTopWidth'), this.getStyle(el, 'borderRightWidth'), this.getStyle(el, 'borderBottomWidth'), this.getStyle(el, 'borderLeftWidth')];
			for(var k = 0; k < 4; k++) {
				margins[k] = ( isNaN(parseInt(margins[k], 10)) ) ? 0 : parseInt(margins[k], 10);
				paddings[k] = ( isNaN(parseInt(paddings[k], 10)) ) ? 0 : parseInt(paddings[k], 10);
				borders[k] = ( isNaN(parseInt(borders[k], 10)) ) ? 0 : parseInt(borders[k], 10);
				all[k] = margins[k] + paddings[k] + borders[k];
			}
*/
			if( width != null ) {
				newWidth = width - all[1] - all[3];
				if( newWidth <= 0 ) { return false; }
				this.setStyle(el, 'width', newWidth + 'px');
				
			}

			if( height != null ) {
				newHeight = height - all[0] - all[2];
				if( newHeight <= 0 ) { return false; }
				this.setStyle(el, 'height', newHeight + 'px');

			}
			return true;
		}
		catch(e) {
			return false;
		}

		return false;
	}
	//-----------------------------------------
		
	//-----------------------------------------
	this.cloneObject = function(obj, copySubTree) {
		copySubTree = !!( copySubTree );
		el = Browser.getObject(obj);
		if( !el ) { return false; }
		
		try {
			clone = el.cloneNode(copySubTree);
			//Browser.setAttribute(clone, 'id', Browser.getAttribute(el, 'id') + '__clone__');
			return clone;
		}
		catch(e) { return false; }
	}
	//-----------------------------------------

	//-----------------------------------------
	this.appendObject = function(newObj, toObj) {
		newEl = this.getObject(newObj);
		toEl = this.getObject(toObj);
		
		if( !newEl || !toEl ) { return false; }
		
		try {
			toEl.appendChild(newEl);
			return true;
		}
		catch(e) { return false; }
	}
	//-----------------------------------------

	//-----------------------------------------
	this.getSize = function(obj) {
		el = this.getObject(obj);
		if( !el ) { return false; }
		
		if( el.offsetWidth && el.offsetHeight ) {
			return [el.offsetWidth, el.offsetHeight];
		}
		else {
			width = this.getStyle(el, 'width');
			height = this.getStyle(el, 'height');
					
			width = parseInt(width, 10);
			height = parseInt(height, 10);
	
			height = isNaN(height) ? 0 : height;
			width = isNaN(width) ? 0 : width;
			
			return [width, height];
		}
	}
	//-----------------------------------------

	//-----------------------------------------
	this.getScroll = function() {
		var scrOfX = 0, scrOfY = 0;
		if( typeof window.pageYOffset  == 'number' ) {
			//Netscape compliant
			scrOfY = window.pageYOffset;
			scrOfX = window.pageXOffset;
		} 
		else if( d.body && ( d.body.scrollLeft || d.body.scrollTop ) ) {
			//DOM compliant
			scrOfY = d.body.scrollTop;
			scrOfX = d.body.scrollLeft;
		} 
		else if( d.documentElement && ( d.documentElement.scrollLeft || d.documentElement.scrollTop ) ) {
			//IE6 standards compliant mode
			scrOfY = d.documentElement.scrollTop;
			scrOfX = d.documentElement.scrollLeft;
		}

		return [ scrOfX, scrOfY ];
	}
	//-----------------------------------------

	//-----------------------------------------
	this.getVisibleSize = function() {
		var myWidth = 0, myHeight = 0;
		if( typeof window.innerWidth == 'number' ) {
			//Non-IE
			myWidth = window.innerWidth;
			myHeight = window.innerHeight;
		}
		else if( d.documentElement && ( d.documentElement.clientWidth || d.documentElement.clientHeight ) ) {
			//IE 6+ in 'standards compliant mode'
			myWidth = d.documentElement.clientWidth;
			myHeight = d.documentElement.clientHeight;
		} 
		else if( d.body && ( d.body.clientWidth || d.body.clientHeight ) ) {
			//IE 4 compatible
			myWidth = d.body.clientWidth;
			myHeight = d.body.clientHeight;
		}
		
		return [ myWidth, myHeight ];
	}
	//-----------------------------------------

	//-----------------------------------------
	this.getObjectsWithClass = function(parent, klass, tag) {
		pObj = this.getObject(parent);
		collection = [];
		temp = this.getObjectsByTag(tag, pObj);

		for(var i = 0, counter = 0, len = temp.length; i < len; i++) {
			token = new RegExp("(^|\\s)" + klass + "($|\\s)", 'g');
			if( token.test(temp[i].className) ) {
				collection[counter++] = temp[i];
			}
		}

		return collection;
	}
	//-----------------------------------------

	//-----------------------------------------
	this.getFirstChild = function(obj) {
		obj = this.getObject(obj);
		if( obj.childNodes && obj.childNodes.length > 0 ) {
			return obj.childNodes[0];
		}
		else {
			return false;
		}
	}
	//-----------------------------------------


	//-----------------------------------------
	this.createTable = function(params) {
		if( typeof params != 'object' ) { return false;}
		
		var table = this.createElement('table');
		
		for(var p in params) {
			if( p != 'klass' ) {
				this.setAttribute(table, p, params[p]);
			}
			else {
				this.addClass(table, params[p]);
			}
		}
		
		var tbody = this.createElement('tbody');
		this.appendObject(tbody, table);
		
		var ret = new Object();
		ret.obj = table;
		ret.appendTo = tbody;
		ret.currentRow = null;
		
		return ret;
	}
	//-----------------------------------------
	
	
	//-----------------------------------------
	this.addRow = function(tblObj, params) {
		if( typeof tblObj != 'object' ) { return false; }
		tblObj.currentRow = null;
		var tr = this.createElement('tr');
	
		for(var p in params) {
			if( p != 'klass' ) {
				this.setAttribute(tr, p, params[p]);
			}
			else {
				this.addClass(tr, params[p]);
			}
		}
		
		this.appendObject(tr, tblObj.appendTo);
		tblObj.currentRow = tr;
	}
	//-----------------------------------------
	
	
	//-----------------------------------------
	this.addCell = function(tblObj, data, params) {
		if( typeof tblObj != 'object' ) { return false; }
		if( tblObj.currentRow == null ) { return false; }
		
		var td = this.createElement('td');
	
		for(var p in params) {
			if( p != 'klass' ) {
				this.setAttribute(td, p, params[p]);
			}
			else {
				this.addClass(td, params[p]);
			}
		}
		
		this.addInnerText(td, data);
		this.appendObject(td, tblObj.currentRow);
	}
	//-----------------------------------------
	
	
	//-----------------------------------------
	this.getTable = function(tblObj) {
		if( typeof tblObj != 'object' ) { return false; }
		return tblObj.obj;
	}
	//-----------------------------------------


	//-----------------------------------------
	this.getEvent = function(e) { return e || window.event; }
	//-----------------------------------------


	//-----------------------------------------
	this.getEventTarget = function(e) { 
		var ev = e || window.event;

		var target = ev.target || ev.srcElement;
		if (  target.nodeType == 3 ) { target = target.parentNode; }
		
		return target;
	}
	//-----------------------------------------


	//-----------------------------------------
	this.clone = function() { return this; }
	//-----------------------------------------
}

