/*

- New VantagePointMarker
- Store directions of visible -> 0-140,150-200 -> Create custom marker icon for these values on save.
- Custom icons for markers showing direction of viewing.
- Other 'custom' properties, such as shelter, etc.
- Photos & URLs of/from vantage point with description.
- RO/RW modes
- Different authenticated users (cookies?)
- Download as GPS waypoints.  Subset of waypoints defined by lat/lon.

- Add in unload call to stop memory leaking....

 */
var markerID = 0;
var markers = new Array();

var MARKER_STATUS_NEW = 0;
var MARKER_STATUS_MODIFIED = 1;
var MARKER_STATUS_SAVED = 2;
var MARKER_STATUS_REMOVED = 3;

//var baseURL='http://www.vantage-points.com/markers/';
//var baseURL='http://www.vantage-points.com/vantage_markers/';
var baseURL='/vantage_markers/';
var username = 'jjb';
var password = 'password';

////////////////////////////////////////////////////////////////////////////////
// Marker
////////////////////////////////////////////////////////////////////////////////
function addMarker(center, title, description, altitude, foreignMarkerID, icon) {
  var marker = new Marker(center, title, description, altitude, foreignMarkerID, icon);
  markers[marker.id] = marker;
  marker.add()
  return marker;
}

function Marker(position, title, description, altitude, foreignMarkerID, icon) {

  this.id = markerID;
  markerID += 1;
  this.foreignMarkerID = foreignMarkerID;
  if (icon)
    this.properties = {draggable: false, title: title, icon: icon};
  else
    this.properties = {draggable: false, title: title};

  this.gmarker = new GMarker(position, this.properties);
  this.title = title;
  this.description = description;
  this.altitude = altitude;
}

function derive_Marker(d) {
  src = Marker.prototype;    
  d.add = src.add;
  d.show = src.show;
  d.edit = src.edit;
  d.hide = src.hide;
  d.getPoint = src.getPoint;
  d.setPoint = src.setPoint;
  d.viewDetails = src.viewDetails;
  d.getAttributes = src.getAttributes;
}

Marker.prototype.add = function() {
  var marker = this;
  GEvent.addListener(this.gmarker, "click", function() {marker.viewDetails()});
  this.show();
};

Marker.prototype.show = function() {
  map.addOverlay(this.gmarker);
}

Marker.prototype.hide = function() {
  map.removeOverlay(this.gmarker);
}

Marker.prototype.getPoint = function() {
  return this.gmarker.getPoint();
}


Marker.prototype.setPoint = function(position) {
  return this.gmarker.setPoint(position);
}

Marker.prototype.getAttributes = function() {
  var attributes = new Array();
  var pt = this.getPoint();
  attributes[attributes.length] = new Array('Title', 'title', this.title);
  attributes[attributes.length] = new Array('Description', 'description', this.description, 'textarea');
  attributes[attributes.length] = new Array('Latitude', 'latitude', pt.y);
  attributes[attributes.length] = new Array('Longitude', 'longitude', pt.x);
  attributes[attributes.length] = new Array('Altitude', 'altitude', this.altitude, '', 'M ASL');
  return attributes;
}

Marker.prototype.viewDetails = function() {
  var attributes = this.getAttributes()

  var html ="<table class='markerViewDetails'>";
  for (i=0;i<attributes.length;i++) {
    var d = attributes[i];
    var notes = d[4]?d[4]:'';
    var inputType = d[3]?d[3]:'text';

    if (inputType == 'image') {      
      if (isValidURL(d[2])) {
	//html += "<tr><td class='markerViewLabel'>" + d[0] + "</td><td class='markerViewText'><img width=200 src='" + d[2] + "'><td class='markerViewNotes'>" + notes + "</td></tr>";
	html += "<tr><td colspan=2 class='markerViewImage'><div id='popupImageBox'><img src='" + d[2] + "'></div></td></tr>";
      }
    } else {
	//html += "<tr><td class='markerViewLabel'>" + d[0] + "</td><td class='markerViewText'>" + d[2] + "</td><td class='markerViewNotes'>" + notes + "</td></tr>";
      html += "<tr><td class='markerViewLabel'>" + d[0] + "</td><td class='markerViewText'>" + d[2] + " <span class='markerViewNotes'>" + notes + "</span></td></tr>";
    }
  }
  html += "</table>";

  this.gmarker.openInfoWindowHtml(html);
};

