editcontrolsIsDragging = false;

function ControlPair(div,control,parent, func) {
	this.div=div;
	this.control=control;
	this.parent=parent;
	this.func = func;
	this.blurCount = 0;
	this.editorVisible=false;
	this.width=300;
}


// regex to the rescue (simply replace \n with <br> fails because we also have \r)
String.prototype.htmlToAscii = function() {
	if (isIE()) {
		return this.replace(/<BR(| _extended=\"true\")>/g, '\n');
	}
	else
		return this.replace(/<br>/g,'\n'); 	// replace every <br> statement with a \newline
}

String.prototype.asciiToHTML = function() {
	if (isIE()) {
		return this.replace(/\n/g, "<BR _extended=\"true\">");	// replace every \n AND \r with a <br/>
	}
	else
		return this.replace(/(\n|\r)/g, "<br>");	// replace every \n OR \r with a <br/>
}

String.prototype.trim = function() {
	return this.replace(/^\s+/, '').replace(/\s+$/, '');
};

// add functionality to the select element
function getSelectedOption(selector) {
	return selector.options[selector.selectedIndex];
}

function getSelectorStrValue(selector) {
	return selector.options[selector.selectedIndex].label;
}

function setSelectorStrValue(selector, strval) {
	for(var i=0; selector.options.length; i++) {
		if (selector.options[i].label == strval) {
			selector.selectedIndex = i;
			return;
		}
	}	
}

var myControlMap = {}; // reset

function resetControlMap() { myControlMap = {}; }


function activateTextControl(id) {
	if(editcontrolsIsDragging == true) {
		editcontrolsIsDragging = false;
		return;
	}
}

function activateEditControl(id) {
	if(editcontrolsIsDragging == true) {
		editcontrolsIsDragging = false;
		return;
	}
	var pair = myControlMap[id];
	pair.editorVisible = true;
	
	// gcole: fix for text areas <br's>
	if(pair.control.type == 'textarea' ) {
		pair.control.value = pair.div.innerHTML.htmlToAscii();
	}
	else {
		pair.control.value = pair.div.innerHTML;
	}
	var width = pair.div.innerHTML.length*6;
//	alert("paid.width = " + pair.width);
	if(pair.width != null) {	
		width = pair.width;
	}
	
	if(pair.form == null) {
		pair.parent.replaceChild(pair.control, pair.div);
	}
	else {
		pair.parent.replaceChild(pair.form, pair.div);
	}
	pair.control.style.width=width+'px';
	if(pair.control.value=="&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;") {
		pair.control.value="     ";
	}
	pair.control.focus();
	pair.control.select();
}

function activateSelectorControl(id) {
	if(editcontrolsIsDragging == true) {
		editcontrolsIsDragging = false;
		return;
	}
	var pair = myControlMap[id];
	pair.editorVisible = true;
	setSelectorStrValue(pair.control, pair.div.innerHTML);

	pair.parent.replaceChild(pair.control, pair.div);
	pair.control.focus();
}


function addSelectorPair(id, pair) {
	myControlMap[id] = pair;
	pair.div.onclick = new Function("return activateSelectorControl('"+id+"');");
	pair.div.style.cursor="pointer";
	pair.div.setAttribute("idz", id);

	pair.control.onchange = new Function("return deactivateSelectorControl('"+id+"','change');");
	pair.control.onblur = new Function("return deactivateSelectorControl('"+id+"', 'blur');");
}


function addControlPair(id, pair) {
	myControlMap[id] = pair;
	pair.div.onclick = new Function("return activateEditControl('"+id+"');");
	pair.div.style.cursor="pointer";
	pair.control.onblur = new Function("return deactivateEditControl('"+id+"');");
	if(pair.form != null) {
		pair.form.onsubmit = new Function("return deactivateEditControl('"+id+"');");
	}
}

function deactivateSelectorControl(id, reason) {
	try {
		var pair = myControlMap[id];
		if(pair.editorVisible) {
			pair.editorVisible = false;
			if(reason == 'blur') {
				if(navigator.platform == "iPhone") {
					if(pair.blurCount == 0) {			
							pair.blurCount++;
						//	alert("skipping deactivation, count now set to " + this.blurCount);
						return;
					}
					else {
						pair.blurCount = 0;
						//	alert("blurCount reset, deactivating control");
					}
				}	
			}

			//var elOptOld = pair.control.options[pair.control.selectedIndex];  
			var elOptOld = getSelectorStrValue(pair.control);
			pair.parent.replaceChild(pair.div, pair.control);			
			var fValueChanged = (pair.div.innerHTML != elOptOld);
			// always do this, otherwise we see the wrong value
			pair.div.innerHTML = elOptOld;
			// gcole: this must be called AFTER you swap children, or it can lead to the control pair unable to function properly 
			if(fValueChanged) {
				/** Call the callback function */
				pair.func(pair);
			}
		}
	}
	catch (E) {
		alert("ERROR: deactivateSelectorControl: " + E);
	}
	return false;
}

function deactivateEditControl(id) {
	try {
		var pair = myControlMap[id];
		if(pair.editorVisible) {
			if(navigator.platform == "iPhone") {
				if(pair.blurCount == 0) {			
					pair.blurCount++;
				//	alert("skipping deactivation, count now set to " + this.blurCount);
					return;
				}
				else {
					pair.blurCount = 0;
				//	alert("blurCount reset, deactivating control");
				}
			}	

			pair.control.value = pair.control.value.asciiToHTML();
			if(pair.control.value=="") {
				pair.control.value="&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
			}
			
	       	if (document.selection)
	       	{
            	document.selection.empty();
	       	}
	       	else
	       	{
	           	window.getSelection().removeAllRanges();
	       	}
			pair.editorVisible = false;
			if(pair.form == null) {
				pair.parent.replaceChild(pair.div, pair.control);
			}
			else {
				pair.parent.replaceChild(pair.div, pair.form);
			}
			if(pair.div.innerHTML != pair.control.value) {
				pair.div.innerHTML = pair.control.value;
				/** Call the callback function */
				pair.func(pair);
			}
		}
	}
	catch (E) {
		alert("ERROR: deactivateEditControl: " + E);
	}
	return false;
}

function createHeaderRow(headings) {
	/** 
	 * Make our header row 
	 */
	var tr = document.createElement("tr");

	for(var i = 0; i< headings.length; i++){
		var dat = document.createElement("th");
		tr.appendChild(dat);
		dat.innerHTML = headings[i];	
		dat.className='projectHeader';
	}
	return tr;
}

/**
 * Helper method:  returns on selector option populated with the values requested
 */
function createOption(label, val, selected) {
	var opt = document.createElement('option');
	if(val == null) {
		val = label;
	}
	if(selected == null) {
		selected = false;
	}
	opt.value=val;
	opt.label=label;
	opt.text=label;
	opt.selected = selected;
	return opt;
}

function createSelector(parent, type, id, labels, index, callbackfunc, elementType, textControl, divText) {
	var elm = 'div';
	if(elementType != null) {
		elm = elementType;
	}	
	
	var temp = document.createElement(elm);
	if(divText != null) {
		temp.innerHTML = divText;
	}

	if(textControl == null) {
		var textControl = document.createElement('select');
		textControl.setAttribute("taskId", id);
		for(var key in labels){
		  	textControl.appendChild(createOption(labels[key], key, (index == key)));
			if(key == index) {
				temp.innerHTML= labels[key];
			}
		}
	}

	var controlPair = new ControlPair(temp, textControl, parent, callbackfunc);
	addSelectorPair(type+id, controlPair);
	parent.appendChild(temp);
	return controlPair;
}

function createEditableTextArea(parent, type, id, text, callbackfunc, width, rows) {
	var textControl = document.createElement('textArea');
	if (text == null) { text = "" }	// gcole: avoid any null pointer errors
	textControl.setAttribute("value", text.unescapeHTML());	// gcole: unescapeHTML gets rid of those <br>s
	textControl.setAttribute("taskId", id);
	var temp = document.createElement("div");
	temp.innerHTML= text;
	var controlPair = new ControlPair(temp, textControl,parent, callbackfunc);
	if(width != null) {
		controlPair.width = width;
	}
	if(rows != null) {
		controlPair.rows = rows;
	}

	addControlPair(type+id, controlPair);
	parent.appendChild(temp);	
	return controlPair;			
}

function createEditableInput(parent, type, id, text, callbackfunc, width, rows) {
	var form = document.createElement('form');
	var textControl = document.createElement('input');
	textControl.type="text";
	textControl.setAttribute("value", text);
	textControl.setAttribute("taskId", id);
	form.appendChild(textControl);
	var temp = document.createElement("div");
	temp.innerHTML= text;
	var controlPair = new ControlPair(temp, textControl,parent, callbackfunc);
	controlPair.form = form;
	if(width != null) {
		controlPair.width = width;
	}
	if(rows != null) {
		controlPair.rows = rows;
	}
	controlPair.control = textControl;
	addControlPair(type+id, controlPair);
	parent.appendChild(temp);	
	return controlPair;			
}
	
