var map; //GMap2
var geocoder; //GClientGeocoder
var home_marker; //GMarker
var attractions = []; //Array of GMarkers
var attraction_ids = []; //Array of ids
var bounds = new GLatLngBounds();


//Setup the map when the page is loaded
function show_map() {
  if (GBrowserIsCompatible()) {
    map = new GMap2(document.getElementById("map"));
    geocoder = new GClientGeocoder();
    map.addControl(new GLargeMapControl());
    map.addControl(new GScaleControl());
    map.addControl(new GMapTypeControl());
    map.enableScrollWheelZoom();
    map.setCenter(new GLatLng(38.90079820,-95.03364324), 4);        
  }
}

//Set the users home location
function setSearchLocation(address) {
  if (geocoder) {
    geocoder.getLatLng(
      address,
      function(point) {
        if (!point) {
          if(address == "") {
            address = "Address";
          }
          alert(address + " not found. Please try again.");
        } else {
	  clearMarkers();
          clearBounds();
          setupSearchResults(point);
          setZoomToBounds();  
        }
      }
    );
  }
}

function setupSearchResults(point) {
    var searchResults = calculatePlaceItemDistances(point);
    //Sort by distance
    searchResults.sort(sortDistance);
    //Keep 10 results
    searchResults = searchResults.splice(0,10);
    //Generate the menu
    createDistanceResults(searchResults);

    addHomeLocationToMap(point);		  
}

function calculatePlaceItemDistances(homePoint) {
  var searchResults = new Array();
  for(var i = 0; i < allPlaceItems.length; i++) {
    var pi = allPlaceItems[i];
    var latlng = new GLatLng(pi.lng, pi.lat);
    pi.search_distance = homePoint.distanceFrom(latlng);
    searchResults.push(pi);
  }
  return searchResults;
}


//Clear all existing attractions and add a new set
function clearAndAddAttractions(attractions) {
  clearMarkers();
  for(attraction in attractions) {
    addAttraction(attraction);
  }
}

//Clear all attractions from the map
function clearMarkers() {
  for(var i = 0; i < attractions.length; i++) {
    map.removeOverlay(attractions[i]);
  }
  attractions = [];
  attraction_ids = [];
  clearBounds();
  removeHomeLocationFromMap();
}

function showAllPlaceItems() {
  for(var i = 0; i < allPlaceItems.length; i++) {
    addAttraction(allPlaceItems[i]);
  }
}

//Add an attraction to the map
function addAttraction(placeItem) {	
  var latlng = new GLatLng(placeItem.lng, placeItem.lat);
  var marker = new GMarker(latlng, { icon:getIcon(placeItem), title:placeItem.name }); 

  GEvent.addListener(marker, "click", function() {
//		placeItem.load();
    marker.openInfoWindowTabs(getAttractionInfoWindowHTML(placeItem));
  });

  attractions.push(marker);
  attraction_ids.push(placeItem.id);
  map.addOverlay(marker);
}

function extendBounds(placeItem) {
  var latlng = new GLatLng(placeItem.lng, placeItem.lat);
  bounds.extend(latlng);
}

function clearBounds() {
  bounds = new GLatLngBounds();
}

function setZoomToBounds() {
  var sw = bounds.getSouthWest();
  var ne = bounds.getNorthEast();

  var latoff = (sw.lat() - ne.lat()) / 10.0;
  var lngoff = (sw.lng() - ne.lng()) / 10.0;
  
  var newsw = new GLatLng(sw.lat() + latoff, sw.lng() + lngoff);
  var newne = new GLatLng(ne.lat() - latoff, ne.lng() - lngoff);
  
  bounds.extend(newsw);
  bounds.extend(newne);
  
  map.setZoom(map.getBoundsZoomLevel(bounds));
  map.setCenter(bounds.getCenter());	
}

//Remove the users home location from the map
function removeHomeLocationFromMap() {
  if (home_marker != null) {
    map.removeOverlay(home_marker);
  }
}

//Add the users home location to the map 
function addHomeLocationToMap(point) {
  if(point !== null) {
    home_marker = new GMarker(point);
    map.addOverlay(home_marker);
    bounds.extend(point);
  }
}

//Calculate the distance to each place
function calculateDistanceToPlaces() {
  for(var i = 0; i < attractions.length; i++) {
    var id = attraction_ids[i];
    var place_marker = attractions[i];
    var menuItem = getMenuItem(id);
    var distance = getDistanceFromHome(place_marker.getPoint());

    menuItem.setDistance(distance);
  }
}


//Get the distance in m from the home location
function getDistanceFromHome(point) {
  if(home_marker != null && point != null) {
    return point.distanceFrom(home_marker.getPoint());
  } else {
    return -1;
  }
}

//Convert a distance in meters to a nice user friendly string
function formatDistance(distance) {
  var mInMiles = 1609.344;
  if(distance > 1000) {
    return formatNumberToResolution(distance/mInMiles, 0.1, 1) + " miles";
  } else {
    return formatNumberToResolution(distance, 50, 0) + "m";
  }
}

