//	TO DO:

//	x Define clickable area around markers
//	x Optimize the X button with clearOverlays (it didn't help)
//	  Remove above-mentioned optimization?
//	  Populate the panel
//	x Make add new location marker draggable to begin (tried it but didn't like it)
//	x Include more update messages?
//	  Clear IWError class from form inputs when one passes but another doesn't

window.onload = loadPage;

var _mSvgEnabled = true;
var _mSvgForced = true;
var map = null;
var lat = 40.711;
var lng = -74.016;
var zoom = 13;
var radius = 1;
var icon = new GIcon();
    icon.image = "iconwhite.png";
    icon.shadow = "iconshadow.png";
    icon.iconSize = new GSize(12,20);
    icon.shadowSize = new GSize(22,20);
    icon.iconAnchor = new GPoint(6,20);
    icon.infoWindowAnchor = new GPoint(5,1);
    icon.imageMap = [5,0, 1,4, 1,8, 3,12, 5,20, 7,20, 8,12, 11,8, 11,4, 7,0];
    icon.transparent = "icontransparent.png"; 
var ic1 = new GIcon(icon);
var ic2 = new GIcon(icon);
var ic3 = new GIcon(icon);
var ic4 = new GIcon(icon);
    ic1.image = "icon1.png";
    ic2.image = "icon2.png";
    ic3.image = "icon3.png";
    ic4.image = "icon4.png";
var ajaxActive = false;
var centeringActive = true;
var m = {};
var markerIDs = [];
var markerAdd = null;
var circle = null;
var defaultInfo = '<h3 id="IWTitle">Add a 24-Hour Location<\/h3>' +
  '<table cellpadding="0" cellspacing="0">' +
  '<tr><th>Business name:<\/th><td><input id="AddName" title="Business name" onkeyup="markerAdd.name=this.value" /><\/td><\/tr>' +
  '<tr><th>Address / Street:<\/th><td><input id="AddAddress" title="Address" onkeyup="markerAdd.address=this.value" /><input id="AddStreet" title="Street" onkeyup="markerAdd.street=this.value" /><\/td><\/tr>' +
  '<tr><th>Cross street:<\/th><td><div id="AddSubmit" class="IWButton" onclick="ajaxAddLocation()">Submit<\/div><input id="AddCross" title="Cross street" onkeyup="markerAdd.cross=this.value" /><\/td><\/tr>' +
  '<tr><th>City:<\/th><td><div id="AddClear" class="IWButton" onclick="clearAddForm()">Clear<\/div><input id="AddCity" title="City" onkeyup="markerAdd.city=this.value" /><\/td><\/tr>' +
  '<tr><th>State / Zip:<\/th><td><input id="AddState" title="State" onkeyup="markerAdd.state=this.value" /><input id="AddZip" title="Zip code" onkeyup="markerAdd.zip=this.value" /><\/td><\/tr>' +
  '<tr><th>Business type:<\/th><td><select id="AddTypeID" title="Business type" onchange="markerAdd.typeID=this.value"><option value="">&nbsp;<\/option><option value="1">Restaurant<\/option><option value="2">Deli / Market / Grocery Store<\/option><option value="3">Convenience / Drug Store<\/option><option value="4">Anything Else<\/option><\/select><\/td><\/tr>' +
  '<tr><th>Hours:<\/th><td><textarea rows="4" cols="60" id="AddHours" title="Hours" onkeyup="markerAdd.hours=this.value"><\/textarea><\/td><\/tr>' +
  '<\/table>';



function readCookie(name) {
  name += "=";
  var ca = document.cookie.split(';');
  var n = ca.length;
  for (var i = 0; i < n; i++) {
    var c = ca[i];
    while (c.charAt(0) == ' ') {c = c.substring(1, c.length)}
    if (c.indexOf(name) == 0) {return c.substring(name.length, c.length)}
  }
  return false;
}



