var map;
var factor;
var val1;
var attrName;
var attrNo;
var city;
var state;
var balloon = "";
var mymapType;
var mymapTypeName;
var mymapZoom;
var delta;
var isCityIconShown;
var markers = new Array();
var markersByAttrNo = new Array();
var attractListHtml;
var hotelMarkers = new Array();
var hotelListHtml;
var shadowUrl = "/map/image/pushpin_shadow40.png";
var shadowPrintUrl = "/map/image/pin_shadow.gif";
var hotelIconUrl = "/map/image/pin_hotel.gif";
var featureIconUrl = "/map/image/pin_feature.png";
var attractIconUrl = "/map/image/pin_tip.png";
var mainIconUrl = "/map/image/pin_main.gif";
var cityIconUrl = "/map/image/pin_city.gif";
var mainIcon = getIcon(mainIconUrl,shadowUrl, shadowPrintUrl );
var cityIcon = getIcon(cityIconUrl,shadowUrl, shadowPrintUrl );
var hotelIcon = getIcon(hotelIconUrl,shadowUrl, shadowPrintUrl );
var ATTR = "attr-";
var HOTEL = "hotel-";
var maxZindex = 10000;
var openInfoKey = "";
var val2;
var isStateQuery;
var isFavQuery;
var path;
var mapHeight = 530;
var mapWidthDelta = 250;
var triplist;
var xslfile="";
var debug=false;
var isFavShown=false;
var tripPlannerUrl = "/map/trip/plan";
var maxcnt=11;
var maxdist=0.10;

var longitude;
var latitude;
var mainIconUrl = "/map/image/pin_main.gif";
var cityIconUrl = "/map/image/pin_city.gif";
var displayFilterOn = [true,true,true,true,true,true];

function cursorWait()
{
  document.body.style.cursor = 'wait';
}

function cursorClear()
{
  document.body.style.cursor = 'default';
}

function onloadForm(val1,val2)
{
  resizeMapDiv();
  if (this.loadMap)
    loadMap(val1*factor,val2*factor);
}

function resizeMapDiv(widthDelta,height){
  var frame = document.getElementById("map");
  if (frame) {
    if (!widthDelta && mapWidthDelta) widthDelta = mapWidthDelta;
    if (!widthDelta) widthDelta = 0;
    if (!height && mapHeight) height = mapHeight;
    if (!height) height = 530;
    var width;
    if (window.innerWidth)
      width = window.innerWidth;
    else
      width = document.body.parentNode.scrollWidth;
    if (widthDelta==0) {
      frame.style.width="100%";
    }
    else {
      frame.style.width=width - widthDelta +"px";
    }
    frame.style.height=height + "px";
  }
}

// Creates a marker whose info window displays the given number
function createHotelMarker(longitude,latitude, html,itemNo,icon,rating) {
  if (icon===undefined) {
    icon = hotelIcon;
  }
  html = "<div style=\"font-size: 10px;\" class=\"mapcallout\">" + html + "</div>";
  var marker = createMarker(longitude,latitude,html,itemNo,icon,HOTEL,rating);
  hotelMarkers[hotelMarkers.length] = marker;
  return marker;
}

// Creates a marker whose info window displays the given number
function createAttrMarker(longitude, latitude, html, attractNo, icon, rating) {
  html = "<div style=\"font-size: 10px;\" class=\"mapcallout\">" + html + "</div>";
  var marker = createMarker(longitude,latitude,html,attractNo,icon,ATTR,rating);
  marker.roadsideListElem = document.getElementById("attr-"+marker.attractNo+"-li");
  markers[markers.length] = marker;
  return marker;
}

function createAttrMarkerWithTrip(longitude, latitude, html, attractNo, icon, rating) {
  if (isFavShown)
  {
    var checked = TripPlanner.isAttrSelected(attractNo)?" checked=\"checked\"":"";
    html += "<div class=\"triplistbar\"><input type=\"checkbox\"" + checked+ " id=\"attr-" +attractNo+ "\" onclick=\"return TripPlanner.updateAttrList(this,'" +attractNo+ "')\">Add to My Sights</input> | <a href=\""+tripPlannerUrl+"\">Show My Sights</a></div>";
  }
  return createAttrMarker(longitude,latitude,html,attractNo,icon,rating);
}

var req = new Array();
var ATTRINDX = 0;
var HOTELINDX = 1;

