//
// Master Javascript File
// All Basic functions...

//
// debugObjToStr - returns: string of Object properties formated for alert box
// debugObjToUL - returns: string of Object properties formated for UL
//
//
// toggleObj(String objectName)
// setObjectDisplay(Object object, boolean state)
// showObj(String objectName)
// hideObj(String objectName) - display:none - also takes array of objects
// 
// debugObj(Object object)
// breakOut(Object object)
//
// getCheckedValue(Object object)
// setCheckedValue(Object object)
//
// dateDiff(Date start, Date end)
// dateBreak(Date diff)


/*
ideas:
=======
drag n drop
minimise / maximise
attach top / bottom


*/

/********* Basics *********************************/

function $(objName){
	return document.getElementById(objName);
}

function set(name,value){$(name).innerHTML = value;}

function timestamp(){return (new Date()).valueOf();}

function checkEvent(e){return (!e)? window.event:e;}

/***** set object display ************************/

function toggle(objName){
	obj = document.getElementById(objName);	
	obj.style.display = (obj.style.display == 'none' || obj.style.display == '')?"block":"none";
}

//set display for object based on boolean state (true=displayed)
//
function setObjDisplay(obj,state){
	if(state){
		obj.style.display = "block";
	}else{
		obj.style.display = "none";
	}
}

function showObj(objName){
	obj = document.getElementById(objName);	
	setObjDisplay(obj,true);
}

function hideObj(objName){
	obj = document.getElementById(objName);	
	setObjDisplay(obj,false);
}




/***** obj debugging ************************/

function debugObj(obj){
    	var str = breakOut(obj);
        document.getElementById("debug").innerHTML += "<hr>" + str + "<br>";
}

function breakOut(obj){
	var str = "<ul>";
	for(prop in obj){
		str += "<li>" + prop + ":";
		if(typeof obj[prop] == "object"){
			str += breakOut(obj[prop]);
		}else{
			str += obj[prop];
		}
	}
	str += "</li></ul>";
	return str;
}


/******* RadioButtons get and set *************************************/

// return the value of the radio button that is checked
// return an empty string if none are checked, or
// there are no radio buttons
function getCheckedValue(radioObj) {
	if(!radioObj)
		return "";
	var radioLength = radioObj.length;
	if(radioLength == undefined)
		if(radioObj.checked)
			return radioObj.value;
		else
			return "";
	for(var i = 0; i < radioLength; i++) {
		if(radioObj[i].checked) {
			return radioObj[i].value;
		}
	}
	return "";
}

// set the radio button with the given value as being checked
// do nothing if there are no radio buttons
// if the given value does not exist, all the radio buttons
// are reset to unchecked
function setCheckedValue(radioObj, newValue) {
	if(!radioObj)
		return;
	var radioLength = radioObj.length;
	if(radioLength == undefined) {
		radioObj.checked = (radioObj.value == newValue.toString());
		return;
	}
	for(var i = 0; i < radioLength; i++) {
		radioObj[i].checked = false;
		if(radioObj[i].value == newValue.toString()) {
			radioObj[i].checked = true;
		}
	}
}

function setRadioStyle(radioObj, styleObj){
	if(!radioObj)
		return;
	var radioLength = radioObj.length;
	console.log("Found ["+radioLength+"] objects");
	if(radioLength == undefined) {
		applyStyle(radioObj,styleObj);
		return;
	}
	for(var i = 0; i < radioLength; i++) {
		applyStyle(radioObj[i],styleObj);
	}
}

function applyStyle(el, styleObj){
	pushobjectProperties(styleObj,el.style,true)
}

function pushobjectProperties(donor,recipient,b_force){
	for (prop in donor) {
        console.log(" writing property: " + [prop,typeof(donor[prop]),donor[prop]]);
		if(recipient[prop] == null  || b_force){
			recipient[prop] = donor[prop];
			console.log("overwriting " + prop + " " + recipient[prop]);
		}else{
			console.log("Already exists " + prop + " = " + recipient[prop]);
		}
    }	
}


/******* date functions *************************/
    var    one_millisec    = 1;
    var    one_second      = one_millisec * 1000;
    var    one_minute      = one_second * 60;
    var    one_hour        = one_minute * 60;
    var    one_day         = one_hour * 24;
    var    one_week        = one_day * 7;
    var    one_year        = one_week * 52;
	
	function dateDiff(start, end){
		return dateBreak(end - start);
	}
	
    //use modulus to break date into parts
    function dateBreak(diff){
        rObj = new Object();
        rObj.years          = Math.floor(diff/one_year);
        diff = diff % one_year;
        rObj.weeks          = Math.floor(diff/one_week);
        diff = diff % one_week;
        rObj.days           = Math.floor(diff/one_day);
        diff = diff % one_day;
        rObj.hours          = Math.floor(diff/one_hour);
        diff = diff % one_hour;
        rObj.minutes        = Math.floor(diff/one_minute);
        diff = diff % one_minute;
        rObj.seconds        = Math.floor(diff/one_second);
        diff = diff % one_second;
        rObj.milliseconds   = Math.floor(diff/one_millisec);
        return rObj;
    }
	
