var Selene = (function() {
	var self = this;
	var xhr = null;
	
	var Config = {
		version : '0.1',
		author : 'unKnown'
	};
	
	/*	@see		onDomReady(fn) function*/
	/*	to be used like this: window.onDomReady(custom_fn);*/
	window.onDomReady = onDomReady;
	
	function isArray(object) {
		var is_array = false;
		
		if(object.constructor == Array) {
			is_array = true;
		}
		
		return is_array;
	}
	
	function detectUserAgent() {
		var user_agent = navigator.userAgent;
		
		if(user_agent.indexOf('Opera') > -1) {
			user_engine = 'Opera';
		} else if(user_agent.indexOf('AppleWebKit') > -1) {
			user_engine = 'Webkit';
		} else if(user_agent.indexOf('MSIE 6.0') > -1) {
			user_engine = 'IE6';
		} else if(user_agent.indexOf('MSIE') > -1) {
			user_engine = 'IE';
		} else if(user_agent.indexOf('Mozilla') > -1) {
			user_engine = 'Mozilla';
		} else {
			user_engine = 'Unknown';
		}
		
		return user_engine;
	}
	
	function timeout(fn, timeout) {
		return window.setTimeout(fn, timeout);
	}
	
	function $(id) {
		return document.getElementById(id);
	}
	
	function $$(tag_name, class_name) {
		var elem_array = document.getElementsByTagName(tag_name);
		var matched_elem_array = [];
		var elem_has_class_attr = null;
		var elem_class_attr = null;	
		
		for(var i = 0; i < elem_array.length; i++) {
			//Does not work for IE (no support for hasAttribute())
			//@see http://reference.sitepoint.com/javascript/Element/hasAttribute#compatibilitysection
			//elem_has_class_attr = elem_array[i].hasAttribute('class');
			
			//if(elem_has_class_attr = true) {
				elem_class_attr = elem_array[i].getAttribute('class');
			
				if(elem_class_attr == class_name) {
					matched_elem_array.push(elem_array[i]);
				}
			//}
		}
		
		return matched_elem_array;
	}
	
	function getClass(elem) {
		if(elem.className == '') {
			return false;
		} else {
			return elem.className;
		}
	}
	
	function setClass(elem, class_name) {
		if(elem.className == '') {
			elem.className = class_name;
		} else {
			if(elem.className.indexOf(class_name) >= 0) {
				return false;
			} else {
				elem.className += ' ' + class_name;
			}
		}
	}
	
	function removeClass(elem, class_name) {
		if(elem.className == '') {
			return false;
		} else {
			if(elem.className.indexOf(class_name) >= 0) {
				//FIXME! regex
				var pattern = new RegExp("(^| )" + class_name + "( |$)");
				elem.className = elem.className.replace(pattern, '');
			} else {
				return false;
			}
		}
	}
	
	/**
	*
	*	@see		http://robertnyman.com/2006/04/24/get-the-rendered-style-of-an-element/
	*	@see		http://www.quirksmode.org/dom/getstyles.html
	*/
	function getStyle(elem, style_rule) {
		if(window.getComputedStyle) {
			return document.defaultView.getComputedStyle(elem, null).getPropertyValue();
		} else if(elem.currentStyle) {
			return elem.currentStyle[style_rule];
		}
	}
	
	function setValue(elem, value) {
		if(elem.constructor == String) {
			elem = document.getElementById(elem);
		}
	
		if(value === undefined) {
			elem.value = '';
		} else {
			elem.value = value;
		}
	}
	
	function switchAttribute(elem, attrib) {
		if(attrib == 'readonly' || attrib == 'checked' || attrib == 'disabled' || attrib == 'selected') {
			if(elem.attrib === true) {
				elem.removeAttribute(attrib);
			} else {
				elem.setAttribute(attrib, 'true');
			}
		}
	}
	
	/*	@see		http://phpperformance.de/javascript-event-onload-und-die-bessere-alternative/ */
	function onDomReady(fn) {
		if(document.addEventListener) {
			document.addEventListener('DOMContentLoaded', fn, false);
		} else {
			//FIXME! Throws IE Exception
			document.onreadystatechange = function(){self.readyStateCheck(fn)};
		}
	}
	
	function readyStateCheck(fn) {
		if(document.readyState == 'complete') {
			fn();
		}
	}
	
	function addEvent(elem, event_type, event_listener, capture) {
		if(capture === undefined || capture == '' ) {
			capture = false;
		}
		
		if(elem.constructor === String) {
			var elem = document.getElementById(elem);
		}
		
		//FIXME! this.bla should be self.bla
		if(this.isArray(elem)) {
			if(elem[0].addEventListener) {
				if(this.isArray(event_type)) {
					for(var i = 0; i < elem.length; i++) {
						for(var j = 0; j < event_type.length; j++) {
							elem[i].addEventListener(event_type[j], event_listener, capture);
						}
					}
				} else {
					for(var i = 0; i < elem.length; i++) {
						elem[i].addEventListener(event_type, event_listener, capture);
					}
				}
			} else {
				if(this.isArray(event_listener)) {
					for(var i = 0; i < elem.length; i++) {
						for(var j = 0; j < event_type.length; j++) {
							elem[i].attachEvent(event_type[j], event_listener);
						}
					}
				} else {
					for(var i = 0; i < elem.length; i++) {
						elem[i].attachEvent(event_type, event_listener);
					}
				}
			}
		} else {
			if(elem.addEventListener) {
				if(this.isArray(event_type)) {
					for(var i = 0; i < event_type.length; i++) {
						elem.addEventListener(event_type[i], event_listener, capture);
					}
				} else {
					elem.addEventListener(event_type, function() {
						eval(event_listener);
					}, capture);
				}
			} else {
				if(this.isArray(event_type)) {
					for(var i = 0; i < event_type.length; i++) {
						elem.attachEvent(event_type[i], event_listener);
					}
				} else {
					elem.attachEvent(event_type, event_listener);
				}
			}
		}
	}
	
	function removeEvent(elem, event_type, event_listener, capture) {
		if(capture === undefined || capture == '') {
			capture = false;
		}
		
		if(self.isArray(elem)) {
			for(var i = 0; i < elem.length; i++) {
				elem[i].removeEventListener(event_type, event_listener, capture);
			}
		} else {
			elem.removeEventListener(event_type, event_listener, capture);
		}
	}

	function preventDefault(ev) {
		if(ev.preventDefault() && ev.canceable) {
			ev.preventDefault();
		} else {
			ev.returnValue = false;
		}
	}
	
	function stopPropagation(ev) {
		if(ev.stopPropagation()) {
			ev.stopPropagation();
		} else {
			ev.cancelBubble = true;
		}
	}
	
	function openPop(file, pop_name, position, post_func) {
		window.open(file, pop_name, position);
		window.focus();
		post_func();
	}
	
	function openLayer(file, layer_name, position) {
		
	}
	
	function xhrLoader(type, file, param) {
		if(param === undefined || param == '') {
			param = null;
		}
		
		if(window.XMLHttpRequest) {
			xhr = new XMLHttpRequest();
		} else if (window.ActiveXObject){
			xhr = new ActiveXObject("Microsoft.XMLHTTP");
		} else {
			xhr = null;
		}
		
		xhr.onreadystatechange = function() {
			if(xhr.readyState == 4 && xhr.status == 200) {
				if(type == 'xml') {
					return xhr.responeXML;
				} else {
					return xhr.responseText;
				}
			} else {
				return false; 
			}
		};
		
		//Needed in order to use POST as transfer method
		xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		xhr.open('GET', file, true);
		xhr.send(param);
	}
	
	return {
		$:$,
		$$:$$,
		getClass:getClass,
		setClass:setClass,
		removeClass:removeClass,
		preventDefault:preventDefault,
		isArray:isArray,
		setValue:setValue,
		switchAttribute:switchAttribute,
		detectUserAgent:detectUserAgent,
		timeout:timeout,
		onDomReady:onDomReady,
		addEvent:addEvent,
		removeEvent:removeEvent,
		openPop:openPop,
		openLayer:openLayer,
		xhrLoader:xhrLoader
	};
}());