function addNearbyAttractions(delta) {
  if (!attractListHtml) {
    if (isStateQuery) {
      loadXMLDoc("/map/attractionsByState.php?state="+state,addAttractions,ATTRINDX,"get");
    }
    else if (isFavQuery) {
      var params = "";
      if (triplist!="") {
      	params="?attrlist="+triplist+"&order=trip";
      }
      if (xslfile!="")
      {
        params += (params.length>0)?"&":"?" + "xslfile="+xslfile;
      }
      if (debug)
      {
        params += (params.length>0)?"&":"?" + "debug="+debug;
      }
      loadXMLDoc((mapPath?mapPath:"/map/") + "favAttractions.php"+params,addAttractions,ATTRINDX,"get",true,true);
    }
    else {
      loadXMLDoc("/map/nearbyAttractions.php?long="+longitude+"&lat="+latitude+"&delta="+delta+"&id="+attrNo+"&xslfile="+xslfile+"&debug="+debug,addAttractions,ATTRINDX,"get");
    }
  } else {
    addListToDiv("nearattract",attractListHtml);
  }
}

/**
 * Loads XML Doc
 */
function loadXMLDoc(url,theParseFunction,indx,method,async,isForceUnique)
{
  // make sure we don't get cached data
  var d = (debug || isForceUnique)?(new Date()).getTime().toString():Date.parse((new Date()).toDateString());
  url = url + (url.indexOf('?')==-1?"?":"&") + "unique=" + d;
  if (async===undefined)
    async = true;
  // branch for native XMLHttpRequest object
  if (window.XMLHttpRequest) {
    req[indx] = new XMLHttpRequest();
    req[indx].onreadystatechange = theParseFunction;
    req[indx].open(method, url, async);
    req[indx].send(null);
  // branch for IE/Windows ActiveX version
  } else if (window.ActiveXObject) {
    req[indx] = new ActiveXObject("Microsoft.XMLHTTP");
    if (req[indx]) {
      req[indx].onreadystatechange = theParseFunction;
      req[indx].open(method, url, async);
      req[indx].send();
    }
  }
  return req[indx];
}

function addAttractions()
{
  // only if req shows "complete"
  var theReq = req[ATTRINDX];
  if (theReq!=null && theReq.readyState == 4) {
    // only if "OK"
    if (theReq.status == 200) {
      if (!attractListHtml) {
        attractListHtml = "No Nearby Attractions";
        if (theReq.responseText!=null) {
          attractListHtml = theReq.responseText;
        }
        addListToDiv("nearattract",attractListHtml);
        loadInfoState();
      }
    } else {
       alert("There was a problem retrieving the attract data:\n" + req[ATTRINDX].statusText);
    }
  }
}

function addMarker(thisAttrNo,longitude,latitude,tip,html,icon,marker,createFunction,rating) {
  if (!marker) {
    if (longitude && latitude && !isNaN(longitude) && !isNaN(latitude)) {
      var  newhtml = "<span class=\"attractname\">" + tip + "</span><br/>" + html;
      marker = createFunction(longitude,latitude,newhtml,thisAttrNo,icon,rating);
      if (tip) {
        marker.setTooltip(tip.replace(/ /g,"&nbsp;"));
      }
      map.addOverlay(marker);
    }
  }
  else
  {
    marker.show();
  }
  return marker;
}

function hideMarkerById(itemNo,prefix)
{
  var itemId = prefix + itemNo;
  var marker = markersByAttrNo[itemId];
  if (marker)
    marker.hide();
  return marker;
}

function addMarkerById(itemNo,prefix,longitude,latitude,attrname,icon,createFunction,rating) {
  var itemId = prefix + itemNo;
  var el = document.getElementById(itemId+"-addr");
  var html = adjustCalloutHtml(el.innerHTML);
  var marker = markersByAttrNo[itemId];
  var iconObj = getIcon(icon, shadowUrl, shadowPrintUrl );
  return addMarker(itemNo,longitude,latitude,attrname,html,iconObj,marker,createFunction,rating);
}

function adjustCalloutHtml(html)
{
  var ioff = html.indexOf("<div class=\"listdata\">");
  if (ioff==-1)
    ioff = html.indexOf("<DIV class=listdata>");
  if (ioff > 0)
  {
    var iend = html.indexOf("</div>",ioff);
    if (iend==-1)
      iend = html.indexOf("</DIV>",ioff)
    html = html.slice(0,ioff) + html.slice(iend+6);
  }
  return html;
}

