//WARNING:  This work is the property of Derek Roth, and May Not Be Used Without His Consent.
//NB:  for positioning of cursor, parent element must have "position: relative" style...
//Riel Specific
var sUser           = "";		//UserName
var sPass           = "";		//Password
var sPage           = "";		//The results page (region/site/event/routes/packages)
var bShowHidden     = true;		//Flag for showing the hidden edit option div
var bIsNew          = false;		//Whether user selected to make new record
var sSelectedType   = "";		//The sitetype selected by dropdown list
var sSelectedRegion = "";		//The sitetype selected by dropdown list
var iSiteX;				//Clicked position on map for new sites
var iSiteY;
var sCurrentRegion = "";		//current region
var sEventYear;				//DD list for date
var sEventMonth;
var sEventDay;
var sRecordCode = "";

////General Editing:
var eChar = null;
var eKeyPressed = null;
var oCursor;				//The Cursor obj for editing
var oFocused;				//The span/element which has the cursor focus
var oParent = null;			//The parent element ("field1.2.3.4....")
var oMouseDown;				//The span/element where the mousedown event happened
var oMouseUp;				//The span/element where the mouseup event happened
var iSpanIndex;				//the indexed position of the charcter node
var bCursorAtEnd   = false;	//Flags for whether cursor shows at end of focused element, or beginning
var bCursorAtStart = false;
/////////////////////////////////////////////////////////////////////////////////////////////////////
var sDeleteConfirmEn = "Are You Sure You Want Delete This Entry? It will be permanently removed in both English and French";
var sDeleteConfirmFr = "Es-tu certain de vouloir supprimer cette entree ? \nLa suppression est permanente pour le site francais et le site anglais.";
var sDelPicConfirmEn = "Are You Sure You Want Delete This Entry? It will be permanently removed.";
var sDelPicConfirmFr = "Es-tu certain de vouloir supprimer cette entrée ? \nLa suppression est permanente.";
var sUsernameEn        = "Please Enter Your Username";
var sUsernameFr        = "Entrez votre nom d'utilisateur.";
var sPasswordEn        = "Please Enter Your Password";
var sPasswordFr        = "Entrez votre mot de passe.";
var sMapZoomWarningEn  = "Please zoom out on the map before selecting a location";
var sMapZoomWarningFr  = "Please zoom out on the map before selecting a location";
var sSelectSiteTypeEn  = "You must select a site type to submit a new record";
var sSelectSiteTypeFr  = "Vous devez choisir le type de site afin de creer une nouvelle entree.";
var sSiteNeedsCoordsEn = "No coordinates were entered for this site! Continue?";
var sSiteNeedsCoordsFr = "Vous n'avez pas inscrit de coordonnees pour ce site. Voulez-vous continuer ??";
var sNeedRegionEn      = "A region must be selected for new records!";
var sNeedRegionFr      = "Vous devez choisir la region du site afin de creer une nouvelle entree.";
/////////////////////////////////////////////////////////////////////////////////////////////////////
var sUpdateGoodEn      = "The update was successful.\nWould you like to alter it in the other language now?";
var sUpdateGoodFr      = "La mise a jour est faite. \nSouhaitez-vous mettre a jour l'entree equivalente dans l'autre langue ?";
var sUpdateBadEn       = "A problem occurred on the Server.  The update may not have been successful.";
var sUpdateBadFr       = "Le serveur a genere une erreur. Votre ajout de donnees ne s'est peut-etre pas fait avec succes.";
var sAddGoodEn         = "The addition was successful.\nWould you like to alter it in the other language now?";
var sAddGoodFr         = "L'addition est faite. \nSouhaitez-vous mettre à jour l'entree equivalente dans l'autre langue ?";
var sAddBadEn          = "A problem occurred on the Server.  The addition may not have been successful.";
var sAddBadFr          = "Le serveur a genere une erreur. Votre ajout de donnees ne s'est peut-etre pas fait avec succes.";
var sDelGoodEn         = "The deletion was successful.";
var sDelGoodFr         = "La suppression de donnees s'est fait avec succes.";
var sDelBadEn          = "A problem occurred on the Server.  The deletion may not have been successful.";
var sDelBadFr          = "Le serveur a genere une erreur. Votre suppression de donnees ne s'est peut-etre pas fait avec succes.";
var sDelConfirmEn      = "Are you sure you want to remove this record?\nIt will be permanently removed in both French and English!";
var sDelConfirmFr      = "Es-tu certain de vouloir supprimer cette entree ? \nLa suppression est permanente pour le site francais et le site anglais.";
var sEventDateEn       = "You must select a date from the dropdown list in order to add a new event!";
var sEventDateFr       = "You must select a date from the dropdown list in order to add a new event!";
var sNeedRegionEn      = "You must select a region from the dropdown list in order to add a new record!";
var sNeedRegionFr      = "You must select a region from the dropdown list in order to add a new record!";
/////////////////////////////////////////////////////////////////////////////////////////////////////
/* The following functions are general functions used by the editing environ:
login			---- called by onload evt, calls login.asp to validate [which then calls setup in joie_general.js]
showHiddenFields	---- shows 'field##' elems that have no content, and inserts '__' into them
clearForNew		---- clears field values of all elements named "field##' 
addDropdownToDiv 	---- called by getSiteTypesDD.asp to populate sitetypes Dropdown
makeDOMTo String	---- returns 'field##' elems back in form not granulated with spans
makeStyledText		---- adds italic/bold/underline styles to selected text */
/////////////////////////////////////////////////////////////////////////////////////////////////////

