// Wilderness.com Javascript
//

/* Count the amount of text in a field, subtract from allowed to show
 * remaining
 */
function textCounter(fieldid,cntid,maxlimit) {
  var field=document.getElementById(fieldid);
  var cntfield=document.getElementById(cntid);
  if (field.value.length > maxlimit) // if too long...trim it!
    field.value = field.value.substring(0, maxlimit);
  // otherwise, update 'characters left' counter
  else
    cntfield.value = maxlimit - field.value.length;
}

/* Get absolute position of an object,
   by recursing up the object model. */
function findPos(obj) {
  var curleft = curtop = 0;
  if (obj.offsetParent) {
    do {
      curleft += obj.offsetLeft;
      curtop += obj.offsetTop;
    } while (obj = obj.offsetParent);
  }
  return [curleft,curtop];
}

/* Show/Hide an element */
function toggleVisibility(idstr) {
  var elem, vis;
  if( document.getElementById ) // this is the way the standards work
    elem = document.getElementById( idstr );
  else if( document.all ) // this is the way old msie versions work
    elem = document.all[idstr];
  else if( document.layers ) // this is the way nn4 works
    elem = document.layers[idstr];
  vis = elem.style;
  // if the style.display value is blank we try to figure it out here
  if(vis.display==''&&elem.offsetWidth!=undefined&&elem.offsetHeight!=undefined)
    vis.display = (elem.offsetWidth!=0&&elem.offsetHeight!=0)?'block':'none';
  vis.display = (vis.display==''||vis.display=='block')?'none':'block';
}

/*
 * Retrieve nearest town name from Geonames.org in JSON via AJAX
 */
function fetchNearestTown(element_id, lat, lon) {
  new Ajax.Request("/geoname/getName?lat="+lat+"&lon="+lon,
     { method: 'get',
       onSuccess: function(transport) {document.getElementById(element_id).innerHTML = transport.responseText},
       onFailure: function(transport) {document.getElementById(element_id).innerHTML = "No matching town for "+lat+", "+lon}
       } );
}

/* Show a slideshow of images, using timers to set rotation
 */
var slideshowArrayIndex = 0; // counter for slideshow; will be wrapped to length of URLs
var slideshowTimerID;
var slideshowImageArray, slideshowAltArray, slideshowLinkArray;
var slideshowInterval;
var slideshowStarted = false;

function setupSlideshow(URLarray, ALTarray, HREFarray, interval) {
  slideshowInterval = interval;
  slideshowImageArray = URLarray;
  slideshowAltArray = ALTarray;
  slideshowLinkArray = HREFarray;
  // preload images for slideshow
  for(i=0; i<URLarray.length; i++) {
    image = new Image();
    image.src = URLarray[i];
    }
  // start show timer
  startSlideshow();
}

/* start the slideshow */
function startSlideshow() {
  if (slideshowStarted) { return; }
  slideshowTimerID = setInterval("updateImage()", slideshowInterval);
  updateImage();
  slideshowStarted = true;
}

function stopSlideshow() {
  clearInterval(slideshowTimerID);
  slideshowStarted = false;
}

function gotoSlide(idx) {
  slideshowArrayIndex = idx;
  stopSlideshow();
  updateImage();
}

function updateImage() {
  if(document.getElementById) {
    document.getElementById('slideshow_img').src = slideshowImageArray[slideshowArrayIndex];
    document.getElementById('slideshow_img').alt = slideshowAltArray[slideshowArrayIndex];
    document.getElementById('slideshow_img').title = slideshowAltArray[slideshowArrayIndex];
    document.getElementById('slideshow_link').href = slideshowLinkArray[slideshowArrayIndex];
    document.getElementById('slideshow_caption').innerHTML = slideshowAltArray[slideshowArrayIndex];
    updateSlideList();
    slideshowArrayIndex++;
    if(slideshowArrayIndex >= slideshowImageArray.length) { slideshowArrayIndex = 0; }
    return(false);
    }
  else {
    return(true);
    }
}

