function tick() {

}
FormHelper = (function() {
  function minMaxPrice() {
    var minprice = $('minprice');
    minprice = minprice.value.strip().empty() ? false : parseInt(minprice.value.gsub(/[\,\.]/, ''))*1000;

    var maxprice = $('maxprice');
    maxprice = maxprice.value.strip().empty() ? false : parseInt(maxprice.value.gsub(/[\,\.]/, ''))*1000;

    return [minprice, maxprice];
  }

  function selectParam(select) {
    var element = $(select);
    if (element && element.selectedIndex > 0) {
      return "&" + element.name + "=" + checkValue(element);
    }
    else
      return "";
  }

  function serialize(with_bounds) {
		if (!$('minprice'))
			return '';

    var params = '',
        root = $('search'),
        prices = FormHelper.minMaxPrice();

    params += "&minprice=" + prices[0];
    params += "&maxprice=" + prices[1];

    params += selectParam('bedrooms');
    params += selectParam('bathrooms');
    if ($('proptype').nodeName == 'SELECT')
      params += selectParam('proptype');

    params += selectParam('fns');
    params += selectParam('pool');
    params += selectParam('pet');
    params += selectParam('frn');
    params += selectParam('cty');
    params += selectParam('zip');

    if ($('street') && $('street').value) {
      params += '&street='   + encodeURIComponent($('street').value);
    }

    root.select('input[type="checkbox"]').each(function(element) {
      element = $(element);
      if (element.checked)
        params += "&" + element.name + "=" + element.value;
    });

    if ($('yearFrom')) {
      var yearFrom = parseFloat($('year_from').value);
      if (yearFrom > 0)
        params += "&year_from=" + yearFrom;

      var yearTo = parseFloat($('year_to').value);
      if (yearTo > 0)
        params += "&year_to=" + yearTo;
    }
    if ($('sqft_min')) {
      params += "&sqft_min=" + parseFloat($('sqft_min').value);
      params += "&sqft_max=" + parseFloat($('sqft_max').value);
    }

    if ($('year_to')) {
      var yearFrom = parseFloat($('year_from').value);
      if (yearFrom > 0)
        params += "&year_from=" + yearFrom;

      var yearTo = parseFloat($('year_to').value);
      if (yearTo > 0)
        params += "&year_to=" + yearTo;
    }

    if (with_bounds) {
      params += "&sw=" + $('sw_value').value + "&ne=" + $('ne_value').value;
    }

    if (with_bounds && $('subdivision_search').value) {
      params += '&search='   + encodeURIComponent($('subdivision_search').value);
      params += '&location=' + encodeURIComponent($('subdivision').value);
    }
    return params;
  }

  function submit(element) {
    var form = element.up('form');
    form.submit();
  }

  function reset(form) {
    var form = $(form);
    form.select('input[type="checkbox"]').each(function(element) { element.checked = false});
    form.select('select').each(function(element) {
        element.selectedIndex = 0;
    });
    form.select('input[type="text"]').each(function(element) { element.value = ''});
  }

  function checkValue(check) {
    var element = $(check),
        value   = (element.options[element.selectedIndex].value);
    return value;
  }

  function checkListValue(list) {
    var element = $(list), values = [];

    element.select('input').each(function(input) {
      if (input.checked)
        values.push(input.value);
    })
    return values;
  }

  function noSubmitOnEnter(element) {
    $(element).observe("keypress", function(event) {
      if (event.keyCode == 13) {
        event.stop();
      }
    });
  }
  return {minMaxPrice:     minMaxPrice,
          serialize:       serialize,
          reset:           reset,
          submit:          submit,
          checkValue:      checkValue,
          checkListValue:  checkListValue,
          noSubmitOnEnter: noSubmitOnEnter}
})();
var oldOnBlur = Autocompleter.Base.prototype.onBlur;
Autocompleter.Base.prototype.onBlur = function(event) {
  if (this.element.id == 'subdivision' && this.selecting) {
    if (this.entryCount >= 1 && this.update.visible())
      this.selectEntry();
    else
      this.element.value = "";
  }
  if (this.element.id == 'mls_number') {
    this.element.value = "";
  }
  oldOnBlur.call(this, event);
}