//Format the number to the specifed resolution
function formatNumberToResolution(number, resolution, precision) {
  number = number / resolution;
  number = number.toFixed(0);
  return (number * resolution).toFixed(precision);
}

function showInfoWindow(attraction_id) {
  for(var i = 0; i < attraction_ids.length; i++) {
    if(attraction_ids[i] == attraction_id) {
      map.panTo(attractions[i].getPoint());
      GEvent.trigger(attractions[i], "click");
      break;
    }
  }
}


//////////////////
//Info Window HTML
//////////////////

function getAttractionInfoWindowHTML(placeItem) {
  var overview = getDiv("iw_attr_name", placeItem.name);
  overview += getInfoWindowKeyValuePair("Full Details", "/resort/" + placeItem.urlized_name, "iw_pair");
  overview += getInfoWindowKeyValuePair("Phone", placeItem.phone, "iw_pair");
  overview += getInfoWindowKeyValuePair("Website", placeItem.url, "iw_pair");
  overview += getInfoWindowKeyValuePair("Trail Map", placeItem.pistemap, "iw_pair");
  overview += getInfoWindowKeyValuePair("Webcam", placeItem.webcam, "iw_pair");
  if (placeItem.ticket_adult_day_peak != null) {
    overview += getInfoWindowKeyValuePair("Day Ticket (Peak)", placeItem.currency + placeItem.ticket_adult_day_peak, "iw_pair_bar", getBarGraph(stat_adult_day_min * placeItem.one_usd, stat_adult_day_max * placeItem.one_usd, placeItem.ticket_adult_day_peak));	
  }
  if (placeItem.ticket_adult_day_off_peak != null) {
    overview += getInfoWindowKeyValuePair("Day Ticket (Off Peak)", placeItem.currency + placeItem.ticket_adult_day_off_peak, "iw_pair_bar", getBarGraph(stat_adult_day_offpeak_min * placeItem.one_usd, stat_adult_day_offpeak_max * placeItem.one_usd, placeItem.ticket_adult_day_peak));	
  }
  if (placeItem.diff_beg_percent != null && placeItem.diff_int_percent != null && placeItem.diff_exp_percent != null) {
    overview += getInfoWindowKeyValuePair("Difficulty", "&nbsp;", "iw_pair_bar", getDifficultyBarGraph(placeItem.diff_beg_percent, placeItem.diff_int_percent, placeItem.diff_exp_percent));
  }


  var details = getInfoWindowKeyValuePair("Lift Served Acres", placeItem.acres, "iw_pair_bar", getBarGraph(stat_acres_min, stat_acres_max, placeItem.acres));
  details += getInfoWindowKeyValuePair("Vertical Feet", placeItem.vertical_feet, "iw_pair_bar", getBarGraph(stat_vert_min, stat_vert_max, placeItem.vertical_feet));
  details += getInfoWindowKeyValuePair("Max Height (ft)", placeItem.summit_height, "iw_pair_bar", getBarGraph(stat_summit_height_min, stat_summit_height_max, placeItem.summit_height));
  details += getInfoWindowKeyValuePair("Base Height (ft)", placeItem.base_height, "iw_pair_bar", getBarGraph(stat_base_height_min, stat_base_height_max, placeItem.base_height));
  details += getInfoWindowKeyValuePair("# Chair & Aerial Lifts", placeItem.lifts_chair_num, "iw_pair_bar", getBarGraph(stat_lifts_chair_min, stat_lifts_chair_max, placeItem.lifts_chair_num));
  details += getInfoWindowKeyValuePair("# Surface Lifts", placeItem.lifts_drag_num, "iw_pair_bar", getBarGraph(stat_lifts_drag_min, stat_lifts_drag_max, placeItem.lifts_drag_num));
  details += getInfoWindowKeyValuePair("Average Snowfall (in)", placeItem.snow_avg, "iw_pair_bar", getBarGraph(stat_snow_avg_min, stat_snow_avg_max, placeItem.snow_avg));
  details += getInfoWindowKeyValuePair("# Trails", placeItem.runs_num, "iw_pair_bar", getBarGraph(stat_runs_num_min, stat_runs_num_max, placeItem.runs_num));
  
  var links = '';
  for(var i = 0; i < placeItem.link_names.length; i++) {
  	links += getInfoWindowLinkRow(placeItem.link_names[i], placeItem.link_urls[i]);
  }

  //Write out tabs
  var retArr = [];
  retArr.push(new GInfoWindowTab("Overview", overview));
  retArr.push(new GInfoWindowTab("Stats", details));
  retArr.push(new GInfoWindowTab("Links", links));

  return retArr;
}


function getInfoWindowKeyValuePair(key, value, div_name, suffix) {
  if(suffix == null) {
    suffix = "";
  }

  if(value == null || value == "") {
    return "";
  }
  value = String(value);
  
  var retStr = "";  
  retStr += "<div class=\"iw_row\">";
  retStr += getDiv(div_name + "_k", key);
  
  var newvalue = value;
  if(newvalue.indexOf("http://") != -1) {
    var value_display = newvalue;
    value_display = key + "...";
    newvalue = "<a href=\"" + newvalue + "\" target=\"_blank\">" + value_display + "</a>"; 
  }

  if(newvalue.indexOf("/") == 0) {
    var value_display = newvalue;
    value_display = key + "...";
    newvalue = "<a href=\"" + newvalue + "\">" + value_display + "</a>"; 
  }

  retStr += getDiv(div_name + "_v", newvalue);
  retStr += suffix;
  retStr += "</div>";
  return retStr;
}

