// +--------------------------------------------------------+
// | namespaces, to prevent potential JS conflicts			|
// +--------------------------------------------------------+
var neteffect = {};

// +--------------------------------------------------------+
// | Form Validator Class									|
// +--------------------------------------------------------+
neteffect.FormValidator = Class.create({
	initialize : function(formElement,params){
		var params = params || {};
		
		// Should the form submit if all fields are correct? // default = true;
		this.submitOnValid = (params.submitOnValid !== undefined) ? params.submitOnValid : true;
		
		// store reference to form element.
		this.formObj = $(formElement);
		
		// set FormValidator className prefix
		this.prefix = params.prefix || "js-validate";
		
		// set observer cache
		this.observers = {};
		
		// get the form fields.
		this.formFields = this.formObj.getElements().select(function(element){
			return element.className.include(this.prefix);
		}.bind(this));
		
		// intercept submit
		this.formObj.observe("submit",function(e){
			e.stop();
			this.validate();
			return false;
		}.bindAsEventListener(this));
		
		// set compare functions
		this.compare = {
			STRING : function(field){ return /\b\w+\b/i.test($F(field)); },
			NUMBER : function(field){ return /\b\d+\b/.test($F(field)); },
			EMAIL : function(field){ return /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b/i.test(field.value); },
			EMPTY : function(field){ return /\b\w+\b/i.test($F(field)); },
			SELECT : function(field) { return field.selectedIndex > 0 },
			RADIO : function(field){
				var n = field.getAttribute("name");
				var fields = this.formObj.getElementsBySelector("input[name="+n+"]");
				for(var i=0;i<fields.length;i++){
					if($F(fields[i])) {
						return true;
					};
				};
				return false;
			}.bind(this),
			CHECK : function(field) { return !!($F(field)); },
			PHONE : function(field){ return /\b\d{10}\b/.test($F(field)); },
			ZIP : function(field){ return /\b\d{4}\s?[a-zA-Z]{2}/.test($F(field)); },
			DATE : function(field){ return /\b\d{1,2}\/\d{1,2}\/\d{4}\b/.test($F(field)); }
		};
		
		if(params.compare){
			Object.extend(this.compare,params.compare);
		};
		
		if(params.onValidate) {
			this.observe("validate",params.onValidate);
		};
		
		if(params.onDone) {
			this.observe("done",params.onDone);
		};
		
	},
	
	observe : function(type,observer){
		if(!this.observers[type]) {
			this.observers[type] = [];
		};
		this.observers[type].push(observer);
	},
	
	notify : function(event){
		if(!this.observers[event.type]) {
			return;
		};
		for(var i=0;i<this.observers[event.type].length;i++){
			this.observers[event.type][i].apply(this,[event]);
		};
	},
	
	validate : function(){		
		// results array for validateDone event.
		var results = [];
		
		// set default error count.
		this.errors = 0;
		
		// iterate over form fields.
		for(var i=0;i<this.formFields.length;i++){
		
			var field = this.formFields[i];
			var validationType = this.getValidationType(field);		
			var valid = this.compare[validationType](field)
			
			if(!valid) {
				this.errors++;
			};
			
			var event = {
				type : "validate",
				element : field,
				valid : valid,
				validationType : validationType
			};
			
			results.push(event);
			
			this.notify(event);
			
		};
		
		var event = {
			type : "done",
			results : results,
			errors : this.errors,
			element : this.formObj
		};
		
		this.notify(event);
		
		if(this.errors == 0 && this.submitOnValid) {
			this.formObj.submit();
		};
		
	},
	
	getValidationType : function(element){
		var re = new RegExp(this.prefix+"-([a-zA-Z]+)","");		
		return element.className.match(re)[1].toUpperCase();
	}
});

