var centerPoint;
var geocoder;

var circle;
var filter = 0;
var gasTypeName = null;
var map = null;
var markerManager = null;
var myCenter = null;
var centerMarker = null;
var lineOverlay = null;
var radiusSlider = 5;
var searchStations = false;
var stationMarker = null;
var reverseGeocoder = null;
var country = 'España';

printf = function() { 
  var num = arguments.length; 
  var oStr = arguments[0];   
  for (var i = 1; i < num; i++) { 
    var pattern = "\\{" + (i-1) + "\\}"; 
    var re = new RegExp(pattern, "g"); 
    oStr = oStr.replace(re, arguments[i]); 
  } 
  return oStr;
} 

function changeCountry(location) {
  if (country != location) {
    country = location;
    
    jQuery('#switcher div').removeClass('active').addClass('inactive');
    jQuery('#switcher div[@name=' + location + ']').removeClass('inactive').addClass('active');
  }
}

/*
 * Function to erase example text from input address
 */
function validateAddress(address) {
  if ((address == 'Choose a location. Example: Lisbon, Portugal') || address.length < 1) {
    return false;
  }
  
  return true;
}

function clearField(div) {
  if (!validateAddress(div.value)) {
    div.value = '';
  }
}

function doLoad() {
  if (GBrowserIsCompatible()) {
    $(document).unload(function() {
      GUnload();
    });

    if (document.getElementById("map")) {
      map = new GMap2(document.getElementById("map"));
      centerPoint = new GLatLng(40.16208338164617, -4.94384765625);
      geocoder = new GClientGeocoder();

      map.addMapType(G_NORMAL_MAP);
      map.setCenter(centerPoint, 6, G_NORMAL_MAP);

      map.addControl(new GScaleControl());
      map.addControl(new GHierarchicalMapTypeControl());
      
      map.enableContinuousZoom();
      map.enableDoubleClickZoom();
      
      new GKeyboardHandler(map);

      markerManager = new MarkerManager(map);

      return true;
    } else {
      return false;
    }
  }
  
  return false;
}

function loadMap(latitude, longitude, radius) {
  searchStations = true;

  if (doLoad()) {
    map.addControl(new GLargeMapControl());
    
    if (latitude && longitude && radius) {
      point = new GLatLng(latitude, longitude);
      radiusSlider = radius;
      draw(point, true, true);
      map.panTo(point);
    };
  }

  $('#add-link').css('float', 'left');
}

function loadSimpleMap() {
  searchStations = false;

  if (doLoad()) { map.addControl(new GLargeMapControl()) }
}

function hasCenterMarker() {
  return centerMarker;
}

function setRadiusSlider(value) {
  radiusSlider = value + 1;
}

function updateStation(id, latitude, longitude, icon)
{
  $('#status').html('Price successfully updated, thank you');

  marker = addStation(id, latitude, longitude, icon);

  GEvent.trigger(marker, "click");

  map.panTo(new GLatLng(latitude, longitude));
}

function showStation(id, latitude, longitude, icon)
{
  $('#status').html('Showing selected station.');

  marker = addStation(id, latitude, longitude, icon);

  GEvent.trigger(marker, "click"); 

  centerMap(point, 1, false, true);

  map.panTo(new GLatLng(latitude, longitude));
}

function addStation(id, lat, lng, icon)
{
  point = new GLatLng(lat, lng);

  if (icon) {
    stationIcon = new GIcon(G_DEFAULT_ICON, '/images/' + icon + '.png');
    stationIcon.iconSize = new GSize(37, 43);
    stationIcon.shadow = '/images/marker_shadow.png';
    stationIcon.transparent = '/images/marker_transparent.png'
    stationIcon.shadowSize = new GSize(59, 43);
    stationIcon.iconAnchor = new GPoint(18, 42);
    stationIcon.infoWindowAnchor = new GPoint(3, 3);
    stationIcon.imageMap = [1,1,37,1,36,33,18,41,2,31,2,2]
  } else {
    stationIcon = new GIcon(G_DEFAULT_ICON, null);
    stationIcon.iconSize = new GSize(0, 0);
  }

  var stationMarker = new GMarker(point, { icon: stationIcon });

  GEvent.addListener(stationMarker, "click", function() {
    $.ajax({ dataType: 'script', url: '/ajax/get/station/' + id });

    pageTracker._trackPageview('/ajax/get/station/' + id);
  });

  markerManager.addMarker(stationMarker, 10);

  return stationMarker;
}