////////////////////////////////////////////////////////////////////////////////
// EditableMarker
////////////////////////////////////////////////////////////////////////////////
function addEditableMarker(center, title, description, altitude, foreignMarkerID, icon) {
  var marker = new EditableMarker(center, title, description, altitude, foreignMarkerID, icon);
  markers[marker.id] = marker;
  marker.add()
  return marker;
}

function EditableMarker(position, title, description, altitude, foreignMarkerID, icon) {

  this.id = markerID;
  markerID += 1;
  this.foreignMarkerID = foreignMarkerID;
  if (icon)
    this.properties = {draggable: true, title: title, icon: icon, bouncy: false, dragCrossMove:false};
  else
    this.properties = {draggable: true, title: title, bouncy: false, dragCrossMove:false};

  this.gmarker = new GMarker(position, this.properties);
  this.title = title;
  this.description = description;
  this.altitude = altitude;
  this.status = MARKER_STATUS_NEW;
  this.updateMethod = "updateMarkerData(" + this.id + ")";
}

function derive_EditableMarker(d) {
  src = EditableMarker.prototype;    
  d.add = src.add;
  d.show = src.show;
  d.edit = src.edit;
  d.hide = src.hide;
  d.recreate = src.recreate;
  d.getPoint = src.getPoint;
  d.setPoint = src.setPoint;
  d.getAttributes = src.getAttributes;
  d.editForm = src.editForm;
  d.saveMarkerData = src.saveMarkerData;
  d.saveMarkerDataResults = src.saveMarkerDataResults;
  d.updatePosition = src.updatePosition;
  d.removeMarkerDataResults = src.removeMarkerDataResults;
}

EditableMarker.prototype.add = function() {
  var marker = this;
  GEvent.addListener(this.gmarker, "click", function() {marker.editForm()});
  GEvent.addListener(this.gmarker, "dragend", function() {marker.updatePosition()});
  GEvent.addListener(this.gmarker, "dragstart", function() {map.closeInfoWindow();});
  this.show();
};

EditableMarker.prototype.show = function() {
  map.addOverlay(this.gmarker);
}

EditableMarker.prototype.hide = function() {
  map.removeOverlay(this.gmarker);
}

EditableMarker.prototype.getPoint = function() {
  return this.gmarker.getPoint();
}


EditableMarker.prototype.setPoint = function(position) {
  return this.gmarker.setPoint(position);
}

EditableMarker.prototype.getAttributes = function() {
  var attributes = new Array();
  var pt = this.getPoint();
  attributes[attributes.length] = new Array('Title', 'title', this.title);
  attributes[attributes.length] = new Array('Description', 'description', this.description, 'textarea');
  attributes[attributes.length] = new Array('Latitude', 'latitude', pt.y);
  attributes[attributes.length] = new Array('Longitude', 'longitude', pt.x);
  attributes[attributes.length] = new Array('Altitude', 'altitude', this.altitude, '', 'M ASL');
  return attributes;
}

EditableMarker.prototype.editForm = function() {
  var attributes = this.getAttributes()

  var html ="<form><table>";
  for (i=0;i<attributes.length;i++) {
    var d = attributes[i];
    var notes = d[4]?d[4]:'';
    var inputType = d[3]?d[3]:'text'

    if (inputType == 'textarea') {
      html += "<tr><td class='markerEditLabel'>" + d[0] + "</td><td><textarea rows=2 cols=45 id='edit_" + d[1] + "' name='" + d[1] + "'>" + d[2] + "</textarea></td><td class='markerEditNotes'>" + notes + "</td></tr>";
    } else if (inputType == 'custom') {
      html += "<tr><td class='markerEditLabel'>" + d[0] + "</td><td colspan=2>" + d[5](d[2]) + "</td></tr>";


    } else if (inputType == 'image') {      
      if (isValidURL(d[2])) {
	html += "<tr><td colspan=3 class='markerViewImage'><div id='popupImageBox'><img id='vantageImage' src='" + d[2] + "'></div></td></tr>";
      }
      html += "<tr><td class='markerEditLabel'>" + d[0] + "</td><td colspan=2><input size=70 type='text' id='edit_" + d[1] + "' name='" + d[1] + "' value='" + d[2] + "'></td></tr>";
    } else {
      //var size = 10;
      //if ((d[1] != 'latitude')&&(d[1] != 'longitude')&&(d[1] != 'altitude')) {}
      size = 40;
      html += "<tr>";
      html += "<td class='markerEditLabel'>" + d[0] + "</td><td><input size=" + size + " type='text' id='edit_" + d[1] + "' name='" + d[1] + "' value='" + d[2] + "'></td><td class='markerEditNotes'>" + notes + "</td>";
      html += "</tr>";
      //if ((d[1] != 'latitude')&&(d[1] != 'longitude'))
    }
  }
  html += "<tr><td colspan='3' align='right'><input type='submit' value='OK' name='OK' onclick='" + this.updateMethod + ";return false;'><input type='submit' value='Remove' name='Remove' onclick='removeMarker(" + this.id + ");return false;'></td></tr>";
  html += "</table></form>";

  this.gmarker.openInfoWindowHtml(html);
};