Autocomplete = (function() {
  var subdivisionAutocomplete, autoUpdateMap;

  function registerMlsNumber() {
    if ($('mls_number')) {
      new Ajax.Autocompleter('mls_number', 'mls_number_auto_complete', 'ul', '/properties/mls_autocomplete',
                                           {parameters: "authenticity_token="+authenticity_token,
                                            paramName: 'search',
                                            minChars: 2,
                                            updateElement: updateMlsNumber});
    }
  }

  function updateMlsNumber(element) {
    element = $(element)
    var value = element.readAttribute('mls');
    document.location.href = '/properties/' + value;
  }

  function registerAgent() {
    if ($('agent')) {
      new Ajax.Autocompleter('agent', 'agent_auto_complete', 'ul', '/agents_autocomplete',
                                           {parameters: "authenticity_token="+authenticity_token,
                                            paramName: 'search',
                                            minChars: 2,
                                            updateElement: updateAgentNumber});
    }
  }

  function updateAgentNumber(element) {
    element = $(element);
    var permalink = element.readAttribute('permalink');
    $('agent').value = $('agent').value.strip();
    document.location.href = '/agent/' + permalink;
  }

  function registerLocationAutocomplete(_autoUpdateMap) {
    autoUpdateMap = _autoUpdateMap;
    if ($('subdivision')) {
      subdivisionAutocomplete = new Ajax.Autocompleter('subdivision', 'subdivision_auto_complete', 'ul', '/properties/autocomplete',
                                                       {parameters: "authenticity_token="+authenticity_token,
                                                        paramName: 'search',
                                                        minChars: 1,
                                                        callback: prepareAutoComplete,
                                                        updateElement:updateSubdivision});
      $('subdivision').observe('keyup', checkSubdivisionField);
      subdivisionAutocomplete.startIndicator = function() {
        $('subdivision').addClassName("loading").removeClassName('notfound')
        $('error_location').hide();
        this.selecting = true;
      }
      subdivisionAutocomplete.stopIndicator = function() {
        $('subdivision').removeClassName("loading");
        if (subdivisionAutocomplete.entryCount == 0 && $('subdivision').value.strip().length > 0) {
          $('error_location').show();
          $('subdivision').addClassName('notfound');
        }
      }

    }
  }

  function updateSubdivision(element) {
    element = $(element);
    var value = element.readAttribute("value").strip();

    $('subdivision').value        = value.gsub(/^City/, '');
    $('subdivision_search').value = value;
    subdivisionAutocomplete.selecting = false;

    var bounds = new GLatLngBounds(new GLatLng(element.readAttribute('sw_lat'), element.readAttribute('sw_lng')),
                                   new GLatLng(element.readAttribute('ne_lat'), element.readAttribute('ne_lng')));

    if (autoUpdateMap) {
      Map.filterMap(false, bounds);
    } else {
      $('sw_value').value = bounds.getSouthWest().toUrlValue();
      $('ne_value').value = bounds.getNorthEast().toUrlValue();
    }
  }

  function prepareAutoComplete(element, entry) {
    subdivisionAutocomplete.options.defaultParams = FormHelper.serialize() + "&authenticity_token=" + authenticity_token ;
    return entry;
  }


  function checkSubdivisionField() {
    var subdivision = $('subdivision');
    if (subdivision.value.strip().empty() && autoUpdateMap) {
      $('subdivision_search').value = '';
      Map.filterMap(false);
      Map.resetViewing();
    }
  }

  return {registerMlsNumber:            registerMlsNumber,
          registerAgent:                registerAgent,
          registerLocationAutocomplete: registerLocationAutocomplete,
          autoUpdateMap:                autoUpdateMap}
})();
Map = (function() {
  var map = null, maptimizeMap, timer, autoRefresh = false, large;

  function appendConditionForList(conditions, list, attribute, type, has) {
    if (!$(list))
      return;

    var values = FormHelper.checkListValue(list);
    if (values.length > 0) {
      tmpCondition = new Maptimize.Condition();
      operator = has ? " HAS ?" : " = ?"
      values.each(function(value) {
        if (type == "AND")
          tmpCondition.appendAnd(attribute + operator, value);
        else
          tmpCondition.appendOr(attribute + operator, value);
      });
      conditions.appendAnd(tmpCondition.toString());
    }
  }

  function appendConditionSelectList(conditions, list, intValue) {
    if (!$(list))
      return;
    var value = FormHelper.checkValue(list);
    if (value != -1 && value != '' && value != 'Any')
      conditions.appendAnd(list + ' = ?', intValue ? parseInt(value) : value);
  }


  function filterMap(noRefresh, bounds) {
    if (!initialized())
      return;

    clearTimer();
    var prices      = FormHelper.minMaxPrice(),
        root        = $('search'),
        subdivision = $('subdivision_search').value.strip();

    function updateMap() {
      var conditions = Maptimize.Condition(), tmpCondition;

      var nbRooms = FormHelper.checkValue('bedrooms');
      if (nbRooms > 0)
         conditions.appendAnd('bdr >= ?', parseInt(nbRooms));

      var nbBaths = FormHelper.checkValue('bathrooms');
      if (nbBaths > 0)
       conditions.appendAnd('btr >= ?', parseInt(nbBaths));

      if ($('proptype').nodeName == 'SELECT')  {
        var proptype = FormHelper.checkValue('proptype');
        if (proptype != 'Any')
          conditions.appendAnd('type = ?', proptype);
      }
      else
        appendConditionForList(conditions, 'proptype', 'type', 'OR', false);

      appendConditionForList(conditions, 'wtft', 'wtft', 'OR', true);
      appendConditionForList(conditions, 'amn', 'amn', 'AND', true);
      appendConditionForList(conditions, 'status_list', 'status', 'OR', false);
      appendConditionForList(conditions, 'cmt', 'cmt', 'AND', true);
      appendConditionForList(conditions, 'waa', 'waa', 'AND', true);

      if ($('fns')) {
        var fns = FormHelper.checkValue('fns');
        switch (fns) {
          case '1': conditions.appendAnd('fcs = ?', 1);break;
          case '2': conditions.appendAnd('shs = ?', 1);break;
          case '3': conditions.appendAnd('fcs = ? AND shs = ?', 0, 0);break;
        }
      }
      appendConditionSelectList(conditions, 'pool', true);
      appendConditionSelectList(conditions, 'pet', true);
      appendConditionSelectList(conditions, 'frn', true);

      if ($('year_to')) {
        var yearFrom = parseFloat($('year_from').value);
        if (yearFrom > 0)
          conditions.appendAnd('ybt >= ?', yearFrom);

        var yearTo = parseFloat($('year_to').value);
        if (yearTo > 0)
          conditions.appendAnd('ybt <= ?', yearTo);
      }

      if ($('sqft_min')) {
        conditions.appendAnd('sqft >= ?', parseFloat($('sqft_min').value));
        var max = parseFloat($('sqft_max').value);
        if (max != -1)
          conditions.appendAnd('sqft <= ?', max);
      }

      if ($('street') && $('street').value) {
        conditions.appendAnd("str LIKE ?", $('street').value.toLowerCase())
      }

      appendConditionSelectList(conditions, 'cty');
      appendConditionSelectList(conditions, 'zip');
      if (prices[0])
        conditions.appendAnd("price >= ?", prices[0])

      if (prices[1])
        conditions.appendAnd("price <= ?", prices[1])

      root.select('input[type="checkbox"]').each(function(check) {
        if (check && check.checked && !check.name.endsWith('[]'))
          conditions.appendAnd(check.name + ' = 1');
      });
      if (subdivision)
        conditions.appendAnd("sub LIKE ?", subdivision)

      maptimizeMap.setCondition(conditions);

      if (bounds) {
        var zoom = map.getBoundsZoomLevel(bounds);
        map.setCenter(bounds.getCenter(), zoom);
      }
      if (!noRefresh) {
        $('loader').show();
        maptimizeMap.refresh();
      }
    }
    updateMap.delay(Prototype.Browser.IE ? 0.2 : 0);
  }

  function updateSaveSearch() {
    var params = FormHelper.serialize(true);
    params += "&authenticity_token=" + authenticity_token;
    new Ajax.Request('/save_search_params', {parameters: params});
  }

  function clearTimer() {
    if (timer) {
      clearTimeout(timer);
    }
    timer = false;
  }

  function filterMapKeyEvent(event) {
    var  element = event.element(),
         value   = element.value;

    value = value.replace(/[^\d\,\.*]/g, "");
    element.value = value;
    clearTimer();
    timer = filterMap.delay(0.5, false);
  }

  function registerUI() {
    var callback = filterMap.curry(false, false), root = $('search');

    root.select('select').each(function(element) {
      element.observe('change', callback);
    });

    root.select('input[type="checkbox"]').each(function(element) {
      element.observe('click', callback);
    });

    Autocomplete.registerMlsNumber();
    Autocomplete.registerAgent();
    $w('minprice maxprice year_from year_to').each(function(id) {
      var element = $(id);
      if (element) {
        element.observe('keyup', filterMapKeyEvent);
      }
    });
    if ($('street'))
      new Form.Element.Observer('street', 0.5, callback);
  }


  function addCommas(nStr) {
  	nStr += '';
  	x = nStr.split('.');
  	x1 = x[0];
  	x2 = x.length > 1 ? '.' + x[1] : '';
  	var rgx = /(\d+)(\d{3})/;
  	while (rgx.test(x1)) {
  		x1 = x1.replace(rgx, '$1' + ',' + '$2');
  	}
  	return x1 + x2;
  }

  function requestContent(marker, ids) {
    var waitingContent = $('waiting_content'),
        content        = new Element('div', {id: 'window'}).addClassName('maptimize_info_window_' + (large ? 'large' : 'home')).insert(waitingContent.cloneNode(true).show());
    marker.openInfoWindowHtml(content);
    return new Ajax.Request("/properties/info_window", {
      method: 'GET',
      parameters: {"id[]": ids},
      onComplete: function(response) {
        content.update(response.responseText);
      }
    })
  }

  function getBoundsFromHiddenField() {
    var ne = $('ne_value'), sw = $('sw_value');
    ne = ne.value.split(',');
    sw = sw.value.split(',');
    return new GLatLngBounds(new GLatLng(sw[0], sw[1]), new GLatLng(ne[0], ne[1]));
  }

  function resetViewing(force) {
    var ne = $('ne_value');
    if (!force && (ne && ne.value)) {
      var bounds = getBoundsFromHiddenField();
      map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds) || 8);
    }
    else {
      map.setCenter(new GLatLng(26.363896,-81.79870), 8);
    }
  }

  function reset() {
    FormHelper.reset('search');
    filterMap(false);
    resetViewing();
  }

  function init() {
    initMap();
  }

  function initialized() {
    return map != null;
  }

  function initMap() {
    var mapElement = $('map');
    if (typeof GBrowserIsCompatible != 'undefined' && GBrowserIsCompatible() && mapElement) {
      map = new GMap2(mapElement);
      large       = mapElement.hasClassName('large');
      autoRefresh = !mapElement.hasClassName('large');
      resetViewing();

      map.setUIToDefault();
      map.disableScrollWheelZoom();

      maptimizeMap = new Maptimize.Map(map);
      GEvent.addListener(maptimizeMap, 'afterRefresh', function() {
        $('nb_properties').innerHTML = addCommas(maptimizeMap.getTotalPointsCount());
        mapElement.fire('maptimize:updated');

        var ne = map.getBounds().getNorthEast().toUrlValue(),
            sw = map.getBounds().getSouthWest().toUrlValue();

        $('ne_value').value = ne;
        $('sw_value').value = sw;

        updateSaveSearch();

        $('loader').hide();
      });

      GEvent.addListener(maptimizeMap, 'markerClicked', function(marker) {
        requestContent(marker.getGMarker(), marker.getId())
      });

      GEvent.addListener(maptimizeMap, 'clusterClicked', function(cluster) {
        cluster.requestIds(function(ids) {
          requestContent(cluster.getGMarker(), ids);
        })
      });

        registerUI();

      filterMap();

      window.map          = map;
      window.maptimizeMap = maptimizeMap;
    }
  }

  function listing(mapView) {
    var bounds   = "&sw=" + map.getBounds().getSouthWest().toUrlValue() + "&ne=" +map.getBounds().getNorthEast().toUrlValue(),
        params   = FormHelper.serialize() + bounds;

    if ($('subdivision_search').value) {
      params += '&search='   + encodeURIComponent($('subdivision_search').value);
      params += '&location=' + encodeURIComponent($('subdivision').value);
    }
    if (mapView)
      params += "&map=true";
    else
      params += "&map=false";

    window.location.href = "/properties/search?" + params;
  }

  function openPopup(mlsid) {
    maptimizeMap.requestMarkerForId(mlsid, function callback(marker) {
      requestContent(marker.getGMarker(), mlsid)
    });
  }

  return {init:                     init,
          initialized:              initialized,
          initMap:                  initMap,
          reset:                    reset,
          getBoundsFromHiddenField: getBoundsFromHiddenField,
          resetViewing:             resetViewing,
          filterMap:                filterMap,
          listing:                  listing,
          openPopup:                openPopup}
})();
Search = (function() {
  var form, ignoreFirstUpdate, lastLocation = null, requestRunning, timer;
  var defaultSW = '25.130366,-83.798218',
      defaultNE = '27.581329,-79.799194';

  function init(autoUpdate) {
    if ($('refine') && $('map')) {
      ignoreFirstUpdate = !Tab.mapSelected();
      $('map').observe('maptimize:updated', updateList);
    }
    Autocomplete.registerLocationAutocomplete(autoUpdate);
  }

  function updateList() {
    if (requestRunning) {
      if (!timer)
        timer = setTimeout(updateList, 250);
      return;
    }
    if (ignoreFirstUpdate) {
      ignoreFirstUpdate = false;
      return
    }
    if (Map.initialized()) {
      var ne = map.getBounds().getNorthEast().toUrlValue(),
          sw = map.getBounds().getSouthWest().toUrlValue();
    }
    else {
      var sw = defaultSW,
          ne = defaultNE;
    }
    $('ne_value').value = ne;
    $('sw_value').value = sw;

    var params = FormHelper.serialize();
    params += "&sw=" + sw;
    params += "&ne=" + ne;
    params += "&authenticity_token=" + authenticity_token;
    params += "&map=" + (Tab.mapSelected() ? "true" : "false");
    if ($('subdivision_search').value)
      params += '&search=' + $('subdivision_search').value;
    if ($('subdivision').value)
      params += '&location=' + $('subdivision').value;

    requestRunning = true;
    showWaiting();
    new Ajax.Request('/properties/update_list', {parameters : params, onSuccess: function() {
      setTimeout(function(){ $('nb_properties').update($('paginate_count').value)}, 100);
    }, onComplete:function(){
      hideWaiting();
      if (timer)
        updateList();
      requestRunning = false;
      timer = null;
    }});
  }

  function showWaiting() {
    var dim = $('lstres').getDimensions(),
        overlay = $('lstresoverlay');

    overlay.style.width  = dim.width + 'px';
    overlay.style.height = dim.height + 'px';
    overlay.show();
  }

  function hideWaiting() {
    $('lstresoverlay').hide();
  }

  function run() {
		var location = $('subdivision').value.strip();
    if (location == '' && location != lastLocation) {
      $('subdivision_search').value = '';
			if (lastLocation != null) {
      	$('ne_value').value = defaultNE;
      	$('sw_value').value = defaultSW;
			}
    }
		if (location != lastLocation)
			lastLocation = location;

    if (!Map.initialized())
      Map.initMap();
    else {
      var sw = $('sw_value').value.split(','),
          ne = $('ne_value').value.split(','),
          bounds = new GLatLngBounds(new GLatLng(sw[0], sw[1]),
                                     new GLatLng(ne[0], ne[1]));
       Map.filterMap(false, bounds);
    }
  }

  function reset() {
    $('sw_value').value = defaultSW;
    $('ne_value').value = defaultNE;

    FormHelper.reset('search');
    run();
  }

  return {init:        init,
          reset:       reset,
          run:         run}
})();