function updateSlideList() {
  for(i=0; i<slideshowImageArray.length; i++) {
    indexStr="slideshow_img_"+(i+1);
    if(document.getElementById(indexStr)) {
      if(i == slideshowArrayIndex) {
	document.getElementById(indexStr).className="SelectedSlideNumber";
	}
      else {
	document.getElementById(indexStr).className="UnSelectedSlideNumber";
	}
      }
    }
}

/***
 *** Google Maps procedures
 ***/
function createGoogleMap(divid) {
  if (GBrowserIsCompatible()) {
    googleMap = new GMap2(document.getElementById(divid));	// Global variable def, so we can use this later
    googleMap.setMapType(G_HYBRID_MAP);		// set map+satellite as default
    geocoder = new GClientGeocoder();
    mapPins = [];	// array of markers added to map so we can play with after creation
  }
  else {
    document.getElementByID(divid).innerHTML="<h2>Google Maps doesn't support this browser.</h2>"
  }
}

function setMapBounds(lat, lon, minLat, minLon, maxLat, maxLon) {
  if (GBrowserIsCompatible()) {
    if( maxLon - minLon > 180){	// recenter if distance > 1/2 the planet
      if ( maxLon == 180 && minLon == -180) { // don't change if plotting the whole planet!
        lon = lon;}
      else {
	lon -= 180;}
      }
    if (Math.abs(maxLat-minLat) < 0.01){maxLat = lat+0.05; minLat=lat-0.05;}
    if (Math.abs(maxLon-minLon) < 0.01){maxLon = lon+0.05; minLon=lon-0.05;}
    var bounds = new GLatLngBounds(new GLatLng(minLat, minLon), new GLatLng(maxLat, maxLon))
    var zoom = googleMap.getBoundsZoomLevel(bounds);
    googleMap.setCenter(new GLatLng(lat, lon), zoom);
  }
}

function setupGoogleMap(lat, lon, minLat, minLon, maxLat, maxLon, divid) {
  var divid = (divid==null) ? "map" : divid;	// set a default value if divid not given
  createGoogleMap(divid);
  setMapBounds(lat, lon, minLat, minLon, maxLat, maxLon);
  if (GBrowserIsCompatible()) {
    size = googleMap.getSize();
    if (size.width >= 300 || size.height >= 300) {
      if (size.width >= 600) {
	googleMap.addControl(new GLargeMapControl());
	googleMap.addControl(new GMapTypeControl());
	}
      else {
	googleMap.addControl(new GSmallMapControl());
	googleMap.addControl(new GMapTypeControl());
	}
      }
  }
}

function addStoryPositions(latArray, lonArray, titles) {
  if (GBrowserIsCompatible()) {
    // add a polyline for the trip
    var polyOpts = {geodesic:true};
    var positions = [];
    var pin = createPinIcon(0);
    // iterate over lat/lons to push onto positions
    for(i=0; i<latArray.length; i++) {
      if(latArray[i] == -91 || lonArray[i] == -181) continue;
      positions.push(new GLatLng(parseFloat(latArray[i]), parseFloat(lonArray[i])));
      googleMap.addOverlay(new GMarker(positions[positions.length-1], {title: titles[i], clickable:false, icon:pin}));
      }
    var polyline= new GPolyline(positions, "#1000f0", 3, 1, polyOpts);
    googleMap.addOverlay(polyline);
  }
}

// Add overlays for tracks, with a single marker for start and stop of each track.
function addEntryTrack(latArray, lonArray) {
  if (GBrowserIsCompatible()) {
    // color rotation for track lines
    var colors = ["#f000f0", "#ff0000", "#00ff00", "#f0f0f0"];
    // add a polyline for the track
    var polyOpts = {geodesic:true};
    // iterate over lat/lons to push onto positions
    for(i=0; i<latArray.length; i++) { // # of tracks
      var positions = [];
      for(j=0; j<latArray[i].length; j++) {
	if(latArray[i][j] == -91 || lonArray[i][j] == -181) continue;
	positions.push(new GLatLng(parseFloat(latArray[i][j]), parseFloat(lonArray[i][j])));
	}
      var polyline= new GPolyline(positions, colors[i%colors.length], 3, 1, polyOpts);
      googleMap.addOverlay(polyline);
      var icon = createPinIcon(i);
      googleMap.addOverlay(new GMarker(positions[0], {icon: icon, title: "Start track #"+(i+1), clickable:false}));
      googleMap.addOverlay(new GMarker(positions[positions.length-1], {icon: icon, title: "End track #"+(i+1), clickable:false}));
      }
  }
}