// Show a geocoded address
function showAddress(address, drawOverlay) {
  search = address + ', ' + country;

  geocoder.getLatLng(search,
    function(point) {
      if (!point) {
        geocoder.getLatLng(address,
          function(point) {
            if (!point) {
              alert(printf('{0} was not found. Did you type the address correctly?', address));
            } else {
              draw(point, drawOverlay, true);

              map.panTo(point);
            }
          }
        );
      } else {
        draw(point, drawOverlay, true);

        map.panTo(point);
      }
    }
  );
}

function centerMap(center, radius, drawOverlay, zoom) {
  var circlePoints = Array();
  var bounds = new GLatLngBounds();

  var rLat = (radius/6378.135) * (180/Math.PI);
  var rLng = rLat/Math.cos(center.lat() * (Math.PI/180));

  for (var i = 0; i < 361; i+=1 ) {
    var aRad = i*(Math.PI/180);
    var x = center.lng() + (rLng * Math.cos(aRad));
    var y = center.lat() + (rLat * Math.sin(aRad));
    var pint = new GLatLng(parseFloat(y),parseFloat(x));

    bounds.extend(pint);
    circlePoints.push(pint);
  }

  if (drawOverlay && centerMarker) {
    circle = new GPolygon(circlePoints, null, 2, null, '#0055ff', null);
    map.addOverlay(circle);
  }

  if (zoom) {
    map.setZoom(map.getBoundsZoomLevel(bounds));
  };
}

/**
 * Map Circle
 */
function drawCircle(center, radius, drawOverlay, zoom)
{
  map.clearOverlays();

  var cenergyIcons = [];

  cenergyIcons["home"] = new GIcon(G_DEFAULT_ICON, "/images/home.png");
  cenergyIcons["home"].iconSize = new GSize(33, 34);
  cenergyIcons["home"].iconAnchor = new GPoint(17, 33);
  cenergyIcons["home"].imageMap = [17,33,30,26,32,14,23,0,2,10,4,27,18,34]
  
  centerMarker = new GMarker(center, { draggable: true, icon: cenergyIcons["home"], zIndexProcess:importanceOrder });
  centerMarker.importance = 2;

  map.addOverlay(centerMarker);

  GEvent.addListener(centerMarker, "dragend", function() {
    point = centerMarker.getPoint();
    draw(point, true, false);
  });

  markerManager.clearMarkers();

  centerMap(center, radius, drawOverlay, zoom);
}

function draw(point, drawOverlay, zoom) {
  var centre = point;
  var name = '';

  map.clearOverlays();
  markerManager.clearMarkers();

  drawCircle(centre, radiusSlider, drawOverlay, zoom);

  if (jQuery("#address").val() == 'Choose a location. Example: Lisbon, Portugal') {
    name = 'Automatic';
  } else {
    name = jQuery("#address").val();
  }

  if (filter > 0) {
    rawData = 'latitude=' + point.lat() + '&longitude=' + point.lng() + '&radius=' + radiusSlider + '&type=' + filter + '&name=' + name;
  } else {
    rawData = 'latitude=' + point.lat() + '&longitude=' + point.lng() + '&radius=' + radiusSlider + '&name=' + name;
  }

  if (searchStations) {
    $.ajax({
      url: '/ajax/get/stations',
      dataType: 'json',
      data: rawData,

      success: function(json) {
        pageTracker._trackPageview('/ajax/get/stations');

        if (json.success) {
          if (filter > 0) {
            var validTotal = 0;

            $.each(json.valid, function(id, station) {
              validTotal++;
              addStation(station.id, station.latitude, station.longitude, 'heatmap/' + station.cluster);
            });

            $.each(json.invalid, function(id, station) {
              addStation(station.id, station.latitude, station.longitude, 'provider_types/' + station.icon + '_unavailable');
            });

            if (validTotal > 0) {
              $('#status').html(printf('Showing {0} petrol stations with prices added to {1} in a total of {2} available in a radius of {3} Km.', validTotal, gasTypeName, json.total, radiusSlider));
            } else {
              if (radiusSlider < 10) {
                $('#status').html(printf('We were not able to find petrol stations with prices added to {0} in a radius of {1} Km. Please try incrementing the radius to {2} Km', gasTypeName, radiusSlider, radiusSlider+1));
              } else {
                $('#status').html(printf('We were not able to find petrol stations with prices added to {0} in a radius of {1} Km.', gasTypeName, radiusSlider));
              }
            }
          } else {
            $.each(json.stations, function(id, station) {
              // Add provider icon
              addStation(station.id, station.latitude, station.longitude, 'provider_types/' + station.icon);
            });

            $('#status').html(printf('Showing {0} petrol stations available in a radius of {1} Km.', json.total, radiusSlider));
          }
        } else {
          if (radiusSlider < 10) {
            $('#status').html(printf('We were not able to find petrol stations in a radius of {0} Km. Please try incrementing the radius to {1} Km.', radiusSlider, radiusSlider+1)); 
          } else {
            $('#status').html(printf('We were not able to find petrol stations in a radius of {0} Km.', radiusSlider));
          }
        }
      }
    });
  };
  
  if (jQuery("#status").size()) {
    getTip(10000);
  };
}

