var calls = new Array();
var pendingResponseCount = 0;
var shouldDebugAjax = false;
var assureUnique = 1;

/**
 * Main function of Ajax calls
 *
 */
function ajaxRequestSender(form, target, qs, dom, resHandler, resHandlerParam, method, async, mungedRef, timerObj, ajaxRef) {

  contextPath = "/tripconnect";
  if (shouldDebugAjax) {
    alert('ajaxRequestSender() called.  About to request URL\n'
    + 'call key: [' + calls.length + ']\n'
    + 'url: [' + contextPath + target + ']\n'
    + 'form: [' + form + ']\n'
    + 'dom(xml): [' + dom + ']\n'
    + 'resHandlerParam: [' + resHandlerParam + ']\n'
    + 'callback function: [' + resHandler + ']\n'
    + 'async: [' + async + ']\n'
    + 'method: [' + method + ']\n'
    + 'mungedRef: [' + mungedRef + ']\n'
    + 'timerObj: [' + timerObj + ']\n'
    + 'method: [' + method + ']\n'
    + 'ajaxRef: [' + ajaxRef + ']\n'
    + 'querystring: [' + qs + ']');
  }

  var xReq = createXMLHttpRequest();

  callKey = '' + calls.length;
  call = {xmlHttpRequest: xReq,
    callbackFunction: resHandler,
    form: form,
    resHandlerParam: resHandlerParam,
    mungedRef: mungedRef,
    timerObj: timerObj,
    ajaxRef: ajaxRef,
    url: contextPath + target + qs};
  calls[callKey] = call;

  eval('f = function() { onResponseStateChange(' + callKey + '); }');
  xReq.onreadystatechange = f;

  var parmInTarget = (target.indexOf('?') > 0);
  if (parmInTarget && qs) {
    qs = qs.replace('?','&');
  }
  if (qs == "" && !parmInTarget) {
    qs = "?";
  } else {
    qs += "&";
  }
  
  aud = new Date();
  aus = '';
  aus += aud.getMonth() + aud.getDay() + aud.getFullYear();
  aus += aud.getHours() + aud.getMinutes();
  aus += aud.getSeconds() + aud.getMilliseconds();
  qs += "assureUnique=" + aus + assureUnique++;
  qs += "&ajaxRef=" + ajaxRef;
  
  var useFormPost = false;
  if(method == 'POST' && !dom) {
  	dom = qs;
  	qs = "";
  	if(dom.indexOf('?') == 0) {
  		dom = dom.substring(1);
  	}
  	useFormPost = true;
  }

  xReq.open(method, contextPath + target + qs, async);
  if(useFormPost) {  
  	xReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  }
  xReq.send(dom);
}
function onResponseStateChange(callKey) {

  call = calls[callKey];
  xmlHttpRequest = call.xmlHttpRequest;

  if (xmlHttpRequest.readyState < 4) {
    return;
  }

  if (xmlHttpRequest.status == 200) {
    if (shouldDebugAjax) {
      alert('Call ' + callKey + ' with context [' + call.resHandlerParam + ']'
           + ' to ' + call.url + ' has returned.');
    }
    callbackFunction = call.callbackFunction;
    if (!callbackFunction) {
      eval('f = function() { onResponseStateChange(' + callKey + '); }'); 
      setTimeout(f, 100); 
    }
    callbackFunction(xmlHttpRequest, call.form, call.resHandlerParam); 
if (call.timerObj != null) {
timerObj = setTimeout(call.mungedRef + "_timedFirer()", eval("delay_" + call.mungedRef));
}
  } else {
    alert(xmlHttpRequest.status);
  }

  call = null;
  delete calls[callKey];
  pendingResponseCount--;
}

function createXMLHttpRequest() {
  var xmlHttpRequest;
  if (window.XMLHttpRequest) {
    return new XMLHttpRequest();
  } else if (window.ActiveXObject) {
    return new ActiveXObject('Microsoft.XMLHTTP')
  }
}

function StdInnerHTML(ajaxXHR, ajaxFRM, ajaxRHP) {
   document.getElementById(ajaxRHP).innerHTML = ajaxXHR.responseText;
   if (ajaxXHR.responseText.match(/<script([^>]{0,100})>([\w|\W]{0,10000})<\/script>/gi)) {
     eval(RegExp.$2);
   }
}

