var ajaxObj = [];

function createRequestObject() {
    var ajaxObj;
    var browser = navigator.appName;
    if(browser.indexOf('Microsoft') >= 0)
        ajaxObj = new ActiveXObject("Microsoft.XMLHTTP");
    else
        ajaxObj = new XMLHttpRequest();

    return ajaxObj;
}

function zeroPad(num, count) {
   var numZeropad = num + '';

   while(numZeropad.length < count)
      numZeropad = "0" + numZeropad;

   return numZeropad;
}

function removeApos(string) {
   return string.replace(/'/g, "");
}

function loading() {
   show("loading");
}

function unloading() {
   hide("loading");
}

function getSalt() {
   return Math.floor(Math.random()*1000);
}

function evalJSON(responseText) {
   var json = eval('(' + responseText + ')');

   return json;
}

function test(text) {
   text = document.getElementById("test").value + "\n" +  text;
   document.getElementById("test").value = text;
}

function getValueOf(objectName) {
   return document.getElementById(objectName).value;
}

function updateValueOf(objectName, value) {
   document.getElementById(objectName).value = value;
}

function updateOpacity(objectName, opacity) {
   var objectElement = document.getElementById(objectName);
   objectElement.style.opacity = opacity;
   if (navigator.appName.indexOf("Microsoft")!=-1&&parseInt(navigator.appVersion)>=4)
      objectElement.filters.alpha.opacity = (opacity * 100);

   objectElement.style.MozOpacity = opacity;

   //test(objectName + " => " + opacity);
}

// Fading out- assuming opacity is at 100 already
function fadeOut(objectName, currentOpacity) {
   currentOpacity = parseFloat(currentOpacity) - 0.05;

   currentOpacity = currentOpacity.toFixed(2);

   // Set the new opacity
   if (currentOpacity <= 0.1)
      currentOpacity = 0.1;

   updateOpacity(objectName, currentOpacity);

   if (currentOpacity > 0.1) {
      //setTimeout("fadeOut('" + objectName + "', " + currentOpacity + ")", 20);
      setTimeout(function() {
         fadeOut(objectName, currentOpacity);
      }, 10);
   } else
      updateOpacity(objectName, 0);
}

// Fading in- assuming opacity is at 0 already
function fadeIn(objectName, currentOpacity) {
   currentOpacity = parseFloat(currentOpacity) + 0.05;
   //currentOpacity += 0.1;

   currentOpacity = currentOpacity.toFixed(2);

   // Set the new opacity
   if (currentOpacity > 0.95)
      currentOpacity = 0.95;

   updateOpacity(objectName, currentOpacity);

   if (currentOpacity < 0.95) {
      //setTimeout("fadeIn('" + objectName + "', " + currentOpacity + ")", 20);
      setTimeout(function() {
         fadeIn(objectName, currentOpacity);
      }, 10);
   } else
      updateOpacity(objectName, 0.99);
}

// Appear to shift a div for interface scrolling of listings (initially)
//------------------------------------------
function shiftLeft(objectName, amount) {
   shiftTo(objectName, amount);
}

function shiftRight(objectName, amount) {
   shiftTo(objectName, -1 * amount);
}

function shiftTo(objectName, amount) {
   var shiftObject = document.getElementById(objectName);

   var currentLeftOffset = parseInt(shiftObject.style.left.replace(/px/g, ""));
   var targetLeftOffset = currentLeftOffset + amount;

   shiftToDestination(objectName, currentLeftOffset, targetLeftOffset);
}

function shiftToDestination(objectName, currentLeftOffset, targetLeftOffset) {
   // amount to shift each time
   var shiftAmount = 20;

   if (currentLeftOffset > targetLeftOffset) {
      currentLeftOffset -= shiftAmount;
      if (currentLeftOffset < targetLeftOffset)
         currentLeftOffset = targetLeftOffset;
   } else {
      currentLeftOffset += shiftAmount;
      if (currentLeftOffset > targetLeftOffset)
         currentLeftOffset = targetLeftOffset;
   }

   document.getElementById(objectName).style.left = currentLeftOffset + "px";

   if (currentLeftOffset != targetLeftOffset) {
      setTimeout(function() {
         shiftToDestination(objectName, currentLeftOffset, targetLeftOffset);
      }, 5);
   }
}

function linkToListing(listingid) {
   window.location.href = '/realestate/' + listingid + '/';
}

//------------------------------------------
function hide(objectName) {
   document.getElementById(objectName).style.display = 'none';
}

function show(objectName) {
   document.getElementById(objectName).style.display = '';
}

function updateInnerHtml(objectName, value) {
   document.getElementById(objectName).innerHTML = value;
}

//--------------------------------------
function changeOptionsBlock(name) {
   hide("rightOptionsDistrict");
   hide("rightOptionsOverlayDistrict");
   hide("rightOptionsVersionTypes");
   hide("rightOptionsOverlayVersionTypes");
   hide("rightOptionsViews");
   hide("rightOptionsOverlayViews");
   show("rightOptions" + name);
   show("rightOptionsOverlay" + name);
}

function rightOptionsConfig(name, blockid) {
   if (!rightOptionsToggle[blockid]) {
      show("rightOptionsConfig" + name);
      show("rightOptionsConfigArrow" + name);
      rightOptionsToggle[blockid] = 1;

      // Hide all
      for (var i = 1; i <= rightOptionTotal; i++) {
         if (i == blockid)
            continue;

         hide("rightOptionsConfig" + rightOptionsName[i]);
         hide("rightOptionsConfigArrow" + rightOptionsName[i]);
         rightOptionsToggle[i] = 0;
      }
   } else {

      hide("rightOptionsConfig" + name);
      hide("rightOptionsConfigArrow" + name);
      rightOptionsToggle[blockid] = 0;
   }
}


function rightOptionsChildDistrict(subdistrictid) {
   // Now initialize the ajax
   var salt = getSalt();
   ajaxObj['subdistrict_' + subdistrictid + "_" + salt] = createRequestObject();
   var subAjaxObj = ajaxObj['subdistrict_' + subdistrictid + "_" + salt];

   var url = '/rightoptions/subdistrict-' + subdistrictid + '/' + salt + '/';
   subAjaxObj.onreadystatechange = function() {
      rightOptionsChildDistrict_handleResponse(subdistrictid, salt);
   }
   subAjaxObj.open("GET", url);
   subAjaxObj.send(null);
}


function rightOptionsChildDistrict_handleResponse(subdistrictid, salt) {
   var subAjaxObj = ajaxObj['subdistrict_' + subdistrictid + "_" + salt];
   if (subAjaxObj.readyState == 4) {
      var json = evalJSON(subAjaxObj.responseText);
      var result = parseInt(json[subdistrictid]);

      var districtid = parseInt(json.districtid);
      var districtResponse = parseInt(json.district);

      // Handle the district information. If the sub is toggled and the district
      // for some reason isn't, then we catch that in the ajax return.
      //updateGraphInventory();
      rightOptionsUpdateSubdistricts(subdistrictid, result, districtid, districtResponse);

      // Delay a refresh
      delayListingsRefresh();
   }

}

function rightOptionsUpdateSubdistricts(subdistrictid, subdistrictResponse, 
                                        districtid, districtResponse) {
   var districtName = 'rightOptionsDistrict_' + districtid;

   if (districtResponse == 1) {
      hide("rightOptionsConfigDistrictEmpty_" + districtid);
      show("rightOptionsConfigDistrictFull_" + districtid);
      updateOpacity(districtName, 0.1);
      show(districtName);
      fadeIn(districtName, 0.1);

      for (var i = 0; i < rightOptionsDistrictChildCount[districtid]; i++) {
         var subid = rightOptionsDistrictChild[districtid][i];
         // Now show the line
         hide("rightOptionsConfigChildDistrictFull_" + subid);
         show("rightOptionsConfigChildDistrictEmpty_" + subid);

         show("rightOptionsConfigChildDistrict_" + subid);
      }
   } else if (districtResponse == 0) {
      hide("rightOptionsConfigDistrictFull_" + districtid);
      show("rightOptionsConfigDistrictEmpty_" + districtid);
      updateOpacity(districtName, 0.95);
      fadeOut(districtName, 0.95);
      setTimeout("hide('" + districtName + "')", 200);


      // Hide all of them
      for (var i = 0; i < rightOptionsDistrictChildCount[districtid]; i++) {
         var subid = rightOptionsDistrictChild[districtid][i];

         // Now hide the line
         hide("rightOptionsConfigChildDistrict_" + subid);
      }
   }

   if (subdistrictResponse) {
      hide("rightOptionsConfigChildDistrictEmpty_" + subdistrictid);
      show("rightOptionsConfigChildDistrictFull_" + subdistrictid);
      if (BROWSEVIEW == VIEWMAP)
         MAPEnableSubdistrict(subdistrictid);
   } else {
      hide("rightOptionsConfigChildDistrictFull_" + subdistrictid);
      show("rightOptionsConfigChildDistrictEmpty_" + subdistrictid);
      if (BROWSEVIEW == VIEWMAP)
         MAPDisableSubdistrict(subdistrictid);
   }


}

function rightOptionsDistrict(districtid) {
   // Now initialize the ajax
   ajaxObj['district_' + districtid] = createRequestObject();
   var subAjaxObj = ajaxObj['district_' + districtid];
   var salt = getSalt();

   var url = '/rightoptions/district-' + districtid + '/' + salt + '/';
   subAjaxObj.onreadystatechange = function() {
      rightOptionsDistrict_handleResponse(districtid);
   }
   subAjaxObj.open("GET", url);
   subAjaxObj.send(null);
}


function rightOptionsDistrict_handleResponse(districtid) {
   var subAjaxObj = ajaxObj['district_' + districtid];

   if (subAjaxObj.readyState == 4) {
      var json = evalJSON(subAjaxObj.responseText);

      var result = parseInt(json[districtid]);

      var districtName = 'rightOptionsDistrict_' + districtid;

      if (result) {
         updateOpacity(districtName, 0.1);
         show(districtName);
         fadeIn(districtName, 0.1);
         hide("rightOptionsConfigDistrictEmpty_" + districtid);
         show("rightOptionsConfigDistrictFull_" + districtid);

         // Activate allof the subs
         // In the AJAX call, we already activate all the subs by default
         // So we need to ensure they are all showing
         for (var i = 0; i < rightOptionsDistrictChildCount[districtid]; i++) {
            var subdistrictid = rightOptionsDistrictChild[districtid][i];

            hide("rightOptionsConfigChildDistrictEmpty_" + subdistrictid);
            show("rightOptionsConfigChildDistrictFull_" + subdistrictid);

            // Now show the line
            show("rightOptionsConfigChildDistrict_" + subdistrictid);

            if (BROWSEVIEW == VIEWMAP)
               MAPEnableSubdistrict(subdistrictid);
         }

      } else {
         hide("rightOptionsConfigDistrictFull_" + districtid);
         show("rightOptionsConfigDistrictEmpty_" + districtid);
         updateOpacity(districtName, 0.95);
         fadeOut(districtName, 0.95);
         setTimeout("hide('" + districtName + "')", 200);

         // Hide all of them
         for (var i = 0; i < rightOptionsDistrictChildCount[districtid]; i++) {
            var subdistrictid = rightOptionsDistrictChild[districtid][i];

            // Now hide the line
            hide("rightOptionsConfigChildDistrict_" + subdistrictid);

            if (BROWSEVIEW == VIEWMAP)
               MAPDisableSubdistrict(subdistrictid);
         }
      }

      //updateGraphInventory();

      // Delay a refresh
      delayListingsRefresh();
   }
}

function rightOptionsConfigMouseoverListingView(listingtypeid) {
   document.getElementById('rightOptionsConfigTitleListingView_' + listingtypeid).style.textDecoration = 'underline';
}

function rightOptionsConfigMouseoutListingView(listingtypeid) {
   document.getElementById('rightOptionsConfigTitleListingView_' + listingtypeid).style.textDecoration = 'none';
}


function rightOptionsConfigMouseoverVersionType(versiontypeid) {
   document.getElementById('rightOptionsConfigTitleVersionType_' + versiontypeid).style.textDecoration = 'underline';
}

function rightOptionsConfigMouseoutVersionType(versiontypeid) {
   document.getElementById('rightOptionsConfigTitleVersionType_' + versiontypeid).style.textDecoration = 'none';
}


function rightOptionsConfigMouseoverDistrict(districtid) {
   document.getElementById('rightOptionsConfigTitleDistrict_' + districtid).style.textDecoration = 'underline';
}

function rightOptionsConfigMouseoutDistrict(districtid) {
   document.getElementById('rightOptionsConfigTitleDistrict_' + districtid).style.textDecoration = 'none';
}

function rightOptionsConfigChildMouseoverDistrict(districtid) {
   document.getElementById('rightOptionsConfigChildTitleDistrict_' + districtid).style.textDecoration = 'underline';
}

function rightOptionsConfigChildMouseoutDistrict(districtid) {
   document.getElementById('rightOptionsConfigChildTitleDistrict_' + districtid).style.textDecoration = 'none';
}

function rightOptionsConfigMouseoverSortBy(sorttypeid) {
   document.getElementById('rightOptionsConfigTitleSortBy_' + sorttypeid).style.textDecoration = 'underline';
}

function rightOptionsConfigMouseoutSortBy(sorttypeid) {
   document.getElementById('rightOptionsConfigTitleSortBy_' + sorttypeid).style.textDecoration = 'none';
}

function rightOptionsConfigChildMouseoverSortBy(sorttypeid) {
   document.getElementById('rightOptionsConfigChildTitleSortBy_' + sorttypeid).style.textDecoration = 'underline';
}

function rightOptionsConfigChildMouseoutSortBy(sorttypeid) {
   document.getElementById('rightOptionsConfigChildTitleSortBy_' + sorttypeid).style.textDecoration = 'none';
}



function rightOptionsTitleMouseover(name) {
   document.getElementById('rightOptionsTItle' + name).style.textDecoration = 'underline';
}

function rightOptionsTitleMouseout(name) {
   document.getElementById('rightOptionsTItle' + name).style.textDecoration = 'none';
}


function rightOptionsVersionType(versiontypeid) {
   // Now initialize the ajax
   ajaxObj['versiontype_' + versiontypeid] = createRequestObject();
   var subAjaxObj = ajaxObj['versiontype_' + versiontypeid];
   var salt = getSalt();

   var url = '/rightoptions/versiontype-' + versiontypeid + '/' + salt + '/';
   subAjaxObj.onreadystatechange = function() {
      rightOptionsVersionType_handleResponse(versiontypeid);
   }
   subAjaxObj.open("GET", url);
   subAjaxObj.send(null);
}

function rightOptionsVersionType_handleResponse(versiontypeid) {
   var subAjaxObj = ajaxObj['versiontype_' + versiontypeid];
   if (subAjaxObj.readyState == 4) {
      var json = evalJSON(subAjaxObj.responseText);

      var result = parseInt(json[versiontypeid]);
      var versionTypeName = 'rightOptionsVersionType_' + versiontypeid;

      if (result) {
         updateOpacity(versionTypeName, 0.1);
         show(versionTypeName);
         fadeIn(versionTypeName, 0.1);
         hide("rightOptionsConfigVersionTypeEmpty_" + versiontypeid);
         show("rightOptionsConfigVersionTypeFull_" + versiontypeid);
      } else {
         hide("rightOptionsConfigVersionTypeFull_" + versiontypeid);
         show("rightOptionsConfigVersionTypeEmpty_" + versiontypeid);
         updateOpacity(versionTypeName, 0.95);
         fadeOut(versionTypeName, 0.95);
         setTimeout("hide('" + versionTypeName + "')", 200);
      }

      // Delay a refresh
      delayListingsRefresh();
   }
}

function rightOptionsListingView(listingviewid) {
   // Now initialize the ajax
   ajaxObj['listingview_' + listingviewid] = createRequestObject();
   var subAjaxObj = ajaxObj['listingview_' + listingviewid];
   var salt = getSalt();

   var url = '/rightoptions/listingview-' + listingviewid + '/' + salt + '/';
   subAjaxObj.onreadystatechange = function() {
      rightOptionsListingView_handleResponse(listingviewid);
   }
   subAjaxObj.open("GET", url);
   subAjaxObj.send(null);
}

function rightOptionsListingView_handleResponse(listingviewid) {
   var subAjaxObj = ajaxObj['listingview_' + listingviewid];
   if (subAjaxObj.readyState == 4) {
      var json = evalJSON(subAjaxObj.responseText);

      var result = parseInt(json[listingviewid]);

      var listingViewName = 'rightOptionsListingView_' + listingviewid;

      if (result) {
         updateOpacity(listingViewName, 0.1);
         show(listingViewName);
         fadeIn(listingViewName, 0.1);
         hide("rightOptionsConfigListingViewEmpty_" + listingviewid);
         show("rightOptionsConfigListingViewFull_" + listingviewid);
      } else {
         hide("rightOptionsConfigListingViewFull_" + listingviewid);
         show("rightOptionsConfigListingViewEmpty_" + listingviewid);
         updateOpacity(listingViewName, 0.95);
         fadeOut(listingViewName, 0.95);
         setTimeout("hide('" + listingViewName + "')", 200);
      }

      // Refresh the listing details
      delayListingRefresh();
   }
}

function rightOptionsSortBy(sorttypeid) {
   // Now initialize the ajax
   ajaxObj['sortby_' + sorttypeid] = createRequestObject();
   var subAjaxObj = ajaxObj['sortby_' + sorttypeid];
   var salt = getSalt();

   var url = '/rightoptions/sortby-' + sorttypeid + '/' + salt + '/';
   subAjaxObj.onreadystatechange = function() {
      if (subAjaxObj.readyState == 4) {
         var json = evalJSON(subAjaxObj.responseText);

         // Kill off all the sortby ids
         var sortbylist = json.list;

         //test(sortbylist);
         sortbylist = sortbylist.split(',');

         var total = sortbylist.length;

         for (var i = 0; i < total; i++) {
            var sortid = sortbylist[i];

            if (sortid == sorttypeid)
               continue;

            show("rightOptionsConfigSortByEmpty_" + sortid);
            hide("rightOptionsConfigSortByFull_" + sortid);

            var currentName = "rightOptionsSortBy_" + sortid;
            updateOpacity(currentName, 0.95);
            fadeOut(currentName, 0.95);
            setTimeout("hide('" + currentName + "')", 200);
         }

         // Enable the id
         var currentName = "rightOptionsSortBy_" + sorttypeid;
         updateOpacity(currentName, 0.1);
         show(currentName);
         fadeIn(currentName, 0.1);
         hide("rightOptionsConfigSortByEmpty_" + sorttypeid);
         show("rightOptionsConfigSortByFull_" + sorttypeid);

         // Refresh the listing details
         delayListingsRefresh();
      }
   }
   subAjaxObj.open("GET", url);
   subAjaxObj.send(null);
}



// Refresh via AJAX for listings (no tags) display
var refreshingListings = 0;

function delayListingsRefresh() {
   // Wait 300 seconds for the refresh to occur
   var delay = 1000;

   // Increment the refreshingListings variable and represent this
   // As the most recent attempt/id
   refreshingListings++;
   loading();

   if (BROWSEVIEW == VIEWLISTING)
      setTimeout('refreshListings(' + refreshingListings + ')', delay);
   else if (BROWSEVIEW == VIEWMAP)
      setTimeout('refreshMapListings(' + refreshingListings + ')', delay);
}

function refreshListings(refreshid) {
   if (!refreshingListings)
      return;

   // Only refresh the most CURRENT event
   if (refreshingListings != refreshid)
      return;

   // Now initialize the ajax
   ajaxObj['listings'] = createRequestObject();
   var subAjaxObj = ajaxObj['listings'];
   var salt = getSalt();

   if (PAGETYPE == JSMAIN)
      var url = '/refreshlistings/' + salt + '/';
   else if (PAGETYPE == JSTAG)
      var url = '/refreshtag/' + TAG + '/' + salt + '/';

   subAjaxObj.onreadystatechange = refreshListings_handleResponse;
   subAjaxObj.open("GET", url);
   subAjaxObj.send(null);

}

function refreshListings_handleResponse(listingviewid) {
   var subAjaxObj = ajaxObj['listings'];
   if (subAjaxObj.readyState == 4) {
      unloading();
      var json = evalJSON(subAjaxObj.responseText);

      var contentName = "contentSubL";
      updateOpacity(contentName, 0.1);
      updateInnerHtml(contentName, json.listings);
      //show(contentName);
      fadeIn(contentName, 0.1);

//      updateGraphInventory();
/*
      var graphInventory = "graphInventory";
      updateOpacity(graphInventory, 0.1);
      updateInnerHtml(graphInventory, json.graphinventory);
      fadeIn(graphInventory, 0.1);
*/
/*
      var graphMedian = "graphMedian";
      updateOpacity(graphMedian, 0.1);
      updateInnerHtml("graphMedian", json.graphmedian);
      fadeIn(graphMedian, 0.1);

      var graphAverage = "graphAverage";
      updateOpacity(graphAverage, 0.1);
      updateInnerHtml("graphAverage", json.graphaverage);
      fadeIn(graphAverage, 0.1);
*/
   }
}


// SINGULAR UPDATES for VIEWING LISTING ITSELF
// Refresh via AJAX for listings (no tags) display
var refreshingListing = 0;

function delayListingRefresh() {
   // Wait 300 seconds for the refresh to occur
   var delay = 1500;

   // Increment the refreshingListing variable and represent this
   // As the most recent attempt/id
   refreshingListing++;
   loading();

   setTimeout('refreshListing(' + refreshingListing + ')', delay);
}

function refreshListing(refreshid) {
   if (!refreshingListing)
      return;

   // Only refresh the most CURRENT event
   if (refreshingListing != refreshid)
      return;

   // Now initialize the ajax
   ajaxObj['listing'] = createRequestObject();
   var subAjaxObj = ajaxObj['listing'];
   var salt = getSalt();

   var url = '/listingdetails/' + LISTINGID + '/' + VERSIONID + '/' + salt + '/';

   subAjaxObj.onreadystatechange = refreshListing_handleResponse;
   subAjaxObj.open("GET", url);
   subAjaxObj.send(null);

}

function loadListing(versionid) {
   loading();
   // Now initialize the ajax
   ajaxObj['listing'] = createRequestObject();
   var subAjaxObj = ajaxObj['listing'];
   var salt = getSalt();

   var url = '/listingdetails/' + LISTINGID + '/' + versionid + '/' + salt + '/';

   subAjaxObj.onreadystatechange = refreshListing_handleResponse;
   subAjaxObj.open("GET", url);
   subAjaxObj.send(null);
}


function refreshListing_handleResponse(listingviewid) {
   var subAjaxObj = ajaxObj['listing'];
   if (subAjaxObj.readyState == 4) {
      unloading();
      var json = evalJSON(subAjaxObj.responseText);

      var contentName = "listingRemarks";
      updateOpacity(contentName, 0.1);
      updateInnerHtml(contentName, json.remarks);
      fadeIn(contentName, 0.1);

      var contentName = "listingPrice";
      updateOpacity(contentName, 0.1);
      updateInnerHtml(contentName, json.price);
      fadeIn(contentName, 0.1);

      var contentName = "listingFooter";
      updateOpacity(contentName, 0.1);
      updateInnerHtml(contentName, json.footer);
      fadeIn(contentName, 0.1);
   }
}






// Viewing individual Listings
//--------------------------------------
// Select photo
//var listingCurrentPhoto = 0;
var listingPhotoThumbBlock = 1; // Default thumb block to the first

function listingSelectPhoto(photoid) {
   if (photoid == listingCurrentPhoto)
      return;

   if (photoid < 1)
      photoid = listingPhotoTotal;
   else if (photoid > listingPhotoTotal)
      photoid = 1;

   // Set the default as hidden
   //hide("listingPhotoDefault");

   if (listingCurrentPhoto)
      hide("listingPhotoLarge_" + listingCurrentPhoto);

   listingCurrentPhoto = photoid;

   // Update the count (# of total)
   updateInnerHtml('listingPhotoLargeCurrent', zeroPad(listingCurrentPhoto, 2));

   // Fade in the new one
   updateOpacity("listingPhotoLarge_" + photoid, 0.1);
   show("listingPhotoLarge_" + photoid);
   fadeIn("listingPhotoLarge_" + photoid, 0.1);
}

function listingPhotoPageUp() {
   if (listingPhotoThumbBlock <= 1)
      return;

   hide('listingPhotoScrollThumbDownOff');
   show('listingPhotoScrollThumbDown');

   // Fade out the current thumb block
   var delay = listingPhotoThumbFadeout(listingPhotoThumbBlock);

   listingPhotoThumbBlock--;

   if (listingPhotoThumbBlock == 1) {
      hide('listingPhotoScrollThumbUp');
      show('listingPhotoScrollThumbUpOff');
   }

   // Fade in the new one
   setTimeout("listingPhotoThumbFadein(" + listingPhotoThumbBlock + ")", delay);
}

function listingPhotoPageDown() {
   if (listingPhotoThumbBlock >= listingPhotoBlocks)
      return;

   hide('listingPhotoScrollThumbUpOff');
   show('listingPhotoScrollThumbUp');

   // Fade out the current thumb block
   var delay = listingPhotoThumbFadeout(listingPhotoThumbBlock);

   listingPhotoThumbBlock++;

   if (listingPhotoThumbBlock == listingPhotoBlocks) {
      hide('listingPhotoScrollThumbDown');
      show('listingPhotoScrollThumbDownOff');
   }

   setTimeout("listingPhotoThumbFadein(" + listingPhotoThumbBlock + ")", delay);
}

function listingPhotoThumbFadeout(blockIndex) {
   // Fade out top to bottom
   var totalThumbs = listingPhotoCounts[blockIndex];
   var delay = 0;

   for (var i = 1; i <= totalThumbs; i++) {
      var objectName = 'listingPhotoThumb_' + blockIndex + '_' + i;
      // Make sure it starts at 1, even though it should already be at it
      updateOpacity(objectName, 0.95);

      // Set timeout to fade this one out
      setTimeout("fadeOut('" + objectName + "', 0.95)", delay);
      // Amount of dleay between images fading out
      delay += 60;
   }

   setTimeout("hide('listingPhotoBrowseThumbs_" + blockIndex + "')", delay);
   // Return the delay so we can setup the next
   return delay;
}

function listingPhotoThumbFadein(blockIndex) {
   // Display the block
   show("listingPhotoBrowseThumbs_" + blockIndex);

   // Fade out top to bottom
   var totalThumbs = listingPhotoCounts[blockIndex];
   var delay = 0;

   for (var i = 1; i <= totalThumbs; i++) {
      var objectName = 'listingPhotoThumb_' + blockIndex + '_' + i;
      // Make sure it starts at 1, even though it should already be at it
      updateOpacity(objectName, 0);

      // Set timeout to fade this one out
      setTimeout("fadeIn('" + objectName + "', 0)", delay);
      // Amount of dleay between images fading out
      delay += 60;
   }
}

// Large photos
function listingPhotoNext() {
   listingSelectPhoto(listingCurrentPhoto + 1);
}

function listingPhotoPrevious() {
   listingSelectPhoto(listingCurrentPhoto - 1);
}

// Price range
//------------------------------------
function rightOptionPriceRange() {
   var priceLow = getValueOf("rightOptionsPriceLow");
   var priceHigh = getValueOf("rightOptionsPriceHigh");

   if (!priceLow.length)
      priceLow = 0;

   if (!priceHigh.length)
      priceHigh = 0;

   priceLow = parseInt(priceLow);
   priceHigh = parseInt(priceHigh);

   if (priceLow < 0 || priceHigh < 0 || (priceLow > priceHigh && priceHigh > 0) || isNaN(priceLow) 
      || isNaN(priceHigh)) {
      show("rightOptionsPriceError");
      return;
   }

   hide("rightOptionsPriceError");
   updateValueOf("rightOptionsPriceLow", priceLow);
   updateValueOf("rightOptionsPriceHigh", priceHigh);

   ajaxObj['pricerange'] = createRequestObject();
   var subAjaxObj = ajaxObj['pricerange'];

   var salt = getSalt();

   var url = '/rightoptions/price-' + priceLow + '-' + priceHigh + '/' + salt + '/';
   subAjaxObj.onreadystatechange = rightOptionsPriceRange_handleResponse;
   subAjaxObj.open("GET", url);
   subAjaxObj.send(null);
}


function rightOptionsPriceRange_handleResponse() {
   var subAjaxObj = ajaxObj['pricerange'];
   if (subAjaxObj.readyState == 4) {
      var json = evalJSON(subAjaxObj.responseText);
      var pricelow = json['pricelow'];
      var pricehigh = json['pricehigh'];

      updateOpacity("rightOptionsPriceValueLow", 0.1);
      updateInnerHtml("rightOptionsPriceValueLow", pricelow);
      fadeIn("rightOptionsPriceValueLow", 0.1);

      updateOpacity("rightOptionsPriceValueHigh", 0.1);
      updateInnerHtml("rightOptionsPriceValueHigh", pricehigh);
      fadeIn("rightOptionsPriceValueHigh", 0.1);


      // Delay a refresh
      delayListingsRefresh();
   }
}

// Assisted search
//------------------------------------
var searchLastQuery = "";

function searchAssist() {

   var query = getValueOf("searchQuery");

   if (query.length < 2 || query == searchLastQuery) {
      // Hide it?
      return;
   }

   searchLastQuery = query;
   updateInnerHtml("searchAssistContent", "<span class=\"searchLoading\">...</span>");
   show("searchAssistBlock");

   ajaxObj['searchquery'] = createRequestObject();
   var subAjaxObj = ajaxObj['searchquery'];

   query = query.replace(/[^0-9a-zA-Z]/g, "+");

   var url = '/ajax_searchassist.php?query=' + query;
   subAjaxObj.onreadystatechange = searchAssist_handleResponse;
   subAjaxObj.open("GET", url);
   subAjaxObj.send(null);
}


function searchAssist_handleResponse() {
   var subAjaxObj = ajaxObj['searchquery'];
   if (subAjaxObj.readyState == 4) {
      var json = evalJSON(subAjaxObj.responseText);

      updateInnerHtml("searchAssistContent", json.results);
   }
}

// Forms
//------------------------------------------
function formCheckUsername() {
   var un = getValueOf('formValue_username');
   updateInnerHtml('formCheck_username', "...");

   if (un.length < 3)
      return;

   // Check if the username exists
   ajaxObj['formUsernameCheck'] = createRequestObject();
   var subAjaxObj = ajaxObj['formUsernameCheck'];
   var salt = getSalt();

   un = escape(un);

   var url = '/ajax_formuncheck.php?query=' + un + '&salt=' + salt;
   subAjaxObj.onreadystatechange = formCheckUsername_handleResponse;
   subAjaxObj.open("GET", url);
   subAjaxObj.send(null);
}

function formCheckUsername_handleResponse() {
   var subAjaxObj = ajaxObj['formUsernameCheck'];
   if (subAjaxObj.readyState == 4) {
      var json = evalJSON(subAjaxObj.responseText);

      var check = parseInt(json.check);

      if (check == 0)
         updateInnerHtml('formCheck_username', json.error);
      else
         updateInnerHtml('formCheck_username', '<img src="/images/checkmark.gif">');
   }
}

function formCheckEmail() {
   var email = getValueOf('formValue_email');
   updateInnerHtml('formCheck_email', "...");

   if (email.length < 5)
      return;

   // Check if the email exists
   ajaxObj['formEmailCheck'] = createRequestObject();
   var subAjaxObj = ajaxObj['formEmailCheck'];
   var salt = getSalt();

   email = escape(email);

   var url = '/ajax_formemailcheck.php?query=' + email + '&salt=' + salt;
   subAjaxObj.onreadystatechange = formCheckEmail_handleResponse;
   subAjaxObj.open("GET", url);
   subAjaxObj.send(null);
}

function formCheckEmail_handleResponse() {
   var subAjaxObj = ajaxObj['formEmailCheck'];
   if (subAjaxObj.readyState == 4) {
      var json = evalJSON(subAjaxObj.responseText);

      var check = parseInt(json.check);

      if (check == 0)
         updateInnerHtml('formCheck_email', json.error);
      else
         updateInnerHtml('formCheck_email', '<img src="/images/checkmark.gif">');
   }
}

function formCheckPassword() {
   var pw1 = getValueOf('formValue_password');

   if (pw1.length < 5)
      updateInnerHtml("formCheck_password", "...");
   else
      updateInnerHtml('formCheck_password', '<img src="/images/checkmark.gif">');
}

function formConfirmPassword() {
   var pw1 = getValueOf('formValue_password');
   var pw2 = getValueOf('formValue_passwordconfirmation');

   if (pw1.length < 5)
      return;

   if (pw1 == pw2)
      updateInnerHtml('formCheck_passwordconfirmation', '<img src="/images/checkmark.gif">');
   else
      updateInnerHtml("formCheck_passwordconfirmation", "...");
}

function formCheckHasInput(name) {
   var inputV = getValueOf('formValue_' + name);

   if (inputV.length > 0)
      updateInnerHtml('formCheck_' + name, '<img src="/images/checkmark.gif">');
   else
      updateInnerHtml("formCheck_" + name, "...");
}

function formCheckSelectedUsertype() {
   var select = document.getElementById('formValue_usertype');
   var selected = select.selectedIndex;
   var selectedValue = select.options[selected].value;


   if (selectedValue > 0)
      updateInnerHtml('formCheck_usertype', '<img src="/images/checkmark.gif">');
   else
      updateInnerHtml("formCheck_usertype", "...");
}

function formCheckCaptcha() {
   var captcha = getValueOf('formValue_captcha');
   updateInnerHtml('formCheck_captcha', "...");

   if (captcha.length != 6)
      return;

   // Check if the captcha exists
   ajaxObj['formCaptchaCheck'] = createRequestObject();
   var subAjaxObj = ajaxObj['formCaptchaCheck'];
   var salt = getSalt();

   captcha = escape(captcha);

   var url = '/ajax_formcaptchacheck.php?query=' + captcha + '&salt=' + salt;
   subAjaxObj.onreadystatechange = formCheckCaptcha_handleResponse;
   subAjaxObj.open("GET", url);
   subAjaxObj.send(null);
}

function formCheckCaptcha_handleResponse() {
   var subAjaxObj = ajaxObj['formCaptchaCheck'];
   if (subAjaxObj.readyState == 4) {
      var json = evalJSON(subAjaxObj.responseText);

      var check = parseInt(json.check);

      if (check == 0)
         updateInnerHtml('formCheck_captcha', json.error);
      else
         updateInnerHtml('formCheck_captcha', '<img src="/images/checkmark.gif">');
   }
}

// Login
//-------------------------------------
function loginDisplay() {
   hide("contentHeaderLinks");
   show("loginBlock");
}

function loginHide() {
   hide("loginBlock");
   show("contentHeaderLinks");
}

function loginQuery() {
   var un = getValueOf('loginUsername');
   var pw = getValueOf('loginPassword');
   updateValueOf('loginButton', "...");
   document.getElementById('loginButton').disabled = true;

   if (un.length < 3)
      return;

   // Check if the un exists
   ajaxObj['loginQuery'] = createRequestObject();
   var subAjaxObj = ajaxObj['loginQuery'];
   var salt = getSalt();

   un = escape(un);
   pw = md5(pw);

   var url = '/ajax_loginquery.php?un=' + un + '&pw=' + pw + '&salt=' + salt;
   subAjaxObj.onreadystatechange = loginQuery_handleResponse;
   subAjaxObj.open("GET", url);
   subAjaxObj.send(null);
}

function loginQuery_handleResponse() {
   var subAjaxObj = ajaxObj['loginQuery'];
   if (subAjaxObj.readyState == 4) {
      var json = evalJSON(subAjaxObj.responseText);

      var check = parseInt(json.check);

      if (check == 0) {
         updateInnerHtml('loginErrorBlock', json.error);
         show('loginErrorBlock');
         updateValueOf('loginButton', "login");
         document.getElementById('loginButton').disabled = false;
      } else
         location.reload(true);
   }
}


function md5(str) {
   var xl;
 
   var RotateLeft = function(lValue, iShiftBits) {
      return (lValue<<iShiftBits) | (lValue>>>(32-iShiftBits));
   };
 
   var AddUnsigned = function(lX,lY) {
      var lX4,lY4,lX8,lY8,lResult;
      lX8 = (lX & 0x80000000);
      lY8 = (lY & 0x80000000);
      lX4 = (lX & 0x40000000);
      lY4 = (lY & 0x40000000);
      lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF);
      if (lX4 & lY4) {
         return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
      }
      if (lX4 | lY4) {
         if (lResult & 0x40000000) {
            return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
         } else {
            return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
         }
      } else {
         return (lResult ^ lX8 ^ lY8);
      }
   };
 
   var F = function(x,y,z) { return (x & y) | ((~x) & z); };
   var G = function(x,y,z) { return (x & z) | (y & (~z)); };
   var H = function(x,y,z) { return (x ^ y ^ z); };
   var I = function(x,y,z) { return (y ^ (x | (~z))); };
 
   var FF = function(a,b,c,d,x,s,ac) {
      a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
      return AddUnsigned(RotateLeft(a, s), b);
   };
 
   var GG = function(a,b,c,d,x,s,ac) {
      a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
      return AddUnsigned(RotateLeft(a, s), b);
   };
 
   var HH = function(a,b,c,d,x,s,ac) {
      a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
      return AddUnsigned(RotateLeft(a, s), b);
   };
 
   var II = function(a,b,c,d,x,s,ac) {
      a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
      return AddUnsigned(RotateLeft(a, s), b);
   };
 
   var ConvertToWordArray = function(str) {
      var lWordCount;
      var lMessageLength = str.length;
      var lNumberOfWords_temp1=lMessageLength + 8;
      var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64;
      var lNumberOfWords = (lNumberOfWords_temp2+1)*16;
      var lWordArray=Array(lNumberOfWords-1);
      var lBytePosition = 0;
      var lByteCount = 0;
      while ( lByteCount < lMessageLength ) {
         lWordCount = (lByteCount-(lByteCount % 4))/4;
         lBytePosition = (lByteCount % 4)*8;
         lWordArray[lWordCount] = (lWordArray[lWordCount] | (str.charCodeAt(lByteCount)<<lBytePosition));
         lByteCount++;
      }
      lWordCount = (lByteCount-(lByteCount % 4))/4;
      lBytePosition = (lByteCount % 4)*8;
      lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition);
      lWordArray[lNumberOfWords-2] = lMessageLength<<3;
      lWordArray[lNumberOfWords-1] = lMessageLength>>>29;
      return lWordArray;
   };
 
   var WordToHex = function(lValue) {
      var WordToHexValue="",WordToHexValue_temp="",lByte,lCount;
      for (lCount = 0;lCount<=3;lCount++) {
         lByte = (lValue>>>(lCount*8)) & 255;
         WordToHexValue_temp = "0" + lByte.toString(16);
         WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2);
      }
      return WordToHexValue;
   };
 
   var x=Array();
   var k,AA,BB,CC,DD,a,b,c,d;
   var S11=7, S12=12, S13=17, S14=22;
   var S21=5, S22=9 , S23=14, S24=20;
   var S31=4, S32=11, S33=16, S34=23;
   var S41=6, S42=10, S43=15, S44=21;
 
   str = utf8_encode(str);
   x = ConvertToWordArray(str);
   a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
   
   xl = x.length;
   for (k=0;k<xl;k+=16) {
      AA=a; BB=b; CC=c; DD=d;
      a=FF(a,b,c,d,x[k+0], S11,0xD76AA478);
      d=FF(d,a,b,c,x[k+1], S12,0xE8C7B756);
      c=FF(c,d,a,b,x[k+2], S13,0x242070DB);
      b=FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE);
      a=FF(a,b,c,d,x[k+4], S11,0xF57C0FAF);
      d=FF(d,a,b,c,x[k+5], S12,0x4787C62A);
      c=FF(c,d,a,b,x[k+6], S13,0xA8304613);
      b=FF(b,c,d,a,x[k+7], S14,0xFD469501);
      a=FF(a,b,c,d,x[k+8], S11,0x698098D8);
      d=FF(d,a,b,c,x[k+9], S12,0x8B44F7AF);
      c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);
      b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE);
      a=FF(a,b,c,d,x[k+12],S11,0x6B901122);
      d=FF(d,a,b,c,x[k+13],S12,0xFD987193);
      c=FF(c,d,a,b,x[k+14],S13,0xA679438E);
      b=FF(b,c,d,a,x[k+15],S14,0x49B40821);
      a=GG(a,b,c,d,x[k+1], S21,0xF61E2562);
      d=GG(d,a,b,c,x[k+6], S22,0xC040B340);
      c=GG(c,d,a,b,x[k+11],S23,0x265E5A51);
      b=GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA);
      a=GG(a,b,c,d,x[k+5], S21,0xD62F105D);
      d=GG(d,a,b,c,x[k+10],S22,0x2441453);
      c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681);
      b=GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8);
      a=GG(a,b,c,d,x[k+9], S21,0x21E1CDE6);
      d=GG(d,a,b,c,x[k+14],S22,0xC33707D6);
      c=GG(c,d,a,b,x[k+3], S23,0xF4D50D87);
      b=GG(b,c,d,a,x[k+8], S24,0x455A14ED);
      a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905);
      d=GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8);
      c=GG(c,d,a,b,x[k+7], S23,0x676F02D9);
      b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);
      a=HH(a,b,c,d,x[k+5], S31,0xFFFA3942);
      d=HH(d,a,b,c,x[k+8], S32,0x8771F681);
      c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122);
      b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C);
      a=HH(a,b,c,d,x[k+1], S31,0xA4BEEA44);
      d=HH(d,a,b,c,x[k+4], S32,0x4BDECFA9);
      c=HH(c,d,a,b,x[k+7], S33,0xF6BB4B60);
      b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);
      a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6);
      d=HH(d,a,b,c,x[k+0], S32,0xEAA127FA);
      c=HH(c,d,a,b,x[k+3], S33,0xD4EF3085);
      b=HH(b,c,d,a,x[k+6], S34,0x4881D05);
      a=HH(a,b,c,d,x[k+9], S31,0xD9D4D039);
      d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);
      c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);
      b=HH(b,c,d,a,x[k+2], S34,0xC4AC5665);
      a=II(a,b,c,d,x[k+0], S41,0xF4292244);
      d=II(d,a,b,c,x[k+7], S42,0x432AFF97);
      c=II(c,d,a,b,x[k+14],S43,0xAB9423A7);
      b=II(b,c,d,a,x[k+5], S44,0xFC93A039);
      a=II(a,b,c,d,x[k+12],S41,0x655B59C3);
      d=II(d,a,b,c,x[k+3], S42,0x8F0CCC92);
      c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D);
      b=II(b,c,d,a,x[k+1], S44,0x85845DD1);
      a=II(a,b,c,d,x[k+8], S41,0x6FA87E4F);
      d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);
      c=II(c,d,a,b,x[k+6], S43,0xA3014314);
      b=II(b,c,d,a,x[k+13],S44,0x4E0811A1);
      a=II(a,b,c,d,x[k+4], S41,0xF7537E82);
      d=II(d,a,b,c,x[k+11],S42,0xBD3AF235);
      c=II(c,d,a,b,x[k+2], S43,0x2AD7D2BB);
      b=II(b,c,d,a,x[k+9], S44,0xEB86D391);
      a=AddUnsigned(a,AA);
      b=AddUnsigned(b,BB);
      c=AddUnsigned(c,CC);
      d=AddUnsigned(d,DD);
   }
 
   var temp = WordToHex(a)+WordToHex(b)+WordToHex(c)+WordToHex(d);
 
   return temp.toLowerCase();
}

