/** 
 ---------------------------------------------------------------------------------------
 * DOM.js
 * CVS versie 1.8 / 27 januari 2008
 * Lichtgewicht DOMscripting interface	
 * Deze versie: Doorn WebBouw 2008
 * http://www.doornwebbouw.nl | info@doornwebbouw.nl
 ----------------------------------------------------------------------------------------
 */	

(function()
	{
	/** 
	 ---------------------------------------------------------------------------------------
	 *functie:	_get(id1 [, id2, id3 ...])
	 *scope:	private
	 *In:		willekeurig aantal node-id's (string) of node-objecten (object)
	 *Uit:		Object handle
	 *beschrijving:	Constructor, plaatst node-objecten met id1..idn in object.array <elements>
	 *Opmerkingen:	
	 ------------------------------------------------------------------------------------------
	 */
	var _get = function()
		{
		this.elements = [];
		
		// we kunen 1 of 2 argumenten ontvangen; 1 => node, 2 => node + contextnode

		for(var t = 0; t < arguments[0].length; t++)
			{
			var el = arguments[0][t];
			if(typeof(el) == "string")
				{
				el = document.getElementById(el);
				};
			// controle op aanwezigheid van element; negeren indien niet
			
			this.elements.push(el);
			};
		this._init();
		return this;
		};




		
	/** 
	 ---------------------------------------------------------------------------------------
	 *functie:	_class(class1 [, class2, class3 ...])
	 *scope:	private
	 *In:		willekeurig aantal node-classnames of node-objecten
	 *Uit:		Object handle
	 *beschrijving:	Constructor, plaatst node-objecten met class1..classn in array <elements>
	 *Opmerkingen:	
	 ------------------------------------------------------------------------------------------
	 */		
	var _class = function()
		{
		this.elements = [];
		for(var t = 0; t < arguments[0].length; t++)
			{
			var r = document.getElementsByTagName("*");
			for(var tt = 0; tt < r.length; tt++)
				{
				if(r[tt].className.indexOf(arguments[0][t]) > -1)
					{
					this.elements.push(r[tt]);
					};
				};
			};
		this._init();			
		return this;
		};
		


	/** 
	 ---------------------------------------------------------------------------------------
	 *functie:	_get(id1 [, id2, id3 ...])
	 *scope:	private
	 *In:		willekeurig aantal node-id's (string) of node-objecten (object)
	 *Uit:		Object handle
	 *beschrijving:	Constructor, plaatst node-objecten met id1..idn in object.array <elements>
	 *Opmerkingen:	
	 ------------------------------------------------------------------------------------------
	 */
	var _tag = function()
		{
		this.elements = [];

		for(var t = 0; t < arguments[0].length; t++)
			{
			var el = arguments[0][t];
			if(typeof(el) == "string")
				{
				el = document.getElementsByTagName(el);
				};
			// controle op aanwezigheid van element; negeren indien niet
			
			for(var u = 0; u < el.length; u++)
				{
				this.elements.push(el[u]);
				}
			};
		this._init();			
		return this;
		};



	

	// _get methoden
	_get.prototype = {
	

		/** 
		 ---------------------------------------------------------------------------------------
		 *functie:	_init()
		 *scope:	private
		 *In:		-
		 *Uit:		-
		 *beschrijving:	set object variabelen
		 *Opmerkingen:	
		 ------------------------------------------------------------------------------------------
		 */	
		_init : function(func)
			{
			
			
			// Backward compatibility: 
			this.first = (typeof(this.elements[0]) != 'undefined') ? this.elements[0]: {};
			
			this.count = this.elements.length;
			for(var t = 0; t < this.count; t++)
				{
				this[t] = (typeof(this.elements[t]) != 'undefined') ? this.elements[t]: {};
				}
			},
			
			
		/** 
		 ---------------------------------------------------------------------------------------
		 *functie:	each(func)
		 *scope:	public
		 *In:		function: func
		 *Uit:		_get object instantie
		 *beschrijving:	Voert <func> uit voor elke entry van <elements> van _get instantie
		 *Opmerkingen:	
		 ------------------------------------------------------------------------------------------
		 */	
		each : function(func)
			{
			for(var t = 0; t < this.elements.length; t++)
				{			
				func.call(this, this.elements[t]);
				};
			return this;
			},
			
			

		/** 
		 ---------------------------------------------------------------------------------------
		 *functie:	css(object: o)
		 *scope:	public
		 *In:		object: stijl-object(?) in de vorm: {color: 'blue', width: '10px'}
		 *Uit:		_get object instantie
		 *beschrijving:	past de stijl(en) zoals opggegeven in <object> toe op de gegeven DOM nodes
		 *Opmerkingen:	
		 ------------------------------------------------------------------------------------------
		 */	
		css : function(o)
			{
			var that = this;
			this.each(function(el)
				{
				for(var prop in o)
					{
					el.style[prop] = o[prop];
					};
				});
			return this;
			},
			
			

		/** 
		 ---------------------------------------------------------------------------------------
		 *functie:	on(string: eventtype, function: fn)
		 *scope:	public
		 *In:		
		 *Uit:		
		 *beschrijving:	
		 *Opmerkingen:	
		 ------------------------------------------------------------------------------------------
		 */
		on: function(type, fn) 
			{
			var listen = function(el) 
				{
				if (window.addEventListener) 
					{
					el.addEventListener(type, fn, false);
					}
				else if (window.attachEvent) 
					{
					el.attachEvent('on'+type, function() 
						{
						fn.call(el, window.event);
						});
					};
				};
			this.each(function(el) 
				{
				listen(el);
				});
			return this;
			},



		/** 
		 ---------------------------------------------------------------------------------------
		 *functie:	
		 *scope:	
		 *In:		
		 *Uit:		
		 *beschrijving:	
		 *Opmerkingen:	
		 ------------------------------------------------------------------------------------------
		 */
		addClass : function(clss)
			{
			this.each(function(el)
				{
				el.className += (' ' + clss); 
				});
			return this;
			},
			
			
			
		/** 
		 ---------------------------------------------------------------------------------------
		 *functie:	
		 *scope:	
		 *In:		
		 *Uit:		
		 *beschrijving:	
		 *Opmerkingen:	
		 ------------------------------------------------------------------------------------------
		 */
		removeClass : function(clss)
			{
			this.each(function(el)
				{
				el.className = el.className.replace(new RegExp(clss, 'g'), '');
				});
			return this;
			},
			
			
			
		/** 
		 ---------------------------------------------------------------------------------------
		 *functie:	
		 *scope:	
		 *In:		
		 *Uit:		
		 *beschrijving:	
		 *Opmerkingen:	
		 ------------------------------------------------------------------------------------------
		 */
		add : function(tag_name)
			{
			if(typeof(arguments[1]) == 'object')
				{
				opties = arguments[1];
				}
				
			this.each(function(el)
				{
				var x = document.createElement(tag_name);
				el.appendChild(x);
				
				if(opties)
					{
					for(var prop in opties)
						{
						switch(prop)
							{
							case 'callBack':
							opties['callBack'].call(x);
							break;
							
							default:
							
							switch(typeof(opties[prop]))
								{
								case 'string':
								x[prop] = opties[prop];
								break;
								
								case 'object':
								for(var prop2 in opties[prop])
									{
									x[prop][prop2] = opties[prop][prop2];
									};
								break;
								};							
							break;
							};
						};
					};
				
				});
				
			return this;
			},
			
			
			
		/** 
		 ---------------------------------------------------------------------------------------
		 *functie:	
		 *scope:	
		 *In:		
		 *Uit:		
		 *beschrijving:	
		 *Opmerkingen:	
		 ------------------------------------------------------------------------------------------
		 */
		remove : function()
			{
			this.each(function(el)
				{
				el.parentNode.removeChild(el);
				});
			return this;
			},
			
			
			
		/** 
		 ---------------------------------------------------------------------------------------
		 *functie:	
		 *scope:	
		 *In:		
		 *Uit:		
		 *beschrijving:	
		 *Opmerkingen:	
		 ------------------------------------------------------------------------------------------
		 */
		swapStyle : function(o)
			{
			this.each(function(el)
				{
				for(var prop in o)
					{
					el.style[prop] = (el.style[prop] == o[prop][0]) ? o[prop][1] : o[prop][0];
					};
				});
			return this;
			},			
			
		/** 
		 ---------------------------------------------------------------------------------------
		 *functie:	
		 *scope:	
		 *In:		
		 *Uit:		
		 *beschrijving:	
		 *Opmerkingen:	
		 ------------------------------------------------------------------------------------------
		 */
		moveUp : function()
			{
			this.each(function(el)
				{
				for(var prop in o)
					{
					el.style[prop] = (el.style[prop] == o[prop][0]) ? o[prop][1] : o[prop][0];
					};
				});
			return this;
			}			
			
		
			
	// Einde _get methoden		
	};
	
	
	function _createXMLHttpRequest() 
		{    
		var ua;    
		if(window.XMLHttpRequest) 
			{    
			try {ua = new XMLHttpRequest();} 
			catch(e) 
				{     
				ua = false;    
				};  
			} 
		else if(window.ActiveXObject) 
			{     
			try {ua = new ActiveXObject('Microsoft.XMLHTTP');} 
			catch(e) 
				{       
				ua = false;     
				};  
			};   
		retObj = {AJAX : ua};
		return retObj;
		};     	

	
	// _class methoden = _get methoden
	
	// css krijgt een alias:
	_get.prototype.setStyle = _get.prototype.css;
	
	_class.prototype = _get.prototype;
	_tag.prototype = _get.prototype;
	
	


	// $el en $class zijn publieke interfaces voor _get en _class
	
	window.$el = function() // backward comp
	  {
	  return new _get(arguments);
	  };

	window.$id = function()
	  {
	  return new _get(arguments);
	  };

	window.$ = function()
	  {
	  return new _get(arguments);
	  };

	window.$class = function()
	  {
	  return new _class(arguments);
	  };

	window.$tag = function()
	  {
	  return new _tag(arguments);
	  };
	  
	  
	  
	/** 
	 ---------------------------------------------------------------------------------------
	 *functie:	sendAsync()
	 *scope:	public
	 *In:		string type, string url, string param, object callBack
	 *Uit:		object XMLHttpRequest
	 *beschrijving:	Voorlopig niets
	 *Opmerkingen:	callBack: succes, failure, [startRequest, elke gewenste eigenschap]
	 ------------------------------------------------------------------------------------------
	 */
	sendAsync = function(typ, url, param, callBack)
		{
		// callBack verwacht 4 objecten: success(vereist), failure(vereist), start
		var req = new _createXMLHttpRequest();
		if(!req.AJAX)
			{
			return false;
			}
		else
			{
			//req.attachedNode = callBack['attachedNode'];
			for(var prop in callBack)
				{
				req[prop] = callBack[prop];
				};
				
			req.abortRequest = function()
				{
				req.isBusy = false;
				if(req.timeoutFunction)
					{
					req.timeoutFunction.call(req);
					};
				req.AJAX.abort();
				req = null;
				};
				
			// cachen GET url voorkomen:
			var x = Math.floor(Math.random(856898)*1000000);
			
			// url maken
			url = (typ=='GET') ? url + "?nocache=" + x + ((param) ? ("&" + param) : "") : url;
			
			req.isBusy = true;
			req.url = url;
			req.type = typ;
			req.param = param;
			req['timeout'] = (typeof(callBack['timeout']) != 'undefined') ? callBack['timeout'] : 10;
			
			// timeout verzorgen
			req.timeoutTimer = setTimeout(function()
				{
				// req.abortRequest.call(req);
				}, req.timeout * 1000);
					
			if(typeof(callBack['startRequest']) != 'undefined')
				{
				callBack['startRequest'].call(req);
				};

			req.AJAX.onreadystatechange=function(e)
				{
				switch(req.AJAX.readyState)
					{
					case(1):
					break;						
					
					case(4):
					// timeoutTimer 
					if(req.isBusy)
						{
						
						clearTimeout(req.timeoutTimer);

						if(req.AJAX.status == 200)
							{
							callBack['success'].call(req);
							break;
							}
						else
							{
							// Geen 200 teruggekregen: fout
							callBack['failure'].call(req);
							};
						}
					break;
						
					default:
					// rS < 4
					break;
					};
				};
				
			req.AJAX.open(typ, url, true);
			if(typ!="GET"){req.AJAX.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");}
			req.AJAX.send((typ=='GET') ? null : param);
			};		
		};
	})();