function switchNearbyAttractionMode(theControl) {
  cursorWait();
  if (theControl) {
    var mode = (theControl.innerHTML.substring(0,1)=="+")?"-":"+";
    if (mode=="+") {
      document.getElementById("nearattract").innerHTML = "";
      removeMarkers(markers,ATTR+attrNo);
      updateAttrCookie(false,true);
      if (showHideFilterBtn) showHideFilterBtn(false);
    }
    else
    {
      addNearbyAttractions(delta);
      updateAttrCookie(true,true);
      if (showHideFilterBtn) showHideFilterBtn(true);
    }
    theControl.innerHTML = mode + theControl.innerHTML.substring(1);
  }
  else {
  	addNearbyAttractions(delta);
  }
  cursorClear();
}

function urlencode(url) {
  return encodeURIComponent(url);
}

function addNearbyHotels(delta) {
  var elem = document.getElementById("nearbyCities");
  if (elem) {
    var arr = elem.value.split(',');
    if (arr.length>1  && (arr[0]!=city || arr[1]!=state)) {
      city = arr[0];
      state = arr[1];
      hotelListHtml = null;
    }
  }
  if (!hotelListHtml)
    loadXMLDoc("/map/nearbyHotels.php?city="+urlencode(city)+"&state="+state+"&latitude="+latitude+"&longitude="+longitude+"&maxcnt="+maxcnt+"&maxdist="+maxdist,addHotels,HOTELINDX,"get");
  else
    addListToDiv("nearhotel",hotelListHtml);
}

function openInfoWindow(itemtype,itemNo) {
  var key = itemtype+itemNo;
  var marker = markersByAttrNo[key];
  if (marker) {
    updateZindex(marker);
    marker.openInfoWindowHtml(marker.html);
    openInfoKey = key;
    updateOpenInfoCookie(itemtype,itemNo);
  }
}

function openInfo(itemNo) {
  openInfoWindow(ATTR,itemNo);
}

function openHotelInfo(itemNo) {
  openInfoWindow(HOTEL,itemNo);
}

function popMarker(itemtype,itemNo) {
  var key = itemtype+itemNo;
  var marker = markersByAttrNo[key];
  if (marker) {
    updateZindex(marker);
  }
}

function addHotels()
{
  // only if req shows "complete"
  var theReq = req[HOTELINDX];
  if (theReq!=null && theReq.readyState == 4) {
    // only if "OK"
    if (theReq.status == 200) {
      if (!hotelListHtml) {
        hotelListHtml = theReq.responseText;
        addListToDiv("nearhotel",hotelListHtml);
        loadInfoState();
      }
    } else {
       alert("There was a problem retrieving the hotel data:\n" + req[HOTELINDX].statusText);
    }
  }
}

function addListToDiv(divId,listHtml) {
  var thediv = document.getElementById(divId);
  if (thediv) {
    var ioff = listHtml.indexOf("<script");
    var script;
    var html=listHtml;
    if (ioff>0) {
      script = listHtml.substring(ioff);
      html = listHtml.substring(0,ioff);
      ioff = script.indexOf(">");
      script = script.substring(ioff+1);
      ioff = script.indexOf("</script");
      script = script.substring(0,ioff);
    }
    thediv.innerHTML = html;
    if (ioff>0) {
      eval(script);
    }
  }
}

function switchNearbyHotelMode(theControl) {
  if (theControl) {
    var oldCursor = theControl.style.cursor;
    theControl.cursor = "wait";
    cursorWait();
    var mode = (theControl.innerHTML.substring(0,1)=="+")?"-":"+";
    if (mode=="+") {
      document.getElementById("nearhotel").innerHTML = "";
      removeMarkers(hotelMarkers,null);
      updateHotelCookie(false,true);
    }
    else
    {
      addNearbyHotels(1);
      updateHotelCookie(true,true);
    }
    theControl.innerHTML = mode + theControl.innerHTML.substring(1);
    theControl.style.cursor = oldCursor;
    cursorClear();
  }
}

function changeCity() {
  var theControl = document.getElementById("hotellink");
  var mode = theControl.innerHTML.substring(0,1);
  if (mode=="-") {
    removeMarkers(hotelMarkers,null);
    addNearbyHotels(1);
  }
  else
  {
    switchNearbyHotelMode(theControl);
  }
}

function getNodeValue(node) {
  if (node.textContent) {
    return node.textContent;
  } else if (node.innerText) {
    return node.innerText;
  } else {
    return node.text;
  }
}


