initialSearch = "1"
today = new Date();

var highlightProp = function() {
  mlsNumber = this.readAttribute('rel')
  resultsMarkers.showMarker(mlsNumber)
  $$('div.active').each(function(el) { el.removeClassName('active') })
  $(this).addClassName('active')
}

function searchObject(triggerId) {
  this.swlat = null
  this.swlng = null
  this.nelat = null
  this.nelng = null

  //set serachtype based on the id of triggering element
  if (triggerId == 'mls_number') {
    this.searchType = 'mls'
    this.activeForm = $('mlsSearchForm')
  }
  else if (triggerId == 'street_number' || triggerId == 'street_name') {
    this.searchType = 'street'
    this.activeForm = $('streetSearchForm')
  }
  else {
    this.searchType = 'default'
    this.activeForm = $('searchForm')
  }

  this.startSearch = function() {
    // while search is running, remove the class which is required for
    // property highlighting to happen.
    $('resultsList').removeClassName('ready');

    this.setMapBounds();
    this.sendSearchRequest();
  }

  this.sendSearchRequest = function() {
    var url = '/residentials/results';
    if (initialSearch == "1") this.params = this.getParams()
    else this.params = this.compileParams()
    // Manually set MLS number value if it is present, because it is not
    // part of the form (de)serialization scheme.
    splitParams = this.params.split("&")
    if (splitParams.first().include("mls_number")) {
      var mls_num = splitParams.first().split("=")[1]
      $("mls_number").value = mls_num
    }

    // Substitute & with / just to make url nicer
    var rm_and = /&/ig;
    var hash_params = this.params.replace(rm_and,"/");

    try {
      // Update link to the list view in the footer. It may not be available
      // on all sites that modify the footer.
      $('residentialsListViewLink').href = url + '?' + this.params;
    } catch (e) {}

    new Ajax.Request(url, {
      method: 'get', 
      accept:'text/javascript',
      parameters: this.params,
      onCreate: function() {
        $('listLoader').addClassName('on')
        $('mapLoader').addClassName('on')
      },
      onComplete: function(r) {
        try {
          $$('#resultsList.ready div.resultRow').each(function(row) {
            row.observe('click', highlightProp)
            row.observe('mouseover', highlightProp)
          })
        }
        catch(e) {
          alert(e)
        }
      }
    });
    // Don't touch window.location unless we have hash to add.
    // Touching window.location without adding a hash couses firefox to reload page in loop
    if(hash_params != "") {
      window.location.hash = hash_params;
    }
  }

  this.getParams = function() {
    var params = null;

    if(window.location.hash) { // the page has just laoded and the url has a hash already set
      var searchHash = window.location.hash;
      var params = this.convertCleanHashToNativeQuery(searchHash)

      //load form with params
      Form.deserialize(this.activeForm, params);

      // params += "&bookmarkedURL=1"
    }
    else { //came to page directly with no hash in url
      if (getCookie($('searchForm').id)) loadSelections($('searchForm'))
      params = this.compileParams();
    }

    initialSearch = "0";
    return params;
  }

  this.compileParams = function() {
    var params = Form.serialize( this.activeForm );

    if (this.searchType == "street") {
      // remove defaults from the query (and URL), if present
      params = params.replace("street_number=Street%23", "");
      params = params.replace("&street_name=Street%20Name", "");

    } else if (this.searchType == "mls" && params.indexOf("mls_number=MLS%23") != -1) {
      // another hack: this means that the user cleared the mls input field
      // and tabbed out of it to street input before search has been completed
      this.searchType = "default";
      this.activeForm = $('searchForm');
      params = Form.serialize(this.activeForm);
    }

    params = params.replace(/[^&]+=(\.|Min|Max|city%2C%20zip%20or%20subdivision)?(?:&|$)/g, '');
    params = params.replace(/&$/g, '');

    params = params.replace(/%2C/ig, ",");
    if (this.searchType == 'mls') params = params.replace(/%20/ig, ""); //remove spaces only in mls number search

    params += '&swlat=' + this.swlat;
    params += '&swlng=' + this.swlng;
    params += '&nelat=' + this.nelat;
    params += '&nelng=' + this.nelng;
    // params += '&initialSearch=' + initialSearch;
    params += "&searchType="+this.searchType
    return params;
  }

  this.setMapBounds = function() {
    if (map) {
      bounds = map.getBounds()
      sw = bounds.getSouthWest()
      ne = bounds.getNorthEast()
      this.swlat = sw.lat()
      this.swlng = sw.lng()
      this.nelat = ne.lat()
      this.nelng = ne.lng()
    }
  }

  this.convertCleanHashToNativeQuery = function(cleanHash) {
    // Restore &
    rm_slash = /\//ig;
    var cleanParams = cleanHash.replace(rm_slash,"&");

    // Remove hash symbol
    var rm_hash = /#/ig;
    return cleanParams.replace(rm_hash,"");
  }
}


