/**
 *  Part of the Blauwdruk website engine
 *  Copyright 2009-2010 by Paul Martens
 *  http://driehoogvoor.nl/blauwdruk/
 */

/**
 *  Wrapper object
 */

function Wrapper() {

	/* Add handler */
	//
	
	this.addHandler = function(event, handler) {
		for(var n in this.selection) {
			var oldHandler = this.selection[n][event];
			this.selection[n][event] = function(e) {
				oldHandler ? oldHandler.call(this, e) : null;
				handler.call(this, e);
			}
		}
	}
	
	/* Click */
	//
	
	this.click = function(handler) {
		this.addHandler('onclick', handler);
		return this;
	}
	
	/* Mouse over */
	//
	
	this.mouseOver = function(handler) {
		this.addHandler('onmouseover', handler);
		return this;
	}
	
	/* Mouse out */
	//
	
	this.mouseOut = function(handler) {
		this.addHandler('onmouseout', handler);
		return this;
	}
	
	/* Focus */
	//
	
	this.focus = function(handler) {
		this.addHandler('onfocus', handler);
		return this;
	}
	
	/* Blur */
	//
	
	this.blur = function(handler) {
		this.addHandler('onblur', handler);
		return this;
	}
	
	/* Load */
	//
	
	this.load = function(handler) {
		this.addHandler('onload', handler);
		return this;
	}
	
	/* Has class */
	//
	
	this.hasClass = function(className) {
		var regExp = new RegExp('\\b' + className + '\\b');
		
		for(var n in this.selection) {
			if(this.selection[n].className.match(regExp)) {
				return true;
			}
		}
		
		return false;
	}
	
	/* Add class */
	//
	
	this.addClass = function(className) {
		for(var n in this.selection) {
			if(!this.selection[n].className.match(new RegExp('\\b' + className + '\\b'))) {
				this.selection[n].className += (this.selection[n].className ? ' ' : '') + className;
			}
		}
		
		return this;
	}
	
	/* Remove class */
	//
	
	this.removeClass = function(className) {
		for(var n in this.selection) {
			this.selection[n].className = this.selection[n].className.replace(new RegExp('\\b' + className + '\\b'), '');
		}
		
		return this;
	}
	
	/* Add attribute */
	//
	
	this.addAttribute = function(attribute, value) {
		var attr = document.createAttribute(attribute);
		attr.value = value;
		
		for(var n in this.selection) {
			this.selection[0].setAttributeNode(attr);
		}
		
		return this;
	}
	
	/* Css */
	//
	
	this.css = function(attribute, value) {
		for(var n in this.selection) {
			this.selection[n].style[attribute] = value;
		}
	}
	
	/* Set text */
	//
	
	this.setText = function(text) {
		for(var n in this.selection) {
			this.selection[n].innerHTML = text;
		}
		
		return this;
	}
	
	/* Append */
	//
	
	this.append = function(element) {
		if(element.constructor == this.constructor) {
			for(var n in this.selection) {
				for(var m in element.selection) {
					this.selection[n].appendChild(element.selection[m]);
				}
			}
		}
	}
	
	/* Each */
	//
	
	this.each = function(func) {
		for(var n in this.selection) {
			func.call(this.selection[n]);
		}
	}
	
	/* Select */
	//
	
	this.select = function(selector, root) {
		if(selector == window) {
			this.selection = [window];
			return this;
		}
		
		if(selector.nodeType) {
			this.selection = [selector];
			return this;
		}
		
		var selectors = selector.split(/\s+/);
		var roots = root ? ((typeof root == Object && root.constructor == Array) ? root : [root]) : [document];
		
		for(var n = 0; n < selectors.length; n++) {
			var tagName = selectors[n].replace(/[\.:].*$/, '') || '*';
			var classNames = selectors[n].replace(/^[^\.]+|:.*$/g, '').substr(1);
			classNames = classNames ? classNames.split('.') : [];

			this.selection = [];
			
			for(var m = 0; m < roots.length; m++) {
				
				var elements = roots[m].getElementsByTagName(tagName);
				for(var l = 0; l < elements.length; l++) {
					var pass = false;
					
					if(classNames.length) {
						for(var k = 0; k < classNames.length; k++) {
							if(!elements[l].className.match(new RegExp('\\b' + classNames[k] + '\\b'))) {
								pass = true;
							}
						}
					}
					
					if(pass) continue;
					
					this.selection.push(elements[l]);
				}
			}
			
			roots = this.selection;
			
			//alert('selector: ' + selectors[n] + '\ntagName: ' + tagName + '\nclassNames: ' + classNames);
		}
		
		return this;
	}
	
	/* Create */
	//
	
	this.create = function(tagName) {
		this.selection = [document.createElement(tagName)];
		return this;
	}
}

/* Select */
//

function select(selector, root) {
	return new Wrapper().select(selector, root);
}

/* Create */
//

function create(tagName) {
	return new Wrapper().create(tagName);
}