AdvancedSearch = (function() {
  function init() {
    Search.init(false);
  }

  function run(event) {
    document.location.href = '/properties/search?map=false&' + FormHelper.serialize(true)
  }
  return {init:        init,
          run:         run};
})();
Tab = (function() {
  mapView = false;

  function init() {
    var s = $('switch');
    if (s) {
      s.observe('click', toggleView);
      Cookie.set({'map' : s.down(".listselected") == null ? 'true' : 'false'});
      Cookie.set({'view' : 'search'});
    }
    else {
      Cookie.set({'view' : 'home'});
    }
  }

  function mapSelected() {
    return mapView;
  }

  function toggleView(event) {
    var li = event.element().up('li');
    if (li.hasClassName("listview"))
      showList();
    else
      showMap();
    event.stop();
  }

  function showMap(mlsid) {
    var li          = $('switch').down('.mapview'),
        mapContent  = $('map_content'),
        listContent = $('list_content');
    mapContent.show();
    mapView = true;
    if (!Map.initialized()) {
      Map.initMap();
    }
    listContent.hide();
    li.addClassName('mapselected');
    mapContent.removeClassName('hidden');
    li.up().down('.listview').removeClassName('listselected');
    Cookie.set({'map' : 'true'});

    if (mlsid) {
      Map.openPopup(mlsid);
    }
  }

  function showList() {
    var li          = $('switch').down('.listview'),
        mapContent  = $('map_content'),
        listContent = $('list_content');

    mapView = false;
    mapContent.addClassName('hidden');
    listContent.show();
    li.addClassName('listselected');
    li.up().down('.mapview').removeClassName('mapselected');
    Cookie.set({'map' : 'false'});
  }

  return {init:         init,
          mapSelected:  mapSelected,
          showMap:      showMap,
          showList:     showList};
})();
Modal = Class.create({
  initialize: function(options){
    options = options || {}

    this.overlay = $(options['overlay'] || 'overlay') || new Element('div', {id: 'overlay'}).hide();
    this.parentNode = $(options['container'] || document.body)

    if (this.overlay.parentNode == null) {
      this.parentNode.insert(this.overlay);
      this.overlay.observe('click', function() {Modal.current.hide()})
    }

    this._createElement(options['id']);
    this._update = this._update.bind(this);
    this.options = {};
  },

  show: function() {
    this.overlay.show();
    this.element.appear({duration: 0.5});
    Modal.current = this;
  },

  hide: function(){
    Modal.current = null;
    this.overlay.fade({duration: 0.5});
    this.element.fade({duration: 0.5});
    if (this.options.cancel) this.options.cancel();
    this.options = {};
  },

  setAjaxContent: function(url, parameters, options) {
    this.options = options;
    new Ajax.Request(url, Object.extend({onComplete: this._update}, parameters || {}));
  },

  setURLContent: function(url, height) {
    var iframe = new Element('iframe', {frameborder: 0, src: url, name: "modal_frame", id:  "modal_frame",
                                        style: 'width:100%;height:' + height + 'px'});
    this.content.setStyle('height', height + 'px');
    this.content.update(iframe);
    this.options = {};
    this.show();
  },

  setContent: function(content, options) {
    this.content.update(content);
    this.options = options || {};
    if (content.show)
      content.show();
    this.show();
  },

  _update: function(response) {
    this.content.update(response.responseText);
    this.show();
  },

  _createElement: function(id) {
    this.element = new Element('div').addClassName('popin');
    if (id)
      this.element.id = id;

    this.content = new Element('div').addClassName('content');
    var middle = new Element('div').addClassName('middle');

    middle.insert(new Element('a').addClassName('small-button button-close').observe('click', this.hide.bind(this)))
          .insert(this.content);

    this.element.insert(new Element('div').addClassName('top'))
                .insert(middle)
                .insert(new Element('div').addClassName('bottom'))
                .hide();
    this.parentNode.insert(this.element);
  }
});
Modal.prototype.close = Modal.prototype.hide;
Modal.current = null;
Popup = (function() {
  var popup;
  function open(url, height) {
    if (popup) {
      popup.close();
    }
    height = height || 400;
    popup = new Modal();
    popup.setURLContent(url, height);
  }

  function close(url) {
    if (popup) {
      popup.close();
      if (url) {
        new Ajax.Request(url, {parameters: {authenticity_token:authenticity_token}});
      }
    }
  }

  function closeWithMessage(message) {
    close();
    var flash = $('flash');
    if (!flash) {
      flash = new Element('div', {id: 'flash'});
      $('hd').insert({after: flash});
    }
    flash.update(new Element('span').addClassName('notice').update(message));
    flash.show().highlight();
  }

  function closeWithRefresh(id, content) {
    close();
    $(id).update(content);
  }

  return {open:             open,
          close:            close,
          closeWithMessage: closeWithMessage}
})();
TreeMenu = (function() {
  function init() {
    var menu = $('subnav');
    if (menu) {
      menu.observe("click", expandCollapse)
    }
  }

  function expandCollapse(event) {
    var element = event.element();

    if (element.nodeName == 'IMG') {
      var ol = element.up("li").down("ol");
      ol.toggle();
      if (ol.visible())
        element.src = "/images/bullet-v.gif"
      else
        element.src = "/images/bullet-h.gif"
      event.stop()
    }
  }

  return {init: init}
})();
Carousel = Class.create({
  initialize: function(root, thumbnails) {
    this.root = $(root) || $$(root).first();
    this.images = this.root.select("li");
    this.current = 0;
    if (this.images.length > 0) {
      this.images.first().show();
      this.next = this.next.bind(this);
      this.nextDelayed = function(){this.timer = setTimeout(this.next, 4000);}.bind(this)
      if (this.images.length > 1)
        this.nextDelayed();
    }

    this.thumbnails = $(thumbnails) || $$(thumbnails).first();

    if (this.thumbnails) {
      this.thumbnails.observe("mouseover", this.setImage.bind(this));
      this.thumbnails.observe("mouseout", this.startAnimation.bind(this));
    }
  },

  next: function() {
    this.fx1 = new Effect.Morph(this.images[this.current], { style: "opacity:0" }, {});
    this.current++;
    if (this.current == this.images.length)
      this.current = 0;
    this.images[this.current].setOpacity(0).show();
    this.fx2 = new Effect.Morph(this.images[this.current], { style: "opacity:1", afterFinish: this.nextDelayed});
  },

  setImage: function(event) {
    var thumb = event.element().up("li"),
        image = this.root.down("#picture_" + thumb.id.split('_').last());

    this.stopAnimation();
    this.images.invoke('setOpacity', 0);
    image.setOpacity(1).show();
    this.current = this.images.indexOf(image);
  },

  stopAnimation: function() {
    if (this.fx1)   this.fx1.cancel();
    if (this.fx2)   this.fx2.cancel();
    if (this.timer) clearTimeout(this.timer);
  },

  startAnimation: function() {
    this.next();
  }
});