function buildSearch(e) {
  //check for id of triggering element
  var elementId = (typeof(e) !== 'undefined' ? e.id : false)
  map.closeExtInfoWindow()
  searcher = new searchObject(elementId)
  searcher.startSearch()
}

function pageResults(page) {

  // Hide map infoWindow, otherwise map refresh will hang
  var mapBubble = $("propertyInfoWindow");
  if (mapBubble) {
    mapBubble.hide();
  }

  new Ajax.Request('/residentials/results?page='+page, {
    asynchronous:true, 
    evalScripts:true, 
    parameters:Form.serialize($('searchForm')),
    accept:'text/javascript',
    onCreate: function() {
      $('listLoader').addClassName('on')
      $('mapLoader').addClassName('on')
    }
  })

}

handleDefaultValues = function(e, phrase) {
  defaultValue = phrase
  currentValue = Event.element(e).value
  input = Event.element(e)

  if (e.type == 'focus' && currentValue == defaultValue) {
    input.value = ''
    input.removeClassName('faded')
  }
  else if (e.type == 'blur' && currentValue == '') {
    input.value = defaultValue
    input.addClassName('faded')
  }
}

function attachEvents() {

  if ($('searchForm')) {
    try {
      Event.observe(this, 'beforeunload', function() {
        saveSelections($('searchForm'))
      })

      if (pageTracker) {
        Event.observe('moreFieldsLink', 'click', function() { pageTracker._trackEvent('searchForm', 'show/hide advanced search form'); })

        if($('minListPrice')) { Event.observe('minListPrice', 'change', function() { pageTracker._trackEvent('searchForm', 'Changed MIN price'); }); }
        if($('maxListPrice')) { Event.observe('maxListPrice', 'change', function() { pageTracker._trackEvent('searchForm', 'Changed Max Price'); }); }
        if($('minBedrooms')) {  Event.observe('minBedrooms', 'change', function() { pageTracker._trackEvent('searchForm', 'Changed Bedrooms'); }); }
        if($('minBathrooms')) {  Event.observe('minBathrooms', 'change', function() { pageTracker._trackEvent('searchForm', 'Changed Bathrooms'); }); }
        if($('minSquareFeet')) {  Event.observe('minSquareFeet', 'change', function() { pageTracker._trackEvent('searchForm', 'Changed MIN square feet'); }); }

        if($('city')) { Event.observe('city', 'change', function() { pageTracker._trackEvent('searchForm', 'Changed City'); }); }
        if($('subdivision')) {  Event.observe('subdivision', 'blur', function() { pageTracker._trackEvent('searchForm', 'Blurred Subdivision'); }); }
        if($('zip')) {  Event.observe('zip', 'blur', function() { pageTracker._trackEvent('searchForm', 'Blurred Zip'); }); }

        if($('minStories')) { Event.observe('minStories', 'click', function() { pageTracker._trackEvent('searchForm', 'Stories radio button changed'); }); }
        if($('pool_on_property')) { Event.observe('pool_on_property', 'click', function() { pageTracker._trackEvent('searchForm', 'Pool radio button changed'); }); }
        if($('waterfront')) { Event.observe('waterfront', 'click', function() { pageTracker._trackEvent('searchForm', 'Waterfront radio button changed'); }); }
      }
    }
    catch(e) {
      // console.log('Error adding unload event '+e)
    }

    Event.observe('searchformResetter', 'click', function() {
      $('searchForm').reset()
      $('mlsSearchForm').reset()
      $('streetSearchForm').reset()
      eraseCookie('more_search_fields')
      window.location.hash = null
      buildSearch()
    });

    enableSearchFormTriggers()
  }

  // show/hide advanced search fields
  if (mf = $('moreFieldsLink')) Event.observe(mf, 'click', showMoreSearchFields)

  // expand results list
  if ($('expandLink')) {
    xLink = $('expandLink')
    Event.observe(xLink, 'click', function() {
      if (xLink.rel == 'contracted') {
        $('leftColumn').addClassName('expanded')
        $('rightColumn').addClassName('contracted')
        xLink.rel = 'expanded'
        xLink.update('❮❮')
      }
      else {
        $('leftColumn').removeClassName('expanded')
        $('rightColumn').removeClassName('contracted')
        xLink.rel = 'contracted'
        xLink.update('❯❯')
      }
      toggleResultsDetail();
    })
  }

  $$('.numberInput').invoke('observe', 'keydown', function(e) {
    if (! isNumberInput(e.keyCode)) {
      e.stop();
    }
  });
}