function writeCookie(name, value, days) {
  if (days) {
    var date = new Date();
    date.setTime(date.getTime() + (days*24*60*60*1000));
    var expires = "; expires=" + date.toGMTString();
  }
  else {var expires = ""}
  document.cookie = name + "=" + value + expires;
}



function deleteCookie(name) {writeCookie(name, "", -1)}



function tabPress() {
  document.getElementById("Tab1").className = document.getElementById("Tab2").className = document.getElementById("Tab3").className = "TabBack";
  document.getElementById("Window1").className = document.getElementById("Window2").className = document.getElementById("Window3").className = "WindowBack";
  this.className = "TabFore";
  if ("Tab1" == this.id) {document.getElementById("Window1").className = "WindowFore"}
  else if ("Tab2" == this.id) {document.getElementById("Window2").className = "WindowFore"; populateList()}
  else if ("Tab3" == this.id) {document.getElementById("Window3").className = "WindowFore"}
}



function checkZip() {
  if (5 == this.value.length && this.value == this.value.replace(/[^0-9]/g,"")) {
    ajaxReceiveZip(this.value);
    this.value = "";
  }
}



function ajaxReceiveZip(val) {
  document.getElementById("Results").innerHTML = "Searching ...";
  var request = GXmlHttp.create();
  var url = "getzip.php";
  var postString = "zip=" + val;
  request.open('POST', url, true);
  request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  request.onreadystatechange = function () {
    if (4 == request.readyState) {
      var xmlDoc = request.responseXML;
      var el = xmlDoc.documentElement.getElementsByTagName("result");
      var zipLat = parseFloat(el[0].getAttribute("lat"));
      var zipLng = parseFloat(el[0].getAttribute("lng"));
      var zipCity = el[0].getAttribute("city");
      var zipState = el[0].getAttribute("state");
      if (!(-180 <= zipLat && 180 >= zipLat)) {
	document.getElementById("Results").innerHTML = val + " cannot be found &bull; <a href=\"javascript:ajaxReceiveZip(" + val + ")\">Search again<\/a>";
	return;
      }
      document.getElementById("Results").innerHTML = val + " &bull; " + zipCity + ", " + zipState;
      newCenter(new GLatLng(zipLat, zipLng));
    }
  }
  request.send(postString);
}



function defineNewMarker(point) {
  markerAdd = new GMarker(point, icon);
  clearMarkerValues();
  markerAdd.info = defaultInfo;
  markerAdd.id = "Add";
}



function displayInfoWindow() {
  markerAdd.openInfoWindowHtml(markerAdd.info);
  populateInfoWindow();
}



function populateInfoWindow() {
  document.getElementById("AddName").value = markerAdd.name;
  document.getElementById("AddAddress").value = markerAdd.address;
  document.getElementById("AddStreet").value = markerAdd.street;
  document.getElementById("AddCross").value = markerAdd.cross;
  document.getElementById("AddCity").value = markerAdd.city;
  document.getElementById("AddState").value = markerAdd.state;
  document.getElementById("AddZip").value = markerAdd.zip;
  document.getElementById("AddTypeID").value = markerAdd.typeID;
  document.getElementById("AddHours").value = markerAdd.hours;
}



function clearMarkerValues() {
  markerAdd.name =
  markerAdd.address =
  markerAdd.street =
  markerAdd.cross =
  markerAdd.city =
  markerAdd.state =
  markerAdd.zip = "";
  markerAdd.typeID = 0;
  markerAdd.hours = "Open 24 hours daily ?";
}



function clearAddForm() {
  clearMarkerValues();
  populateInfoWindow();
}



function verifyAdd() {
  var status = "";
  if ("" == markerAdd.name) {
    document.getElementById("AddName").className = "IWError";
    status += "Business name\n";
  }
  if (0 == markerAdd.typeID) {
    document.getElementById("AddTypeID").className = "IWError";
    status += "Business type\n";
  }
  if (status) {
    alert("The following information is necessary:\n\n" + status);
    return false;
  }
  return true;
}