MiniMap = (function() {
  var map, position, mapElement;

  function init() {
    mapElement = $('minimap');

    if (typeof GBrowserIsCompatible != 'undefined' && GBrowserIsCompatible() && mapElement) {
      initMap();
      initStreetView();
    }
  }


  function initMap() {
    map = new GMap2(mapElement);
    map.setUIToDefault();
    map.disableScrollWheelZoom();

    position = new GLatLng($('lat').value,$('lng').value);
    map.setCenter(position, 14)
    map.addOverlay(new GMarker(position));

  }

  function initStreetView() {
    var panorama = new GStreetviewPanorama($("street-view"), { latlng:position });
    GEvent.addListener(panorama, "error", handleNoFlash);
  }

  function handleNoFlash(errorCode) {
    $('street-view').hide()
    if (errorCode == 603) {
      return;
    }
  }

  return {init: init}
})();
FavoriteMap = (function() {
  var map, mapElement, points, markers = new Hash;
  var icon = null;

  function init(pts) {
    points = pts;
    mapElement = $('favorite_map');
    if (typeof GBrowserIsCompatible != 'undefined' && GBrowserIsCompatible() && mapElement) {
      initMap();
    }
  }

  function getBounds() {
    var ne = [points.first().lat, points.first().lng],
        sw = [points.first().lat, points.first().lng];
    points.each(function(pt) {
      var lat = pt.lat, lng = pt.lng;
      if (sw[0] > lat) sw[0] = lat;
      if (sw[1] > lng) sw[1] = lng;
      if (ne[0] < lat) ne[0] = lat;
      if (ne[1] < lng) ne[1] = lng;
    });
    return new GLatLngBounds(new GLatLng(sw[0], sw[1]), new GLatLng(ne[0], ne[1]));
  }

  function openWindow(mls, marker) {
    return new Ajax.Request("/properties/info_window", {
      method: 'GET',
      parameters: {"id[]": mls},
      onComplete: function(response) {
        var html = response.responseText;
        marker.openInfoWindowHtml(html);
      }
    });
  }

	function getIcon() {
		if (!icon) {
			icon	= new GIcon({image:            "/images/marker-blue.png",
			                   iconSize:         new GSize(20, 30),
			                   iconAnchor:       new GPoint(9, 34),
			                   infoWindowAnchor: new GPoint(9, 2),
			                   infoShadowAnchor: new GPoint(18, 25),
			                   shadow:           "http://www.google.com/mapfiles/shadow50.png"});
		}
		return icon;
	}

  function initMap() {
    map = new GMap2(mapElement);
    map.setUIToDefault();
    map.disableScrollWheelZoom();

    var bounds = getBounds();
    map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));

    points.each(function(pt) {
      var ll = new GLatLng(pt.lat, pt.lng),
          marker = new GMarker(ll, {icon: getIcon()});

      GEvent.addListener(marker, 'click', openWindow.curry(pt.mls, marker));
      map.addOverlay(marker);
			markers.set(pt.mls, marker);
    });
  }

	function highlight(mls) {
		var marker = markers.get(mls);
		marker.setImage("/images/marker-pink.png");
		map.panTo(marker.getLatLng())
	}

	function unhighlight(mls) {
		markers.get(mls).setImage("/images/marker-blue.png");
	}

  return {init:        init,
					highlight:   highlight,
					unhighlight: unhighlight}
})();

