/* ============================     NAjaxLink    ===========================*/
function NAjaxLink(element){
	this.element = element;
	this.container = null;
	this.data = null;
	this.url = null;
	this.pipe = null;
	this.newContent = null;
	this.method = "get";
}

NAjaxLink.prototype.setPipeAndContainer = function(){
	var className = this.element.className;
	var classes = className.split(" ");
	for(var j = 0; j < classes.length; j++){
		if(classes[j].indexOf("n_") != -1){
			var props = classes[j].split("__");

			this.pipe = props[1];
			this.container = document.getElementById(props[2]);
		}
	}
}

NAjaxLink.prototype.init = function(){
	this.setPipeAndContainer();
	this.url = this.element.getAttribute("href");
	if(this.url.indexOf('?') != -1){
		this.url += '&nmode=htmlfrag&npipe=' + this.pipe;
	}else{
		this.url += '?nmode=htmlfrag&npipe=' + this.pipe;
	}
	var n = this;
	this.element.onclick = function(){
		return !ajax.submitRequest(n);
	}
}

NAjaxLink.prototype.render = function(){
	this.container.innerHTML = this.newContent;
		
	// rewire events on new content of container
	ajax.wireAjax();
}

NAjaxLink.prototype.renderLoadingCue = function(){
	var height = getCSSProp(this.container, 'height');
	this.container.innerHTML = "<p style=\"margin:0;height:" + height + ";\"><image src=\"http://nephtaliproject.com/images/ajax-loader.gif\" /> Loading</p>";
}

/* ==============================    NAjaxForm    ============================*/
function NAjaxForm(element){
	this.element = element;
	this.container = null;
	this.data = '';
	this.url = null;
	this.tempURL = null;
	this.pipe = null;
	this.newContent = null;
	this.method = null;
	this.stage = 'validate';
}

NAjaxForm.prototype.setPipeAndContainer = function(){
	var className = this.element.className;
	var classes = className.split(" ");
	for(var j = 0; j < classes.length; j++){
		if(classes[j].indexOf("n_") != -1){
			var props = classes[j].split("__");

			this.pipe = props[1];
			this.container = document.getElementById(props[2]);
		}
	}
}

NAjaxForm.prototype.init = function(){
	this.setPipeAndContainer();
	this.url = this.element.getAttribute("action");
	this.method = this.element.getAttribute("method");
	if(this.url.indexOf('?') != -1){
		this.url += '&nmode=validate&npipe=' + this.pipe;
	}else{
		this.url += '?nmode=validate&npipe=' + this.pipe;
	}
	
	var nAjaxElement = this;
	this.element.onsubmit = function(){
		nAjaxElement.data = '';
		for(var k = 0; k < this.elements.length; k++){
			if(this.elements[k].type != 'submit'){
				nAjaxElement.data += this.elements[k].name;
				nAjaxElement.data += "=";
				nAjaxElement.data += escape(this.elements[k].value) + '&';
			}
		}
		
		if(nAjaxElement.method == "get"){
			nAjaxElement.url += "&" + nAjaxElement.data;
		}
		
		return !ajax.submitRequest(nAjaxElement);				
	}
}

NAjaxForm.prototype.render = function(){
	if(this.stage == 'validate'){
		if(this.newContent.indexOf("n__none") == -1){
			this.renderValidationErrors();
		}else{
			this.stage = 'htmlfrag';
			this.url = this.url.replace("nmode=validate", "nmode=htmlfrag");
			
			ajax.submitRequest(this);
		}
	}else{
		this.container.innerHTML = this.newContent;
		
		// rewire events on new content of container
		ajax.wireAjax();
	}
}

NAjaxForm.prototype.renderLoadingCue = function(){
	if(this.stage == 'validate'){
	
	}else{
		var height = getCSSProp(this.container, 'height');
		this.container.innerHTML = "<p style=\"margin:0;height:" + height + ";\"><image src=\"http://nephtaliproject.com/images/ajax-loader.gif\" /> Loading</p>";
	}
}

NAjaxForm.prototype.renderValidationErrors = function(){
	var keyValuePairs = this.newContent.split('__');
	for(var i = 1; i < keyValuePairs.length; i++){
		var tandem = keyValuePairs[i].split('--');
		var elem = document.getElementById(tandem[0]);
		addClass(elem, 'invalid');
		elem.setAttribute('title', tandem[1]);
	}
}

/* ===============================    NAjax      ===============================*/
function NAjax(){
	this.ajaxLinks = new Array();
	this.ajaxForms = new Array();
}