function getInfoWindowLinkRow(description, url) {
  var retStr = "<div class=\"iw_row\">";
  retStr += getLink('iw_link_single', url, description);
  retStr += "</div>";
  return retStr;	
}

function getLink(style, url, title) {
  return getDiv(style, "<a href=\"" + url + "\" target=\"_blank\">" + title + "</a>");
}

function getDiv(style, content) {
  return "<div class=\"" + style + "\">" + content + "</div>";
}

function getSpan(style, content) {
  return "<span class=\"" + style + "\">" + content + "</span>";
}

function getBarGraph(min, max, value) {
  //Convert to %
  var min_pc   = Math.round((min / max) * 100);
  var value_pc = Math.round((value / max) * 100);

  var retStr = "";
  retStr += "<span class=\"bar-arrows\" style=\"background-position: " +  (value_pc + 1) + "px 0px;\">";
  retStr += "<span class=\"bar-outer\">";
  retStr += "<span class=\"bar-range\" style=\"margin-left: " + min_pc + "px; width: " + (100 - min_pc) + "px;\">";
  retStr += "<span class=\"bar-value\" style=\"margin-left: " + (value_pc - min_pc - 1) + "px;\">";
  retStr += "</span></span></span></span>";
  return retStr;	
}

function getDifficultyBarGraph(beg, inter, exp) {
  beg = beg * 1.1;
  inter = inter * 1.1;
  exp = exp * 1.1;

  if((beg + inter + exp) <= 111) {
    inter++;
  }
  if((beg + inter + exp) <= 111) {
    inter++;
  }
	
  var retStr = "";
  retStr += "<span class=\"bar-no-arrows\">";
  retStr += "<span class=\"bar-outer\">";
  retStr += "<span class=\"bar-range\" style=\"background-color: #2CD828;  margin-left: 0px; width: " + beg + "px;\" />";
  retStr += "<span class=\"bar-range\" style=\"background-color: #6371F3;   margin-left: " + beg + "px; width: " + inter + "px;\" />";
  retStr += "<span class=\"bar-range\" style=\"background-color: black; margin-left: " + inter + "px; width: " + exp + "px;\" />";
  retStr += "</span>";
  retStr += "</span>";
  return retStr;	
}

  function getIcon(placeItem) {
    var size = placeItem.relative_size;
    
    switch(parseInt(size))
    {
      case 1: return icon1;
      case 2: return icon2;
      case 3: return icon3;
      case 4: return icon4;
      case 5: return icon5;
    }
  }


var icon1 = new GIcon();
icon1.image = "http://www.snowwheretogo.com/images/map/marker1.png";
icon1.shadow = "http://www.snowwheretogo.com/images/map/shadow1.png";
icon1.iconSize = new GSize(11, 19);
icon1.shadowSize = new GSize(20, 19);
icon1.iconAnchor = new GPoint(6, 19);
icon1.infoWindowAnchor = new GPoint(6, 0);

var icon2 = new GIcon();
icon2.image = "http://www.snowwheretogo.com/images/map/marker2.png";
icon2.shadow = "http://www.snowwheretogo.com/images/map/shadow2.png";
icon2.iconSize = new GSize(14, 24);
icon2.shadowSize = new GSize(26, 24);
icon2.iconAnchor = new GPoint(7, 24);
icon2.infoWindowAnchor = new GPoint(7, 0);

var icon3 = new GIcon();
icon3.image = "http://www.snowwheretogo.com/images/map/marker3.png";
icon3.shadow = "http://www.snowwheretogo.com/images/map/shadow3.png";
icon3.iconSize = new GSize(17, 29);
icon3.shadowSize = new GSize(31, 29);
icon3.iconAnchor = new GPoint(9, 29);
icon3.infoWindowAnchor = new GPoint(9, 0);

var icon4 = new GIcon();
icon4.image = "http://www.snowwheretogo.com/images/map/marker4.png";
icon4.shadow = "http://www.snowwheretogo.com/images/map/shadow4.png";
icon4.iconSize = new GSize(20, 34);
icon4.shadowSize = new GSize(37, 34);
icon4.iconAnchor = new GPoint(10, 34);
icon4.infoWindowAnchor = new GPoint(10, 0);

var icon5 = new GIcon();
icon5.image = "http://www.snowwheretogo.com/images/map/marker5.png";
icon5.shadow = "http://www.snowwheretogo.com/images/map/shadow5.png";
icon5.iconSize = new GSize(23, 39);
icon5.shadowSize = new GSize(43, 39);
icon5.iconAnchor = new GPoint(12, 39);
icon5.infoWindowAnchor = new GPoint(12, 0);