function StdSendByID(form, target, param, resHandler, resHandlerParam, method, mungedRef, timerObj, ajaxRef) {
  a = param.split(",");
  requestType = a[0];
  if (requestType.toLowerCase().indexOf("querystring") != -1) {
    qs = "?";
    for (i = 1; i < a.length; i++) {
      nextElement = a[i];
      b = nextElement.split(".");
      id = b[0];
      attr = b[1];
      if (qs != "?") {
        qs += "&";
      }
      qs += id + "=";
      qs += escape(eval("document.getElementById('" + id + "')." + attr));
    }
    ajaxRequestSender(form, target, qs, null, resHandler, resHandlerParam, method, true);
  }
  if (requestType.toLowerCase().indexOf("xml") != -1) {
    b = requestType.split(".");
    rootNode = b[1];
    xml = "<" + rootNode + ">";
    for (i = 1; i < a.length; i++) {
      nextElement = a[i];
      b = nextElement.split(".");
      id = b[0];
      attr = b[1];
      xml += "<" + id + ">";
      xml += escape(eval("document.getElementById('" + id + "')." + attr));
      xml += "</" + id + ">";
    }
    xml += "</" + rootNode + ">";
    ajaxRequestSender(form, target, '', xml, resHandler, resHandlerParam, method, true, mungedRef, timerObj, ajaxRef);
  }
}

function popInnerHTMLList(ajaxXHR, ajaxFRM, ajaxRHP) {
	var list = ajaxXHR.responseXML.getElementsByTagName('list').item(0); 
	var params = ajaxRHP.split(","); 
	var targetId = params[0];
	var referField = params[1];
	var formname = params[2];
	var locfield = params[3];
	var textfield = params[4];
	var target = document.getElementById(targetId); 
	if (list != null) {
		var items = list.childNodes; 
		if (items.length > 0) {
			var htmlString = "";
			for (var i=0; i < items.length; i++) { 
				var locationName = items[i].firstChild.nodeValue;
				var locationID = items[i].getAttribute("value");
				htmlString += "<a href=\"#\" id=\"link-"+i+"\" onclick='updateLocation(\"" + referField + "\",\"" + locationID + "\",\"" + escape(locationName) + "\",\"" + formname + "\",\"" +locfield + "\",\"" + textfield+"\" );return false;'>" + locationName + "</a>";
			}
			target.style.display = "block";
			target.innerHTML = htmlString;
			attachEvents(targetId);
		} else {
			target.innerHTML = "";
			target.style.display = "none";
			clearFormField( formname, "locationID["+referField+"]" ); 
		}
	}
}

function lookup( value, index, form, listprefix, locfield, textfield, parentID ) {
	var parentParam = "";
	if (parentID) {
		parentParam = '&parentID=' + parentID;
	} 
	if (isPrintable(keycode) || keycode==8) { // printable or backspace
		form.elements[locfield].value = ""; // clear locationID before lookup
		ajaxRequestSender(	form,
							'/ajax/PopulateTextbox.do',
							'?searchKey='+value+parentParam,
							null,
							popInnerHTMLList,
							listprefix+'-'+index+','+index+','+form.name+','+locfield+','+textfield,
							'POST', 
							true);
	} else if ( keycode == 40 ) { // down arrow
		try { document.getElementById(listprefix+"-"+index).firstChild.focus(); } catch(e) {}
	}
}

/** 
 * For updating user locations from Ajax-enabled pages (ex. displayplacesbeen) 
 */
function updateUserLocation( id, form ) {
	lid = id.substring( id.indexOf("-")+1, id.indexOf("-")+7 );
	try {
		uid = userID; // defined elsewhere in the page
	} catch(e) {
		uid = form.userID.value; // else must be a form field
	}
	rating = getCheckedValue(form.elements["r-"+lid]);
	knowlevel = (form.elements["ct-"+lid].checked?"1":"0") + "|" + (form.elements["ch-"+lid].checked?"1":"0") + "|" + (form.elements["cr-"+lid].checked?"1":"0");
	try {
		advice = form.elements["t-"+lid].value;
	} catch(e) {
		advice = "null";
	}
	locname = form.elements["ln-"+lid].value;
	qs = "?userID="+uid+"&locationID="+lid+"&rating="+rating+"&knowlevel="+knowlevel+"&advice="+advice+"&locname="+locname;
	if ( isBlank(uid) ) { // if not logged in, forward to regular page
		document.location.href = "/tripconnect/updatelocation.do" + qs;
	} else {
		ajaxRequestSender(document.forms["displayplacesbeen"],"/ajax/UpdateUserLocation.do",qs,null,StdInnerHTML,"status-message", "POST", true); 
	}
}

function lookupSingleKeyword( keyword, type, formname, fieldname, handler ) {
	if( handler == null ) {
		handler = updateSingleKeyword;
	} 
	ajaxRequestSender(null,"/ajax/GetListByKeyword.do",
							'?searchKey='+keyword+'&type='+type,null,handler,formname+","+fieldname, "POST", true); 
}
function updateSingleKeyword(ajaxXHR, ajaxFRM, ajaxRHP) {
	var id = '';
	var list=ajaxXHR.responseXML.getElementsByTagName('list').item(0);
	if (list != null) {
		var items = list.childNodes; 
		if (items.length > 0) {
			var htmlString = "";
			var name = items[0].firstChild.nodeValue;
			id = items[0].getAttribute("value"); 
			var params = ajaxRHP.split(",");
			var formname = params[0];
			var fieldname = params[1];
			document.forms[formname].elements[fieldname].value = id;
		}
	} 
	return id;
}

