/*****************************************
- Safire - 
An iPhone web app interface development framework developed for the RemindsYou application [ http://remindsyou.com ]
Based on Joe Hewitt's iUI --> [ http://code.google.com/p/iui/ ]
With additional code based on Sam Stephenson's prototype --> [ http://prototypejs.org ]

For more information visit [http://code.google.com/p/safire/]
Questions? visit [http://code.rememberthisguy.com/safire/]
****************************************/


/*switch to detect what type of link was clicked, uses the class attribute value*/
function clicker(){
	var linktype = this.className;
	var href = this.getAttribute('href');
	var newdiv = linktype == 'list-item' ? this.getAttribute('type') : 'none';
	var overlayid = linktype == 'overlay-link' ? this.getAttribute('type') : 'none';
	var number = linktype == 'append-entries' ? this.getAttribute('number') : 'none';
	var listid = linktype == 'append-entries' ? this.getAttribute('type') : 'none';
	
	
	switch(linktype){
		case 'tab':
			//replaces innerHTML of curdiv (stage) with the href's contents BECAUSE the first argument is 'inplace'
			var tabs = $$('tab');
			for(i = 0; i < tabs.length; i++){
				tabs[i].parentNode.setAttribute('id', 'none');
			}
			this.parentNode.setAttribute('id', 'selected');
			getPage('stage-replace', this);
	  	break;    
	
		case 'sub-nav':
			//replaces innerHTML of curdiv (stage-mat) with the href's contents BECAUSE the first argument is 'inplace'
			var tabs = $$('sub-nav');
			for(i = 0; i < tabs.length; i++){
				tabs[i].setAttribute('id', 'none');
			}
			this.setAttribute('id', 'selected');
			getPage('inplace', this);
	  	break;
	
		case 'list-item':
			//slides in a new div from the right BECAUSE the first argument is 'slidein'
			this.setAttribute('selected', 'progress');
			getPage('slidein', this);
	  	break;
	
		case 'icon':
			//slides in a new div based on the icon click...
			getPage('slidein', this);
  		break;
	
		case 'overlay-link':
			//shows an overlay based on the overlayid passed through //debugging --> alert(overlayid);
	  		getOverlay(overlayid);
	  	break;
	
		case 'append-entries':
			//pass through number of items to append, and the id of the list they are going to be appended too 
			appendItems(this);
	  	break;
	
		case 'submit-button':
	  		//pass through this element to move backwards through DOM for form element
			submitForm(this);
	  	break;
	
		case 'cancel-button':
	  		//pass through this element to move backwards through DOM for div element with overlay class
			closeOverlay(this);
	  	break;
	
		case 'back-button':
	  		//pass through this element to move backwards through DOM for div element with overlay class
			goBack(this);
	  	break;
	  	
	}
}


/********************************************
****Event Handling / Listening functions****
*******************************************/

/*onload detection, triggers loaded function*/
window.addEventListener("load", loaded, false);

/*executes linkevents + buttonevent functions and makes a fake page in history*/
function loaded(){
	linkevents();
	hideURLbar();
	//Next release of Safire will have back button functionality
	//pollHash();
}

/*loops through anchor tags and adds event listeners*/
function linkevents(){
	var links = document.getElementsByTagName("a");
	for(i=0; i < links.length; i++){
		links[i].addEventListener("click", clicker, false);
	}
}

//End of Event Handling / Listening functions




/********************************************
***Animation Functions [Needs Improvement]**
*******************************************/

/*Needs three arguments, id (of the new div to be created), the old id & milliseconds (ms) */ 
function slide(id, oldid, ms){
	ms = typeof(ms) != 'undefined' ? ms : 25;
	$(oldid).style.position = 'absolute';
	if(slideInterval > 0){
		setTimeout(slideinfromRight, ms, id, oldid);
		setTimeout(slide, ms*2, id, oldid);
	}
	if(slideInterval == 0){
		$(id).setAttribute('class', 'stage-mat');
		$(id).style.left = "0%";
		$(oldid).setAttribute('class', 'stage-mat-left');
	}
}

function slideinfromRight(id, oldid){
	$(oldid).style.left = "-" + p + "%";
	$(id).removeAttribute('selected');
	--slideInterval;
	p = p + pc;
}

//End of Animation Functions [Needs Improvement]




/**************************************************************
***AJAX Functions called from switch within clicker function**
**************************************************************/

/*AJAX function to APPEND new list items (should only return fragmented list items (<li>The Heat Win</li>)) */
function appendItems(link){
	link.innerHTML = "Loading...";
	var href = link.getAttribute('href').split("#");
	var url = href[1]; 
	var number = link.getAttribute('number');
	var listid = link.getAttribute('type');
	var ajax = new XMLHttpRequest();
	
	ajax.onerror = function()
    {
        if (cb)
            cb(false);
    };

	ajax.onreadystatechange = function()
    {
        if (ajax.readyState == 4)
        {
            if (listid){
					$(listid).removeChild(link.parentNode);
            		$(listid).innerHTML += ajax.responseText;
					loaded();
               	}
            else
            {
				alert('Error: No ul id specified as type attribute came from appendItems on line 167');
            }
        }
    };

	ajax.open("GET", url, true);
    ajax.send(null);
	
}