//########## FAKE IE7 PROMPT ##################################

	function promptCheck(str,def){
		try{
			if(window.showModalDialog){
				iePrompt(str,def);
			}else{
				return prompt(str,def);
			}
		}catch(e){
			alert("Error loading prompt " + e.message);
			return def;
		}
	}
	
	function iePrompt(str,def){
		var settings = "dialogWidth: 290px; dialogHeight: 160px; center: yes; edge: raised; scroll: no; status: no;";
		return window.showModalDialog("iePrompt.html", str, settings);
	}

	//###########################################

	//
	// Get the page position of an Element
	//
	function getObjPos(obj){
		var pos = {
			x: obj.offsetLeft || 0,
			y: obj.offsetTop || 0
		};
		while (obj = obj.offsetParent) {
			pos.x += obj.offsetLeft || 0;
			pos.y += obj.offsetTop || 0;
		}
		return pos;
	}

//########### SELECT FUNCTIONS #########################################
		
	
	/**
	 * 
	 * @param {Object} el SELECT Element to check
	 * @param {Object} badReturnValue Value to return if BAD
	 * @return {Object} either the value of the option, or FALSE/Null depending on badReturnValue
	 */
	function checkSelectedValue(el,returnFalse){
		var returnValue = (returnFalse)?false:null;
		if(!el){return returnValue;}
		el.style.backgroundColor = "yellow";
		var v = el.options[el.selectedIndex].value.toUpperCase();
		var t = el.options[el.selectedIndex].text.toUpperCase();
		//default to good
		el.style.backgroundColor = "GREEN";
		//check for bad
		var bad = ['OTHER','DIVIDER','DEFAULT'];
		for(var i  = 0; i<bad.length; i++){
			if((v == bad[i]) || (v == '' && t == bad[i])){
				el.style.backgroundColor = "RED";
				//alert("value["+v+"] or text["+t+"] = " + bad[i]);
				return returnValue;
			}
		}
		var ret = v || t;
		return ret;
	}
	
	function makeSelectEditable(el, modal){
		modal = modal || false;
		//create text box to put replace it
		var i = document.createElement("input");
		var focusOnEdit = function(){i.focus();}
		// FIX WIDTH ERROR
		i.style.width = el.clientWidth;
		i.tabIndex = el.tabIndex;
		// FIX RETURN KEY ERROR, ie: stop form submitting (fails on Opera)
		i.onkeypress=function(event) {
			event=checkEvent(event);
			key = (window.event)?event.keyCode:event.which;
			//alert("detected " + key);
			//console.log(key);
			if (key==13) {
				i.blur();
				//alert("return detected");
				return false;
			}
		}
		i.onblur = function(){
			var txt = i.value;
			var val = txt;
			if(txt == '' && modal){
				alert("Please enter a value");
				i.style.backgroundColor = "RED";
				setTimeout(focusOnEdit,1);
				return;
			}
			i.parentNode.replaceChild(el,i);
			var opt = new Option(txt, val, false, true);
			el.options[el.options.length] = opt;
			el.selectedIndex = el.options.length - 1;
			el.onchange();
			el.focus();
			return false;
		}
		el.parentNode.replaceChild(i,el);
		setTimeout(focusOnEdit,1);
		return i;
	}
	
	// uses makeEditable
	function addoption2(el){
		var v = el.options[el.selectedIndex].value;
		var t = el.options[el.selectedIndex].text;
		if (v.toUpperCase() == 'OTHER' || (v=='' && t.toUpperCase() == 'OTHER')) {
			// find location of el
			makeSelectEditable(el,true);
			//return false;
		}
	}
	
	//uses prompt box
	function addoption(el){
		var v = el.options[el.selectedIndex].value;
		var t = el.options[el.selectedIndex].text;
		if (v.toUpperCase() == 'OTHER' || (v=='' && t.toUpperCase() == 'OTHER')) {
			var addMe = "Add me!";
			//var txt = promptCheck('Please enter the New Option:', addMe);
			var txt = Prompt.show("Please enter the New Option:", addMe, 'Silly question dialog');
			if (txt == null || txt == addMe) {
				return;
			}
			var val = txt
			var opt = new Option(txt, val, false, true);
			el.options[el.options.length] = opt;
		}
	}
	
	// modify select box, adds addOption behavior
	function addAddOptionToSelect(el){
		var fOLD = el.onchange || function(){};
		var f = function(){
			fOLD();
			addoption(el);
		};
		el.onchange = f;
	}

	function checkForSelect(node){
		if(node.tagName === 'SELECT'){
			addAddOptionToSelect(node);
		}
	}
//########################################################################
//
// DOUGLAS CROCKFORDS ALGORYTHM
// pass function that can be called by func(node)
function walkTheDOM(node, func) {
    func(node); 
    node = node.firstChild; 
    while (node) { 
        walkTheDOM(node, func); 
        node = node.nextSibling; 
    } 
} 

function def(first,second){
	var fnfirst = (typeof first === 'function')?true:false;
	var object = (fnfirst)?this:first;
	var fn = (fnfirst)?first:second;
	var ind = (fnfirst)?1:2;
	// convert arguments into a real ARRAY
	var args = Array.prototype.slice.apply(arguments, [ind]); 
	return function(){
		// => object.func(args)
		fn.apply(object,args);
	};
}
	
	// call func for each array element === arrayWalk function
	function foreach(arr,func){
		for(var i=0;i < arr.length; i ++){
			alert("looping");
			func(arr[i]);
		}
	}
	
	