function addSearchPositions(latArray, lonArray) {
  if (GBrowserIsCompatible()) {
    // iterate over lat/lons to add markers
    pin = createPinIcon(1);
    for(i=0; i<latArray.length; i++) {
      if(latArray[i] == -91 || lonArray[i] == -181) continue;
      googleMap.addOverlay( new GMarker(new GLatLng(latArray[i], lonArray[i]), {icon: pin}) );
      }
  }
}

function addProfilePositions(latArrays, lonArrays, offset) {
  var offset = (offset==null) ? 0 : offset;	// set a default value if offset not given
  if (GBrowserIsCompatible()) {
    // iterate over arrays of lat/lons to add markers
    for(j=0; j<latArrays.length; j++) {
      pin = createPinIcon(j+offset);
      for(i=0; i<latArrays[j].length; i++) {
	if(latArrays[j][i] == -91 || lonArrays[j][i] == -181) continue;
	googleMap.addOverlay( new GMarker(new GLatLng(latArrays[j][i], lonArrays[j][i]), {icon: pin}) );
	}
      }
  }
}

function addStoryPosition(lat, lon) {
  if (GBrowserIsCompatible()) {
    // add a marker for the trip
    var pin = createPinIcon(0);
    var marker= new GMarker(new GLatLng(lat, lon), {icon:pin});
    googleMap.addOverlay(marker);
  }
}

// Create a new GIcon instance set to a colored pin, where the color is taken
// from the available files in a round-robin
function createPinIcon(color_index) {
  colors = new Array("red_pin", "blue_pin", "grn_pin", "purple_pin", "yellow_pin");
  var pin = new GIcon(); // marker is a pin, not the default
  idx = color_index%colors.length;
  pin.image = "/images/"+colors[idx]+".png";
  pin.shadow = "/images/shadow.png";
  pin.imageSize = new GSize(9, 21);
  pin.shadowSize = new GSize(19, 16);
  pin.iconAnchor = new GPoint(5, 21);
  pin.infoWindowAnchor = new GPoint(5, 2);
  return pin
}

// Run when many places match a name, to help users choose...
function addPlacePositions(latArray, lonArray, strings) {
  if (GBrowserIsCompatible()) {
    var minLat = latArray[0]; var minLon = lonArray[0];
    var maxLat = minLat; var maxLon = minLon;
    for(var i=0; i<latArray.length; i++) {
      if(latArray[i] == -91 || lonArray[i] == -181) continue;
      if(latArray[i] > maxLat) maxLat = latArray[i];
      if(latArray[i] < minLat) minLat = latArray[i];
      if(lonArray[i] > maxLon) maxLon = lonArray[i];
      if(lonArray[i] < minLon) minLon = lonArray[i];
      }
    setMapBounds((maxLat+minLat)/2, (maxLon+minLon)/2, minLat, minLon, maxLat, maxLon);
    // must be global, so we can reference in removePlacePositions()
    markers = new Array();
    pin = createPinIcon(0);	// get first color
    // iterate over lat/lons to add markers
    for(var i=0; i<latArray.length; i++) {
      if(latArray[i] == -91 || lonArray[i] == -181) continue;
      markers[i] = new GMarker(new GLatLng(latArray[i], lonArray[i]), {icon: pin, title: strings[i], clickable:true});
      GEvent.addListener(markers[i], "click", function(latlng) {
	// Update selection box by setting i'th option to true
	var selectObj = document.getElementById("place_place_id").options;
	for (var j=0; j<selectObj.length; j++) {
	  selectObj[j].selected = false;
	  if((latArray[j] == latlng.lat()) && (lonArray[j] == latlng.lng())) {
	    selectObj[j].selected = true;
	    }
	  }
	});
      googleMap.addOverlay(markers[i]);
      }
  }
}