// +--------------------------------------------------------+
// | PopInBox Validator Class								|
// +--------------------------------------------------------+
neteffect.PopInBox = Class.create({
	initialize : function(params){
		
		this.params = {
			boxClass : null,
			boxStyle : null,
			contentClass : null,
			contentStyle : null,
			closeButton : null,
			closeable : false,
			x : "center",
			y : "middle",
			draggable : false,
			depth : 10000,
			dropShadow : true,
			dropShadowDistance : 3
		};
		
		Object.extend(this.params,params);
		
		this.placeBox();
		
	},
	
	placeBox : function(){
		if(this.box)
			document.body.removeChild(this.box);
			
		var box = document.createElement("div");
		box = $(document.body.appendChild(box));
		
		box.setStyle({
			position : "absolute",
			background : "#FFF",
			overflow : "hidden",
			zIndex : this.params.depth
		});
		
		if(this.params.boxClass)
			box.addClassName(this.params.boxClass);
			
		if(this.params.boxStyle)
			box.setStyle(this.params.boxStyle);
			
		this.box = box;	
		
		var bar = document.createElement("div");
		bar = $(box.appendChild(bar));
		
		if(this.params.barClass)
			bar.addClassName(this.params.barClass);
		else
			bar.addClassName("bar");
			
		if(this.params.boxStyle)
			bar.setStyle(this.params.barStyle);
		
		this.bar = bar;
		
		var content = document.createElement("div");
		content = $(box.appendChild(content));
		
		if(this.params.contentClass)
			content.addClassName(this.params.contentClass);
		else
			content.addClassName("content")
		
		if(this.params.contentStyle)
			content.setStyle(this.params.contentStyle);
		
		this.content = content;
		this.content.observe("click",function(e){e.stop()});
		
		if(this.params.closeable) {
		
			if (!this.params.closeButton) {
				var closeBtn = document.createElement("a");
				closeBtn = $(bar.appendChild(closeBtn));
				closeBtn.innerHTML = "close";
			} else {
				var closeBtn = document.createElement("img");
				closeBtn = $(bar.appendChild(closeBtn));
				closeBtn.src = this.params.closeButton;
				closeBtn.alt = "close";
			};
			
			
			if(this.params.closeClass) {
				closeBtn.addClassName(this.params.closeClass);
			} else {
				closeBtn.addClassName("close");
			};
			
			if(this.params.closeStyle) {
				closeBtn.setStyle(this.params.closeStyle);
			};
			
			this.closeBtn = closeBtn;
			
			this.closeBtn.observe("click",function(e){
				e.stop();
				this.close();
			}.bind(this))
		};
		
		this.setPosition();
		
		if(this.params.dropShadow){
			var dropShadow = document.createElement("div");
			dropShadow = $(document.body.appendChild(dropShadow));
			dropShadow.hide();
			
			dropShadow.setStyle({
				background : "#000",
				opacity : .3,
				zIndex : (this.params.depth - 1),
				position: "absolute"
			});
			
			this.dropShadow = dropShadow;
		}
		
		if(this.params.draggable)
			this.makeDraggable();
	},
	
	setContent : function(value){
		this.contentHTML = value;
	},
	
	updateDimensions : function(){
		var a = this.box.getHeight();
		var b = this.box.getWidth();

		if(this.dropShadow) {
			this.dropShadow.setStyle({
				height : a + "px",
				width : b + "px"
			});
		};
		this.setPosition();
	},
	
	setPosition : function(x,y){
		var x = x || this.params.x || 0;
		var y = y || this.params.y || 0;
		
		switch(x){
			case "center":
				var boxWidth = this.box.getDimensions().width;
				var clientWidth = document.body.offsetWidth;
				x = (clientWidth/2) - (boxWidth/2);
				break;
			case "left":
				x = 0;
				break;
			case "right":
				var boxWidth = this.box.getDimensions().width;
				var clientWidth = document.body.offsetWidth;
				x = clientWidth - boxWidth;
				break;
		};
		
		switch(y){
			case "middle":
				var boxHeight = this.box.getDimensions().height;
				var clientHeight = document.body.offsetHeight;
				y = (clientHeight/2) - (boxHeight/2);
				break;
			case "top":
				y = 0;
				break;
			case "bottom":
				var boxHeight = this.box.getDimensions().height;
				var clientHeight = document.body.offsetHeight;
				y = clientHeight - boxHeight;
				break;
		};
		
		if(typeof x == "number" && typeof y == "number"){
			this.box.setStyle({
				top : y+"px",
				left : x+"px"
			});
			
			if(this.dropShadow) {			
				this.dropShadow.setStyle({
					top : (y + this.params.dropShadowDistance) + "px",
					left : (x + this.params.dropShadowDistance) + "px"
				});
			};
		};
	},
	
	open : function(){
		this.box.show();
		this.content.innerHTML = this.contentHTML;
		if(this.dropShadow){
			this.dropShadow.show();
		};
		this.updateDimensions();
	},
	
	close : function(){
		this.box.hide();
		if(this.dropShadow){
			this.dropShadow.hide();
		};
		this.content.innerHTML = "";
	},
	
	makeDraggable : function(){
		this.drag = this.drag.bind(this);
		this.bar.observe("mousedown",this.startDrag.bind(this));
		$(document).observe("mouseup",this.stopDrag.bind(this));
		
		this.bar.setStyle({
			cursor : "move"
		});
	},
	
	startDrag : function(event){
		var coords = this.box.cumulativeOffset();

		this.clickOffset = {
			x : (event.clientX - coords.left),
			y : (event.clientY - coords.top)
		};
		
		$(document).observe("mousemove",this.drag);
	},
	
	stopDrag : function(event){
		$(document).stopObserving("mousemove",this.drag);
	},
	
	drag : function(event){
		this.box.setStyle({
			top : (event.clientY - this.clickOffset.y)+"px",
			left : (event.clientX - this.clickOffset.x)+"px"
		});
		if(this.dropShadow) {
			this.dropShadow.setStyle({
				top : ((event.clientY - this.clickOffset.y) + this.params.dropShadowDistance ) + "px",
				left : ((event.clientX - this.clickOffset.x) + this.params.dropShadowDistance ) + "px"
			});
		}
	}
	
});
