var Lib = {};



/** LIB.VALIDATE **/



Lib.Validate = {};

Lib.Validate.isEmail = function(string) {
	if (!Object.isString(string)) { return false; }

	return /^([0-9,a-z,A-Z,_]+)([.,-]([0-9,a-z,A-Z,_]+))*[@]([0-9,a-z,A-Z]+)([.,_,-]([0-9,a-z,A-Z]+))*[.]([0-9,a-z,A-Z]+){2}([0-9,a-z,A-Z])?$/.test(string);
}



/** LIB.IMPORTANT **/



Lib.Important = Class.create({
	initialize: function(text) {
		Class.methodize(this); // bind the methods
		
		// init the object
		text = Object.isUndefined(text) ? '' : text;
		elm = $(text);

		if (Object.isElement(elm)) {
			this.elm = elm;
			this.text = Lib.Important.parse(elm);
		} else {
			this.elm = new Element('div', {'class': 'important'});
			this.text = new Array();

			if (Object.isArray(text)) {
				this.text.concat(text);
			} else {
				this.text.push(text);				
			}
		}
		
		if (this.hasMessage()) {
			this.elm.hide();
		}
	},
	
	/* PRIVATE methods */
	
	_render: function() {
		if (this.timeout) {
			clearTimeout(this.timeout);
			this.timeout = false;
		}
		
		this.timeout = this.render.delay(0.5);
	},
	
	/* PUBLIC methods */

	toElement: function() {
		return this.elm;
	},
	toArray: function() {
		return $A(this.text);
	},
	hasMessage: function() {
		return this.text.size() ? true : false;
	},
	clear: function() {
		this.text = new Array();
		this._render();
	},
	add: function(text) {
		if (Object.isArray(text)) {
			this.text = this.text.concat(text);
		} else {
			this.text.push(text);				
		}

		this.elm.update('<div class="message">' + this.text.join('</div><div class="message">') + '</div>');
		this._render();
	},
	replace: function(text) {
		if (Object.isUndefined(text)) {
			this.clear();
		} else {
			this.text = new Array();
			this.add(text);
		}
	},
	render: function() {
		if (this.elm.visible() && !this.hasMessage()) {
			this.elm.hide();
		}
		
		if (!this.elm.visible() && this.hasMessage()) {
			new Effect.Appear(this.elm, {'duration': 0.5});
		}
		
		if (this.elm.visible() && this.hasMessage()) {
			new Effect.Highlight(this.elm, {'duration': 3});
		}
	}
});

Lib.Important.parse = function(div) {
	div = $(div);
	
	if (!Object.isElement(div)) {
		return new Array();
	}

	return $A($A(div.select('div.message')).pluck('innerHTML')).compact();
}



/** LIB.ERROR **/



Lib.Error = Class.create({
	initialize: function(text) {
		Class.methodize(this); // bind the methods
		
		// init the object
		text = Object.isUndefined(text) ? '' : text;
		elm = $(text);
		
		if (Object.isElement(elm)) {
			this.elm = elm;
			this.text = Lib.Error.parse(elm);
		} else {
			this.elm = new Element('div', {'class': 'error'});
			this.text = new Array();

			if (Object.isArray(text)) {
				this.text.concat(text);
			} else {
				this.text.push(text);				
			}
		}
		
		if (this.hasError()) {
			this.elm.hide();
		}
	},
	
	/* PRIVATE methods */
	
	_render: function() {
		if (this.timeout) {
			clearTimeout(this.timeout);
			this.timeout = false;
		}
		
		this.timeout = this.render.delay(0.5);
	},
	
	/* PUBLIC methods */

	toElement: function() {
		return this.elm;
	},
	toArray: function() {
		return $A(this.text);
	},
	hasError: function() {
		return this.text.size() ? true : false;
	},
	clear: function() {
		this.text = new Array();
		this._render();
	},
	add: function(text) {
		if (Object.isArray(text)) {
			this.text = this.text.concat(text);
		} else {
			this.text.push(text);				
		}

		this.elm.update('<h2>Er zijn één of meerdere fouten opgetreden.</h2><ul><li>' + this.text.join('</li><li>') + '</li></ul>');
		this._render();
	},
	replace: function(text) {
		if (Object.isUndefined(text)) {
			this.clear();
		} else {
			this.text = new Array();
			this.add(text);
		}
	},
	render: function() {
		if (this.elm.visible() && !this.hasError()) {
			this.elm.hide();
		}
		
		if (!this.elm.visible() && this.hasError()) {
			new Effect.Appear(this.elm, {'duration': 0.5});
		}
		
		if (this.elm.visible() && this.hasError()) {
			new Effect.Highlight(this.elm, {'duration': 3});
		}
	}
});

Lib.Error.parse = function(div) {
	div = $(div);
	
	if (!Object.isElement(div)) {
		return new Array();
	}

	return $A($A(div.select('ul li')).pluck('innerHTML')).compact();
}


/** LIB.ERROR.POPUP **/