function ajaxAddLocation() {
  if (!verifyAdd()) {return;}
  document.getElementById("Status").innerHTML = "Adding location to database ...";
  var request = GXmlHttp.create();
  var url = "addlocation.php";
  var postString = "name=" + escape(markerAdd.name) + "&lat=" + markerAdd.getPoint().y + "&lng=" + markerAdd.getPoint().x + "&address=" + markerAdd.address + "&street=" + markerAdd.street + "&cross=" + markerAdd.cross + "&city=" + markerAdd.city + "&state=" + markerAdd.state + "&zip=" + markerAdd.zip + "&typeid=" + markerAdd.typeID + "&hours=" + markerAdd.hours;
  request.open('POST', url , true);
  request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  request.onreadystatechange = function () {
    if (4 == request.readyState) {
      var xmlDoc = request.responseText;
      if (xmlDoc) {
	ajaxReceiveMarkers();
	map.removeOverlay(markerAdd);
	clearMarkerValues();
	document.getElementById("Status").innerHTML += "New location added with ID number " + xmlDoc;
      }
      else {
	document.getElementById("Status").innerHTML = "Submission failed!";
      }
    }
  }
  request.send(postString);
}



function ajaxEditLocation(mkr) {
  document.getElementById("Status").innerHTML = "Updating database with new information ... ";
  var request = GXmlHttp.create();
  var url = "updatelocation.php";
  if (true == mkr.rem) {
    var postString = "id=" + mkr.id + "&remove=true";
  }
  else {
//    var postString = "name=" + encodeURIComponent(mkr.name) + "&lat=" + mkr.getPoint().y + "&lng=" + mkr.getPoint().x + "&address=" + mkr.address + "&street=" + mkr.street + "&cross=" + mkr.cross + "&city=" + mkr.city + "&state=" + mkr.state + "&zip=" + mkr.zip + "&typeid=" + mkr.typeID + "&hours=" + mkr.hours;
  }
  request.open('POST', url , true);
  request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  request.onreadystatechange = function () {
    if (4 == request.readyState) {
      ajaxReceiveMarkers();
    }
  }
  request.send(postString);
}



function locationMove(id) {
  alert("Repositioning feature coming soon ...");
}



function locationEdit(id) {
  alert("Editing feature coming soon ...");
}



function locationRemove(id) {
  m[id].rem = true;
  ajaxEditLocation(m[id].m);
}



function ajaxReceiveMarkers() {
  if (ajaxActive) {return}
  ajaxActive = true;
  var startAJAX = new Date();
  startAJAX = startAJAX.getTime();
  map.closeInfoWindow();
  var showGroups = [];
  if (document.getElementById("CheckRestaurants").checked) {showGroups.push(1)}
  if (document.getElementById("CheckMarkets").checked) {showGroups.push(2)}
  if (document.getElementById("CheckDrugStores").checked) {showGroups.push(3)}
  if (document.getElementById("CheckEverythingElse").checked) {showGroups.push(4)}
  document.getElementById("Status").innerHTML = "Updating information ...";
  var request = GXmlHttp.create();
  var url = "AJAX-JS-read.php";
  var postString = "visible=" + markerIDs.join() + "&centerLat=" + lat + "&centerLng=" + lng + "&radius=" + radius + "&showGroups=" + showGroups.join();
  request.open('POST', url , true);
  request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  request.onreadystatechange = function () {
    if (4 == request.readyState) {
      var xmlDoc = request.responseText;
      eval(xmlDoc);
      removeMarkers(markersToRemove);
      displayMarkers(markersToAdd);
      ajaxActive = false;
      var endAJAX = new Date();
      endAJAX = endAJAX.getTime();
      var totalAJAX = endAJAX - startAJAX;
      var plural = (1 == markerIDs.length) ? "" : "s";
      document.getElementById("Status").innerHTML = markerIDs.length + " location" + plural + " &nbsp; &nbsp; " + ttime + " / " + totalAJAX/1000 + " seconds &nbsp; &nbsp; " + (xmlDoc.length / 1000) + "KB";
      document.getElementById("Count").innerHTML = count;
    }
  }
  request.send(postString);
}