function utf8_encode(string) {
   string = (string+'').replace(/\r\n/g, "\n").replace(/\r/g, "\n");
 
   var utftext = "";
   var start, end;
   var stringl = 0;
 
   start = end = 0;
   stringl = string.length;
   for (var n = 0; n < stringl; n++) {
      var c1 = string.charCodeAt(n);
      var enc = null;
 
      if (c1 < 128) {
         end++;
      } else if((c1 > 127) && (c1 < 2048)) {
         enc = String.fromCharCode((c1 >> 6) | 192) + String.fromCharCode((c1 & 63) | 128);
      } else {
         enc = String.fromCharCode((c1 >> 12) | 224) + String.fromCharCode(((c1 >> 6) & 63) | 128) + String.fromCharCode((c1 & 63) | 128);
      }
      if (enc != null) {
         if (end > start) {
            utftext += string.substring(start, end);
         }
         utftext += enc;
         start = end = n+1;
      }
   }
 
   if (end > start) {
      utftext += string.substring(start, string.length);
   }
 
   return utftext;
} 

// Nearby interface
//----------------------------------------
var NEARBYLISTINGWIDTH = 280; // Corresponds width width of offset
var NEARBYLISTINGMAX = 10;
var nearbyCurrentView = 1;
var nearbyMapOverlay = 0;

