/* elementary.js 
 * cross browser api for easing javascript development
 * see http://benipsen.com/technology/elementary/
*/

/* this is the code you will care about */

var Signup = {
		onData:function(data){
			var a = new Animation("signupmsg", {alpha:99.9});
			document.getElementById("signupmsg").style.display = 'block';
			document.getElementById("signupmsg").innerHTML = "<p>You have been subscribed to the Legitify Newsletter</p>";
			window.setTimeout(Signup.fadeout, 4000);
		},
		validate:function(_form){		
			var valid_email = /^.+\@.+\..+$/
			var btn = document.getElementById("signupbtn");
			if(_form.email.value.toString().match(valid_email)) {
				btn.disabled = false;
				btn.style.color = "#000";
			}else{
				btn.disabled = true;
				btn.style.color = "#CCC";
			}
		},
		send:function(_form){
			var obj = '{"mail":"'+_form.email.value+'"}';
			RemoteCall.handlers = Signup;
			RemoteCall.make("contacts","subscribe", obj);
			return false;
		},
		fadeout:function(){
			var a = new Animation("signupmsg", {alpha:99.9});				
				a.effect({alpha:0.01, duration:0.3, fps:1/50, trans:physics.easeOut}, function(){
																							a.element.hide('none');	   																				   	
																					   });
		}
}

function addWindowEventListener(eventName, callback, bubble){
	if(window.addEventListener){          
		window.addEventListener(eventName, callback, bubble);
	} else {
		document.attachEvent('on' + eventName, callback);
	}                                                  
}

function addPageLoadListener(listener){
	if (window.addEventListener) {
		window.addEventListener('load',listener,false);	
	} else if (document.addEventListener) {
		document.addEventListener('load',listener,false);
	} else if (window.attachEvent) {
		window.attachEvent('onload',listener);
	} else {
		if (typeof window.onload=='function') {
				var previously = window.onload;
				window.onload=function(){
					previously.call();
					listener.call();
				}
		} else { 
			window.onload = listener;
		}
	}	
}

/** effects wrapper. makes calls like Effect.FadeOut(element) possible using powerful animation engine */
var Effect = {
	fadeOut:function(element, options, after, args){
		
	}	
}

var Valid = function(frm){
		var match = "";
		var password = "";	
		for(var e = 0; e < frm.elements.length; e++){
			if(frm.elements[e].getAttribute("notempty") && frm.elements[e].value == ""){
				var name = frm.elements[e].getAttribute("name");
					name = name.replace(/_/g,' ');
					name = name.replace(/\[|\]/g,' ');
				var msg = document.createElement("p");
					msg.className = "error";
					msg.innerHTML = name + " is required.";
				frm.elements[e].parentNode.insertBefore(msg, frm.elements[e].previousSibling);
				frm.elements[e].focus();
				return false;
			}else if(frm.elements[e].getAttribute("type") == "password"){
				if(!match){
					match = frm.elements[e].value;
					password = frm.elements[e];
				}else{
					if(frm.elements[e].value != match){
						var msg = document.createElement("p");
							msg.className = "error";
							msg.innerHTML = "Your passwords do not match. Please re-enter";
						password.parentNode.appendChild(msg, frm.elements[e]);		
						password.focus();
						password.select();
						return false;
					}
				}
			}
		}
		return true;
	}


/** remote call wraper a call to the controler method or "action", and returns the resulting object **/
var RemoteCall = {
	handlers:null,
	make:function(controller, action, object, string){
		if(!string) string = true;
		var req = new Request(RemoteCall.handlers, string);
			req.send(WEB_HOME + "/remotecall/?name="+controller+"&action="+action+"&obj=" + object);
	}
}