function login(lng) {
	sLang = lng;
	if ((sUser == "" && sPass == "") || !bLogin) {
		sUser = (sLang == "en") ? prompt(sUsernameEn) : prompt(sUsernameFr);
		sPass = (sLang == "en") ? prompt(sPasswordEn) : prompt(sPasswordFr);
		str   = "./login.asp?user=" + sUser + "&pass=" + sPass + "&lang=" + sLang;
		loadPage(str);
	}
}
function showHiddenFields() {	
	if (!bLogin) return;
	i = 1;
	if (bShowHidden) {
		while (getElem("field" + i)) {
			if (sPage =="sitelist") {
				if (getElem("field" + i).parentNode.style.display == "none"  && i < 5) {
					getElem("field" + i).parentNode.style.display = "";
					getElem("field" + i).innerHTML                = "<span>_<\/span><span>_<\/span>"
				}
			}
			else if (getElem("field" + i).parentNode.style.display == "none"  && i < 48 && sPage == "site") {
				getElem("field" + i).parentNode.style.display = "";
				getElem("field" + i).innerHTML                = "<span>_<\/span><span>_<\/span>"
			}
			else if (!getElem("field" + i).hasChildNodes() && (sPage == "events" || sPage == "packages" 					|| sPage == "links"))
				getElem("field" + i).innerHTML      = "<span>_<\/span><span>_<\/span>"
			i++;
		}
		bShowHidden = false;
	}
	else {
		while (document.getElementById("field" + i) && i < 48) {
			if (getElem("field" + i).innerHTML == "<span>_<\/span><span>_<\/span>") {
				getElem("field" + i).innerHTML = "";
				getElem("field" + i).parentNode.style.display = "none";
			}
			i++;
		}
		bShowHidden = true;
	}
}
function clearForNew() {
	if (!bLogin) return;
	if (sPage == "region") return;
	sLangTemp = "";
	i = 1;
	while (getElem("field" + i)){
		getElem("field" + i).innerHTML                = "";
		getElem("field" + i).parentNode.style.display = "none";
		i++;
     	}
     	sSelectedType = "";
     	bShowHidden   = true;
     	bIsNew        = true;
     	iSiteX        = "";
     	iSiteY        = "";
     	showHiddenFields();
     	if (sPage == "site") {
        	getElem("xmlFrame4").src = "./getSiteTypesDD.asp?lang=" + sLang;
	}
	else if (sPage == "packages" || sPage == "events" || sPage == "links") {
		iTemp = 2;
		while(getElem("record" + iTemp)) {
			getElem("record" + iTemp).innerHTML = ""; //style.display = "none";
			getElem("record" + iTemp).parentNode.removeChild(getElem("record" + iTemp));
			iTemp++;
          	}
		getElem("record1").style.display = "";
		iTemp = 1;
		while (getElem("field" + iTemp)) {
			getElem("field" + iTemp).parentNode.style.display = "";
			iTemp++;
		}
//		alert(getElem("record1").innerHTML);
		setDivVisible(sDivName);
     	}
	getElem("rm_site").style.display = "none";
}
function addDropdownToDiv(sHTML, sId) {
	getElem(sId).innerHTML = sHTML;
	getElem(sId).style.display = "";
}
function makeDOMToString(obj) {
	str = obj.innerHTML;
	str = str.replace(/<b><\/b>/g, "");
	str = str.replace(/<span>/g, "");
	str = str.replace(/<\/span>/g, "");
	str = str.replace(/<B><\/B>/g, "");
	str = str.replace(/<SPAN>/g, "");
	str = str.replace(/<\/SPAN>/g, "");
	str = str.replace(/\"/g, "''");	
	str = str.replace(/<span style=''display: inline;''>/g, "");
	return str;
}
function setLang(str) { sLangTemp = str; }
function makeStyledText(sType) {
	if (oMouseDown != null && oMouseUp != null && oMouseDown.parentNode == oMouseUp.parentNode) {
		elem   = document.createElement(sType);
		iStart = -1;
		iEnd   = -1;
		oPar   = oMouseDown.parentNode;
//Get the start and end character positions
		for (i = 0; i < oPar.getElementsByTagName("span").length; i++)	{
			if (oPar.getElementsByTagName("span")[i] == oMouseDown)
				iStart = i;
			if (oPar.getElementsByTagName("span")[i] == oMouseUp)
				iEnd = i;
		}
		if (iStart > iEnd) {
			iTemp  = iStart;
			iStart = iEnd;
			iEnd   = iTemp;
		}
		oMouseDown = oPar.getElementsByTagName("span")[iStart];
		oMouseUp   = oPar.getElementsByTagName("span")[iEnd];
//Do this to remove formatting:
//Find if the tag already exists as a parent:
		if (oPar.tagName.toUpperCase() == sType.toUpperCase()) {
			var arrHead   = new Array();
			var arrSelect = new Array();
			var arrFoot   = new Array();
//Get any nodes before the start of selection:
			oTemp = oPar.firstChild;
			while (oTemp != oMouseDown) {
				oTemp2 = oTemp.nextSibling;
				arrHead.push(oTemp);
				oTemp = oTemp2;
			}
//get Selected nodes:
			while (oTemp != oMouseUp) {
				oTemp      = oMouseDown;
				oMouseDown = oMouseDown.nextSibling;
				arrSelect.push(oTemp);
			} 
//Get any nodes after selection:			
			if (oMouseUp != oPar.lastChild) {
				oTemp = oMouseUp.nextSibling;
				while (oTemp != oPar.lastChild) {
					oTemp2 = oTemp.nextSibling;
					arrFoot.push(oTemp);
					oTemp = oTemp2;
				}
			}
//Add header/selected text/ and footer to DOM
			oHead = document.createElement(sType);
			for (i = 0; i < arrHead.length; i++)
				oHead.appendChild(arrHead[i]);
			oFoot = document.createElement(sType);
			for (i = 0; i < arrFoot.length; i++)
				oFoot.appendChild(arrFoot[i]);
			if (oHead.hasChildNodes())
				oPar.parentNode.insertBefore(oHead,oPar);
			for (i = 0; i < arrSelect.length; i++)
				oPar.parentNode.insertBefore(arrSelect[i], oPar);
			if (oFoot.hasChildNodes())
				oPar.parentNode.insertBefore(oFoot, oPar);
			oPar.parentNode.removeChild(oPar);
		}
//Do this to add formatting:
		else {
			do {
				oTemp      = oMouseDown;
				oMouseDown = oMouseDown.nextSibling;
				elem.appendChild(oTemp);
			} while (oTemp != oMouseUp)
			oPar.insertBefore(elem, oMouseDown);
		}
	}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
/* Map functions:
setMapCrosshairs	---- onOver event handler for map to make cursor "crosshairs"
setLocation		---- captures mouse click position on map and sets glob vars for site/town x,y pos*/
/////////////////////////////////////////////////////////////////////////////////////////////////////
function setMapCrosshairs(e) {	getElem("map").style.cursor = "crosshair"; }
function setLocation(e) {
	if (sPage != "site" && sPage != "sitelist") return;
	if (window.event)
		e = window.event;
	if (isMapZoomed) {
		(sLang == "en") ? alert(sMapZoomWarningEn) : alert(sMapZoomWarningFr);
		return;
	}
	iX     = parseInt(e.clientX);
	iY     = parseInt(e.clientY);
	iLeft  = parseInt(getElem("map").offsetLeft);
	iTop   = parseInt(getElem("map").offsetTop);
	if (window.pageXOffset) {
		iXScroll = parseInt(window.pageXOffset);
		iYScroll = parseInt(window.pageYOffset);
	}
	if (document.body) {
		iXScroll = parseInt(document.body.scrollLeft);
		iYScroll = parseInt(document.body.scrollTop);
	}	
	iSiteX = (iX - iLeft) + Math.abs(parseInt(getElem("map_container").offsetLeft)) + iXScroll;
	iSiteY = (iY - iTop)  +  Math.abs(parseInt(getElem("map_container").offsetTop)) + iYScroll;
//Set Icon in click location and remove other points::
	o = getElem("map_container");
	if (o.getElementsByTagName("div")) {
		while(o.getElementsByTagName("div").length > 0)
			o.removeChild(o.getElementsByTagName("div")[0]);
	}
	oDiv = document.createElement("div");
	oDiv.setAttribute("style", "position: absolute; left: " + (iSiteX - 12) + "px; top: " + (iSiteY - 12) + "px;");

	oImg = document.createElement("img");
	oImg.src = "./riel_img/star.gif";
	oImg.setAttribute("style", "width: 24px; height: 24px;");
	oDiv.appendChild(oImg);
	o.appendChild(oDiv);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
/* The Following functions are used directly for updating/deleting/adding records or adding images:
uploadImg		---- calls uploadImage.asp to upload town/site images
delComplete		---- called from delete.asp to notify completed delete
updateComplete		---- called from update.asp to notify completed update & prompt for lang switch
addComplete		---- called from add.asp to notify completed add & prompt for lang switch
deleteRecord		---- calls delete.asp to delete record
submitChanges		---- calls add.asp or update.asp to add or update record*/
/////////////////////////////////////////////////////////////////////////////////////////////////////
function delPic(sFile) {
	if (bLogin) {
		bVal = (sLang == "fr") ? confirm(sDelPicConfirmFr) : confirm(sDelPicConfirmEn);
		if (bVal)
			loadPage("./deletePic.asp?user=" + sUser + "&pass=" + sPass + "&file=" + sFile);
	}
}
function uploadImg() {
	frm = getElem("imgFrame").contentWindow.document.getElementsByTagName("form")[0];
	if (sPage != "site" && sPage != "packages") return;
	if (sPage == "packages") {
		if (frm.elements[6].value == "")
			return;
		else
			frm.elements[0].value = frm.elements[6].options[frm.elements[6].selectedIndex].value;
	}
	else if (sPage == "site") {
		if (sRecordCode == "") return;
		frm.elements[0].value = sRecordCode;
	}
	frm.elements[1].value = sPage;
	frm.elements[2].value = sUser;
	frm.elements[3].value = sPass;
	frm.elements[5].value = sLang;
	getElem("imgFrame").contentWindow.document.getElementsByTagName("form")[0].focus();	
	frm.submit();
}
function picDelComplete(iSuccess, sFile) {
	if (iSuccess) 
		(sLang == "fr") ? alert(sDelGoodFr) : alert(sDelGoodEn);
	else
		(sLang == "fr") ? alert(sDelBadFr) : alert(sDelBadEn);
	pos = -1;
	sFile = sFile.substr(sFile.lastIndexOf("/"));
	arr = document.getElementsByTagName("img");
	for (i=0; i < arr.length; i++) {
		if (arr[i].src.indexOf(sFile) > 0) 
			pos = i;
	}
	arr[pos].parentNode.parentNode.innerHTML = "";
}
function delComplete(iSuccess) {
	if (iSuccess != 1)
		(sLang == "en") ? alert(sDelBadEn) : alert(sDelBadFr);
	else
		(sLang == "en") ? alert(sDelGoodEn) : alert(sDelGoodFr);
}		
function updateComplete(iSuccess, sLng, sTbl, sCode) {
	if (iSuccess != 1) {
		(sLang == "en") ? alert(sUpdateBadEn) : alert(sUpdateBadFr);
		return;
	}
	else {
		bTemp = (sLang == "en") ? confirm(sUpdateGoodEn) : confirm(sUpdateGoodFr);
		if (bTemp) {
			sLangTemp = (sLng == "en") ? "fr" : "en";
			if (sTbl == "site") 
				loadPage("./getSite.asp?lang=" + sLangTemp + "&site=" + sCode);
			else if (sTbl == "town") {
			     if (getElem("rielAll"))
			            sCode = "all";
				loadPage("./getRegion.asp?lang=" + sLangTemp + "&region=" + sCode);
			}
			else if (sTbl == "packages") 
				loadPage("./getPackages.asp?lang=" + sLangTemp);
			else if (sTbl == "events") 
				loadPage("./getEvents.asp?lang=" + sLangTemp);
			else if (sTbl == "links") 
				loadPage("./getLinks.asp?lang=" + sLangTemp);
		}
	}
}
function addComplete(iSuccess, sLng, sTbl, sCode) {
	if (iSuccess != 1)
		(sLang == "en") ? alert(sAddBadEn) : alert(sAddBadFr);
	else {
		bTemp = (sLang == "en") ? confirm(sAddGoodEn) : confirm(sAddGoodFr);
		if (bTemp) {
			sLangTemp = (sLng == "en") ? "fr" : "en";
			if (sTbl == "site") 
				loadPage("./getSite.asp?lang=" + sLangTemp + "&site=" + sCode);
			else if (sTbl == "events")
				loadPage("./getEvents.asp?lang=" + sLangTemp + "&code=" + sCode);
			else if (sTbl == "packages")
				loadPage("./getPackages.asp?lang=" + sLangTemp + "&code=" + sCode);
			else if (sTbl == "links")
				loadPage("./getLinks.asp?lang=" + sLangTemp + "&code=" + sCode);
			else if (sTbl == "town") {
				if (getElem("rielAll"))
			            sCode = "all";
				loadPage("./getRegion.asp?lang=" + sLangTemp + "&region=" + sCode);
			}
		}
	}
}
function deleteRecord(sTbl, sId, rec) {
	if (!bLogin) return;
	if (bIsNew) 
		clearForNew();
	else {
		if ( ((sLang == "en") ? confirm(sDelConfirmEn) : confirm(sDelConfirmFr))   ) {
                	if (sPage == "site")
                       		loadPage("./delete.asp?table="+sTbl+"&code="+sRecordCode+"&user="+sUser+"&pass=" + sPass);
			if (sPage == "events" || sPage =="packages" || sPage=="links")
				loadPage("./delete.asp?table=" + sTbl + "&code=" +sId +"&user=" + sUser + "&pass=" + sPass);
		}
	}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
//Called when "submit" button clicked
function submitChanges(sTable, sId, rec) {
	if (!bLogin) return;
//Make sure a sitetype is selected for new site elements and check for coords entered:
	if (sTable.toLowerCase() == "site" && sSelectedType == "" && bIsNew) {
		(sLang == "en") ? alert(sSelectSiteTypeEn) : alert(sSelectSiteTypeFr);
		return;
	}
	if (bIsNew && (iSiteX == "" || iSiteY == "") && 
		(sTable.toLowerCase() == "site" || sTable.toLowerCase() == "sitelist") ) {
		bTemp = (sLang == "en") ? confirm(sSiteNeedsCoordsEn) : confirm(sSiteNeedsCoordsFr);
		if (!bTemp)  return;
	}
	tmp = "<form method='post' action='";
//Find out if this is an update, or a new record
	tmp += (bIsNew) ? "./add.asp'>" : "./update.asp'>";
	i = 1;
//Do this if updating site/region desc:
	if (sPage == "site" || sPage == "region" || sPage == "sitelist") {
		while (getElem("field" + i) ) {
			if (i != 47) {
				if (getElem("field" + i).innerHTML == "<span>_<\/span><span>_<\/span>")
					getElem("field" + i).innerHTML = "";
				tmp+="<input type='hidden' name='newfield"+i+"' value=\"" + 
					makeDOMToString(getElem("field"+i))+"\">";
			}
			else 
				tmp += "<input type='hidden' name='newfield" + i + "' value=\"" + "\">";
			i++;
		}
	}
//For links/packages/events:
	else {
		if (bIsNew && sPage == "events") {
			if (sEventYear != "" && sEventMonth != "" && sEventDay != "") {
				tmp += "<input type='hidden' name='year' value='" + sEventYear + "'>";
				tmp += "<input type='hidden' name='month' value='" + sEventMonth + "'>";
				tmp += "<input type='hidden' name='day' value='" + sEventDay + "'>";
			}
			else {
				(sLang == "en") ? alert(sEventDateEn) : alert(sEventDateFr);
				return;
			}
		} 
		tmp += "<input type='hidden' name='code' value='" + sId + "'>";
		oRecord = getElem(rec);
		if (oRecord != null) {
			iCnt = 1;
/*			for (i = 0; i < oRecord.getElementsByTagName("span").length; i++) {
				if (oRecord.getElementsByTagName("span")[i].id.match("field") == "field") {
					if (oRecord.getElementsByTagName("span")[i].innerHTML == 
						"<span>_<\/span><span>_<\/span>");
						oRecord.getElementsByTagName("span")[i].innerHTML = "";
					tmp += "<input type='hidden' name='newfield" + iCnt + "' value=\"" + 
						makeDOMToString(oRecord.getElementsByTagName("span")[i])+"\">";
					iCnt++;
				}
			}*/
			i = 0;
			while (oRecord.getElementsByTagName("span")[i]) {
				if (oRecord.getElementsByTagName("span")[i].id.match("field") == "field") {
					sValue = makeDOMToString(oRecord.getElementsByTagName("span")[i]); 
					if (sValue == "__")
						sValue = "";
					tmp += "<input type='hidden' name='newfield" + iCnt + "' value=\"" + sValue +"\">";
					iCnt++;
				}
				i++;
			}

		}
		else
			return;
	}
//Set the table to update/ language/username/password/x/ypos
	sLangChoice = (sLangTemp == "") ? sLang : sLangTemp;
	tmp += "<input type='hidden' name='region' value='" + sCurrentRegion + "'>";  		//towncode
	tmp += "<input type='hidden' name='table' value='" + sTable + "'>";           	//dbtable
	tmp += "<input type='hidden' name='lang' value='"  + sLangChoice  + "'>";	//language
	tmp += "<input type='hidden' name='user' value='"  + sUser  + "'>";		//username
	tmp += "<input type='hidden' name='pass' value='"  + sPass  + "'>";		//password
	tmp += "<input type='hidden' name='sitetype' value='"  + sSelectedType  + "'>";
	if ((sPage.toLowerCase() == "site" || sPage.toLowerCase() == "sitelist") && iSiteX != "" & iSiteY != "") {
		tmp += "<input type='hidden' name='xpos' value='" + iSiteX + "'>";
		tmp += "<input type='hidden' name='ypos' value='" + iSiteY + "'>";
	}
//Hack to get rielregion descript:
	if (getElem("rielAll"))
		tmp += "<input type='hidden' name='rielAll' value='true'>";
	tmp += "<\/form>";
	getElem("xmlFrame4").contentWindow.document.getElementsByTagName("body")[0].innerHTML = tmp; 
	getElem("xmlFrame4").contentWindow.document.getElementsByTagName("form")[0].focus();
	getElem("xmlFrame4").contentWindow.document.getElementsByTagName("form")[0].submit();
	bIsNew = false;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
/*The following are various event handlers for selection/positioning/and typing:
clearMouseSelect	---- clears global vars which were set when selecting text
focusText		---- onclick for editable text areas to register selected and set cursor pos
startSelection		---- sets glob var to indicate a the start of an editable text selection
endSelection		---- sets glob var to indicate a the end of an editable text selection
setType			---- puts sitetype/event date Dropdown values into global vars for updates
stopBack		---- either deletes selected text or stops bksp behaviour of browser
getKey			---- fuction for keyboard actions (deleting/typng etc)*/
/////////////////////////////////////////////////////////////////////////////////////////////////////
function clearMouseSelect(e) {
	oMouseDown = null;
	oMouseUp = null;
}
function focusText(e) {
	if (window.event)
		e = window.event;
	oParent        = this;
	oFocused       = (e.target) ?  e.target : e.srcElement;
	iSpanIndex     = getIndex(oFocused);
	bCursorAtEnd   = false;
	bCursorAtStart = false;
	(document.all) ? oCursor.setAttribute("className", oParent.getAttribute("className")) : 
		oCursor.setAttribute("class", oParent.getAttribute("class"));
	oParent.parentNode.appendChild(oCursor);
	setCursorPos();	
	getElem("keyinput").focus();
//Clear "___" from empty field:
	if (oParent.childNodes.length == 2) {
		if (oParent.childNodes[1].firstChild.nodeType == 3)
			if (oParent.childNodes[1].firstChild.nodeValue == "_")
				oParent.removeChild(oParent.childNodes[1]);
		if (oParent.childNodes[0].firstChild.nodeType == 3)
			if (oParent.childNodes[0].firstChild.nodeValue == "_")
				oParent.removeChild(oParent.childNodes[0]);
		if (oParent.childNodes.length == 0)
			oFocused = null;
	}
}
function startSelection(e) {
	if (window.event)
		e = window.event;
	oMouseDown = (e.target) ? e.target : e.srcElement;
	oMouseUp   = null;
	oParent = this;
}
function endSelection(e) {
	if (window.event)
		e = window.event;	
	oMouseUp = (e.target) ? e.target : e.srcElement;
	oParent = this;
}
function setType(obj) {
	if  (obj.id == "siteTypeDD" && obj.options[obj.selectedIndex])
		sSelectedType = obj.options[obj.selectedIndex].value;
	if (obj.id == "eventYearDD" && obj.options[obj.selectedIndex])
		sEventYear =  obj.options[obj.selectedIndex].value;
	if (obj.id == "eventMonthDD" && obj.options[obj.selectedIndex])
		sEventMonth =  obj.options[obj.selectedIndex].value;
	if (obj.id == "eventDayDD" && obj.options[obj.selectedIndex])
		sEventDay =  obj.options[obj.selectedIndex].value;
	if (obj.id == "eventsDD" && obj.options[obj.selectedIndex])
		sSelectedRegion =  obj.options[obj.selectedIndex].value;
}
function stopBack(e) { 
	if (oMouseDown && oMouseUp && (e.keyCode == 8 || e.keyCode == 46) ) {
		if (oMouseDown.parentNode != oMouseUp.parentNode) return false;
		oPar = oMouseDown.parentNode;
		for (i = 0; i < oPar.getElementsByTagName("span").length; i++)	{
			if (oPar.getElementsByTagName("span")[i] == oMouseDown)
				iStart = i;
			if (oPar.getElementsByTagName("span")[i] == oMouseUp)
				iEnd = i;
		}
		if (iStart > iEnd) {
			iTemp  = iStart;
			iStart = iEnd;
			iEnd   = iTemp;
		}
		oMouseDown = oPar.getElementsByTagName("span")[iStart];
		oFocused = oMouseDown;
		oMouseUp   = oPar.getElementsByTagName("span")[iEnd];
		oTemp = oMouseDown.nextSibling;
		do {
			oPar.removeChild(oTemp);
			oTemp = oMouseDown.nextSibling;
		} while (oTemp != oMouseUp);
		oPar.removeChild(oMouseUp);
		oPar.removeChild(oMouseDown);
		getElem("keyinput").focus();
		return false; 
	}
	oMouseDown = null;
	oMouseUp = null;
	return false;
}
function getKey(e) {
	if (window.event)
			e = window.event;
	eKeyPressed = e.keyCode;
	switch (e.keyCode) {
		case 36: //Home
			if (oFocused != null) {
				oFocused       = getFirstSpan();
				bCursorAtStart = true;
				bCursorAtEnd   = false;
				iSpanIndex     = 0;
			}
			setCursorPos();
			break;
		case 35: //End
			if (oFocused != null) {
				oFocused       = getLastSpan();
				bCursorAtStart = false;
				bCursorAtEnd   = true;
				iSpanIndex     = oParent.getElementsByTagName("span").length-1;
			}
			setCursorPos();
			break;
		
		case 37:  //Left Arrow
			if (oFocused != null && !bCursorAtStart) {
				oFocused = previousSpan(oFocused);
				if (oFocused != getFirstSpan())
					bCursorAtEnd = false;
				else {
					bCursorAtStart = true;
					bCursorAtEnd   = false;
				}
			}
			setCursorPos();
			break;
		case 39:  //Right Arrow
			if (oFocused != null && !bCursorAtEnd) {
				oFocused = nextSpan(oFocused);
				if (oFocused != getLastSpan())
					bCursorAtStart = false;
				else {
					bCursorAtEnd   = true;
					bCursorAtStart = false;
				}
				setCursorPos();				
			}
			break;
		case 13:   //Return Key
			tmp  = document.createElement("br");
			tmp2 = document.createElement("span");
			tmp2.appendChild(tmp);
			if (oFocused == null) {
				oFocused       = oParent.appendChild(tmp2);
				bCursorAtEnd   = true;
				bCursorAtStart = false;
			}
			else {
				if (bCursorAtEnd) 
					oFocused = oParent.appendChild(tmp2);
				else
					oFocused.parentNode.insertBefore(tmp2, oFocused);
			}
			setCursorPos();
			break;
		case 8:	//Backspace
			//If children exist, and cursor is not at beginning of string do:
			if (oFocused != null && !bCursorAtStart) {
				//If deleting last char in node				
				if (oFocused.parentNode.getElementsByTagName("span").length == 1){
					tmp = nextSpan(oFocused);
					if (tmp == oFocused) {
						iSpanIndex--;
						tmp            = previousSpan(oFocused);
						bCursorAtEnd   = true;
						bCursorAtStart = false;
					}
					oTemp = oFocused.parentNode;
					oFocused.parentNode.removeChild(oFocused);
					while (oTemp != oParent && !oTemp.hasChildNodes()) {
						oTemp2 = oTemp;
						oTemp  = oTemp.parentNode;
						oTemp.removeChild(oTemp2);
					}
					if (oParent.getElementsByTagName("span").length == 0) {
						oFocused       = null;
						bCursorAtEnd   = false;
						bCursorAtStart = false;
						iSpanIndex     = -1;
					}
					else 
						oFocused = tmp;
				}
				else {
					if (bCursorAtEnd) {
						oFocused.parentNode.removeChild(oFocused);
						oFocused = getLastSpan();
						iSpanIndex--;
					}
					else {
						tmp = previousSpan(oFocused);
						if (tmp == getFirstSpan())
							bCursorAtStart= true;
						tmp.parentNode.removeChild(tmp);
						if (oFocused == getFirstSpan)
							bCursorAtStart = true;
					}
				}
				setCursorPos();	
			}
			break;	
		case 46:  //delete
			if (oFocused != null && !bCursorAtEnd) {
				if (oFocused.parentNode.getElementsByTagName("span").length == 1){
					tmp = nextSpan(oFocused);
					if (tmp == oFocused) {
						iSpanIndex--;
						tmp            = previousSpan(oFocused);
						bCursorAtEnd   = true;
						bCursorAtStart = false;
					}
					oTemp = oFocused.parentNode;
					oFocused.parentNode.removeChild(oFocused);
					while (oTemp != oParent && !oTemp.hasChildNodes()) {
						oTemp2 = oTemp;
						oTemp  = oTemp.parentNode;
						oTemp.removeChild(oTemp2);
					}
					if (oParent.getElementsByTagName("span").length == 0) {
						oFocused       = null;
						bCursorAtEnd   = false;
						bCursorAtStart = false;
						iSpanIndex     = -1;
					}
					else
						oFocused = tmp;
				}
				else {
				//Do this if characters still remain in sub/elem
					if (oFocused == getLastSpan()) {
						bCursorAtEnd   = true;
						bCursorAtStart = false;
						oFocused.parentNode.removeChild(oFocused);
						tmp            = getLastSpan();
					}
					else {
						tmp = nextSpan(oFocused);
						oFocused.parentNode.removeChild(oFocused);
					}
					iSpanIndex--;
					oFocused = tmp;
				}
				setCursorPos();
			}
			break;
		default:
			if (e.type == "keypress") {
				cChar = (document.all) ?  e.keyCode : e.charCode;
				eChar = cChar;
				if ((cChar < 127 && cChar > 31)||(cChar < 253 && cChar > 191) || cChar==181 || cChar==171){
					tmp = document.createElement("span");
					txt = String.fromCharCode(cChar);
					tmp.appendChild(document.createTextNode(txt));
					if (cChar == 32)
						tmp.style.display = "inline";
					if (oFocused == null) {
						oFocused       = oParent.appendChild(tmp);
						bCursorAtEnd   = true;
						bCursorAtStart = false;
					}
					else {
						if (bCursorAtEnd)
							oFocused = oFocused.parentNode.appendChild(tmp);
						else {
							oFocused.parentNode.insertBefore(tmp, oFocused);
						}
					}
					iSpanIndex++;
					setCursorPos();
				}
			}
			break;
	}
	return false;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
/* General functions for navigating granulated 'field##' elems:
getIndex		---- returns span index of character-span "o"
previousSpan		---- returns previous span 'field##' elem
nextSpan		---- returns next span in 'field##' elem
getFirstSpan		---- returns first span in 'field##' elem
getLastSpan		---- returns last span in 'field##' elem
setCursorPos		---- sets cursor position at char span */
/////////////////////////////////////////////////////////////////////////////////////////////////////
function getIndex(o) {
	for (i = 0; i < oParent.getElementsByTagName("span").length; i++)
		if (o == oParent.getElementsByTagName("span")[i])
			return i;
	return -1;
}
function previousSpan(o) {
	if (o != getFirstSpan()) {
		if (bCursorAtEnd)
			bCursorAtEnd = false;
		else {
			iSpanIndex--;
			return oParent.getElementsByTagName("span")[iSpanIndex];
		}
	}
	return o;
}
function nextSpan(o) {
	if (o != getLastSpan()) {
		iSpanIndex++;
		return oParent.getElementsByTagName("span")[iSpanIndex];
	}
	return o;
}
function getFirstSpan() {
	return oParent.getElementsByTagName("span")[0];
}
function getLastSpan() {
	return oParent.getElementsByTagName("span")[oParent.getElementsByTagName("span").length-1];
}
function setCursorPos() {
//TOP POSITION:
	oTemp = oFocused;
	if (sPage == "region") 
		iPosOffset = 0;
	else if (sPage == "site") 
		iPosOffset = 18;
	else if (sPage == "packages" || sPage== "links" || sPage == "events" || sPage=="sitelist") {
		n = oParent;
		iPosOffset = 0;
		arrTemp = new Array("TD","TABLE","DIV","TD","TR","TBODY","TABLE");
		for (i = 0; i < arrTemp.length; i++) {
			while (n.tagName.toUpperCase() != arrTemp[i])
				n = n.parentNode;
			if (sPage == "packages" && i == 1)
				iPosOffset += 0;
			else
				iPosOffset += parseInt(n.offsetTop);
		}
	}

	if (oFocused.firstChild.nodeType == 1 && oFocused != getFirstSpan()) {
		if (oFocused.firstChild.tagName.toUpperCase() == "BR" )
			oTemp = oParent.getElementsByTagName("span")[getIndex(oFocused) - 1];
	}
	oCursor.style.top = parseInt(oTemp.offsetTop) + iPosOffset + "px";
//LEFT POSITION:
	if (oParent.getElementsByTagName("span").length == 0 ) {
		if (oParent != oParent.parentNode.firstChild) {
			oCursor.style.left = (parseInt(oParent.parentNode.parentNode.offsetLeft) + 
				parseInt(oParent.previousSibling.offsetLeft) + 
				parseInt(oParent.previousSibling.offsetWidth)) + "px";
		}
		else
			oCursor.style.left = parseInt(oParent.parentNode.parentNode.offsetLeft) + "px";
	}
	else {
		if (sPage == "events" || sPage == "packages" || sPage == "links" || sPage == "sitelist") {
			p = oParent;
			while (p.tagName.toUpperCase() != "TD")
				p = p.parentNode;
			t = p;
			while (t.tagName.toUpperCase() != "TABLE")
				t = t.parentNode;
			if (sPage == "events" || sPage == "packages")
				iPosX = parseInt(oParent.parentNode.offsetLeft);
			else if (sPage == "links")
				iPosX = parseInt(oParent.parentNode.offsetLeft) + 
				parseInt(oParent.parentNode.parentNode.parentNode.parentNode.offsetLeft)
			else
			 iPosX = parseInt(p.offsetLeft)+parseInt(p.parentNode.parentNode.offsetLeft)+parseInt(t.offsetLeft);
			if (oFocused.firstChild.nodeType == 1 && oFocused == oTemp) {
				if (oFocused.firstChild.tagName.toUpperCase() == "BR")
					oCursor.style.left = iPosX - 2 + "px";
				else
					oCursor.style.left = parseInt(oFocused.offsetLeft) + iPosX - 2 + "px";
			}
			else
				oCursor.style.left = parseInt(oFocused.offsetLeft) + iPosX - 2 + "px";
		}
		else
			oCursor.style.left = (parseInt(oFocused.offsetLeft) - 2 +
				parseInt(oParent.parentNode.parentNode.offsetLeft)) + "px";
		if (bCursorAtEnd)
			oCursor.style.left = parseInt(oCursor.style.left) + parseInt(oFocused.offsetWidth) + "px";
	}
	eChar = null;
	eKeyPressed = null;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*Functions to setup elements for editing:
makeEditable		---- called by joie_general.js to setup various values/labels etc for editing
setupEdit		---- sets event handlers, creates cursor, and calls func to granulate 'field##' elems
rewriteNodes		---- Recursive function to granulate 'field##' elems into individual char elems*/
//////////////////////////////////////////////////////////////////////////////////////////////////////
function makeEditable(sP) {
	switch (sP) {
		case "siteListDiv": sP = "sitelist";
			break;
		case "siteDiv": sP = "site";
			break;
		case "regionDiv": sP = "region";
			break;
		case "eventsDiv": sP = "events";
			break;
		case "routesDiv": sP = "routes";
			break;
		case "packagesDiv": sP = "packages";
			break;
		case "linksDiv" : sP = "links";
			break;
		default: return;
	}
	if (sLang == sLangTemp)
		sLangTemp = "";
	bLogin                     = true;
	bIsNew                     = false;
	bShowHidden                = true;
	iSiteX                     = "";
	iSiteY                     = "";
	sEventYear		   = "";
	sEventMonth		   = "";
	sEventDay		   = "";
	sPage                      = sP;
	if (sPage.toLowerCase() == "site") {
		getElem("rm_site").style.display = "";
		sCurrentRegion = getElem("field49").firstChild.nodeValue;
		if (getElem("field48").hasChildNodes())
			sRecordCode =  getElem("field48").firstChild.nodeValue;
		else
			sRecordCode = "";
	}
	if (sPage.toLowerCase() == "sitelist") {
		sCurrentRegion = getElem("field5").firstChild.nodeValue;
		sRecordCode = getElem("field5").firstChild.nodeValue;
	}
	setupEdit();
	if (sRecordCode == "" &&  sPage == "site")
		clearForNew();
	if (sPage.toLowerCase() == "site" || sPage.toLowerCase() == "packages" || 
		sPage.toLowerCase() == "events" || sPage.toLowerCase() == "sitelist") {
//Setup map clicking location placement:
		if (sPage.toLowerCase() == "site" || sPage.toLowerCase() == "sitelist") {
			if (isMapZoomed)
				zoomMap("out");
			getElem("map").onclick = setLocation;
			getElem("map").onmouseover = setMapCrosshairs;
		}
		if (sPage.toLowerCase() == "site") {
			arrField = new Array(2, 3,4, 15);
			if (sLang == "en") 
				arrLabel = new Array("Address", "Postal Code", "Location", "Description");
			else
				arrLabel = new Array("Adresse", "Code Postal", "Location", "Description");
//Add labels to fields with no labels:
			for (i = 0; i < arrField.length; i++) {
				var spn = document.createElement("span");
				(document.all) ? spn.setAttribute("className", "sitelables") : 
					spn.setAttribute("class", "sitelables");
				spn.appendChild(document.createTextNode(arrLabel[i]));
				if (getElem("field" + arrField[i]).parentNode.hasChildNodes()) 
			 		getElem("field" + arrField[i]).parentNode.insertBefore(spn, getElem("field" + arrField[i]).parentNode.firstChild);
				else
					getElem("field" + arrField[i]).parentNode.appendChild(spn);
			}
		}
		else if (sPage == "sitelist") {
			if (isMapZoomed)
				zoomMap("out");
			getElem("map").onclick = setLocation;
			getElem("map").onmouseover = setMapCrosshairs;
		}
		else if (sPage == "events") {
			iStep = 4;
			arrField = new Array(1,3,4);
			if (sLang == "en") 
				arrLabel = new Array("When", "Description", "Website");
			else
				arrLabel = new Array("Quand", "Description", "Site web");
			iCount = 0;
			while (getElem("field" + ((iCount*iStep) + arrField[0]))) {
				for (i = 0; i < arrField.length; i++) {
					var spn = document.createElement("span");
					(document.all) ? spn.setAttribute("className", "sitelables") : 
						spn.setAttribute("class", "sitelables");
					spn.appendChild(document.createTextNode(arrLabel[i]));
					if (getElem("field" + ((iCount*iStep) + arrField[i])).parentNode.hasChildNodes()) 
				 			getElem("field" + ((iCount*iStep) + arrField[i])).parentNode.insertBefore(spn, getElem("field" + ((iCount*iStep) + arrField[i])).parentNode.firstChild);
					else
  					getElem("field" + ((iCount*iStep) + arrField[i])).parentNode.appendChild(spn);
				}
				iCount++;
			}
 		}
		else if (sPage == "packages") {
			iStep = 10;
			arrField = new Array(2,3,4,5,6,7,8,9,10);
			if (sLang == "en") 
				arrLabel = new Array("Subtitle", "Cost", "Price Description", "Description", "List Items",
					"Second Description", "Contact", "Email", "Website");
			else
				arrLabel = new Array("Subtitle", "Cost", "Price Description", "Description", "List Items",
					"Second Description", "Contact", "Email", "Website");
			iCount = 0;
			while (getElem("field" + ((iCount*iStep) + arrField[0]))) {
				for (i = 0; i < arrField.length; i++) {
					var spn = document.createElement("span");
					(document.all) ? spn.setAttribute("className", "sitelables") : 
						spn.setAttribute("class", "sitelables");
					spn.appendChild(document.createTextNode(arrLabel[i]));
					if (getElem("field" + ((iCount*iStep) + arrField[i])).parentNode.hasChildNodes()) 
				 getElem("field" + ((iCount*iStep) + arrField[i])).parentNode.insertBefore(spn, getElem("field" + ((iCount*iStep) + arrField[i])).parentNode.firstChild);
					else
  					getElem("field" + ((iCount*iStep) + arrField[i])).parentNode.appendChild(spn);
				}
				iCount++;
			}
		}
	}
}
function setupEdit() {
	var iPos = 1;
	if (document.all) { 
		getElem("keyinput").onkeypress = getKey;		
		getElem("keyinput").onkeyup    = getKey;		
	}
	else
		getElem("keyinput").onkeypress   = getKey;
//Create Cursor:
	oCursor                = document.createElement("span");
	txt                    = document.createTextNode("|");
	oCursor.style.position = "absolute";
	oCursor.appendChild(txt);
	str = "";
//Make fields into character nodes
	while (getElem("field" + iPos)) {
		if (iPos != 47) {
			rewriteNodes(document.getElementById("field" + iPos));
			getElem("field" + iPos).onclick     = focusText;
			getElem("field" + iPos).onmousedown = startSelection;
			getElem("field" + iPos).onmouseup   = endSelection;
			getElem("field" + iPos).style.color = "#650909";
		}
		iPos++;
	}
}
function rewriteNodes(obj) {
	var iCount = 0;								
//Go through each childnode of obj
	while(iCount < obj.childNodes.length) {
//if it is a text node, loop through characters and convert into character spans:
		if (obj.childNodes[iCount].nodeType == 3) {
			var sTemp = obj.childNodes[iCount].nodeValue;
			for (var j =0; j < sTemp.length; j++) {
				var spn = document.createElement("span");
				var txt = document.createTextNode(sTemp.charAt(j));
				if (sTemp.charAt(j) == " ")	
					spn.style.display = "inline";
				//	spn.appendChild(document.createElement("b"));
				spn.appendChild(txt);	
				obj.insertBefore(spn, obj.childNodes[iCount]);
				iCount++;
			}
			obj.removeChild(obj.childNodes[iCount]);
		}
//Convert "<br>" tags into character spans
		else if (obj.childNodes[iCount].tagName.toUpperCase() == "BR") {
			var spn = document.createElement("span");
			var brk = document.createElement("br");
			spn.appendChild(brk);
			obj.replaceChild(spn, obj.childNodes[iCount]);
			iCount++;
		}
		else {
//Change anchor to text:
			if (obj.childNodes[iCount].tagName.toUpperCase() == "A") {
				if (obj.childNodes[iCount].hasChildNodes()) {
					var txt = document.createTextNode(obj.childNodes[iCount].firstChild.nodeValue);
 					obj.replaceChild(txt, obj.childNodes[iCount]);
				}	
				else
					obj.removeChild(obj.childNodes[iCount]);
			}
//Otherwise recursively call function for node
			else {
				if (obj.childNodes[iCount])
					obj.childNodes[iCount] = rewriteNodes(obj.childNodes[iCount]);
				iCount++;
			}
		}
	}
	return obj;
}