Comment = (function() {
	function init() {
		$$('.property').invoke('observe', 'mouseenter', mouseenter);
		$$('.property').invoke('observe', 'mouseleave', mouseleave);
	}

	function mouseenter(event) {
		var element = event.findElement('.property'),
		    mls = getMLS(element);
		element.addClassName("property_selected");
		FavoriteMap.highlight(mls);
	}

	function mouseleave(event) {
		var element = event.findElement('.property_selected'),
		    mls = getMLS(element);
		FavoriteMap.unhighlight(mls);
		element.removeClassName("selected");
	}

	function getMLS(element) {
		return element.id.split('_').last();
	}

	function edit(element) {
		var li = element.up("li");
		li.hide();
		li.next().show();
	}

	function updated(id, content) {
		var comment = $(id), li = comment.up("li");
		comment.update(content.gsub('\n', '<br/>'));
		li.show();
		li.next().hide();
		comment.highlight();
	}
  return {init: init,
	        edit: edit,
					updated: updated};
})();
Hint = (function() {
	var checkboxes = null;
  function toggle(id) {
    var element = $(id),
        shim = element.retrieve('shim'),
        doHide = element.visible();

    element.observe('click', hide);

		if (Prototype.Browser.IE && !shim) {
		  shim = new IframeShim();
      element.store('shim', shim);
      element.setOpacity(0).show();
      shim.positionUnder(element);
		}

		if (element.up() != document.body) {
		  element.setOpacity(0).show();

      var offset = element.cumulativeOffset();
		  document.body.appendChild(element);
		  element.style.top = offset[1] + 'px';
		  element.style.left = offset[0] + 'px';
		}

    if (shim)
      shim.show();

    if (doHide)
      hide(element);
    else {
      show(element);
		}
  }

  function show(element) {
    element.appear({duration: 0.3});
  }

  function hide(element) {
    if (element.element)
      element = element.element().up(".hint");
    element.fade({duration: 0.3});

    if (element.retrieve('shim')) {
      element.retrieve('shim').hide();
    }

    element.stopObserving('click', hide);
  }
  return {toggle: toggle}
})();
IframeShim = Class.create({

  options: {
    parent: document.body
  },

  /*
    Method: initialize
    Constructor

      Creates iframe shim and appends it to the body.
      Note that this method does not perform proper positioning and resizing of an iframe.
      To do that use positionUnder method

    Returns:
      this
  */
  initialize: function(options) {
    this.element = new Element('iframe', {
      style: 'position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=1);',
      src: 'javascript:false;',
      frameborder: 0
    });
    $(this.options.parent || document.body).insert(this.element);
  },

  /*
    Method: hide
      Hides iframe shim leaving its position and dimensions intact

    Returns:
      this
  */
  hide: function() {
    this.element.hide();
    return this;
  },

  /*
    Method: show
      Show iframe shim leaving its position and dimensions intact

    Returns:
      this
  */
  show: function() {
    this.element.show();
    return this;
  },

  /*
    Method: positionUnder
      Positions iframe shim under the specified element
      Sets proper dimensions, offset, zIndex and shows it
      Note that the element should have explicitly specified zIndex

    Returns:
      this
  */
  positionUnder: function(element) {
    var element = $(element),
        offset = element.cumulativeOffset(),
        dimensions = element.getDimensions(),
        style = {
          left: offset[0] + 'px',
          top: offset[1] + 'px',
          width: dimensions.width + 'px',
          height: dimensions.height + 'px',
          zIndex: element.getStyle('zIndex') - 1
        };
    this.element.setStyle(style).show();

    return this;
  },

  /*
    Method: setBounds
      Sets element's width, height, top and left css properties using 'px' as units

    Returns:
      this
  */
  setBounds: function(bounds) {
    for (prop in bounds) {
      bounds[prop] = parseInt(bounds[prop]) + 'px';
    }
    this.element.setStyle(bounds);
    return this;
  },

  /*
    Method: setSize
      Sets element's width, height

    Returns:
      this
  */
  setSize: function(width, height) {
    this.element.style.width  = parseInt(width) + "px";
    this.element.style.height = parseInt(height) + "px";
    return this;
  },

  /*
    Method: setPosition
      Sets element's top and left

    Returns:
      this
  */
  setPosition: function(top, left) {
    this.element.style.top  = parseInt(top) + "px";
    this.element.style.left = parseInt(left) + "px";
    return this;
  },

  /*
    Method: destroy
      Completely removes the iframe shim from the document

    Returns:
      this
  */
  destroy: function() {
    if (this.element)
      this.element.remove();

    return this;
  }
});
Event.addBehavior.reassignAfterAjax = true;
Remote.Link = Behavior.create(Remote.Base, {
  onclick : function() {
    this.options.parameters = FormHelper.serialize(true);
    var options = Object.extend({ url : this.element.href, method : 'get' }, this.options);
    return this._makeRequest(options);
  }
});
Event.addBehavior({
  'div.ajax_pagination a': Remote.Link
});

