/**
 * @author Jesse Chrestler
 * 07/21/2008
 * @version 0.02
 */
var binding = {
	bindings:{},
	animating:false,
	add:function(o){
		$.extend(this.bindings, o)
		return this.bind();
	},
	chain:function(t, i){
		i = i||0;
		if (i < t.length && t[i] != undefined && t[i] != null && typeof t[i] != "undefined") {
			if(typeof t[i].beforeAnim == "function"){
				t[i].beforeAnim();
			}
			var el = $(t[i].target);
			
			if (el.html() != null) {
		  	if (t[i].type == "animate") {
					el[t[i].type](t[i].options, t[i].speed, function(){
			  		if (t[i] != undefined && typeof t[i].afterAnim == "function") {
			  			t[i].afterAnim();
			  		}
			  		binding.chain(t, ++i);
			  	});
				}else{
					el[t[i].type](t[i].speed, function(){
			  		if (t[i] != undefined && typeof t[i].afterAnim == "function") {
			  			t[i].afterAnim();
			  		}
			  		binding.chain(t, ++i);
			  	});
				}
				
		  }else{
				binding.chain(t, ++i);
			}
	  }
	},
	exec: function(el, allowSelected, type){
		var bind = el.attr("bind");
		var b = binding.bindings;
		var async = (b[bind].async != undefined)?b[bind].async:false;
		if(b[bind].relativeTarget != undefined){
			var path = b[bind].relativeTarget.split(".");
			for (var i = 0; i < path.length; i++) {
				if (b[bind].parent != undefined) {
					otarget = otarget[path[i]]();
				}
				el = el[path[i]]();
			}
		}
		if (b[bind].target != undefined) {
			el = el.parents(b[bind].target);
		}
		allowSelected = (allowSelected != undefined) ? allowSelected : false;
		if (bind != undefined && el != undefined && !binding.animating) {
			if ((!el.hasClass(b[bind].selectedClass)) || allowSelected ) {
				if (typeof b[bind].beforeSelect == "function") {
					b[bind].beforeSelect(el, otarget);
				}
				if (b[bind].before != undefined) {
					if (!async) {
				  	binding.chain(b[bind].before);
				  }else{
						for (var i = 0; i < b[bind].before.length; i++) {
							var t = b[bind].before[i];
							if (t != undefined && typeof t.beforeAnim == "function") {
								t.beforeAnim(el, otarget);
							}
							$(t.target)[t.type](t.options, t.speed, function(){
								if (t != undefined && typeof t.afterAnim == "function") {
									t.afterAnim(el, otarget);
								}
							});
						}
					}
				}
				var otarget = null;
				if (b[bind].parent != undefined) {
					otarget = el.parents(b[bind].parent).find("." + b[bind].selectedClass)
					if(b[bind].lastSelectedClass != undefined){
						el.parents(b[bind].parent).find("." + b[bind].lastSelectedClass).removeClass(b[bind].lastSelectedClass);
					}
				}
				else {
					otarget = $("." + b[bind].selectedClass)
					if(b[bind].lastSelectedClass != undefined){
						$("." + b[bind].lastSelectedClass).removeClass(b[bind].lastSelectedClass);
					}
				}
				if(otarget != null || otarget != undefined){
					otarget.removeClass(b[bind].selectedClass);
				}
				if(b[bind].lastSelectedClass != undefined && !allowSelected){
					otarget.addClass(b[bind].lastSelectedClass);
				}
				if(b[bind].disabledClass != undefined){
						otarget.addClass(b[bind].disabledClass);
						el.removeClass(b[bind].disabledClass);
				}
				el.addClass(b[bind].selectedClass);
				if (b[bind].after != undefined) {
					if (!async) {
				  	binding.chain(b[bind].after);
				  }else{
						for(var i = 0; i < b[bind].after.length;i++){
							var t = b[bind].after[i];
							if (t != undefined && typeof t.beforeAnim == "function") {
				  			t.beforeAnim(el);
				  		}
							$(t.target)[t.type](t.options, t.speed, function(){
								if (t != undefined && typeof t.afterAnim == "function") {
					  			t.afterAnim(el);
					  		}
									binding.animating = false;
							});
						}
					}
				}
				if (typeof b[bind].afterSelect == "function") {
					b[bind].afterSelect(el, otarget);
				}
			}else{
				if(type != "load")
					if(typeof b[bind].afterSelectAgain == "function"){
						b[bind].afterSelectAgain(el, otarget);
					}
			}
		}
		return this;
	},
	bind:function(){
		var b = binding.bindings;
		for (o in b) {
			//object
			var obj = $(o);
			if (obj.attr("bind") == undefined) {
				obj.attr({
					bind: o
				});
				obj.each(function(){
					var el = $(this);
					var bind = el.attr("bind");
					var b = binding.bindings;
					var sc = binding.bindings[bind].selectedClass;
					//checking to see if the element already has the 
					//class so we can perform the transitions upfront
					if (b[bind].relativeTarget != undefined) {
						var path = b[bind].relativeTarget.split(".");
						for (var i = 0; i < path.length; i++) {
							el = el[path[i]]();
						}
					}
					if (el.hasClass(sc)) {
						//console.log(el);
						var autoStart = (b[bind].autoStart == undefined) ? true : b[bind].autoStart;
						binding.exec($(this), autoStart, "load");
					}
					el[b[o].type || "click"](function(){
						binding.exec($(this));
						if (b[bind].trackHistory) {
							h = this.href.replace(/^.*#/, '#');
							ch = window.location.hash;
							if(h != ch && typeof $.historyLoad == "function")
								$.historyLoad(h.replace(/#/,''));
						}
						return b[bind].defaultAction || false;
					});
				})
			}
		}
		return this;
	}
}