function cmxElement()
{
	//Private variables
	var _isInitialized = false;
	
	//Public properties
	this.backgroundColor = '';
	this.backgroundImage = '';
	this.bottom = '';
	this.clipBottom = '';
	this.clipHeight = '';
	this.clipLeft = '';
	this.clipRight = '';
	this.clipTop = '';
	this.clipValues = '';
	this.clipWidth = '';
	this.element = null;
	this.height = '';
	this.id = '';
	this.left = '';
	this.right = '';
	this.style = null;
	this.top = '';
	this.visibility = '';
	this.width = '';
	this.zIndex = '';

	//Private methods
	function _backgroundColor(el)
	{
		if (cmxbrowser.supportsLayers)
			return el.bgColor;
			
		if (cmxbrowser.ie || cmxbrowser.supportsDOM)
			return el.style.backgroundColor;
	}

	function _backgroundImage(el)
	{
		if (cmxbrowser.supportsLayers)
			return el.background.src;
			
		if (cmxbrowser.ie || cmxbrowser.supportsDOM)
			return el.style.backgroundImage;
	}

	function _bottom(el)
	{
		if (cmxbrowser.supportsLayers)
			return el.top + el.height;
		else if (cmxbrowser.ie || cmxbrowser.supportsDOM)
			return parseInt(el.style.top) + parseInt(el.height);
			
		return -1;
	}

	function _clipBottom(el)
	{
		if (cmxbrowser.supportsLayers)
			return !isNaN(el.clip.bottom) ? el.clip.bottom : "auto";
			
		if (cmxbrowser.ie || cmxbrowser.supportsDOM)
		{
			var str =  el.style.clip;

			if (!str)
				return !isNaN(el.style.height) ? el.style.height : "auto";
				
			var clip = _clipValues(el.style.clip);
			
			return !isNaN(clip[2]) ? clip[2] : "auto";
		}
		
		return -1;
	}

	function _clipHeight(el)
	{
		if (cmxbrowser.supportsLayers)
			return !isNaN(el.clip.height) ? el.clip.height : "auto";
			
		if (cmxbrowser.ie || cmxbrowser.supportsDOM)
		{
			var str =  el.style.clip;
			
			if (!str)
				return !isNaN(el.style.height) ? el.style.height : "auto";
				
			var clip = _clipValues(el.style.clip);
			
			return !isNaN(clip[2] - clip[0]) ? clip[2] - clip[0] : "auto";
		}
		
		return -1;
	}
	
	function _clipLeft(el)
	{
		if (cmxbrowser.supportsLayers)
			return !isNaN(el.clip.left) ? el.clip.left : "auto";
			
		if (cmxbrowser.ie || cmxbrowser.supportsDOM)
		{
			var str =  el.style.clip;
			
			if (!str)
				return 0;
				
			var clip = _clipValues(el.style.clip);
			
			return !isNaN(clip[3]) ? clip[3] : "auto";
		}
		
		return -1;
	}

	function _clipRight(el)
	{
		if (cmxbrowser.supportsLayers)
			return !isNaN(el.clip.right) ? el.clip.right : "auto";
			
		if (cmxbrowser.ie || cmxbrowser.supportsDOM)
		{
			var str =  el.style.clip;
			
			if (!str)
				return !isNaN(el.style.width) ? el.style.width : "auto";
				
			var clip = _clipValues(el.style.clip);
			
			return !isNaN(clip[1]) ? clip[1] : "auto";
		}
		
		return -1;
	}

	function _clipTop(el)
	{
		if (cmxbrowser.supportsLayers)
			return !isNaN(el.clip.top) ? el.clip.top : "auto";
			
		if (cmxbrowser.ie || cmxbrowser.supportsDOM)
		{
			var str = el.style.clip;
			
			if (!str)
				return 0;
				
			var clip = _clipValues(el.style.clip);
			
			return !isNaN(clip[0]) ? clip[0] : "auto";
		}
		
		return -1;
	}

	function _clipValues(el)
	{
		var clip = new Array();
		var str = el.style.clip;
		var i;

		i = str.indexOf("(");
		clip[0] = parseInt(str.substring(i + 1, str.length), 10);
		
		i = str.indexOf(" ", i + 1);
		clip[1] = parseInt(str.substring(i + 1, str.length), 10);
		
		i = str.indexOf(" ", i + 1);
		clip[2] = parseInt(str.substring(i + 1, str.length), 10);
		
		i = str.indexOf(" ", i + 1);
		clip[3] = parseInt(str.substring(i + 1, str.length), 10);

		return clip;
	}

	function _clipWidth(el)
	{
		if (cmxbrowser.supportsLayers)
			return !isNaN(el.clip.width) ? el.clip.width : "auto";
			
		if (cmxbrowser.ie || cmxbrowser.supportsDOM)
		{
			var str = el.style.clip;
			
			if (!str)
				return !isNaN(el.style.width) ? el.style.width : "auto";
				
			var clip = _clipValues(el.style.clip);
			
			return !isNaN(clip[1] - clip[3]) ? clip[1] - clip[3] : "auto";
		}
		
		return -1;
	}

	function _height(el)
	{
		if (cmxbrowser.supportsLayers)
		{
			if (this.element.document.height)
				return el.document.height;
			else
				return el.clip.bottom - el.clip.top;
		}
		
		if (cmxbrowser.ie || cmxbrowser.supportsDOM)
			return parseInt(el.offsetHeight);
		
		return -1;
	}

	function _left(el)
	{
		if (cmxbrowser.supportsLayers)
			return el.left;
			
		if (cmxbrowser.ie || cmxbrowser.supportsDOM)
			return parseInt(el.style.left);
			
		return -1;
	}

	function _right(el)
	{
		if (cmxbrowser.supportsLayers)
			return el.left + el.width;
			
		if (cmxbrowser.ie || cmxbrowser.supportsDOM)
			return parseInt(el.style.left) + parseInt(el.width);
			
		return -1;
	}

	function _top(el)
	{
		if (cmxbrowser.supportsLayers)
			return el.top;
			
		if (cmxbrowser.ie || cmxbrowser.supportsDOM)
			return parseInt(el.style.top);
			
		return -1;
	}

	function _visibility(el)
	{
		var returnValue = '';
		
		if (cmxbrowser.supportsLayers)
		{
			if (el.visibility == "show")
				returnValue = "visible";

			if (el.visibility == "hide")
				returnValue = "hidden";

			returnValue = el.visibility == '' ? "visible" : el.visibility
		}
		
		if (cmxbrowser.ie || cmxbrowser.supportsDOM)
			returnValue = el.style.visibility == '' ? "visible" : el.style.visibility;
			
		return returnValue;
	}

	function _width(el)
	{
		if (cmxbrowser.supportsLayers)
		{
			if (el.document.width)
				return el.document.width;
			else
				return el.clip.right - el.clip.left;
		}
		
		if (cmxbrowser.ie || cmxbrowser.supportsDOM)
			return parseInt(el.offsetWidth);
		
		return -1;
	}

	function _zIndex(el)
	{
		if (cmxbrowser.supportsLayers)
			return el.zIndex;
			
		if (cmxbrowser.ie || cmxbrowser.supportsDOM)
			return el.style.zIndex;

		return -1;
	}

	//Initialization
	this.initialize = function()
		{
			if (!_isInitialized)
			{
				if (this.element == null)
				{
					if (this.id != '')
					{
						if (cmxbrowser.supportsDOM)
							this.element = document.getElementById(this.id);
						else if (cmxbrowser.supportsLayers)
							this.element = this.findLayer(this.id, document);
						else if (cmxbrowser.ie)
							this.element = eval('document.all.' + this.id);
						
						_isInitialized = true;
					}
				}
				else
				{
					this.id = this.element.id != '' ? this.element.id : '';
					_isInitialized = true;
				}
			}
			
			if (this.element != null)
			{
				if (cmxbrowser.supportsDOM)
					this.style = this.element.style;
				else if (cmxbrowser.supportsLayers)
					this.style = this.element;
				else if (cmxbrowser.ie)
					this.style = this.element.style;

				if (this.height == '')
					this.height = _height(this.element);

				if (this.width == '')
					this.width = _width(this.element);
				
				if (this.visibility == '')
					this.visibility = _visibility(this.element);
					
				if (this.left == '')
					this.left = _left(this.element);
					
				if (this.top == '')
					this.top = _top(this.element);
					
				if (this.right == '')
					this.right = _right(this.element);
					
				if (this.bottom == '')
					this.bottom = _bottom(this.element);
				
				if (this.zIndex == '')
					this.zIndex = _zIndex(this.element);
					
				if (this.clipLeft == '')
					this.clipLeft = _clipLeft(this.element);
				
				if (this.clipTop == '')
					this.clipTop = _clipTop(this.element);
				
				if (this.clipRight == '')
					this.clipRight = _clipRight(this.element);
				
				if (this.clipBottom == '')
					this.clipBottom = _clipBottom(this.element);
				
				if (this.clipWidth == '')
					this.clipWidth = _clipWidth(this.element);
				
				if (this.clipHeight == '')
					this.clipHeight = _clipHeight(this.element);
				
				if (this.clipValues == '')
					this.clipValues = _clipValues(this.element);
				
				if (this.backgroundColor == '')
					this.backgroundColor = _backgroundColor(this.element);
				
				if (this.backgroundImage == '')
					this.backgroundImage = _backgroundImage(this.element);
			}
		};
	
	//Public methods
	this.absoluteLeft = function(el)
	{
		this.initialize();

		if (el.offsetParent == null) 
			return el.offsetLeft;
		else 
			return el.offsetLeft + this.absoluteLeft(el.offsetParent);
	};

	this.absoluteTop = function(el)
	{
		this.initialize();

		if (el.offsetParent == null)
			return el.offsetTop;
		else 
			return el.offsetTop + this.absoluteTop(el.offsetParent);
	};

	this.clip = function(top, right, bottom, left)
	{
		this.initialize();

		if (cmxbrowser.supportsLayers)
		{
			this.element.clip.top = top;
			this.element.clip.right = right;
			this.element.clip.bottom = bottom;
			this.element.clip.left = left;
		}
		
		if (cmxbrowser.ie || cmxbrowser.supportsDOM)
			this.style.clip = "rect(" + top + " " +  right + " " + bottom + " " + left +")";
	};

	this.findLayer = function(name, doc)
	{
		var layer;

		for (var i = 0; i < doc.layers.length; i++)
		{
			layer = doc.layers[i];
			
			if (layer.name == name)
				return layer;
				
			if (layer.document.layers.length > 0)
			{
				layer = this.findLayer(name, layer.document);

				if (layer != null)
					return layer;
			}
		}
		
		return null;
	};

	this.getElementById = function(id)
	{
		this.id = id;
		this.initialize();
		
		return this.element;
	};

	this.hide = function()
	{
		this.initialize();

		if (cmxbrowser.supportsLayers)
			this.element.visibility = "hide";
			
		if (cmxbrowser.ie || cmxbrowser.supportsDOM)
			this.style.visibility = "hidden";
	};

	this.inherit = function() 
	{
		this.initialize();

		if (cmxbrowser.supportsLayers)
			this.element.visibility = "inherit";
			
		if (cmxbrowser.ie || cmxbrowser.supportsDOM)
			this.style.visibility = "inherit";
	};

	this.isVisible = function()
	{
		this.initialize();

		if (cmxbrowser.supportsLayers && this.element.visibility == "show")
			return true;
		
		if (cmxbrowser.ie || cmxbrowser.supportsDOM && this.style.visibility == "visible")
			return true;

		return false;
	};

	this.moveBy = function(x, y)
	{
		this.initialize();

		if (cmxbrowser.supportsLayers)
			this.element.moveBy(x, y);
			
		if (cmxbrowser.ie || cmxbrowser.supportsDOM)
		{
			this.style.left = parseInt(this.style.left) + x;
			this.style.top = parseInt(this.style.top) + y;
		}
	};

	this.moveTo = function(x, y)
	{
		this.initialize();

		if (cmxbrowser.supportsLayers)
			this.element.moveTo(x, y);
			
		if (cmxbrowser.ie || cmxbrowser.supportsDOM)
		{
			this.style.left = x;
			this.style.top = y;
		}
	};

	this.pageLeft = function()
	{
		this.initialize();

		if (cmxbrowser.supportsLayers)
			return this.element.pageX;
			
		if (cmxbrowser.ie || cmxbrowser.supportsDOM)
			return this.element.offsetLeft;
			
		return -1;
	};

	this.pageTop = function()
	{
		this.initialize();

		if (cmxbrowser.supportsLayers)
			return this.element.pageY;
			
		if (cmxbrowser.ie || cmxbrowser.supportsDOM)
			return this.element.offsetTop;
			
		return -1;
	};

	this.setElement = function(el)
	{
		this.element = el;
		this.initialize();
	};

	this.setId = function(id)
	{
		this.id = id;
		this.initialize();
	};
	
	this.show = function()
	{
		this.initialize();

		if (cmxbrowser.supportsLayers)
			this.element.visibility = "show";
			
		if (cmxbrowser.ie || cmxbrowser.supportsDOM)
			this.style.visibility = "visible";
	};

	this.scrollTo = function(x, y, bound)
	{
		this.initialize();

		var dx = this.clipLeft() - x;
		var dy = this.clipTop() - y;

		this.scrollBy(-dx, -dy, bound);
	};

	this.scrollBy = function(x, y, bound)
	{
		this.initialize();

		var cl = this.clipLeft();
		var ct = this.clipTop();
		var cr = this.clipRight();
		var cb = this.clipBottom();

		if (bound)
		{
			if (cl + x < 0)
				x = -cl;
			else if (cr + x > this.width)
				x = this.width - cr;
				
			if (ct + y < 0)
				y = -ct;
			else if (cb + y > this.height)
				y = this.height - cb;
		}

		this.clip(cl + x, ct + y, cr + x, cb + y);
		this.moveBy(-x, -y);
	};

	this.swapStyle = function(className, useAlternateClassName)
	{
		this.initialize();

		if (useAlternateClassName)
		{
			this.element.setAttribute('temporaryClassName', this.element.className);
			this.element.className = className;
		}
		else
			this.element.className = this.element.getAttribute('temporaryClassName');
	};
}