Map.init();
TreeMenu.init();
MiniMap.init();
Tab.init();
AddressPicker = function() {
  var map_ac = $('map_addresschooser'),
      areaBounds,
      map;

  function viewDidChange() {
    var bounds = map.getBounds();
    if (!bounds.intersects(areaBounds))
      resetViewing();
    $('sw_value').value = map.getBounds().getSouthWest().toUrlValue();
    $('ne_value').value = map.getBounds().getNorthEast().toUrlValue();
  }

  function resetViewing() {
    map.setCenter(areaBounds.getCenter(), map.getBoundsZoomLevel(areaBounds) || 8);

  }
  function init() {
    if (map_ac) {
      function onInitialized(widget) {
        var bounds = Map.getBoundsFromHiddenField();
        map = widget.getMap();

        map.setUIToDefault();
        map.disableScrollWheelZoom();

        map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds) || 8);
        areaBounds = map.getBounds();

        widget.initMap();
        GEvent.addListener(map, "moveend", viewDidChange);

      }

      widget = new Maptimize.AddressChooser.Widget({spinner: 'big_spinner',
                                                    map: "map_addresschooser",
                                                    onInitialized:onInitialized});
    }
  }
  return {init:init};
}();

AddressPicker.init();
Rental = (function() {
  function init() {
    registerUI();
    RentalMap.init();
  }

  function filterParams(with_bounds) {
    var params = {};
    var bedrooms = FormHelper.checkValue('bedrooms');
    if (bedrooms != "0")
      params['bedrooms'] = bedrooms;

    var sleep = FormHelper.checkValue('sleeps');
    if (sleep != "0")
      params['sleeps'] = sleep;

    if ($('complex')) {
      var complex = $('complex').value.strip()
      if (complex.length > 0) {
        params["complex"] = complex;
      }
    }
    var week =  FormHelper.checkValue('week');
    if (week != "0") {
      params["week"] = week;
    }

    var length =  FormHelper.checkValue('length');
    if (length > 0) {
      params["length"] = length;
    }

    var pet = $('pet') && $('pet').checked;
    if (pet) {
      params["pet"] = 1;
    }

    if (with_bounds) {
      params["sw"] = $('sw_value').value;
      params["ne"] = $('ne_value').value;
    }
    return params;
  }

  function updateCallback(event) {
    if (event.type == 'click') {
      var input = event.findElement('input[type="checkbox"]');
      if (input) {
        update();
      }
    }
    else {
      var select = event.findElement('select');
      if (select) {
        update();
      }
    }
  }

  function update() {
    updateList();
    RentalMap.update();
  }

  function updateList() {
    if ($('list_content')) {
      var params = filterParams(true);
      params["authenticity_token"] = authenticity_token;
      new Ajax.Request('/rentals/search', {parameters: params});
    }
  }

  function registerUI() {
    if ($('search')) {
      $('search').observe('change', updateCallback);
      $('search').observe('click', updateCallback);
      new Ajax.Autocompleter('complex', 'complex_auto_complete', 'ul', '/rentals/complex_autocomplete',
                                         {parameters: "authenticity_token="+authenticity_token,
                                          paramName: 'search',
                                          minChars: 1,
                                          updateElement: updateComplex});
      $('complex').observe('keyup', checkComplexField);
      FormHelper.noSubmitOnEnter('complex');
    } else {
      $$('#content .c1 select').invoke('observe', 'change', updateCheckButton);
    }
    if ($('complex-list-content')) {
      $('complex-list-content').observe('click', function(event) {
        event.stop();
        var link = event.findElement('a');
        if (link) {
          updateComplex(link);
          $('complex-list-content').fade();
        }
      })
    }
  }

  function checkComplexField(event) {
    var complex = $('complex');
    if (complex.value.strip().empty()) {
      RentalMap.setBounds();
      update();
    }
    event.stop();
  }


  function updateCheckButton() {
    var week = FormHelper.checkValue('week'),
        length = FormHelper.checkValue('length');
    $('check_button').show();
    if (week != 0 && length != 0) {
      $('check_button').disabled = false;
    }
    else {
      $('check_button').disabled = true;
    }
    $('reserve_button').hide();
  }

  function updateComplex(element, value) {
    var bounds = new GLatLngBounds(new GLatLng(element.readAttribute('sw_lat'), element.readAttribute('sw_lng')),
                                   new GLatLng(element.readAttribute('ne_lat'), element.readAttribute('ne_lng')));
    $('complex').value = element.readAttribute("value") || element.innerHTML;
    RentalMap.setBounds(bounds);
    RentalMap.update();
  }

  function listing(mapView, options) {
    var params = $H(Rental.filterParams());
    if (options) {
      $H(options).each(function(data) {
        params.set(data[0], data[1]);
      })
    }
    params.set("ne", $('ne_value').value);
    params.set("sw", $('sw_value').value);
    params.set("mapView", mapView);
    window.location.href = "/rentals/search?" + params.toQueryString();
  }

  function reserve() {
    var week = FormHelper.checkValue('week'),
        length = FormHelper.checkValue('length');

    if (week != 0 && length != 0) {

      var url = "https://secure.vip-vacationrentals.com/rns/search/rentalterms.aspx?locid=1";
      url += "&id=" + $('unit_id').value;
      url += "&arr=" + arriveDate();
      url += "&depart=" + departDate();
      url += "&nights=" + parseInt(length);

      document.location.href = url;
    }
  }

  function departDate() {
    var week = FormHelper.checkValue('week').split('-'),
        length = FormHelper.checkValue('length');

    var arriveDate = new Date(parseInt(week[0]), parseInt(week[1])-1, parseInt(week[2])),
        departDate = new Date(arriveDate.getTime() + 86400000 * parseInt(length));
    return (departDate.getMonth()+1) + "/" + departDate.getDate() + "/" + (1900 + departDate.getYear());
  }

  function arriveDate() {
    var week = FormHelper.checkValue('week').split('-'),
        arriveDate = new Date(parseInt(week[0]), parseInt(week[1])-1, parseInt(week[2]));
    return (arriveDate.getMonth()+1) + "/" + arriveDate.getDate() + "/" + (1900 + arriveDate.getYear());
  }

  function check() {
    var params = "";
    params += "depart_date=" + departDate();
    params += "&arrive_date=" + arriveDate();
    params += "&length=" + FormHelper.checkValue('length');
    params += "&authenticity_token=" + authenticity_token;

    $('check_button').disabled = true;
    $('check_button').value = "Checking ..."
    new Ajax.Request("/rentals/" + $('unit_id').value + '/check', {parameters: params, onComplete: displayAvailabilty});
  }

  function displayAvailabilty(response) {
    $('check_button').disabled = false;
    $('check_button').value = "Check for availabilty";

    if (response.responseText == 'true') {
      $('check_button').hide();
      $('reserve_button').show();
      if (confirm("This property is available, do you want to make a reservation?")) {
        reserve();
      }
    } else if (response.responseText == 'false') {
      alert("not available");
    } else {
    }
  }

  return {init:          init,
          listing:       listing,
          filterParams:  filterParams,
          updateList:    updateList,
          reserve:       reserve,
          check:         check}
})();