function displayMarkers(arr) {
  var n = arr.length;
  while (n--) {
    var tempmarker = m[arr[n]].m;
    tempmarker.nm = m[arr[n]].nm;
    tempmarker.ad = m[arr[n]].ad;
    tempmarker.as = m[arr[n]].as;
    tempmarker.cr = m[arr[n]].cr;
    tempmarker.ci = m[arr[n]].ci;
    tempmarker.st = m[arr[n]].st;
    tempmarker.zp = m[arr[n]].zp;
    tempmarker.hours = m[arr[n]].h;
    map.addOverlay(tempmarker);
  }
}



function removeMarkers(arr) {
  var n = arr.length;
  while (n--) {
    map.removeOverlay(m[arr[n]].m);
  }
}



function drawCircle() {
  var cColor = "#3366ff";
  var stroke = 5;
  var d2r = Math.PI / 180;
  var r2d = 180 / Math.PI;
  var cLat = (radius / 3963.2) * r2d;
  var cLng = cLat / Math.cos(lat * d2r);
  var cPoints = [];
  for (var i = 0; i < 33; i++) {
    var theta = Math.PI * (i / 16);
    var cX = lng + (cLng * Math.cos(theta));
    var cY = lat + (cLat * Math.sin(theta));
    var p = new GPoint(cX, cY);
    cPoints.push(p);
  }
  if (circle) {map.removeOverlay(circle)}
  circle = new GPolyline(cPoints, cColor, stroke);
  map.addOverlay(circle);
}



function clickRadius() {
  var newRad = this.id.charAt(3);
  if (newRad == radius) {return}
  document.getElementById("Rad1").className =
  document.getElementById("Rad2").className =
  document.getElementById("Rad3").className =
  document.getElementById("Rad4").className =
  document.getElementById("Rad6").className =
  document.getElementById("Rad8").className = "";
  this.className = "Checked";
  setRadius(newRad);
}



function setRadius(newRadius) {
  radius = newRadius;
  drawCircle();
  ajaxReceiveMarkers();
  writeCookie('radius', radius, 30);
}



function clearAll() {
  if (markerAdd) {
    map.removeOverlay(circle);
    removeMarkers(markerIDs);
  }
  else {
    map.clearOverlays();
  }
  document.getElementById("Rad" + radius).className = "";
  radius = 0;
  markerIDs=[];
  document.getElementById("Status").innerHTML = "Map cleared. Choose a new radius ...";
}



function newCenter(point) {
  lat = point.y;
  lng = point.x;
  map.panTo(point);
  if (0 != radius) {
    drawCircle();
    ajaxReceiveMarkers();
  }
  writeCookie('centerLat', lat, 30);
  writeCookie('centerLng', lng, 30);
}



function clickAdd() {
  centeringActive = false;
  document.getElementById("ButtonCenter").className = "";
  this.className = "ButtonCurrent";
  document.getElementById("Status").innerHTML = "Click on map to place new 24-hour location ...";
}



function clickCenter() {
  centeringActive = true;
  document.getElementById("ButtonAdd").className = "";
  this.className = "ButtonCurrent";
  document.getElementById("Status").innerHTML = "Click on map to center search area ...";
}



function populateList() {
  var pluralVerb = (1 == markerIDs.length) ? "is " : "are ";
  var pluralCount = (1 == markerIDs.length) ? "" : "s";
  var pluralRadius = (1 == radius) ? "" : "s";
  var jss = "<p>There " + pluralVerb + markerIDs.length + " all-night location" + pluralCount + " within a radius of " + radius + " mile" + pluralRadius + ".</p>" +
    '<table style="width: 100%">';
  var l = markerIDs.length;
  for (var i = 0; i < l; i++) {
    var n = m[markerIDs[i]];
    jss += "<tr><td>" + n.nm + "</td><td>" + n.ad + " " + n.as + " @ " + n.cr + "</td><td>" + n.ci + "</td><td>" + n.st + "</td><td>" + n.zp + "</td></tr>";
  }
  jss += "</table>";
  document.getElementById("List").innerHTML = jss;
}



