phocus.DOM2=
{
	// DOM2 properties
	d:document,
	context:document,
	
	// methods
	// getNode - tests for a string and returns a node
	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
					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
	// 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':
						_n=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);
		}
	},
	// 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);