Lib.Error.Popup = Class.create({
	overlay: null,
	container: null,
	content: null,
	text: null,

	initialize: function(){
		Class.methodize(this); // bind the methods
		
		this.text = new Array();
		
		//overlay
		var height = Math.max($$('html').first().getHeight(), document.viewport.getHeight(), document.body.offsetHeight) + 'px';
		this.overlay = new Element('div', {'class': 'overlay', style: 'height:' + height +'; width:100%; top:0px; position:absolute'});
		
		// Popup
		this.container = new Element('div', {style: 'top:' + (document.viewport.getScrollOffsets().top + 175) + 'px; position:absolute; width:100%;'});
		this.popup = new Element('div', {'class': 'popup error'});
		this.button = new Element('input', {'class': 'button close', type: 'button'});
		this.button.value = 'Sluiten';
		this.content = new Element('div');
		
		this.popup.insert(this.content);
		this.popup.insert(this.button);
		
		this.container.update(this.popup);
		
		// event listners
		this.overlay.observe('click', this.clear );
		this.button.observe('click', this.clear );
		
		Element.observe(window, 'resize', this.event._onResize );
		
		this.overlay.hide();
		this.container.hide();
		
		// add to the body
		$(document.body).insert(this.overlay, 'bottom');
		$(document.body).insert(this.container, 'bottom');
	},
	
	/* EVENT methods */
	
	event: {
		_onResize: function(event) {
			// redo the overlay height
			var height = Math.max($$('html').first().getHeight(), document.viewport.getHeight(), document.body.offsetHeight, (this.container.offsetTop + this.container.getHeight() + 100)) + 'px';
			this.overlay.setStyle({'height': height});	
		}
	},
	
	/* PUBLIC methods */
	
	hasError: function() {
		return this.text.size() ? true : false;
	},
	clear: function() {
		this.text = new Array();

		this.overlay.hide();
		this.container.hide();
	},
	add: function(text) {
		if (Object.isArray(text)) {
			this.text = this.text.concat(text);
		} else {
			this.text.push(text);				
		}

		this.content.update('<h2>Er zijn één of meerdere fouten opgetreden.</h2><ul><li>' + this.text.join('</li><li>') + '</li></ul>');
		
		this.overlay.show();
		this.container.show();
	},
	replace: function(text) {
		if (Object.isUndefined(text)) {
			this.clear();
		} else {
			this.text = new Array();
			this.add(text);
		}
	}
});


Lib.Error.Popup.instance = null
Lib.Error.Popup.getInstance = function() {
	if (!Lib.Error.Popup.instance) {
		Lib.Error.Popup.instance = new Lib.Error.Popup();
	}
	
	return Lib.Error.Popup.instance;
}

/** LIB.ERROR.INLINE **/



Lib.Error.Inline = Class.create({
	initialize: function(text) {
		// bind the methods
		this.toElement = this.toElement.bind(this);
		this.remove = this.remove.bind(this);
		
		this._mousemove = this._mousemove.bind(this);
		this._mouseout = this._mouseout.bind(this);
		this._register = this._register.bind(this);
		this._destroy = this._destroy.bind(this);
		
		// creat the error div
		this.elm = new Element('div', {'class':'error inline', 'title':text.stripTags()});
		this.elm.update(text);
		this.elm.hide();
		
		// automotic hide or not
		this.autohide = parseFloat(arguments[1]) || false;
		this.timer = false;
	},

	/* PRIVATE methods */

	_mousemove: function() {
		if (this.timer) {
			clearInterval(this.timer);
			this.timer = false;
		}
	},
	_mouseout: function() {
		if (this.autohide && !this.timer) {
			this.timer = this.remove.delay(this.autohide);
		}
	},
	_register: function() {
		if (this.autohide) {
			this.timer = this.remove.delay(this.autohide);

			this.elm.observe('mousemove', this._mousemove);
			this.elm.observe('mouseout', this._mouseout);
		}
	},
	_destroy: function() {
		this.elm.stopObserving('mousemove', this._mousemove);
		this.elm.stopObserving('mouseout', this._mouseout);

		this.elm.remove();
		this.elm = null;

		if (this.timer) {
			clearInterval(this.timer);
			this.timer = false;
		}
	},

	/* PUBLIC methods */

	toElement: function() {
		Effect.Appear.curry(this.elm, {'duration':0.5, 'afterFinish':this._register}).defer();
		
		return this.elm;
	},
	remove: function() {
		Effect.Fade(this.elm, {'duration':0.5, 'afterFinish':this._destroy});
	}
});


/** CLASS **/


Class.methodize = function(obj) {
	if (obj.event && typeof obj.event == "object") {
		obj.event = Object.clone(obj.event);
		
		for (var func in obj.event) {
			if (Object.isFunction(obj.event[func])) {
				obj.event[func] = obj.event[func].bindAsEventListener(obj);
			}
		}
	}

	for (var func in obj) {
		if (Object.isFunction(obj[func])) {
			obj[func] = obj[func].bind(obj);
		}
	}
}


/** DOCUMENT.COOKIE **/


document.setCookie = function(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}	
document.getCookie = function(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}	
document.removeCookie = function(name) {
	document.setCookie(name,"",-1);
}