// Run when a choice is made, to unclutter the map...
function removePlacePositions() {
  for(i=0; i<markers.length; i++) {
    googleMap.removeOverlay(markers[i]);
    }
}

function zoomMapToPoint(lat, lon) {
  if (GBrowserIsCompatible()) {
    var maxLat = lat+0.05; var minLat=lat-0.05;
    var maxLon = lon+0.05; var minLon=lon-0.05;
    var bounds = new GLatLngBounds(new GLatLng(minLat, minLon), new GLatLng(maxLat, maxLon))
    var zoom = googleMap.getBoundsZoomLevel(bounds);
    googleMap.setCenter(new GLatLng(lat, lon), zoom);
  }
}

function setupLatLonFeedback(basename, latitude, longitude, pinIdx, zoomMovesPin) {
  // add event handlers to Google Map googleMap 
  // so dragging marker sets basename_latitude, basename_longitude 

  if (GBrowserIsCompatible()) {
    // add movement, zoom controls
    //googleMap.addControl(new GSmallMapControl());
    //googleMap.addControl(new GMapTypeControl());

    // add global var stored marker for a crosshair
    var pin = createPinIcon(pinIdx);	// use a pin, not the icky pink blob
    var crossHair = new GMarker(new GLatLng(latitude, longitude),
      {icon:pin, title:"Move the pin where you want", clickable:false, draggable:true});
    googleMap.addOverlay(crossHair);
    mapPins.push(crossHair);

    /*
    GEvent.addListener(googleMap, "moveend", function() {
      var center = googleMap.getCenter();
      setLatLonBoxes(basename, center.lat(), center.lng());
      crossHair.setLatLng(googleMap.getCenter());
      });
    GEvent.addListener(googleMap, "move", function() {
      crossHair.setLatLng(googleMap.getCenter());
      });
    */
    if(zoomMovesPin) {
      GEvent.addListener(googleMap, "zoomend", function() {	// recenter pin  when zooming...
	pnt = googleMap.getCenter()
	crossHair.setLatLng(pnt);
	setLatLonBoxes(basename, pnt.lat(), pnt.lng());
	});
    }
    GEvent.addListener(crossHair, "dragend", function() {	// update lat/lon boxes when dragging done
      pnt = crossHair.getLatLng();
      setLatLonBoxes(basename, pnt.lat(), pnt.lng());
      });
    GEvent.addListener(crossHair, "visibilitychanged", function(visible) {	// update lat/lon boxes when marker shown
      if(visible) {
	pnt = crossHair.getLatLng();
	setLatLonBoxes(basename, pnt.lat(), pnt.lng());
	}
      });
  }
}

function setLatLonBoxes(basename, lat, lon) {
  document.getElementById(basename+"_latitude").value = lat.toString();
  document.getElementById(basename+"_longitude").value = lon.toString();
  // reset N/S, E/W radio buttons so sign is preserved
  document.getElementById(basename+"_latlon_ns_n").checked = true;
  document.getElementById(basename+"_latlon_ns_s").checked = false;
  document.getElementById(basename+"_latlon_ew_e").checked = true;
  document.getElementById(basename+"_latlon_ew_w").checked = false;
}

function searchGoogleChangeMap(element_id, pin_idx) {
  if (GBrowserIsCompatible()) {
    search_string = document.getElementById(element_id).value
    if(!search_string) { return; }
    geocoder.getLatLng(search_string,
      function(point) {
	if (!point) {
	  alert(search_string + " not found");
	  }
	else {
	  googleMap.setCenter(point, 13);
	  mapPins[pin_idx].setLatLng(point);
	  mapPins[pin_idx].hide();	// hide, then show marker to fire visibilitychanged
	  mapPins[pin_idx].show();	// events to update lat/lon boxes
	  }
      });
  }
}

function movePin(pin_idx, lat, lon) {
  mapPins[pin_idx].setLatLng(new GLatLng(lat, lon));
  mapPins[pin_idx].hide();	// hide, then show marker to fire visibilitychanged
  mapPins[pin_idx].show();	// events to update lat/lon boxes
}