/** allows for editable block elements, id attribute must be present to work correctly. **/
var TextEditor = {
	elements:false,
	control:false,
	action:false,
	active:false,
	appended:false,
	original_value:false,
	make:function(element, control, action, field, appended){
		if(!TextEditor.elements){
			TextEditor.elements = new Array();
			TextEditor.field = field;
			TextEditor.appended = appended;
			//addWindowEventListener('mouseup',TextEditor.cancel)
		} 
		var obj = new Element(element, { onclick:TextEditor.click, onrollover:TextEditor.over, onrollout:TextEditor.out});
		TextEditor.elements.push(obj); 
		this.control = control;
		this.action = action;
		
	},
	click:function(e){
		TextEditor.cancel();
		var inst = TextEditor.getinstance(this);
		var cont = inst.getContent();
			inst.setContent("");
			var field = inst.append("input",false,'type="text" value="'+cont+'"');
			inst.append("input",false,'type="button" class="button" value="save" onclick="TextEditor.save(this)"');
			inst.append("input",false,'type="button" class="button" value="cancel" onclick="TextEditor.cancel(this)"');
			inst.append("br",false,'style="clear:both;"');		
		TextEditor.active = inst;
		TextEditor.original_value = field.value;
		field.focus(); field.select();			
	},
	over:function(e){
		this.style.backgroundColor = "#EEEEEE";
		this.style.cursor = "pointer";
	},
	out:function(e){
		this.style.backgroundColor = "#FFF";
	},
	getinstance:function(source){
		for(var e = 0; e < TextEditor.elements.length; e++){
			if(TextEditor.elements[e].id == source.getAttribute("id"))
				return TextEditor.elements[e];
		}
	},
	cancel:function(){
		if(TextEditor.active){
			var value = TextEditor.active.element.firstChild.value;
			TextEditor.active.setStyleProperty('backgroundColor','#FFF');			
			TextEditor.active.setContent(TextEditor.original_value);
			TextEditor.active = null;
		}
	},
	onData:function(result){
		if(result.okay){
			TextEditor.active.setStyleProperty('backgroundColor','#FFF');			
			TextEditor.active.setContent(result.saved.name);
			TextEditor.active = null;
		}
	},
	save:function(){
		if(TextEditor.active){
			var id = TextEditor.active.element.id;
			if(TextEditor.appended){
				id = id.substring(0, id.indexOf(TextEditor.appended));
			}
			
			var value = TextEditor.active.element.firstChild.value;
			var save = '{"id":"'+id+'","'+TextEditor.field+'":"'+value+'"}';
			
			RemoteCall.handlers = TextEditor;
			RemoteCall.make(TextEditor.control, TextEditor.action, save);
			
			TextEditor.active.setContent("Saving...");
			
		}
	},
	revert:function(){
		
	}	
}


/** assign observer objects to keypress events.. **/
var KeyEventObservers = {
	list:null,
	add:function(key, handler){ 
		if(KeyEventObservers.list == null){
			 KeyEventObservers.list = new Object();
			 addWindowEventListener('keydown',KeyEventObservers.onkeydown, false);
			 addWindowEventListener('keyup',KeyEventObservers.onkeyup, false);
		}
		if(!KeyEventObservers.list[key]) KeyEventObservers.list[key] = new Array();
		KeyEventObservers.list[key].push(handler);			
	},
	onkeydown:function(e){
		if( ! KeyEventObservers.list[KeyMap.lookup(e.keyCode)]) return true;
		var observers = KeyEventObservers.list[KeyMap.lookup(e.keyCode)];
	    for(var o = 0; o < observers.length; o++){
			if(observers[o].down) observers[o].down(e);
		}
		return true;
	},
   	onkeyup:function(e){ 
		if( ! KeyEventObservers.list[KeyMap.lookup(e.keyCode)]) return true;
		var observers = KeyEventObservers.list[KeyMap.lookup(e.keyCode)];
	    for(var o = 0; o < observers.length; o++){
			if(observers[o].up) observers[o].up(e);
		}
		return true;
	}
}

var KeyMap = {
	names:['shift','ctl','up','down','left','right'],
	//note: safari shift, ctl, and alt don't fire events!
	safari:[16,17,38,40,37,39],
	moz:[16,17,38,40,37.39],
	ie:[16,17,38,40,37,39],
	mac:[16,224,38,40,37,39],
	lookup:function(test){	
		var code = internet_explorer ? KeyMap.ie : KeyMap.moz;
		if(macintosh) code = KeyMap.mac;
		if(safari) code = KeyMap.safari;
		for(var i = 0; i < code.length; i++){
			if(code[i] == test)
				return KeyMap.names[i];
		}
		return "all";
	}
}