function updateCookies()
{
  setMapValue("mapAttrNo",attrNo);
  setMapValue("mapCity",city);
  setMapValue("mapState",state);
	var center = map.getCenter();
  setMapValue("mapX",""+center.x);
  setMapValue("mapY",""+center.y);
  setMapValue("mapBBOX",map.getBounds());
  var mtype = map.getCurrentMapType();
  setMapValue("mapType",getMapTypeName(mtype));
  updateZoomCookie(map.getZoom(),map.getZoom());
}

function updateZoomCookie(oldZoom, newZoom) {
	setMapValue("mapZoom",""+newZoom,true);
}

function updateAttrCookie(isOpen,isPersisted) {
  setMapValue("mapAttr",""+isOpen,isPersisted);
}

function updateHotelCookie(isOpen,isPersisted) {
  setMapValue("mapHotel",""+isOpen,isPersisted);
}

function updateOpenInfoCookie(infoType,id) {
  setMapValue("mapInfoType",infoType,false);
  setMapValue("mapInfoId",id,true);
}

function loadInfoState() {
  var attrType = getMapValue("mapInfoType");
  var id = getMapValue("mapInfoId");
  openInfoWindow(attrType,id);
//  popMarker(attrType,id);
}

var MAP_STATE_COOKIE = "mapState";

function loadStateFromCookies() {
  var cvalue = CookieMgr.getCookie(MAP_STATE_COOKIE);
  document.mapstate = CookieMgr.parseParameters(cvalue);
  var aNo = getMapValue("mapAttrNo");
  if (!aNo==null || aNo != attrNo)
    return false;
  var mtype = getMapValue("mapType");
  if (mtype==null || mtype!=mymapTypeName) {
    return false;
  }
  if (aNo=="" || aNo=="0") {
    var c = getMapValue("mapCity");
    var s = getMapValue("mapState");
    if ((c==null || c!=city) || (s==null || s!=state)) {
      return false;
    }
  }
  var x = getMapValue("mapX");
  var y = getMapValue("mapY");
  var z = getMapValue("mapZoom");
  var xx=parseFloat(x);
  var yy=parseFloat(y);
  var zz=parseInt(z);
  initMap(xx,yy,zz,getMapType(mtype));
  var isOpen = getMapValue("mapAttr");
  if (isOpen=="true") {
    switchNearbyAttractionMode(document.getElementById("attractlink"));
  }
  isOpen = getMapValue("mapHotel");
  if (isOpen=="true") {
    switchNearbyHotelMode(document.getElementById("hotellink"));
  }
  return true;
}

function getMapValue(name) {
  var val = null;
  if (document.mapstate) {
    val = document.mapstate[name];
  }
  return val;
}

function setMapValue(name,value,isPersisted) {
  if (document.mapstate) {
    document.mapstate[name] = value;
    if (isPersisted) {
      saveMapState();
    }
  }
}

function saveMapState(mapstate) {
  mapstate = mapstate || document.mapstate;
  CookieMgr.saveCookieParams(MAP_STATE_COOKIE,mapstate);
}

function removeMarkers(markerArray,skipKey) {
  for (var i = 0; i < markerArray.length; i++) {
    var marker = markerArray[i];
    var key = marker.roadsideType+marker.attractNo;
    if (key!=skipKey) {
      if (key==openInfoKey) {
        map.closeInfoWindow();
      }
      marker.hide();
    }
  }
}

function showMarkers(markerArray,skipKey) {
  for (var i = 0; i < markerArray.length; i++) {
    var marker = markerArray[i];
    var key = marker.roadsideType+marker.attractNo;
    if (key!=skipKey && (!marker.roadsideRating || displayFilterOn[marker.roadsideRating])) {
      marker.show();
      marker.roadsideListElem.style.display = "";
      if (marker.roadsideListElem.previousSibling)
        marker.roadsideListElem.previousSibling.style.display = "";
    }
    else if (marker.roadsideListElem) {
      marker.roadsideListElem.style.display = "none";
      if (marker.roadsideListElem.previousSibling)
        marker.roadsideListElem.previousSibling.style.display = "none";
    }
  }
}

function getMapType(mtypeName) {
  if (mtypeName==null && mtypeName=="") {
    mtypeName = "G_MAP_TYPE";
  }
  return mapTypeArray[mtypeName] || mapTypeArray["G_MAP_TYPE"];
}

function getMapTypeName(mtype) {
  for (var key in mapTypeArray) {
    if (mtype == mapTypeArray[key]) {
      return key;
    }
  }
  return null;
}