function nearbyPrevious() {
   if (nearbyCurrentView <= 1)
      return;

   nearbyCurrentView--;

   if (nearbyCurrentView <= 1)
      hide("nearbyPrevious");

   if (nearbyCurrentView < NEARBYLISTINGMAX)
      show("nearbyNext");

   shiftLeft("nearbyListings", NEARBYLISTINGWIDTH);

   var latitude = document.getElementById("nearbyLatitude_" + nearbyCurrentView).innerHTML;
   var longitude = document.getElementById("nearbyLongitude_" + nearbyCurrentView).innerHTML;
   var blueIcon = new GIcon(G_DEFAULT_ICON);
   blueIcon.image = "http://www.google.com/intl/en_us/mapfiles/ms/micons/blue-dot.png";
   var point = new GLatLng(latitude, longitude);
   markerOptions = { icon:blueIcon };

   if (nearbyMapOverlay != 0)
      map.removeOverlay(nearbyMapOverlay);

   nearbyMapOverlay = new GMarker(point, markerOptions);
   map.addOverlay(nearbyMapOverlay);


}

function nearbyNext() {
   if (nearbyCurrentView >= NEARBYLISTINGMAX)
      return;

   nearbyCurrentView++;

   if (nearbyCurrentView > 1)
      show("nearbyPrevious");

   if (nearbyCurrentView >= NEARBYLISTINGMAX)
      hide("nearbyNext");

   shiftRight("nearbyListings", NEARBYLISTINGWIDTH);

   var latitude = document.getElementById("nearbyLatitude_" + nearbyCurrentView).innerHTML;
   var longitude = document.getElementById("nearbyLongitude_" + nearbyCurrentView).innerHTML;
   var blueIcon = new GIcon(G_DEFAULT_ICON);
   blueIcon.image = "http://www.google.com/intl/en_us/mapfiles/ms/micons/blue-dot.png";
   var point = new GLatLng(latitude, longitude);
   markerOptions = { icon:blueIcon };

   if (nearbyMapOverlay != 0)
      map.removeOverlay(nearbyMapOverlay);

   nearbyMapOverlay = new GMarker(point, markerOptions);
   map.addOverlay(nearbyMapOverlay);

}