var Window = {
	construct:function(){
		
  	   //without scrolling...
	  if( typeof( window.innerWidth ) == 'number' ) {
		//moz, opera
		this.width = window.innerWidth;
		this.height = window.innerHeight;
	  } else if( document.documentElement &&
		( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
		//ie
		this.width = document.documentElement.clientWidth;
		this.height = document.documentElement.clientHeight;
	  }
	
	  //with scrolling..
	  if( document.body ) {
		//dom
			this.scrollheight = document.body.scrollHeight;
			this.scrollwidth = document.body.scrollWidth;
	   } else if(document.documentElement && document.documentElement.scrollHeight){
	    //ie
	   		this.scrollheight =  document.documentElement.scrollHeight;
			this.scrollwidth =  document.documentElement.scrollWidth;
		
	  } 
	  
	  //srolling offset
	  if (window.innerHeight){
	 	  	this.scrolledy = window.pageYOffset;
			this.scrolledx = window.pageXOffset;
	  } else if (document.documentElement && document.documentElement.scrollTop) {
			this.scrolledy = document.documentElement.scrollTop;
			this.scrolledx = document.documentElement.scrollLeft;
	  }else if (document.body){
		  this.scrolledy = document.body.scrollTop;
		  this.scrolledy = document.body.scrollLeft;
	  }	
	}
}
Window.construct();
addWindowEventListener("resize",Window.construct);
//dependencies - "not so clean" code, this is old and should all be replaced but it works- well.  

var internet_explorer = navigator.appName.indexOf("xplorer") > 0;
var macintosh = navigator.platform.indexOf("Mac") >= 0;
var safari = navigator.appVersion.indexOf("fari") > 0;


function Request(handlers, evaluate){
  this.onData = handlers.onData;
  this.onError = handlers.onError ? handlers.onError : false;
  this.onLoading = handlers.onLoading ? handlers.onLoading : false;
  this.evaluate = evaluate;
  this.lastRequest = ""; 
  var xmlhttp=false;
  var This = this;
  try { 
  	xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
 	} catch (e) {
 		 try {
  	 		xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  		  } catch (E) {
   			xmlhttp = false;
  		 }
 	}
   if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
  		xmlhttp = new XMLHttpRequest();
    }
   this.stateChange = function( ){
		if ( xmlhttp.readyState == 4) {
        	if (xmlhttp.status == 200) {
		    	var response = (xmlhttp.responseText) ? xmlhttp.responseText : ""; 
				if(This.evaluate){
					var result;
					var str = 'result = ' + response + ';';
					try{
						eval(str);
					}catch(e){
						alert("Request Runtime error: " + e+ "\nReturned Response:\n\n" + response);
					}
					response = result;					
				}
				This.onData(response, This);
       		} else {
            	var e = xmlhttp.statusText;
				if(This.onError) This.onError(e, This);
        	}
	   }
   } 
   this.send = function( url, requestHeaders ) {
	  if(xmlhttp){		
	    	if(This.onLoading) This.onLoading();
  			xmlhttp.open("POST", url , true);
			xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
 			xmlhttp.onreadystatechange = This.stateChange;
			This.lastRequest = url;
			xmlhttp.send(null);
	   }else{
		   if(This.onError) This.onError("Sorry, your browser does not support remote requests.");
	   }
   }
}
function Element(id, io){	
	var This = this;
	if(typeof(id) == 'string'){
		if(!document.getElementById(id)){
			//alert("Can't find element with id: " + id);
			This.element = false;
		}
		This.element = document.getElementById(id);
		This.id = id;	
	}else{
		This.element = id;
		try{		
			This.id = This.element.getAttribute('id');
		}catch(e){
			This.id = null;
		}
	}
	if(!io) io = {};
	var units = io.units ? io.units : 'px';
	this.x = io.x ? io.x : false;
	this.y = io.y ? io.y : false; 
	this.width = io.width ? io.width : false; 
	this.height = io.height ? io.height : false; 
	this.alpha = (io.alpha != undefined) ? io.alpha : false;
	this.center = (io.center) ? io.center : false;
	this.contentElement = false;
	if(io.contentElement)  
		this.contentElement = document.getElementById(io.contentElement); 	
	this.setDimensions = function(w,h){
		if(isNum(w)) { this.element.style.width = (w + units); this.width = w;   }
		if(isNum(h)) { this.element.style.height = (h + units); this.height = h; }
		if(This.center){
			var cx = (This.width-w) * This.center.x;
			var cy = (This.height-h) * This.center.y;
			This.setPosition( This.x + cx, This.y + cy);
		}
	}
	this.setPosition = function(x,y){
	  if(isNum(y)) { this.element.style.top = y + units;  this.y = y;   }
	  if(isNum(x)) { this.element.style.left = x + units; this.x = x;  }
	  //if(this.center) this.setDimenions(this.width, this.height);
	}
	this.setOpacity = function(a){ 
		if(isNum(a)){
			this.element.style.opacity = (a/100);		
			this.element.style.filter = "Alpha(Opacity=" + a + ")";  
			this.alpha = a;
		}
	}	
	this.setStyleProperty = function(property, value){
		eval("this.element.style." + property + "=\"" + value + "\"");
	}
	this.setClass = function(name){
		this.element.className = name;	
	}
	this.addClass = function(name){
		if(this.element.className.toString().indexOf(name) < 0)
			this.element.className = this.element.className + " " + name;
	}
	this.removeClass = function(name){
		var cc = this.element.className.toString();
		var e = cc.substring(0,cc.indexOf(name));
		var b = cc.substring(cc.indexOf(name) + name.length, cc.length);
		this.element.className = b + " " + e;
	}	
	this.hide = function(disp){
		this.element.style.visibility = 'hidden';
		if(disp) this.element.style.display = disp;
	}	
	this.show = function(disp){
		this.element.style.visibility = 'visible';
		if(disp) this.element.style.display = disp;
	}	
	this.getRealHeight = function(){
		return this.element.offsetHeight;
	}
	this.getRealWidth = function(){
		return this.element.offsetWidth;
	}
	this.getRealTop = function(){
		if(internet_explorer){
			var top = 0;
	   	 	var obj = This.element;
				if (obj.offsetParent)
				{
					while (obj.offsetParent)
					{
						if(obj.offsetParent.getAttribute("id")) top += obj.offsetTop
						obj = obj.offsetParent;
					}
				}
				else if (obj.y)
					top += obj.y;
			return top;
		}else{
			return this.element.offsetTop;
		}  
	}
	this.getRealLeft = function(){
		if(this.ie){
			var left = 0;
			var obj = this.element;
				if (obj.parentNode)
				{
					while (obj.parentNode)
					{
						if(obj.offsetParent.getAttribute("id")) left += obj.parentNode.offsetLeft
						obj = obj.parentNode;
					}
				}
				else if (obj.x)
					left += obj.x;
			return left; 
		} else {
			return this.element.offsetLeft;
		}     
	}
	this.getRelativeTop = function(){
		var top = 0;
   	 	var obj = This.element;
			if (obj.offsetParent)
			{
				while (obj.offsetParent)
				{
					top += obj.offsetTop
					obj = obj.offsetParent;
				}
			}
			else if (obj.y)
				top += obj.y;
		return top;
	}
	this.getRelativeLeft = function(){	
		var left = 0;
		var obj = this.element;
			if (obj.offsetParent)
			{
				while (obj.offsetParent)
				{
					left += obj.offsetLeft
					obj = obj.offsetParent;
				}
			}
			else if (obj.x)
				left += obj.x;
		return left; 	  
	}
	this.getTop = function(){
		return this.element.offsetTop;
	}
	this.getLeft = function(){
		return this.element.offsetLeft;
	}
	this.getContent = function(cont){
		if(this.contentElement) return this.contentElement.innerHTML;
		return this.element.innerHTML;	
	}
	this.setContent = function(cont){
		if(this.contentElement) this.contentElement.innerHTML = cont;
		else this.element.innerHTML = cont;	
	}
	this.insertContent = function(cont, pos){
		var bCont = this.getContent();
		if(pos=='before') this.setContent(cont + bCont);
		else this.setContent(bCont + cont);
	}
	this.getChildren = function(tag){
		if(this.element)
			return this.element.getElementsByTagName(tag);
		else
			return new Array();
	}
	this.append = function(type, content, attributes){
		var ne;	
		if(!internet_explorer){ 
			ne = document.createElement(type);
			if(attributes){
				var atts = attributes.split('" ');
				for(var a=0; a < atts.length; a++){
					var data = atts[a].split('="');
					var value = data[1].indexOf('"') > 0 ? data[1].substring(0,data[1].length-1) : data[1];
					ne.setAttribute(data[0], value);
				}
			}
		}else{
			var make = '<' + type + ' ' + attributes + '>';
			ne = document.createElement(make);
		}
		if(content) ne.innerHTML = content;	
		this.element.appendChild(ne);
		return ne;
	}
	this.prepend = function(type, content){
			var ne = document.createElement(type);   
		    this.element.insertBefore(ne, This.element.firstChild); 
			if(content) ne.innerHTML = content; 
			return ne;
	}
	this.remove = function(node){
		this.element.removeChild(node);
	}
	this.insert = function(node, before){
		this.element.insertBefore(node, before);
	}
	this.setHandlers = function(io){   
		if(io.onclick) this.element.onclick = io.onclick;
		if(io.onrollover) this.element.onmouseover = io.onrollover;
		if(io.onrollout) this.element.onmouseout = io.onrollout;
		if(io.onpress) this.element.onmousedown = io.onpress;
		if(io.onrelease) this.element.onmouseup = io.onrelease;
		if(io.ondouble) this.element.ondblclick = io.ondouble;
		if(io.onmove) this.element.onmousemove = io.onmove;
	}	
	if(this.width || this.height)
		this.setDimensions(this.width, this.height);
	if(this.x || this.y)
		this.setPosition(this.x, this.y);
	if(this.alpha)
		this.setOpacity(this.alpha);
	if(io)
		this.setHandlers(io);
	function isNum(num){ if(num==0) return true; if(!num) return false; else return typeof(num) == 'number' };	
}
function Animation(el, io){
	var This = this;
	this.element = new Element(el, io);
	var next = function(){ };
	var args = false;  
	this.cancel = function(){ this.time.reset(); this.time.stop(); } 
	this.update = function() { 
		var t = This.trans( This.time.getTime() / This.dur );
		if(isNum(da)){
			var na  = oa + (t * da);
			This.element.setOpacity(na);
		}
		if(isNum(dx) || isNum(dy)){
			var nx  = ox + t * dx;  	     
			var ny  = oy + t * dy;
			This.element.setPosition(nx, ny);
		}
		if(isNum(dw) || isNum(dh)){
			var nw  =  ow + (t * dw);  	     
			var nh  =  oh + (t * dh);
			if(This.element.center){
				var cx = (This.element.width - nw) * This.element.center.x;
				var cy = (This.element.height - nh) * This.element.center.y;
				This.element.setPosition( This.element.x + cx, This.element.y + cy);
			}
			This.element.setDimensions(nw, nh);
		}
		if(observer) observer();
		if(t == 1){
			if(_effect.y && isNum(_effect.y)) This.element.element.style.top = _effect.y + 'px';
			if(_effect.x && isNum(_effect.x)) This.element.element.style.left = _effect.x + 'px';
			This.complete = true;
			try{ 
				 next(args);
				 next = new function(){};
			}catch(e){ }
		}
	}
	var _effect;
	var oa; var ox; var oy; var ow; var oh; 
	var da; var dx; var dy; var dw; var dh;
	this.effect = function(fect, after, afterArgs){
		if(This.complete){
			_effect = fect;
			if(fect.duration) This.dur = fect.duration;
			if(fect.fps) This.fps = fect.fps;
			if(fect.trans) This.trans = fect.trans;
			if(after) next = after;
			if(afterArgs) args = afterArgs;
			if(isNum(fect.alpha)){   oa = This.element.alpha;     da = fect.alpha - oa; }
			if(isNum(fect.width)){  ow = This.element.width;   dw = fect.width - ow;  }
			if(isNum(fect.height)){  oh = This.element.height;  dh = fect.height - oh; }
			if(isNum(fect.x)){	 ox = This.element.x;       dx = fect.x - ox;  }
			if(isNum(fect.y)){	  oy = This.element.y;	    dy = fect.y - oy; }
			This.complete = false;
			this.time.reset();
			this.time.start(This.dur, This.fps);  
		}
	}	
	var observer = false
	this.setUpdateObserver= function(obj){ observer = obj; }
	this.linear = function(x){ return x; }
	if(!io) io = { };
	this.time = new Timer(this.dur, this.fps, this.update);
	this.trans = (!io.trans) ? this.linear : io.trans;
	this.fps = (io.fps) ? io.fps : (1/24);
	this.dur = (io.duration) ? io.duration : 1;
	this.complete = true;
	function isNum(val) { 
		if(val==0) 
			return true; 
		else if(typeof(val) == 'number');
		 	return true;
		return false; }
}  
function Timer(duration, updateInterval, listener){
  	this.update = (updateInterval) ? updateInterval : (1/24);
	this.duration = (duration) ? duration : 1;
	this.listeners = new Array();
	if(listener) this.listeners.push(listener);
	var time = 0;  var timer = null;
	var self = this; var check;
	this.addListener = function(listenerObj){
		this.listeners.push(listenerObj);
	}	
	this.start = function(duration, interval){
		if(duration) this.duration = duration;
		if(interval) this.update = interval;
		check = this.update;
		run();
	}	
	this.stop = function(nocall){ 
		window.clearTimeout(timer);
		time = this.duration; 
		for(var l=0; l < self.listeners.length; l++)
			self.listeners[l].call(this, self); 		
	}							 
	this.getTime = function(){ return time; }
	this.reset = function() {  
		window.clearTimeout(timer); 
		time = 0; 
		check = 0; 
		timer = null; 
	}
    function run(){
		if(time <= self.duration){
			if(time >= check){
				for(var l=0; l < self.listeners.length; l++)
						self.listeners[l].call(this, self);
				check += self.update;	
			}
			time+= 0.01;			
			loop();
			return;	
		}
	  self.stop();
	}	
	function loop(){
		timer = window.setTimeout(run, 10);
	}
};
function Physics(){
	this.linear = function(x){ return x; }
	this.easeIn = function(x){ return Math.pow(x,2); }
	this.easeOut = function(x){ return 1 - Math.pow((x-1), 2); }
	this.sineWave = function(x){ return Math.sin(x*Math.PI/2); }
	this.spring = function(x){
		if(x < 0.65)
			return 1.1 * Math.sin(x * (Math.PI/1.5666) ); 
		else if(x < 1)
			return 1 + 0.1 * Math.sin(3.3 * (x +0.21) * Math.PI);	
		else
			return 1;		
	}	
	this.snap = function(x){ 
		if(x < 1)
			return 1.1 * Math.sin(x * (Math.PI/1.5666) );  
		else
			return 1;
	}
}
var physics = new Physics();

function EventInfo(e, cancel){
		if (!e) var e = window.event;			
		if (e.target) this.source = e.target;
		else if (e.srcElement) this.source = e.srcElement;
		if (this.source.nodeType == 3)
			this.source = this.source.parentNode;			
		if (e.pageX || e.pageY) {
			this.xmouse = e.pageX;
			this.ymouse = e.pageY;
		}
		else if (e.clientX || e.clientY) {
			this.xmouse = e.clientX + document.body.scrollLeft;
			this.ymouse = e.clientY + document.body.scrollTop;
		}		
		if(cancel){
			e.cancelBubble = true;
			if (e.stopPropagation) e.stopPropagation();
		}	
}