RentalMap =(function() {
  var map, maptimizeMap, large;

  function addCommas(nStr) {
  	nStr += '';
  	x = nStr.split('.');
  	x1 = x[0];
  	x2 = x.length > 1 ? '.' + x[1] : '';
  	var rgx = /(\d+)(\d{3})/;
  	while (rgx.test(x1)) {
  		x1 = x1.replace(rgx, '$1' + ',' + '$2');
  	}
  	return x1 + x2;
  }


  function update() {
    var params = Rental.filterParams();
    params["authenticity_token"] = authenticity_token;
    new Ajax.Request('/rentals/update_map', {parameters: params, onComplete: updateMapCallback});
  }

  function updateMapCallback(response) {
    var condition = new Maptimize.Condition();
    condition.appendAnd("id IN ?", response.responseJSON);
    maptimizeMap.setCondition(condition);
    maptimizeMap.refresh();
  }

  function requestContent(marker, ids) {
    var waitingContent = $('waiting_content'),
        content        = new Element('div', {id: 'window'}).addClassName('maptimize_info_window_' + (large ? 'large' : 'home')).insert(waitingContent.cloneNode(true).show());
    marker.openInfoWindowHtml(content);
    return new Ajax.Request("/rentals/info_window", {
      method: 'GET',
      parameters: {"id[]": ids},
      onComplete: function(response) {
        content.update(response.responseText);
      }
    })
  }

  function init() {
    var mapElement = $('rental_map');
    large = mapElement.hasClassName('large');

    if (typeof GBrowserIsCompatible != 'undefined' && GBrowserIsCompatible() && mapElement) {
      map = new GMap2(mapElement);

      var ne = GLatLng.fromUrlValue($('ne_value').value);
      var sw = GLatLng.fromUrlValue($('sw_value').value);
      var bounds = new GLatLngBounds(sw, ne);
      map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));

      map.setUIToDefault();
      map.disableScrollWheelZoom();

      maptimizeMap = new Maptimize.Map(map);
      GEvent.addListener(maptimizeMap, 'afterRefresh', function() {
        $('nb_properties').innerHTML = addCommas(maptimizeMap.getTotalPointsCount());
        mapElement.fire('maptimize:updated');

        var ne = map.getBounds().getNorthEast().toUrlValue(),
            sw = map.getBounds().getSouthWest().toUrlValue();

        $('ne_value').value = ne;
        $('sw_value').value = sw;

        $('loader').hide();
      });
      GEvent.addListener(map, 'moveend', function() {
        var ne = map.getBounds().getNorthEast().toUrlValue(),
            sw = map.getBounds().getSouthWest().toUrlValue();

        $('ne_value').value = ne;
        $('sw_value').value = sw;
        Rental.updateList();
      });
      GEvent.addListener(maptimizeMap, 'markerClicked', function(marker) {
        requestContent(marker.getGMarker(), marker.getId())
      });

      GEvent.addListener(maptimizeMap, 'clusterClicked', function(cluster) {
        cluster.requestIds(function(ids) {
          requestContent(cluster.getGMarker(), ids);
        })
      });

      update();

      window.map          = map;
      window.maptimizeMap = maptimizeMap;
    }
  }

  function reset() {
    FormHelper.reset('search');
    map.setCenter(new GLatLng(26.437944,-82.066837), 10);
    update();
  }

  function setBounds(bounds) {
    if (bounds) {
      var zoom = map.getBoundsZoomLevel(bounds);
      map.setCenter(bounds.getCenter(), zoom);
    } else {
      map.setCenter(new GLatLng(26.437944,-82.066837), 10);

    }
  }

  return {init:      init,
          update:    update,
          setBounds: setBounds,
          reset:     reset}
})();

Remote.RentalLink = Behavior.create(Remote.Base, {
  onclick : function() {
    this.options.parameters = Rental.filterParams();
    var options = Object.extend({ url : this.element.href, method : 'get' }, this.options);
    return this._makeRequest(options);
  }
});
Event.addBehavior({
  'div.rental_pagination a': Remote.RentalLink
});
Tooltip = (function() {
  var current;

  function init() {
    $$('.tooltip').invoke("observe", "click", openTooltip);
  }

  function openTooltip(event) {
    if (current) {
      closeTooltip(event);
    }
    else {
      event.stop();
      var element = event.findElement(),
          id = element.id;
          content = $(id + '-content');

      var offset = element.cumulativeOffset();
      content.style.top = offset[1] + element.getHeight() + 5 + "px";
      content.style.left = offset[0] + "px";
      $(document.body).insert(content.appear({duration : 0.5}));

      current = content;
      document.observe('click', closeTooltip);
    }
  }

  function closeTooltip(event) {
    event.stop();
    content.fade({duration : 0.5});
    current = null;
    document.stopObserving('click', closeTooltip);
  }
  return {init: init}
})();