function displaySearchInformation() {
  if (!centerMarker) {
    $('#status').html('Type an address to find the cheapest fuel prices in your area.');
  }
}

function redrawCircle() {
  if (centerMarker) { draw(centerMarker.getPoint(), true); return false; } else { return false; }
}

function importanceOrder (marker,b) {
  return GOverlay.getZIndex(marker.getPoint().lat()) + marker.importance*1000000;
}

function closeStationBox() {
  jQuery('#add-station').hide();
  jQuery('#add-link').show();
}

function createStation() {
  map.clearOverlays(); 

  if (!stationMarker) {
    stationIcon = new GIcon(G_DEFAULT_ICON, '/images/icons/new_station.png');
    stationIcon.iconSize = new GSize(37, 43);
    stationIcon.shadow = '/images/marker_shadow.png';
    stationIcon.transparent = '/images/marker_transparent.png'
    stationIcon.shadowSize = new GSize(59, 43);
    stationIcon.iconAnchor = new GPoint(18, 42);
    stationIcon.infoWindowAnchor = new GPoint(3, 3);
    stationIcon.imageMap = [1,1,37,1,36,33,18,41,2,31,2,2]

    stationMarker = new GMarker(map.getCenter(), { draggable: true, zIndexProcess:importanceOrder, icon: stationIcon });
    stationMarker.importance = 3;

    markerManager.addMarker(stationMarker, 10);
  };
}

function removeStation() {
  markerManager.removeMarker(stationMarker);
  
  stationMarker = null;
}

function saveStation() {
  if (!reverseGeocoder) {
    reverseGeocoder = new GReverseGeocoder(map);

    GEvent.addListener(reverseGeocoder, "error",
      function() {
        var name = jQuery('#name').val();
        var type = document.getElementById("type").value;
        var latlng = stationMarker.getLatLng();
        var lat = latlng.lat();
        var lng = latlng.lng();

        var url = "/ajax/create/station" + '?name=' + name + "&type=" + type + "&latitude=" + lat + "&longitude=" + lng;

        GDownloadUrl(url, function(data, responseCode) {
          if (responseCode == 200) {
            removeStation();

            alert('We were not able to correctly detect this new station address. But don\'t worry, our team will take a closer look and you will be noticed soon!');

            loadMap(map.getCenter().lat(), map.getCenter().lng(), 5);
          } else {
            alert('There was an error trying to add this new station. Please contact our support team.')
            
            loadMap(map.getCenter().lat(), map.getCenter().lng(), 5);
          }
        });

        closeStationBox();

        return false;
      }
    );

    GEvent.addListener(reverseGeocoder, "load",
      function(placemark) {
        var name = jQuery('#name').val();
        var type = document.getElementById("type").value;
        var latlng = stationMarker.getLatLng();
        var lat = latlng.lat();
        var lng = latlng.lng();
        
        var country = reverseGeocoder.getPlacemarkProperty(placemark, "CountryNameCode");
        var address = reverseGeocoder.getPlacemarkProperty(placemark, "ThoroughfareName");
        var zip = reverseGeocoder.getPlacemarkProperty(placemark, "PostalCodeNumber");
        var city = reverseGeocoder.getPlacemarkProperty(placemark, "SubAdministrativeAreaName");

        var url = "/ajax/create/station" + '?name=' + name + "&type=" + type + "&latitude=" + lat + "&longitude=" + lng + '&address=' + address + '&country=' + country + '&zip=' + zip + '&city=' + city;

        GDownloadUrl(url, function(data, responseCode) {
          if (responseCode == 200) {
            removeStation();

            alert('Your station has been successfully submitted! We will now check the data you sent to make sure it\'s valid. Thank you for your contribution. Great job, \'mapper!');
            
            loadMap(map.getCenter().lat(), map.getCenter().lng(), 5);
          } else {
            alert('There was an error when trying to submit a new station. Please contact the support team.');
            
            loadMap(map.getCenter().lat(), map.getCenter().lng(), 5);
          }
        });

        closeStationBox();
      }
    );
  };

  reverseGeocoder.reverseGeocode(stationMarker.getLatLng());
}

function getTip(delay) {
  setTimeout(ajaxTip, delay);
}

function ajaxTip() {
  jQuery.get(
    "/ajax/get/tip", {}, function(data)
    {
      jQuery("#status").html(data).find('ul').newsTicker(10000);
    }
  );
}