/** 
 * Add Cheers to objects 
 */
function addCheer( ctype, cid ) {
	ajaxRequestSender(null,"/ajax/AddCheer.do","?ctype="+ctype+"&cid="+cid,null,updateCheersOnPage,"num-cheers-"+cid+",cheer-link-"+cid+",thumb-cheer-link-"+cid, "POST", true); 
}

function updateCheersOnPage(ajaxXHR, ajaxFRM, ajaxRHP) {
	var numCheers = ajaxXHR.responseText; 
	var params = ajaxRHP.split(",");
	var numCheersID = params[0];
	var cheersLinkID = params[1];
	var thumbLinkID = params[2];
	var parentID = cheersLinkID.split("-")[2];
	var cheerText = "<img src='"+IMAGEPATH+"cheer_smiley.gif' border='0'/> "+numCheers+" cheers";
	setInnerHTMLById(numCheersID, cheerText);
	setInnerHTMLById(cheersLinkID, " Thanks, your Cheer was added!");
	try { // only need to do this for thumbnails, i.e. photo cheers
		setInnerHTMLById(thumbLinkID, cheerText);
		thumbList.get(thumbList.getIndexByParentid(parentID)).setCheers(numCheers);
	} catch(e) {
		// not thumbnail
	}
}

/* admin resize photo */
function resizePhoto( idprefix, popupprefix, homeprefix, table, imageid, archiveimageid, parentid, dimclass ) {
	ajaxRequestSender(null,"/admin/resizephoto.do","?t="+table+"&i="+archiveimageid+"&p="+parentid+"&d="+dimclass,null,updateResizePhotoOnPage,idprefix +"," + popupprefix + "," + homeprefix + "," + imageid + "," + dimclass,  "POST", true); 
}
function updateResizePhotoOnPage(ajaxXHR, ajaxFRM, ajaxRHP) {
	
	var messageparams = ajaxXHR.responseText.split(",");
	var returnmsg = messageparams[0];
	var featureimageid = messageparams[1];
	
	var params = ajaxRHP.split(",");
	var idprefix = params[0];
	var popupprefix = params[1];
	var homeprefix = params[2];
	var imageid = params[3];
	var dimclass = params[4];
	
	if(dimclass == 'FEATURE') {
		if(returnmsg == 'done') {
			setInnerHTMLById(idprefix + "-" + imageid, "");
			setInnerHTMLById(popupprefix + "-image-" + imageid, "<img src='" + DynamicImage.replace("id=0", "id=" + featureimageid) + "'/>");
			toggleCssDisplay(popupprefix + "-" + imageid, "block");
			toggleCssDisplay(homeprefix + "-" + imageid, "block");
		} else {
			setInnerHTMLById(idprefix + "-" + imageid, returnmsg);
		}
	} else {
		setInnerHTMLById(idprefix + "-" + imageid, returnmsg);
	}
}

/** 
 * Update Image Caption 
 */

function updateCaption(ajaxXHR, ajaxFRM, ajaxRHP) {
	var status = ajaxXHR.responseText; 
	var caption = ajaxRHP;
	var id = ajaxFRM.id.value;
	setInnerHTMLById('caption-status-'+id, status);
	setInnerHTMLById('caption-text-'+id, caption);
	showElement('view-caption-'+id); 
	hideElement('edit-caption-'+id);
}

/**
 * Compliments
 */


var TCAdminUrlPrefix = "";

function sendCompliment( etype, eid, text, action, uid ) {
	if ( text.trim() == '' ) {
		alert("Please enter a Thank You message.");
		return false;
	}
	var id = "compliment-"+ (uid?uid:eid);
	var a = action || "create";
	ajaxRequestSender(null, "/ajax/UpdateCompliment.do","?etype="+etype+"&eid="+eid+"&text="+text+"&action="+a,null,StdInnerHTML,id, "POST", true); 
	return true;
}

function updateCompliment( cid, status, action, eid ) {
	var a = action || "update"; 
	ajaxRequestSender(null, TCAdminUrlPrefix + "/ajax/UpdateCompliment.do","?cid="+cid+"&action="+a+"&status="+status,null,StdInnerHTML,eid,"POST",true); 
}

function approveCompliment(cid) {
	updateCompliment(cid, 'enabled', 'update', 'updatecomp-'+cid);
	$('compliment-'+cid).style.backgroundColor = "#fff";
}

