phocus.DOM2=
{
	// DOM2 properties
	d:document,
	context:document,
	
	// methods
	// getNode - tests for a string and returns a node
	/* NOTES
		SHOULD REPLACE THE COLON SEPERATED SYNTAX
		WITH CSS SYNTAX INSTEAD..
		NODE
		NODE.CLASS
		NODE#ID
	*/
	getNode:function(node,c) // : Array
	{
		if(!c)
			var c=this.context;
		try
		{
			if(typeof node == 'string')
			{
				var n=node.split(':');
				if(n[0]=='tag')
					return c.getElementsByTagName(n[1]);
				else if(n[0]=='children')
					return c.childNodes();
				else if(n[0]=='class')
				{
					var rtn=[];
					var ch=c.getElementsByTagName('*');
					for(var i in ch)
						if(typeof ch[i].className != 'undefined' && ch[i].className.indexOf(n[1])!=-1)
							rtn.push(ch[i]);
					return rtn;
				}
				else
					return [c.getElementById(n[0])];
			}
			else if (node.length) // if this is an array
				return node;
			else if(typeof node == 'object')
				return [node];
			
			// error
			this.error='Wrong parameter passed as a node reference.';
			throw(this.error);
		} catch(err)
		{
			this.Catcher.log(err);
		}
	},
	// add node. Multi purpose node addition.
	// node:string/object, e:string[, m:string[, a:array[, t:text[, c:node[, n:number]]]]]
	// node - the node to operate on
	// e - the element to add
	// m - mode. This determines where the node[s] are attached. legal values: BEFORE, AFTER, REPLACE, REPLACECHILDREN, BEGINNING, END (default: END)
	// a - attributes : array of objects - [{p:property;v:variable},{p:property;v:variable}]
	// t - text
	// c - nodal context. will default to document if undefined. Allows you to add to, for example, all nodes under a specific node
	// n - number. Will add the node 'n' number of times
	addNode:function(node,e,m,a,t,c,n)
	{
		// verifying method properties
		if(!m || m==undefined)
			var m='END';
		if(!n || n==undefined)
			var n=1;
		if(!a || a==undefined)
			var a=[];
		if(!t || t==undefined)
			var t='';
		
		var ns=this.getNode(node,c); // array
			
		var rtn=[];
		for(var i in ns)
		{
			for(var j=0;j<n;j++)
			{
				if(typeof e == 'string')
					var _n=this.d.createElement(e);
				else
					var _n=e.cloneNode(true);
				
				switch(m)
				{
					case 'BEFORE':
						_n=ns[i].parentNode.insertBefore(_n,ns[i])
						break
					case 'AFTER':
						_n=ns[i].parentNode.insertBefore(_n,ns[i].nextSibling)
						break
					case 'REPLACE':
						ns[i].parentNode.replaceChild(_n,ns[i])
						break
					case 'BEGINNING':
						_n=ns[i].insertBefore(_n,ns[i].firstChild)
						break
					case 'REPLACECHILDREN':
						this.clear(ns[i])
					default:
						_n=ns[i].appendChild(_n)
				}
				for(var k in a)
					this.setAttribute(_n,a[k].p,a[k].v);
				if(t!='')
					_n.appendChild(this.d.createTextNode(t));
				rtn.push(_n);
			};
		}
		return rtn;
	},
	// add attribute
	// node:string/object, p:string, v:string[, c:node]
	// node - the node to operate on
	// p - the property to add
	// v - the property value
	// c - nodal context. will default to document if undefined. Allows you to add to, for example, all nodes under a specific node
	setAttribute:function(node,p,v,c)
	{
		var ns=this.getNode(node,c); // array
		for(var i in ns)
		{
			if(ns[i].attributes[p])
				this.removeAttribute(ns[i],p);
			ns[i].setAttribute(p,v);
		}
	},
	// add event
	// node:string/object, e:string, m:method[, cap:node=false[, c:node]]
	// node - the node to operate on
	// e    - the event to add
	// m    - The method to add
	// cap  - Whether the event is applied during capture or bubble
	// c    - nodal context. will default to document if undefined. Allows you to add to, for example, all nodes under a specific node
	setEvent:function(node,e,m,cap,c)
	{
		var ns=this.getNode(node,c); // array
		if(!cap)
			var cap=false;
		for(var i in ns)
		{
			ae='attachEvent'; // ie
			ael='addEventListener'; // everything else
			if(typeof ns[i][ael] != 'undefined')
				ns[i][ael](e,m,cap);
			else if(typeof ns[i][ae] != 'undefined')
				ns[i][ae]('on'+e,m);
			else
			{
				var et='on'+e; // event type
				var te=ns[i][et];// target event
				if(typeof te == 'function')
				{
					var ol=te; // old listener
					te=function()
					{
						ol();
						return m();
					}
				} else
				{
					te=m;
				}
			}
		}
	},
	unsetEvent:function(node,e,m,cap,c)
	{
		var ns=this.getNode(node,c); // array
		if(!cap)
			var cap=false;
		for(var i in ns)
		{
			de='detachEvent'; // ie
			rel='removeEventListener'; // everything else
			if(typeof ns[i][rel] != 'undefined')
				ns[i][rel](e,m,cap);
			else if(typeof ns[i][de] != 'undefined')
				ns[i][de]('on'+e,m);
			else
				ns[i]["on"+e]=null;
		}
	},
	getETarget:function(e)
	{
		var te=null; // target element
		if(typeof e.target != 'undefined')
			te=e.target;
		else
			te=e.srcElement;
		while(te.nodeType==3 && te.parentNode!= null)
			te=te.parentNode;
		return te;
	},
	getScroll:function()
	{
		var w=window;
		var d=document;
		var pos=[0,0];
		if(typeof w.pageYOffset != 'undefined')
			pos=[w.pageXOffset,w.pageYOffset];
		else if(typeof d.documentElement.scrollTop!='undefined' && d.documentElement.scrollTop>0)
			pos=[d.documentElement.scrollLeft,d.documentElement.scrollTop];
		else if(typeof d.body.scrollTop != 'undefined')
			pos=[d.body.scrollLeft,d.body.scrollTop];
		return pos;
	},
	stopEvent:function(e)
	{
		e.returnValue=false;
		if(typeof e.preventDefault != 'undefined')
			e.preventDefault();
	},
	getPosition:function(node,c)
	{
		var ns=this.getNode(node,c); // array
		var rtn=[];
		for(var i in ns)
		{
			var op=[0,0];
			while(node!=null)
			{
				op[0]+=node.offsetLeft;
				op[1]+=node.offsetTop;
				node=node.offsetParent;
			}
			rtn.push(op);
		}
		return rtn;
	},
	getDims:function(node,c)
	{
		var ns=this.getNode(node,c); // array
		var rtn=[];
		for(var i in ns)
		{
			var op=[0,0];
			op[0]=ns[i].offsetWidth;
			op[1]=ns[i].offsetHeight;
			rtn.push(op);
		}
		return rtn;
	},
	getWindowSize:function()
	{
		var s=[0,0];
		if(typeof window.innerWidth != 'undefined')
			s=[window.innerWidth,window.innerHeight];
		else if(typeof document.documentElement != 'undefined' && typeof document.documentElement.clientWidth != 'undefined' && document.documentElement.clientWidth != 0)
			s=[document.documentElement.clientWidth,document.documentElement.clientHeight];
		else
			s=[document.getElementsByTagName('body')[0].clientWidth,document.getElementsByTagName('body')[0].clientHeight];
		return s;
	},
	getmousepos:function(e,el)
	{
		var rtn=[];
		var screenx=e.clientX;
		var screeny=e.clientY;
		var offset=this.getScroll();
		rtn[0]=screenx+offset[0];
		rtn[1]=screeny+offset[1];
		if(typeof el != 'undefined')
		{
			var elpos=this.getPosition(el)[0];
			rtn[0]=rtn[0]-elpos[0];
			rtn[1]=rtn[1]-elpos[1];
		}
		return rtn;
	},
	// remove attribute
	// node:string/object, p:string[, c:node]
	// node - the node to operate on
	// p - the property to add
	// c - nodal context. will default to document if undefined. Allows you to add to, for example, all nodes under a specific node
	removeAttribute:function(node,p,c)
	{
		var ns=this.getNode(node,c); // array
		for(var i in ns)
			if(ns[i].attributes[p]!=undefined)
				ns[i].removeAttribute(p);
	},
	// clear
	// node:string/object[, c:node]
	// node - the node to operate on
	// c - nodal context. will default to document if undefined. Allows you to add to, for example, all nodes under a specific node
	clear:function(node,c)
	{
		var ns=this.getNode(node,c); // array
		for(var i in ns)
		{
			if(ns[i].hasChildNodes)
				for(var j in ns[i].childNodes)
					ns[i].removeChild(ns[i].childNodes[j]);
		}
	},
	// removeNode
	// node:string/object[, c:node]
	// node - the node to operate on
	// c - nodal context. will default to document if undefined. Allows you to add to, for example, all nodes under a specific node
	removeNode:function(node,c)
	{
		var ns=this.getNode(node,c); // array
		for(var i in ns)
			ns[i].parentNode.removeChild(ns[i]);
	},
	// swapNodes
	// node_a:string/object, node_b:string/object[, c:node]
	// node_a - the node to operate on
	// node_b - the node to operate on
	// c - nodal context. will default to document if undefined. Allows you to add to, for example, all nodes under a specific node
	swapNodes:function(node_a,node_b,c)
	{
		var nsa=this.getNode(node_a,c)[0]; // array
		var nsb=this.getNode(node_b,c)[0]; // array
		var a=this.addNode(nsb,nsa,'BEFORE');
		var b=this.addNode(nsa,nsb,'BEFORE');
		this.removeNode([nsa,nsb]);
		return [a[0],b[0]];
	},
	// cloneNode
	// node_a:string/object, node_b:string/object[, c:node]
	// node_a - the node to attach the clone to
	// node_b - the node to clone
	// m - mode. This determines where the node[s] are attached. legal values: BEFORE, AFTER, REPLACE, REPLACECHILDREN, BEGINNING, END (default: END)
	// c - nodal context. will default to document if undefined. Allows you to add to, for example, all nodes under a specific node
	// n - number. Will add the node 'n' number of times
	cloneNode:function(node_a,node_b,m,c,n)
	{
		var nsb=this.getNode(node_b,c)[0]; // node
		return this.addNode(node_a,nsb,m,null,null,c,n);
	},
	// passDocument
	passDocument:function(node,xml)
	{
		
	},
	// base alteration methods
	setContext:function(c)
	{
		this.context=c;
	},
	resetContext:function()
	{
		this.context=this.d;
	}
};
phocus.register(phocus.DOM2);