NAjax.prototype.getHTTPObject = function(){
	var xhr = false;
	if(window.XMLHttpRequest){
		xhr = new XMLHttpRequest();
	}else if(window.ActiveXObject){
		try{
			xhr = new ActiveXObject("Msxml2.XMLHTTP");
		}catch(e){
			try{
				xhr = new ActiveXObject("Microsoft.XMLHTTP");
			}catch(e){
				xhr = false;
			}
		}
	}
	return xhr;
}

NAjax.prototype.saveAjaxElements = function(tag){
	var elements = document.getElementsByTagName(tag);
	for(var i = 0; i < elements.length; i++){
		var nodeClassName = elements[i].className;
		if(nodeClassName && nodeClassName.indexOf("n__") != -1){
			if(tag == 'a'){
				this.ajaxLinks.push(new NAjaxLink(elements[i]));
			}
			if(tag == 'form'){
				this.ajaxForms.push(new NAjaxForm(elements[i]));
			}
		}
	}
}

NAjax.prototype.submitRequest = function(nAjaxElement){
	var request = this.getHTTPObject();
	if(request){
		nAjaxElement.renderLoadingCue();
		var n = this;
		request.onreadystatechange = function(){
			if(request.readyState == 4){
				if(request.status == 200 || request.status == 304){
					nAjaxElement.newContent = request.responseText;
					nAjaxElement.render();
				}
			}
		};
		
		if(nAjaxElement.method == "get"){
			request.open("GET", nAjaxElement.url, true);
			request.send(null);
			return true;
		}
		else{
			request.open("POST", nAjaxElement.url, true);
			request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
			request.send(nAjaxElement.data);
			return true;			
		}
	}else{
		return false;
	}
}

NAjax.prototype.reset = function(){
	this.ajaxLinks = new Array();
	this.ajaxForms = new Array();
}

NAjax.prototype.wireAjax = function(){
	this.reset();
	
	this.saveAjaxElements('a');
	this.saveAjaxElements('form');
	for(var i = 0; i < this.ajaxLinks.length; i++){
		this.ajaxLinks[i].init();
	}
	for(var i = 0; i < this.ajaxForms.length; i++){
		this.ajaxForms[i].init();
	}
}

/* ===================================    General    ===================================*/
function getCSSProp(element, prop){
    var realStyle = null;
    if(element.currentStyle){
        realStyle = element.currentStyle[prop];
    } else if(document.defaultView && document.defaultView.getComputedStyle){
	    prop = prop.replace(/([A-Z])/g,"-$1");
	    prop = prop.toLowerCase();
	    return document.defaultView.getComputedStyle(element,null).getPropertyValue(prop);
    }
    if(realStyle == "auto"){
		if(prop == "height"){
        	realStyle = element.offsetHeight;
		}
		if(prop == "width"){
			realStyle = element.offsetWidth;	
		}
    }
    return realStyle;
}

function addClass(element, value){
	if(!element.className){
		element.className = value;
	}else{
		element.className = element.className + " " + value;
	}
}

/*
 * Mode values must be one of: set, clear, or reset set is to check the value on page load 
 * clear is to clear the default value when someone clicks on the field reset is to fill in 
 * the default value when someone clicks off the field
 * field is the value of the ID attribute of the input or textarea element.
 *
 * Use .blurred and .sharpened selectors in your CSS file
 */
function setSuggestedFormText(mode, field) {
    var key = null
	key = document.getElementById(field);
	if(key == null)
		return;
		
    var defaultText = key.title;
    switch(mode) {
        case 'set':
            if(key.value == '') {
                key.value = defaultText;
                key.setAttribute('class', 'blurred');
            }                    
            break;
            
        case 'clear':
            if(key.value == defaultText) {
                key.value = '';
                key.setAttribute('class', 'sharpened');
            }            
            break;
            
        case 'reset':
            if(key.value == '') {
                key.value = defaultText;
                key.setAttribute('class', 'blurred');
            }            
            break;
            
        default:
            break;
    }
    
}
 
function setUpSuggestedFormText(field){
	var node = null;
	node = document.getElementById(field);
	if(node == null)
		return;
		
    setSuggestedFormText('set', field);
    
    node.onblur = function(){
        setSuggestedFormText('reset', field);
    }
    node.onfocus = function(){
        setSuggestedFormText('clear', field);
    }
}

function wireMenu(){
	var nodes = null;
	nodes = document.getElementById("nav_primary");
	if(node == null)
		return;
	
	nodes.getElement
}

var ajax = new NAjax();

function setUp(){
	if(!(document.getElementsByTagName && document.getElementById)) 
		return;
	
	ajax.wireAjax();
	wireMenu();

}