// Graphs
//----------------------------------------
function updateGraphInventory() {
   var salt = getSalt();
   var graphInventory = "graphInventory";
   updateOpacity(graphInventory, 0.1);
   updateInnerHtml(graphInventory, '<img src="/graph/inventory-' + salt + '/sf.gif">');
   fadeIn(graphInventory, 0.1);
}


// User options
//----------------------------------------
function userOptions(name, value) {
   loading();
   var salt = getSalt();
   ajaxObj['useroptions' + salt] = createRequestObject();
   var subAjaxObj = ajaxObj['useroptions' + salt];
   var url = '/ajax_useroptions.php?name=' + name + '&value=' + value + '&salt=' + salt;
   subAjaxObj.onreadystatechange = function() {
      if (subAjaxObj.readyState == 4) {
         var json = evalJSON(subAjaxObj.responseText);
         var refreshList = json.refreshlist;
         refreshList = refreshList.split(',');
         var numToRefresh = refreshList.length;

         for (var i = 0; i < numToRefresh; i++) {
            var refreshName = refreshList[i];

            updateInnerHtml(refreshName, json[refreshName]);
         }
         unloading();
      }
   }

   subAjaxObj.open("GET", url);
   subAjaxObj.send(null);

}

function toggleDefaultView() {
   loading();
   var salt = getSalt();
   ajaxObj['toggledefaultview' + salt] = createRequestObject();
   var subAjaxObj = ajaxObj['toggledefaultview' + salt];
   var url = '/ajax_toggledefaultview.php?salt=' + salt;
   subAjaxObj.onreadystatechange = function() {
      if (subAjaxObj.readyState == 4) {
         var json = evalJSON(subAjaxObj.responseText);

         var newview = parseInt(json.response);
         if (newview == BROWSEVIEW)
            updateInnerHtml("defaultView", json.responseon);
         else
            updateInnerHtml("defaultView", json.responseoff);

         unloading();
      }
   }

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



// MAP
//----------------------------------------
var MAPBoundaries = [];
var MAPSubdistricts = [];
var MAPSubdistrictCount = 0;
var MAPPlottedListings = [];
var MAPPlottedListingCount = 0;
var MAPViewingMarker = 0;

function displayMapMessage(content) {
   updateInnerHtml("mapRefreshingContent", content);
   show("mapRefreshingBg");
   show("mapRefreshingContent");
}

function hideMapMessage() {
   hide("mapRefreshingBg");
   hide("mapRefreshingContent");
}

function refreshMapListings(refreshid) {
   if (!refreshingListings)
      return;

   // Only refresh the most CURRENT event
   if (refreshingListings != refreshid)
      return;

   unloading();
   hideMapMessage();
   refreshingListings = 0;
   //updateGraphInventory();

   // Deliver a PAGE parameter only if we are zoomed out. If zoomed in
   // Then we deliver a 0 page to obtain the point data also
   if (map.getZoom() >= MAPZOOMTHRESHOLD)
      MAPRefreshListings(0);
   else
      MAPRefreshListings(1);

   //MAPRetrievePoints();
}

// Should only be called once, properly
function MAPRetrievePoints() {
   MapBoundaries = [];
   displayMapMessage("Loading map contents...");

   ajaxObj['mapretrieve'] = createRequestObject();
   var subAjaxObj = ajaxObj['mapretrieve'];
   var salt = getSalt();
   var url = '/mapdata/' + salt + '/';
   subAjaxObj.onreadystatechange = function() {
      if (subAjaxObj.readyState == 4) {
         map.clearOverlays();
         unloading();
         var json = evalJSON(subAjaxObj.responseText);

         // Active 
         var sdactivelist = json.sdactivelist;
         sdactivelist = sdactivelist.split(',');
         numSD = sdactivelist.length;

         for (var i = 0; i < numSD; i++) {
            var currentSd = sdactivelist[i];
            var vertexes = [];

            var pointCount = json[currentSd + '_count'];
            for (var j = 1; j <= pointCount; j++) {
               var latitude = json['point_' + currentSd + '_' + j + '_latitude'];
               var longitude = json['point_' + currentSd + '_' + j + '_longitude'];

               vertexes.push(new GLatLng(latitude, longitude));
            }

            //var polygon = new GPolygon(vertexes, "#000000", 1, 0.5);
            var polygon = new GPolygon(vertexes, "#000000", 1, 0.5, "#ffffff", 0);
            polygon.Subid = currentSd;
            polygon.Enabled = true;

            // Assign the polygon locally
            MAPSetSubdistrictEnable(polygon);
            MAPBoundaries[currentSd] = polygon;

            map.addOverlay(polygon);

            // Cache the subdistrict so we know
            MAPSubdistricts[MAPSubdistrictCount] = currentSd;
            MAPSubdistrictCount++;
         }

         // Inactive 
         var sdinactivelist = json.sdinactivelist;
         sdinactivelist = sdinactivelist.split(',');
         numSD = sdinactivelist.length;

         for (var i = 0; i < numSD; i++) {
            var currentSd = sdinactivelist[i];
            var vertexes = [];

            var pointCount = json[currentSd + '_count'];
            for (var j = 1; j <= pointCount; j++) {
               var latitude = json['point_' + currentSd + '_' + j + '_latitude'];
               var longitude = json['point_' + currentSd + '_' + j + '_longitude'];

               vertexes.push(new GLatLng(latitude, longitude));
            }

            var polygon = new GPolygon(vertexes, "#000000", 1, 0.5, "#ffffff", 0);
            polygon.Subid = currentSd;
            polygon.Enabled = false;

            // Assign the polygon locally
            MAPSetSubdistrictDisable(polygon);
            MAPBoundaries[currentSd] = polygon;
            map.addOverlay(polygon);

            MAPSubdistricts[MAPSubdistrictCount] = currentSd;
            MAPSubdistrictCount++;
         }

         // Add teh listener for moving the map around
         GEvent.addListener(map, "moveend", function() {

            // Clear the row of listings
            //MAPClearListings();

            // Delay a refresh
            delayListingsRefresh();
         });

         // Set the zoom events
         GEvent.addListener(map, "zoomend", function (oldLevel, newLevel) {
            // Clear the row of listings
            //MAPClearListings();

            if (newLevel >= MAPZOOMTHRESHOLD && oldLevel < MAPZOOMTHRESHOLD) {
               map.clearOverlays();

               // Add the overlays back again but set them as lighter/borders only
               for (var i = 0; i < MAPSubdistrictCount; i++) {
                  var subid = MAPSubdistricts[i];
                  var polygon = MAPBoundaries[subid];

                  if (polygon.Enabled)
                     MAPSetSubdistrictZoomEnable(polygon);
                  else
                     MAPSetSubdistrictZoomDisable(polygon);

                  MAPBoundaries[subid] = polygon;
                  map.addOverlay(polygon);
               }

            } else if (newLevel < MAPZOOMTHRESHOLD && oldLevel >= MAPZOOMTHRESHOLD) {
               // Load the districts
               map.clearOverlays();

               // Add the overlays back again but set them as lighter/borders only
               for (var i = 0; i < MAPSubdistrictCount; i++) {
                  var subid = MAPSubdistricts[i];
                  var polygon = MAPBoundaries[subid];

                  if (polygon.Enabled)
                     MAPSetSubdistrictEnable(polygon);
                  else
                     MAPSetSubdistrictDisable(polygon);

                  MAPBoundaries[subid] = polygon;
                  map.addOverlay(polygon);
               }
            }
            delayListingsRefresh();
         });

         hideMapMessage();
         refreshingListings = 0;
      }
   }

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

function MAPEnableSubdistrict(subdistrictid) {
   var polygon = MAPBoundaries[subdistrictid];
   if (map.getZoom() >= 14)
      MAPSetSubdistrictZoomEnable(polygon)
   else
      MAPSetSubdistrictEnable(polygon)
}

function MAPDisableSubdistrict(subdistrictid) {

   var polygon = MAPBoundaries[subdistrictid];
   if (map.getZoom() >= 14)
      MAPSetSubdistrictZoomDisable(polygon)
   else
      MAPSetSubdistrictDisable(polygon)
}

function MAPSetSubdistrictZoomEnable(polygon) {
   polygon.Enabled = true;

   polygon.setFillStyle({color: "#00ff00", opacity: 0.08});
   polygon.setStrokeStyle({color: "#444444", weight: 2});

   GEvent.clearListeners(polygon);
}

function MAPSetSubdistrictZoomDisable(polygon) {
   polygon.Enabled = false;

   polygon.setFillStyle({color: "#ffffff", opacity: 0.0});
   polygon.setStrokeStyle({color: "#aaaaaa", weight: 1});

   GEvent.clearListeners(polygon);
}

function MAPSetSubdistrictDisable(polygon) {
   polygon.Enabled = false;

   polygon.setStrokeStyle({color: "#000000", weight: 1});
   polygon.setFillStyle({color: "#ffffff", opacity: 0});
   GEvent.clearListeners(polygon);

   // Add the event listeners for toggling these
   GEvent.addListener(polygon, "mouseover", function() {
      displayMapMessage("Click to add area to search");
      this.setFillStyle({opacity: 0.15, color: "#00ff00"});
   });

   GEvent.addListener(polygon, "mouseout", function() {
      hideMapMessage();
      this.setFillStyle({opacity: 0});
   });

   GEvent.addListener(polygon, "click", function() {
      displayMapMessage("Updating search areas...");
      //this.setFillStyle({opacity: 0.3, color: "#00ff00"});
      MAPSetSubdistrictEnable(this);
      rightOptionsChildDistrict(this.Subid);
   });


}

function MAPSetSubdistrictEnable(polygon) {
   polygon.Enabled = true;

   polygon.setStrokeStyle({color: "#000000", weight: 1});
   polygon.setFillStyle({color: "#00ff00", opacity: 0.3});

   GEvent.clearListeners(polygon);

   GEvent.addListener(polygon, "mouseover", function() {
      displayMapMessage("Click to remove area from search");
      this.setFillStyle({opacity: 0.15, color: "#ff0000"});
   });

   GEvent.addListener(polygon, "mouseout", function() {
      hideMapMessage();
      this.setFillStyle({opacity: 0.3, color: "#00ff00"});
   });

   GEvent.addListener(polygon, "click", function() {
      displayMapMessage("Updating search areas...");
      //this.setFillStyle({opacity: 0});
      MAPSetSubdistrictDisable(this);
      rightOptionsChildDistrict(this.Subid);
   });
}

function MAPClearListings() {
   for (var i = 1; i <= MAPMAXLISTINGSPERPAGE; i++) {
      updateInnerHtml("listingrow_" + i, "");
   }
}

function MAPClearListingsFrom(from) {
   for (var i = from; i <= MAPMAXLISTINGSPERPAGE; i++) {
      updateInnerHtml("listingrow_" + i, "");
   }
}

function MAPRefreshListings(page) {
   displayMapMessage("Refreshing data...");
   loading();
   var bounds = map.getBounds();
   var boundsSW = bounds.getSouthWest();
   var boundsNE = bounds.getNorthEast();

   var salt = getSalt();
   ajaxObj['maprefreshlistings'] = createRequestObject();
   var subAjaxObj = ajaxObj['maprefreshlistings'];
   var url = '/mapdata/listings/' + page + '/' + boundsSW.lat() + '/' + boundsNE.lat() + '/' +
             boundsSW.lng() + '/' + boundsNE.lng() + '/';

   subAjaxObj.onreadystatechange = function() {
      if (subAjaxObj.readyState == 4) {
         var json = evalJSON(subAjaxObj.responseText);

         var numresults = parseInt(json.numresults);
         var total = parseInt(json.total);

         updateInnerHtml('mapListingsTotal', total);
         updateInnerHtml('mapListingPaging', json.paging);

         var delay = 0;

         // Update the data rows
         for (var i = 1; i <= numresults; i++) {
            var listingrow = removeApos(json[i]);

            // First fade out the listing
            var objectName = "listingrow_" + i;
            delay += 20;

            //updateInnerHtml(objectName, listingrow);
            // Fade it in
            setTimeout("updateInnerHtml('" + objectName + "', '" + listingrow + "')", delay);
         }

         if (numresults < MAPLISTINGSPERPAGE)
            MAPClearListingsFrom(numresults+1);

         // Plot the points on the map
         if (map.getZoom() >= MAPZOOMTHRESHOLD && !page) {
            // Clear the old overlays
            for (var k = 0; k < MAPPlottedListingCount; k++) {
               var marker = MAPPlottedListings[k];
               map.removeOverlay(marker);
            }

            for (var j = 1; j <= total; j++) {
               var lat = json['latitude_' + j];
               var lng = json['longitude_' + j];
               var point = new GLatLng(lat, lng);

               var marker = new GMarker(point);
               MAPPlottedListings[j-1] = marker;
               map.addOverlay(marker);
            }

            MAPPlottedListingCount = total;
         }

         hideMapMessage();
         unloading();
      }
   }

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

function MAPListingsPerPage(count) {
   if (count < 1 || count > MAPMAXLISTINGSPERPAGE)
      return;

   userOptions("maplistingsperpage", count);

   MAPLISTINGSPERPAGE = count;

   MAPClearListingsFrom(MAPLISTINGSPERPAGE+1);

   for (var i = 1; i <= MAPLISTINGSPERPAGE; i++)
      show("listingrow_" + i);

   for (i; i <= MAPMAXLISTINGSPERPAGE; i++)
      hide("listingrow_" + i);

   MAPRefreshListings(1); // Start from page 1 again
}

function MAPPage(page) {
   updateInnerHtml('mapListingPaging', "...");
   MAPRefreshListings(page);
}

function MAPOverListingRow(listingid, latitude, longitude) {
   if (MAPViewingMarker != 0)
      map.removeOverlay(MAPViewingMarker);

   var point = new GLatLng(latitude, longitude);
   var blueIcon = new GIcon(G_DEFAULT_ICON);
   blueIcon.image = "http://www.google.com/intl/en_us/mapfiles/ms/micons/blue-dot.png";
   var tmpMarkerOptions = { icon:blueIcon };
   MAPViewingMarker = new GMarker(point, tmpMarkerOptions);
   map.addOverlay(MAPViewingMarker);


   //updateInnerHtml("listingRowDisplayContent_" + listingid, "this is a test");
   show("listingRowDisplayArrow_" + listingid);
   show("listingRowDisplay_" + listingid);
}

function MAPOffListingRow(listingid) {
   hide("listingRowDisplay_" + listingid);
   hide("listingRowDisplayArrow_" + listingid);

   if (MAPViewingMarker != 0)
      map.removeOverlay(MAPViewingMarker);

   MAPViewingMarker = 0;
}