function deleteCompliment(cid) {
	updateCompliment(cid, 'disabled', 'update', 'compliment-'+cid);
}

/** 
 * Utility functions used in conjunction with Location dropdown 
 */
var noFocus = false;
function updateLocation( index, lid, lname, formname, locfield, textfield ) {
	var formname = formname || "msgadd";
	var textfield = textfield || "msg.locationEntries[" + index + "]";
	var locfield = locfield || "locationID[" + index + "]";
	document.forms[formname].elements[textfield].value = unescape(lname);
	document.forms[formname].elements[locfield].value = lid;
	if (!noFocus) {
		closeLocList(index,true);
		currLinkFocus = -1;
		document.forms[formname].elements[textfield].focus();
	}
	var postTo = getCheckedValue(document.forms[formname].elements["msg.strPostTo"]);
	if ( postTo == 'all' || postTo == 'selectandfof' ) {
		updateNetworkForLocations();
	}
}
document.onkeydown = function(e) {
	if (!e) { e = window.event; }
	var k = e.keyCode;
	if ( isArrowKey(k) && isLocationListOpen() ) {
		return false; 
	}
};

function isLocationListOpen() {
	var ml; 
	try { ml = maxLocations; } catch(e) { return false; } // no maxLocations = no location lists
	for (var i=0; i<ml; i++) {
		try {
			if (document.getElementById("location-list-"+i).innerHTML != "") {
				return true;
			}
		} catch(e) { 
			// no location list defined 
		}
	}
	return false;
}
var currLinkFocus=-1; // if this is -1, then a location list is open somewhere. used for preventing arrow scrolling the page in IE
function attachEvents(t) {
	list = document.getElementById(t);
	list.onkeydown	= function(e) { getKey(e); if(e) {e.preventDefault();e.stopPropagation(); debug("inner preventdefault event: "+e.type+"\n",true); return false;} };
	list.onkeyup	= function() { keyScroll(this);  };
	links = list.getElementsByTagName("a");
	for(var i=0;i<links.length;i++) {
		index = i;
		links[i].onfocus	= function() { this.className="link-focused"; currLinkFocus=parseInt(this.id.substring(this.id.indexOf("-")+1)); };
		links[i].onblur		= function() { this.className="link-blurred"; };
		try{links[i].constructor.prototype.click = linkClick;} catch(e) {} // IE doesn't like this
	}
}
function linkClick () {
	var executeAction = true;
	if (this.onclick) {
		executeAction = this.onclick({type: 'click'});
	}
	if (executeAction) 
		return false;
}
var keycode;
function getKey(e) {
	if (!e) var e = window.event;
	keycode = e.keyCode;
	debug("Keycode: " + keycode+"\n");
}
function keyScroll(t) {
	links = t.getElementsByTagName("a");
	if (keycode==13) {
		try {
			links[currLinkFocus].click();
		} catch(e) {
			// Firefox doesn't like the click() function on this element,
			// but pressing enter (keycode=13) simulates this anyway in FF 
			// so it's not necessary
			// alert("onclick value: "+links[currLinkFocus].onclick);
		}
	} else if (keycode==39 || keycode==40) { // right or down arrow
		if (currLinkFocus<(links.length-1)) { 
			links[currLinkFocus+1].focus();
		}
	} else if (keycode==37 || keycode==38) { // left or up arrow
		if(currLinkFocus>0) { 
			links[currLinkFocus-1].focus();
		}
	}
}	
function closeLocLists(index) {
	var i2 = index || -1;
	for(var i=0; i<maxLocations; i++) {
		if(i != i2) {
			closeLocList(i);
		}
	}
}

function closeLocList(index, isSelf) {
	var isSelf = isSelf || false;
	var locList = document.getElementById("location-list-"+index);
	if (typeof(locList) != 'undefined' ) {
		if (!isSelf) {
			noFocus = true;
			try {
				locList.getElementsByTagName('a').item(0).click();
			} catch(e) {
				// list is already closed, links don't exist
			}
			noFocus = false;
		}
		locList.innerHTML = "";
		locList.style.display="none";
	}
}

			
function getFormValuesAsString(fobj) {
	var str = "";
	for(var i = 0;i < fobj.elements.length;i++) {
		var field = fobj.elements[i];
		switch(field.type) {
			case "text":
			case "hidden":
				str += field.name +	"=" + escape(field.value) + "&";
				break;
			case "radio":
			case "checkbox":
				if ( field.checked )
					str += field.name +	"=" + escape(field.value) + "&";
				break;
			case "select-one":
				str += field.name + "=" + field.options[field.selectedIndex].value + "&";
				break;
		}
	}
	str = str.substr(0,(str.length - 1));
	return str;
}