/*simple page getter, requires a display method & an anchor with # */
function getPage(displaymethod, anchor){
	var href = anchor.getAttribute('href').split("#");
	var url = href[1];
	var title = anchor.innerHTML;
	var divid = anchor.getAttribute('type');
	var ajax = new XMLHttpRequest();
	
	if(displaymethod == 'inplace' || displaymethod == 'stage-replace'){
		$$('stage-mat')[0].innerHTML = "<img src='images/loading.gif' class='loading' />";
	}
	
	ajax.onerror = function()
    {
        alert('Error: Ajax function getPage on line 191.');
    };

	ajax.onreadystatechange = function()
    {
        if (ajax.readyState == 4)
        {
            if(displaymethod == 'inplace'){
				$$('stage-mat')[0].innerHTML = ajax.responseText;
			} else if(displaymethod == 'stage-replace'){
				$('stage').innerHTML = ajax.responseText;
			} else if(displaymethod == 'slidein'){
				//setting up the new div
				newdiv = document.createElement('div');
				newdiv.setAttribute('id', divid);
				newdiv.setAttribute('class', 'stage-mat-right');
				newdiv.innerHTML = ajax.responseText;
				//getting the old divs id
				olddivid = findStage(anchor);
				//setting the anchor to not be selected
				anchor.removeAttribute('selected');
				//appending the new div
				$('stage').appendChild(newdiv);
				//sliding the new div and setting the slide interval
				slideInterval = 4;
				p = 25;
				pc = p;
				slide(divid, olddivid);
			} else {
				alert('Error: No ul id specified as type attribute in getPage on line 220');
			}
			loaded();
        }
    };

	ajax.open("GET", url, true);
    ajax.send(null);
	
}

/*a href element must be passed to this function along with form values retrieved using encodeform*/
function ajaxForm(child, values){
	var href = child.getAttribute('href').split('#');
	var url = href[1];
	var cb = child.getAttribute('callback');
	var m = getFormMethod(child);
	method = typeof(m) != 'undefined' ? m : 'GET';
	callback = typeof(cb) != 'undefined' ? cb : "closeOverlay(child);";
	var ajax = new XMLHttpRequest();
	
	ajax.onerror = function()
    {
        alert('Error: Ajax function ajaxForm on line 243.');
    };

	ajax.onreadystatechange = function()
    {
        if (ajax.readyState == 4)
        {
            if (cb){
				var response = ajax.responseXML ? ajax.responseXML : ajax.responseText;
				eval(callback);
				loaded();
               	}
            else {
				alert('Error: No callback specified anywhere? came from ajaxForm on line 256');
            }
        }
    };
	
	
	ajax.open(method, url, true);
    ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    ajax.setRequestHeader("Content-Length", values.length);
    ajax.send(values.join("&"));
}

//End of AJAX Functions called from switch within clicker function




/******************************************
***Functions used in correlation to forms**
******************************************/

/*Recursive function to get to the form element and then uses "encodeForm()" to loop through inputs + selects and return vals*/
function submitForm(child){
	var vals = getFormVals(child);
	ajaxForm(child, vals);
}

function getFormVals(child){
	node = child;
	if(node.localName.toLowerCase() == 'form'){
		formvals = encodeForm(node);
	}else{
		node = node.parentNode;
		getFormVals(node);
	}
	return formvals;
}


function getFormMethod(child){
	node = child;
	if(node.localName.toLowerCase() == 'form'){
	 	method = node.getAttribute('method');
	}else{
		node = node.parentNode;
		getFormMethod(node);
	}
	return method;
}

//End of Functions used in correlation to forms



/***********************************************************************************
***Overlay related functions [called from the switch within the clicker function]***
***********************************************************************************/

/*Simple function that takes an id argument and show's an overlay*/
function getOverlay(byid){
	$(byid).style.display = 'block';
}


/*Recursive function to close an overlay that was opened!*/
function closeOverlay(child){
	el = child;
	if(el.localName.toLowerCase() == 'div' && el.className == 'overlay'){
		el.style.display = 'none';
	} else {
		el = el.parentNode;
		closeOverlay(el);
	}
}

//End of Overlay related functions [called from the switch within the clicker function]




/****************************
***Miscellaneous Functions**
***************************/

/*Recursive function to get to the stage mat element and return it*/
function findStage(anchor){
	el = anchor;
	if(el.localName.toLowerCase() == 'div' && el.className == 'stage-mat'){
		divid = el.getAttribute('id');
	} else {
		el = el.parentNode;
		findStage(el);
	}
	return divid;
}

/*random function */
function rand( min, max ) {
    if( max ) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    } else {
        return Math.floor(Math.random() * (min + 1));
    }
}

//End of Miscellaneous Functions




/*************************************************
***Code borrowed or based off other peoples code**
*************************************************/


/*Taken from iUI, Thanks Joe Hewitt! Needs a form object passed into this function*/
function encodeForm(form)
{
    function encode(inputs)
    {
        for (var i = 0; i < inputs.length; ++i)
        {
            if (inputs[i].name)
                args.push(inputs[i].name + "=" + escape(inputs[i].value));
        }
    }

    var args = [];
    encode(form.getElementsByTagName("input"));
    encode(form.getElementsByTagName("textarea"));
	encode(form.getElementsByTagName("select"));
    return args;    
}


/*Taken from prototype, Thanks Sam Stephenson! Needs at least a classname passed into this function */
function $$(classname){ return document.getElementsByClassName(classname); }

/*Stolen from iPhoneWebDev, Thanks iPhone Web Dev Team! Used onload to hide the menu bar */
function hideURLbar() { window.scrollTo(0, 1); }

/*Based off protoype function. Thanks again Sam Stephenson! Needs an id passed into this function*/
function $(id) { return document.getElementById(id); }