function enableSearchFormTriggers() {

  var delay = 0.4;

  // execute search when these fields change

  $$('input.searchTrigger').each(function(e) {
    new Form.Element.DelayedObserver(e, delay, buildSearch.bindAsEventListener(e));
  });

  $$('select.searchTrigger').invoke('observe', 'change', buildSearch.bindAsEventListener(this));

  $$('label.triggerLabel').invoke('observe', 'click', buildSearch.bindAsEventListener(this))

  // city and subdivision are observer only for cleared input - otherwise they do auto-completion
  if( $('city') ) {
    new Form.Element.DelayedObserver($('city'), delay, function() {
      if ($('city').value === "") buildSearch($('city'));
    });
  }
  if( $('subdivision') ) {
    new Form.Element.DelayedObserver($('subdivision'), delay, function() {
      if ($('subdivision').value === "") buildSearch($('subdivision'));
    });
  }

  //quick search defaults
  if (mls = $('mls_number')) {
    mlsDefault = 'MLS#'
    new Form.Element.DelayedObserver(mls, delay, buildSearch.bindAsEventListener(this));
    Event.observe(mls, 'blur', handleDefaultValues.bindAsEventListener(this, mlsDefault));
    Event.observe(mls, 'focus', handleDefaultValues.bindAsEventListener(this, mlsDefault));
  }
  if ( streetNumber = $('street_number') ) {
    new Form.Element.DelayedObserver($(streetNumber), delay, buildSearch.bindAsEventListener(this));
    streetNumberDefault = 'Street#';
    Event.observe(streetNumber, 'blur', handleDefaultValues.bindAsEventListener(this, streetNumberDefault));
    Event.observe(streetNumber, 'focus', handleDefaultValues.bindAsEventListener(this, streetNumberDefault));
  }
  if (streetName = $('street_name')) {
    new Form.Element.DelayedObserver($(streetName), delay, buildSearch.bindAsEventListener(this));
    streetNameDefault = 'Street Name';
    Event.observe(streetName, 'blur', handleDefaultValues.bindAsEventListener(this, streetNameDefault));
    Event.observe(streetName, 'focus', handleDefaultValues.bindAsEventListener(this, streetNameDefault));
  }
}

var init = function () {
  try {
    attachEvents();
  }
  catch(e) {
    alert(e)
  }


  // make sure this only runs on index page
  try {
    if ($('resultsMap')) {
      if (map) {
        buildSearch()
      }
      else {
        setTimeout("buildSearch()", 500)
      }
    }
  }
  catch (e) {
   console.log('MAP ERROR: '+e)
  }

  if (hc = $("horizontal_carousel")) {
    dCar = new UI.Carousel(hc)
    dCar.observe('scroll:ended', function(event) {
     $('currentPic').innerHTML = Math.ceil(event.memo.carousel.currentIndex()+1)
    })
  }
}

// document.observe('dom:loaded', init)
Event.observe (window, 'load', init)

//
// Various helper functions
//

// shows/hides advanced search fields
function showMoreSearchFields() {
  currentText = $('moreFewer')
  currentArrow = $('moreLessArrow')
  activeText = "Fewer"
  inactiveText = "More"
  activeArrow = "↑"
  inactiveArrow = "↓"
  duration = 0.5

  var days = 0.5
  var exp = new Date(today.getTime()+days*24*60*60*1000);
  if (currentText.innerHTML == activeText) {
    Effect.BlindUp('advancedExtra', {duration:duration})
    currentText.update(inactiveText);
    currentArrow.update(inactiveArrow);
    setCookie('more_search_fields', "0", exp)
  }
  else if (currentText.innerHTML == inactiveText) {
    Effect.BlindDown('advancedExtra', {duration:duration})
    currentText.update(activeText);
    currentArrow.update(activeArrow);
    setCookie('more_search_fields', "1", exp)
  }
  else {
    currentText.textContent = activeText;
  }
}

function toggleResultsDetail() {
  if (xLink = $('expandLink')) {
    if (xLink.rel == 'expanded') {
      $$('.propertyPreviewPic').invoke('show');
      $$('.propertyActions').invoke('show');
      $$('.propertySquareFeet').invoke('show');
      $$('.propertySubdivision').invoke('show');
    } else if (xLink.rel == 'contracted') {
      $$('.propertyPreviewPic').invoke('hide');
      $$('.propertyActions').invoke('hide');
      $$('.propertySquareFeet').invoke('hide');
      $$('.propertySubdivision').invoke('hide');
    }
  }
}

// Removes any leading or trailing whitespace from a string.
//
function stripWhitespace(str) {
  return str.replace(/^\s*|\s*$/g,'');
}



// A generic function to call after user selects a list item from the
// auto-complete list.
//
// It keeps previous entries, replaces the partial input which triggered
// the auto-completion with the selected item and calls the search function.
//
// selectedLi: the element (li) selected, as it comes from Ajax.Autocompleter
// fieldId:    DOM ID, as a string, of the input field that is to be updated
//
function autoCompleteUpdate(selectedLi, fieldId) {
  var values = $(fieldId).value.split(',');
  var oldVal = '';

  for (i = 0; i < values.length - 1; ++i) {
    oldVal += ', ' + stripWhitespace(values[i]);
  }

  $(fieldId).value = oldVal + ', ' + $(selectedLi).innerHTML;
  $(fieldId).value = $(fieldId).value.substring(2); // rm leading ", "

  buildSearch($(fieldId));
}