function loadPage() {
  if (!(lat = parseFloat(readCookie('centerLat')))) {lat = 40.711}
  if (!(lng = parseFloat(readCookie('centerLng')))) {lng = -74.016}
  if (!(radius = parseInt(readCookie('radius')))) {radius = 1}
  map = new GMap2(document.getElementById("Map"), {draggableCursor: 'default', draggingCursor: 'pointer'});
  map.addControl(new GLargeMapControl());
  map.addControl(new GMapTypeControl());
  map.setCenter(new GLatLng(lat, lng), zoom);
  GEvent.addListener(map, "click", function(overlay, point) {
    if (overlay) {
      if (!overlay.info) {
	var cross = "";
	var city = "";
	if (overlay.cr) {cross = " @ " + overlay.cr}
	if (overlay.ci) {city = overlay.ci + ", "}
	overlay.info = "<b>" + overlay.nm + "</b><p>" + overlay.ad + " " + overlay.as + cross + "<br />" + city + overlay.st + " " + overlay.zp + "<\/p>";
	if (overlay.hours) {overlay.info += "<p class=\"InfoHours\">" + overlay.hours + "</p>"}
      }
      var tabInfo = new GInfoWindowTab("Info", overlay.info);
      var tabHours = new GInfoWindowTab("Hours", overlay.hours);
      var tabEdit = new GInfoWindowTab("Edit", '<div class="IWEditTab"><p>Until this new location is approved, you can make the following changes:<\/p><span id="IWMove" onclick="locationMove(' + overlay.id + ')">Reposition<\/span><span id="IWEdit" onclick="locationEdit(' + overlay.id + ')">Edit info<\/span><span id="IWDelete" onclick="locationRemove(' + overlay.id + ')">Delete<\/span><\/div>')
      if ("Add" == overlay.id) {displayInfoWindow()}
      else if (overlay.unapproved) {overlay.openInfoWindowTabsHtml([tabInfo,tabEdit])}
      else {overlay.openInfoWindowHtml(overlay.info)}
    }
    else if (point) {
      if (centeringActive) {
	if (!ajaxActive) {newCenter(point)}
      }
      else if (!markerAdd) {
	defineNewMarker(point);
	map.addOverlay(markerAdd);
	displayInfoWindow();
	document.getElementById("Status").innerHTML = "Enter business info or click to reposition ...";
      }
      else {
	map.closeInfoWindow();
	markerAdd.setPoint(point);
	displayInfoWindow();
      }
    }
  });
  document.getElementById("Rad" + radius).className = "Checked";
  var sz = document.getElementById("SearchZip");
  sz.focus();
  sz.onkeyup = checkZip;
  sz.onfocus =
  sz.onclick = function() {this.value = ""};
  document.getElementById("Tab1").onclick =
  document.getElementById("Tab2").onclick =
  document.getElementById("Tab3").onclick = tabPress;
  document.getElementById("Rad1").onclick =
  document.getElementById("Rad2").onclick =
  document.getElementById("Rad3").onclick =
  document.getElementById("Rad4").onclick =
  document.getElementById("Rad6").onclick =
  document.getElementById("Rad8").onclick = clickRadius;
  document.getElementById("Rad0").onclick = clearAll;
  document.getElementById("CheckRestaurants").onchange	=
  document.getElementById("CheckMarkets").onchange	=
  document.getElementById("CheckDrugStores").onchange	=
  document.getElementById("CheckEverythingElse").onchange = ajaxReceiveMarkers;
  document.getElementById("ButtonAdd").onclick = clickAdd;
  document.getElementById("ButtonCenter").onclick = clickCenter;
  window.onunload = GUnload;
  drawCircle();
  ajaxReceiveMarkers();
}