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);