$(window).addEvent('domready', function() {
  
  var markers = new Hash();
  var firstLoadUpdate;
  
  if (!$('map')) {
    return;
  }
  
  var lat = 24.47654341525496;
  var lng = -35.643566738902535;
  var zoom = 2;
  var type = 'satellite';
  
  var viewMatch = window.location.search.match(/view=([0-9.-]+,[0-9.-]+,\d+,[a-z]+)/);
  var checkGeolocation = false;
  
  if ($('spot-view')) {
    var view = $('spot-view').get('content').split(',');
    var latlng = $('spot-latlng').get('content').split(', ');
    view.shift();
    view.shift();
    view.unshift(latlng[1]);
    view.unshift(latlng[0]);
    view = view.join(',');
  } else if (viewMatch) {
    var view = viewMatch[1];
  } else if (Cookie.read('view')) {
    var view = Cookie.read('view');
  } else if (typeof navigator != 'undefined' &&
             typeof navigator.geolocation != 'undefined') {
    var checkGeolocation = true;
  }
  
  if (view) {
    view = view.split(',');
    lat = parseFloat(view[0]);
    lng = parseFloat(view[1]);
    zoom = parseInt(view[2]);
    type = view[3];
  }
  
  if (typeof google == 'undefined') {
    if ($('lat') && $('lng')) {
      $('lat').value = lat;
      $('lng').value = lng;
    }
    return;
  }
  
  var map = new google.maps.Map($('map'), {
    center: new google.maps.LatLng(lat, lng),
    zoom: zoom,
    mapTypeId: type
  });
  
  if (checkGeolocation) {
    navigator.geolocation.getCurrentPosition(function(position) {
      lat = position.coords.latitude;
      lng = position.coords.longitude;
      zoom = 12;
      map.setCenter(new google.maps.LatLng(lat, lng));
      map.setZoom(zoom);
    });
  }
  
  if (!$('spot-view') && ($('permalink') || $('view-input'))) {
    var geocoder = new google.maps.Geocoder();
    google.maps.event.addListener(map, 'zoom_changed', function() {
      setTimeout(updateView, 0);
    });
    google.maps.event.addListener(map, 'dragend', updateView);
    google.maps.event.addListener(map, 'mapTypeId_changed', updateView);
    firstLoadUpdate = google.maps.event.addListener(map, 'bounds_changed', updateView);
  }
  
  if ($('search')) {
    $('search').addEvent('submit', searchMap);
  }
  
  var searchMatch = window.location.search.match(/q=([^&]+)/);
  if (searchMatch) {
    searchMap(searchMatch[1]);
  }
  
  
  if ($('spot-color')) {
    var image = '/images/markers/' + $('spot-color').get('content') + '.png';
  } else {
    var image = '/images/marker.png';
  }
  
  var icon = getIcon(image);
  
  var shadow = new google.maps.MarkerImage(
    "/images/shadow.png",
    new google.maps.Size(22, 20),
    new google.maps.Point(0, 0),
    new google.maps.Point(6, 20));
  
  if ($('spot-latlng')) {
    var center = map.getCenter();
    var marker = new google.maps.Marker({
      position: center, 
      map: map,
      title: document.title,
      icon: icon,
      shadow: shadow
    });
  }
  
  function updateView() {
    if (!$('permalink') && !$('view-input')) {
      return;
    }
    var center = map.getCenter();
    zoom = map.getZoom();
    lat = center.lat().round(5);
    lng = center.lng().round(5);
    type = map.getMapTypeId();
    var view = lat + ',' + lng + ',' + zoom + ',' + type;
    Cookie.write('view', view, {
      duration: 365
    });
    if (!$('view-input')) {
      $('permalink').set('href', '/find?view=' + view);
    } else {
      //$('lat').value = lat;
      //$('lng').value = lng;
      $('view-input').value = view;
    }
    if (!$('create')) {
      checkForSpots();
    }
    if (firstLoadUpdate) {
      google.maps.event.removeListener(firstLoadUpdate);
      firstLoadUpdate = false;
    }
    return view;
  }
  
  function searchMap(q) {
    if (typeof q != 'string' && $('q_input')) {
      var q = $('q_input').value;
    }
    var query = {
      address: q,
      bounds: map.getBounds()
    };
    geocoder.geocode(query, function(results, status) {
      if (status == 'ZERO_RESULTS') {
        $('search-feedback').set('html', "Oops, couldn't find that.");
      } else {
        $('search-feedback').set('html', '');
        map.fitBounds(results[0].geometry.bounds);
        setTimeout(updateView, 0);
      }
    });
    return false;
  }
  
  function checkForSpots(page) {
    var bounds = map.getBounds();
    if (!bounds) {
      return;
    }
    if (!page) {
      page = 1;
    }
    var ne = bounds.getNorthEast();
    var sw = bounds.getSouthWest();
    var request = new Request.JSON({
      url: '/spot.find',
      onSuccess: function(response) {
        response.spots.each(function(spot) {
          if (markers[spot.id]) {
            return;
          }
          var icon = getIcon('/images/markers/' + spot.color + '.png');
          markers[spot.id] = new google.maps.Marker({
            position: new google.maps.LatLng(spot.lat, spot.lng),
            map: map,
            title: spot.title,
            icon: icon,
            shadow: shadow
          });
          google.maps.event.addListener(markers[spot.id], 'click', function() {
            window.location = '/' + spot.id;
          });
        });
        if (response.count > markers.getLength()) {
          var start = markers.getLength() - response.spots.length + 1;
          var end = markers.getLength();
          $('map_page').set('html', 'Showing spots ' + start + '&ndash;' + end + ' <a href="#">Load next page</a>');
          $('map_page').removeClass('hidden');
          $('map_page').getElement('a').addEvent('click', function() {
            $('map_page').set('html', 'Loading...');
            checkForSpots(page + 1);
            return false;
          });
        } else {
          $('map_page').set('html', 'Showing all ' + response.count + ' spots');
          $('map_page').removeClass('hidden');
        }
      }
    }).get({
      n: ne.lat(),
      s: sw.lat(),
      e: ne.lng(),
      w: sw.lng(),
      p: page
    });
  }
  
  if ($('choose')) {
    var chosen = false;
    $('create').addEvent('submit', function() {
      if (!chosen) {
        alert('Please click the button marked Choose location and position your spot on the map.');
        return false;
      }
      return true;
    });
    var marker;
    var picker = new MooRainbow($('color'), {
      imgPath: '/library/mooRainbow/images/',
      startColor: [255, 255, 255],
      onComplete: function(color) {
        $('color').setStyle('background-color', color.hex);
        $('color-input').value = color.hex.substr(1);
        icon = new google.maps.MarkerImage(
          "/image.marker?color=" + color.hex.substr(1),
          new google.maps.Size(12, 20),
          new google.maps.Point(0, 0),
          new google.maps.Point(6, 20));
        marker.setIcon(icon);
      }
    });
    $('color').addEvent('click', function() {
      picker.show();
    });
    $('choose').addEvent('click', function() {
      chosen = true;
      $('choose').set('disabled', 'disabled');
      $('choose').set('value', 'Drag the pin to its correct location');
      $('create').getElement('.color').setStyle('display', 'block');
      var center = map.getCenter();
      marker = new google.maps.Marker({
        position: center, 
        map: map,
        draggable: true,
        icon: icon,
        shadow: shadow
      });
      google.maps.event.addListener(marker, 'dragend', function() {
        $('lat').value = marker.getPosition().lat();
        $('lng').value = marker.getPosition().lng();
      });
      $('lat').value = center.lat();
      $('lng').value = center.lng();
      return false;
    });
  }
  
  function getIcon(image) {
    var icon = new google.maps.MarkerImage(
      image,
      new google.maps.Size(12, 20),
      new google.maps.Point(0, 0),
      new google.maps.Point(6, 20)
    );
    return icon;
  }
  
});