EditableMarker.prototype.edit = function(title, description, latitude, longitude, altitude) {
  // Change details for this marker   
  var pt = this.getPoint();
  this.title = title;
  this.description = description;
  this.altitude = altitude;

  if ((latitude != pt.y) || (longitude != pt.x)) {
    this.setPoint(new GLatLng(latitude, longitude));
  }
  this.status = MARKER_STATUS_MODIFIED;
  this.saveMarkerData();
}

EditableMarker.prototype.saveMarkerData = function() {
  // Save via http the data for this marker.

  var url = 'http://' + window.location.hostname + baseURL;
  var marker = this;
  if (this.foreignMarkerID == -1) {
    url += 'addMarker?'
  } else {
    url += 'editMarker?markerID:int=' + this.foreignMarkerID + '&';
  }
  var pt = this.getPoint();
  var title = encodeURIComponent(this.title);
  var description = encodeURIComponent(this.description);
  var latitude = pt.y;
  var longitude = pt.x;
  var altitude = this.altitude;

  url += 'title=' + title + '&description=' + description + '&latitude:float=' + latitude + '&longitude:float=' + longitude + '&altitude:float=' + altitude;

  var res = webRequest(url, username, password, false, function (res) {marker.saveMarkerDataResults(res);});
}

EditableMarker.prototype.saveMarkerDataResults = function(res) {
  
  if (this.foreignMarkerID == -1) {
    var id = parseInt(res);
    if (isNaN(id)) {
      window.alert('ERROR : Failed to create new marker');
    } else {
      this.foreignMarkerID = id;
    }
  } else {
    if (res != 'True') {
      window.alert('ERROR : Failed to save marker ' + this.foreignMarkerID);
    }
  }
}
 
EditableMarker.prototype.updatePosition = function() {
  //window.alert('Position updated to ' +   this.getPoint());
  this.status = MARKER_STATUS_MODIFIED;
  this.saveMarkerData();
};

EditableMarker.prototype.removeMarkerDataResults = function(res) {  
  if (res != 'True') {
    window.alert('ERROR : Failed to remove marker ' + this.foreignMarkerID);
  }
};


EditableMarker.prototype.recreate = function() {
  // Recreate the GMarker for this marker :
  position = this.getPoint();
  this.hide();
  delete this.gmarker;
  this.gmarker = new GMarker(position, this.properties);
  this.add();
};

function updateMarkerData(id) {
  
  var title = document.getElementById('edit_title').value;
  if (title == '') {
    window.alert('You must at least enter a title for this marker.');
    return;
  }

  var description = document.getElementById('edit_description').value;
  var latitude = parseFloat(document.getElementById('edit_latitude').value);
  var longitude = parseFloat(document.getElementById('edit_longitude').value);
  var altitude = parseFloat(document.getElementById('edit_altitude').value);

  var marker = markers[id];

  var doRecreateMarker = false;
  if (marker.title != title)
    doRecreateMarker = true;

  marker.edit(title, description, latitude, longitude, altitude);
  map.closeInfoWindow();
  
  if (doRecreateMarker) 
    marker.recreate() //Marker(id); // For some reason this needs to be done separate, when the info window is closed...

}

function removeMarker(id) {

  var marker = markers[id];

  if (marker.status == MARKER_STATUS_MODIFIED)
    if (!window.confirm('Are you sure you want to remove this marker?'))
      return false;

  if (this.foreignMarkerID != -1) {
    var url = 'http://' + window.location.hostname + baseURL + 'deleteMarker?markerID:int=' + marker.foreignMarkerID;
    var res = webRequest(url, username, password, false, function (res) {marker.removeMarkerDataResults(res);});
  }

  marker.status = MARKER_STATUS_REMOVED;  
  map.closeInfoWindow();
  marker.hide();
  delete marker.gmarker;
}

