var allProj = new Array();
var gxmlArr = new Array();
var gxmlGroupArr = new Array();
var allImgSrc = new Array();
var allImgProjId = new Array();
var allImgToolTip = new Array();
var allDocSrc = new Array();
var allDocProjId = new Array();
var allDocToolTip = new Array();
var allDocTitle = new Array();
var allVideoSrc = new Array();
var allVideoCapSrc = new Array();
var allVideoProjId = new Array();
var allVideoToolTip = new Array();
var allVideoWidth = new Array();
var allVideoHeight = new Array();
var projMediaLoaded = false;
var aspProjResult, aspImageResult, aspDocResult, aspVideoResult, aspMediaResult; // return strings from ASP for debugging purposes

function Project(a) {
  if (typeof a == 'undefined')
    a = { id: null, name: null, description: null, type: null, planarea: null, facility: null, from: null, to: null, source: null, capnoncap: null, kml: null, primimg: null, primimgindex: null, gxmlIndex: null, polylineIndex: null, kmlGroup: null };

  if (typeof a.id != 'undefined')
    this.id = a.id;
  else
    this.id = null;

  if (typeof a.name != 'undefined')
    this.name = a.name;
  else
    this.name = null;

  if (typeof a.description != 'undefined')
    this.description = a.description;
  else
    this.description = null;

  if (typeof a.type != 'undefined')
    this.type = a.type;
  else
    this.type = null;

  if (typeof a.planarea != 'undefined')
    this.planarea = a.planarea;
  else
    this.planarea = null;

  if (typeof a.facility != 'undefined')
    this.facility = a.facility;
  else
    this.facility = null;

  if (typeof a.from != 'undefined')
    this.from = a.from;
  else
    this.from = null;

  if (typeof a.to != 'undefined')
    this.to = a.to;
  else
    this.to = null;

  if (typeof a.source != 'undefined')
    this.source = a.source;
  else
    this.source = null;

  if (typeof a.capnoncap != 'undefined')
    this.capnoncap = a.capnoncap;
  else
    this.capnoncap = null;

  if (typeof a.kml != 'undefined')
    this.kml = a.kml;
  else
    this.kml = null;

  if (typeof a.primimg != 'undefined')
    this.primimg = a.primimg;
  else
    this.primimg = null;

  if (typeof a.primimgindex != 'undefined')
    this.primimgindex = a.primimgindex;
  else
    this.primimgindex = null;

  if (typeof a.gxmlIndex != 'undefined')
    this.gxmlIndex = a.gxmlIndex;
  else
    this.gxmlIndex = null;

  if (typeof a.polylineIndex != 'undefined')
    this.polylineIndex = a.polylineIndex;
  else
    this.polylineIndex = null;

  if (typeof a.kmlGroup != 'undefined')
    this.kmlGroup = a.kmlGroup;
  else
    this.kmlGroup = null;
}

function ASP_receiveProjectInfo(result) {
  //debugger;
  // If there was an error, report it.
  if (result.indexOf("<error>") >= 0) {
    alert(result.substr(result.indexOf("<error>") + 7) + "\nPlease refresh.");
    return;
  }

  // is this ALL projects?
  if (ASP_projNumber == "all") {
    aspProjResult = result;
    fillProjectArray(result, map);
    window.setTimeout("loadMedia();", 1000);
  }
  else if (ASP_projNumber == "image-all") {
    aspImageResult = result;
    fillImageArray(result);
  }
  else if (ASP_projNumber == "doc-all") {
    aspDocResult = result;
    fillDocArray(result);
  }
  else if (ASP_projNumber == "video-all") {
    aspVideoResult = result;
    fillVideoArray(result);
  }
  else if (ASP_projNumber == "media-all") {
    aspMediaResult = result;
    fillMediaArrays(result);
    if (typeof _After_ASP_Callback == "function")
      window.setTimeout("_After_ASP_Callback()", 1000);
  }
  else
    return;
}

var ASP_projNumber;
var _After_ASP_Callback = null;
function loadProjects(callback) {
  _After_ASP_Callback = callback;
  ASP_projNumber = "all";
  ASP_getProjectInfo();
}

function loadImages() {
  ASP_projNumber = "image-all";
  ASP_getProjectInfo();
}

function loadDocs() {
  ASP_projNumber = "doc-all";
  ASP_getProjectInfo();
}

function loadVideos() {
  ASP_projNumber = "video-all";
  ASP_getProjectInfo();
}

function loadMedia() {
  ASP_projNumber = "media-all";
  ASP_getProjectInfo();
}

var _alertStr = "";
var _gotPolylineIndexes = false;
var getPolylineIndexExecuting = false;
function getPolylineIndexes() {
  if (_gotPolylineIndexes || getPolylineIndexExecuting)
    return;
  getPolylineIndexExecuting = true;
  /*if ($("#pleaseWaitThinking").length > 0)
  $("#pleaseWaitThinking").dialog('open');*/

  for (var projIndex = 0; projIndex < allProj.length; projIndex++) {
    if (typeof allProj[projIndex].kml != 'undefined' && allProj[projIndex].kml != null && allProj[projIndex].kml.length > 1 && allProj[projIndex].kmlGroup == _currentKMLGroup) {
      allProj[projIndex].polylineIndex = getPolylineIndex(projIndex);
    }
  }
  _gotPolylineIndexes = true;

  /*if ($("#pleaseWaitThinking").length > 0)
  $("#pleaseWaitThinking").dialog('close');*/
  getPolylineIndexExecuting = false;
}

function getPolylineIndex(projIndex) {
  //debugger;
  var gxmlIndex = allProj[projIndex].gxmlIndex;
  for (var plindex = 0; plindex < gxmlArr[gxmlIndex].polylines.length; plindex++) {
    if (gxmlArr[gxmlIndex].polylines[plindex].name == allProj[projIndex].id) {
      return plindex;
    }
  }
  return null;
}

var _currentKMLGroup = null;
function fillProjectArray(projXmlStr, mapObj) {
  if (typeof projXmlStr == "undefined" || !projXmlStr || projXmlStr.length == 0) return;

  var projXml;
  try {
    projXml = GetXmlFromStr(projXmlStr);
  }
  catch (e) {
    alert(e.message);
    return;
  }

  if (typeof projXml == "undefined" || !projXml) return;

  var projIndex = 0;

  $('project', projXml).each(
    function() {

      allProj[projIndex] = new Project(
      {
        id: $(this).find("ID").text(),
        name: $(this).find("Name").text() != null ? $(this).find("Name").text() : "",
        description: $(this).find("Description").text(),
        type: $(this).find("Type").text(),
        planarea: $(this).find("PlanArea").text(),
        facility: $(this).find("Facility").text(),
        from: $(this).find("From").text(),
        to: $(this).find("To").text(),
        source: $(this).find("Source").text(),
        capnoncap: $(this).find("CapNonCap").text(),
        kml: $(this).find("KML").text(),
        primimg: null,
        gxmlIndex: null,
        polylineIndex: null,
        kmlGroup: null
      });

      if (typeof allProj[projIndex].type == 'undefined' || allProj[projIndex].type == null)
        allProj[projIndex].kmlGroup = null;
      else if (allProj[projIndex].type == "Congestion Management Corridors" || allProj[projIndex].type == "Congestion Management Spots" || allProj[projIndex].type == "Highway" || allProj[projIndex].type == "Transit")
        allProj[projIndex].kmlGroup = "Trans";
      else
        allProj[projIndex].kmlGroup = "BikePed";

      if (typeof allProj[projIndex].kml != 'undefined' && allProj[projIndex].kml != null && allProj[projIndex].kml.length > 1) {
        allProj[projIndex].gxmlIndex = getGxmlIndex(allProj[projIndex].kml);
        if (allProj[projIndex].gxmlIndex >= gxmlArr.length) {
          gxmlArr[allProj[projIndex].gxmlIndex] = new GeoXml("gxmlArr[" + allProj[projIndex].gxmlIndex.toString() + "]", mapObj, "kml/" + allProj[projIndex].kml, { nozoom: true, clickablelines: false, clickablepolys: false, clickablelinefn: identifyClickLoc });
          gxmlGroupArr[allProj[projIndex].gxmlIndex] = allProj[projIndex].kmlGroup;
          if (allProj[projIndex].kmlGroup == _currentKMLGroup)
            gxmlArr[allProj[projIndex].gxmlIndex].parse();
        }
      }

      projIndex++;
    }
  );
}

function clearAllGxml() {
  for (var i = 0; i < gxmlArr.length; i++)
    gxmlArr[i].clear();
}

function getGxmlIndex(argkml) {
  for (var i = 0; i < gxmlArr.length; i++) {
    if (gxmlArr[i].url == "kml/" + argkml) {
      return i;
    }
  }
  return gxmlArr.length;
}



function fillImageArray(imgXmlStr) {
  var imgXml;
  if (imgXmlStr == "") return;
  try {
    imgXml = GetXmlFromStr(imgXmlStr);
  }
  catch (e) {
    alert(e.message);
    return;
  }

  if (typeof imgXml == "undefined" || !imgXml) return;

  var imgIndex = 0;
  $('image', imgXml).each(
    function() {
      allImgSrc[imgIndex] = $(this).find("imgSrc").text();
      allImgProjId[imgIndex] = $(this).find("projID").text();
      allImgToolTip[imgIndex] = $(this).find("tooltip").text();
      if ($(this).find("primary").text() == 'true') {
        var projIndex = getProjIndex(allImgProjId[imgIndex]);
        if (typeof projIndex != 'undefined' && projIndex != null) {
          allProj[projIndex].primimg = allImgSrc[imgIndex];
          allProj[projIndex].primimgindex = imgIndex;
        }
      }
      imgIndex++;
    }
  );
}

function fillDocArray(docXmlStr) {
  var docXml;
  if (docXmlStr == "") return;
  try {
    docXml = GetXmlFromStr(docXmlStr);
  }
  catch (e) {
    alert(e.message);
    return;
  }

  if (typeof docXml == "undefined" || !docXml) return;

  var docIndex = 0;
  $('doc', docXml).each(
    function() {
      allDocSrc[docIndex] = $(this).find("docSrc").text();
      allDocProjId[docIndex] = $(this).find("projID").text();
      allDocToolTip[docIndex] = $(this).find("tooltip").text();
      allDocTitle[docIndex] = $(this).find("title").text();
      docIndex++;
    }
  );
}

function fillVideoArray(vidXmlStr) {
  var vidXml;
  if (vidXmlStr == "") return;
  try {
    vidXml = GetXmlFromStr(vidXmlStr);
  }
  catch (e) {
    alert(e.message);
    return;
  }

  if (typeof vidXml == "undefined" || !vidXml) return;

  var vidIndex = 0;
  $('video', vidXml).each(
    function() {
      allVideoSrc[vidIndex] = $(this).find("vidSrc").text();
      allVideoCapSrc[vidIndex] = $(this).find("vidCapSrc").text();
      allVideoProjId[vidIndex] = $(this).find("projID").text();
      allVideoToolTip[vidIndex] = $(this).find("tooltip").text();
      allVideoWidth[vidIndex] = parseInt($(this).find("width").text());
      allVideoHeight[vidIndex] = parseInt($(this).find("height").text());
      vidIndex++;
    }
  );
}

function fillMediaArrays(mediaXmlStr) {
  fillImageArray(mediaXmlStr);
  fillVideoArray(mediaXmlStr);
  fillDocArray(mediaXmlStr);
  projMediaLoaded = true;
}

function GetXmlFromStr(str) {
  var projXml;
  try //Internet Explorer
  {
    projXml = new ActiveXObject("Microsoft.XMLDOM");
    projXml.async = "false";
    projXml.loadXML(str);
  }
  catch (e) {
    try //Firefox, Mozilla, Opera, etc.
    {
      var parser = new DOMParser();
      projXml = parser.parseFromString(str, "text/xml");
    }
    catch (e) {
      //alert(e.message);
      throw e;
      return;
    }
  }

  return projXml;
}

function identifyClickLoc(point, a) {

  //if(!point) {point = this.getPoint();}
  var index = getProjIndex(this.mytitle);

  if (typeof index != 'undefined' && index != null)
    fillProjectInfo(index);
  else
    fillProjectInfo(-1);
}

function clearMapFilter() {
  filterProjectsOnMap(getMatchingProjects({ type: null }));
}



function filterProjectsByAttr() {
  if (!_gotPolylineIndexes)
    getPolylineIndexes();
  //debugger;
  var projType = $("#selProjType :selected").val();
  if (projType == '0') projType = null;
  //var capNonCap = $("#selCapNonCap :selected").val();
  //if (capNonCap == '0') capNonCap = null;
  clearAddressAndRouteSearch();
  var matchProjs = getMatchingProjects({ type: projType });
  filterProjectsOnMap(matchProjs);
}

function filterProjectsOnMap(matchProjs) {
  if (!_gotPolylineIndexes)
    getPolylineIndexes();
  var index;
  var matchIndex = 0;
  var maxMatchIndex = matchProjs[matchProjs.length - 1];
  for (var i = 0; i < gxmlArr.length; i++) {
    if (gxmlGroupArr[i] == _currentKMLGroup)
      gxmlArr[i].hide();
  }
  for (index = 0; index < allProj.length; index++) {
    if (matchIndex < maxMatchIndex && matchProjs[matchIndex] == index) {
      matchIndex++;
      if (allProj[index].gxmlIndex != null && allProj[index].polylineIndex != null) {
        gxmlArr[allProj[index].gxmlIndex].showHide(null, true, allProj[index].polylineIndex);
        //gxmlArr[allProj[index].gxmlIndex].showHide(allProj[index].polylineIndex, true, allProj[index].polylineIndex);
      }
    }
    //else {
    //  if (allProj[index].gxmlIndex != null && allProj[index].polylineIndex!=null) 
    //    gxmlArr[allProj[index].gxmlIndex].showHide(null, false, allProj[index].polylineIndex);
    //}
  }
  //for (var i = 0; i < gxmlArr.length; i++) {
  //    gxmlArr[i].clear();
  //  gxmlArr[i].parse();
  //gxmlArr.hide();
  //gxmlArr.show();
  //}
}

// returns a list of project indexes which match the parameters given in the passed parameter object
function getMatchingProjects(a) {
  var index;
  var rplIndex = 0;
  var retProjList = new Array();

  if (typeof a == 'undefined' || a == null)
    return null;

  for (index = 0; index < allProj.length; index++) {
    var keeper = true;

    if (typeof a.capnoncap != 'undefined' && a.capnoncap != null && allProj[index].capnoncap != a.capnoncap) {
      keeper = false;
    }
    if (typeof a.type != 'undefined' && a.type != null && allProj[index].type != a.type) {
      keeper = false;
    }

    if (keeper) {
      retProjList[rplIndex] = index;
      rplIndex++;
    }
  }

  return retProjList;
}


function zoomToProject(rowindex, mapObj, hideOthers, projindex) {
  if (!_gotPolylineIndexes)
    getPolylineIndexes();
  //debugger;
  if (typeof hideOthers == 'undefined' || hideOthers == null)
    hideOthers = true;
  if (typeof mapObj == 'undefined' || mapObj == null)
    mapObj = map;
  if (typeof mapObj == 'undefined' || mapObj == null)
    return; // no map to zoom on

  if (rowindex == -2) {
    rowindex = $("#projSearchResultsGrid").getGridParam("selrow");
  }
  var index;
  if (typeof rowindex == 'undefined' || rowindex == null || rowindex <= -1) {
    if (typeof projindex == 'undefined' || projindex == null)
      return; // error
    else {
      index = projindex;
    }
  }
  else {
    index = $("#projSearchResultsGrid").getRowData(rowindex).projindex;
  }

  for (var i = 0; i < gxmlArr.length; i++) {
    if (gxmlGroupArr[i] == _currentKMLGroup)
      gxmlArr[i].hide();
  }
  if (allProj[index].polylineIndex != null && allProj[index].gxmlIndex != null)
    gxmlArr[allProj[index].gxmlIndex].showHide(null, true, allProj[index].polylineIndex);
  var projBounds = getProjBounds(index);
  if (projBounds != null) {
    var zoomLvl = mapObj.getBoundsZoomLevel(projBounds);
    if (zoomLvl > 15) zoomLvl = 15;
    mapObj.setCenter(projBounds.getCenter(), zoomLvl);
  }
  //fillProjectInfo(index,false);
}

function getProjBounds(projIndex) {
  if (!_gotPolylineIndexes)
    getPolylineIndexes();
  //debugger;
  var gxmlIndex = allProj[projIndex].gxmlIndex;
  var plIndex = allProj[projIndex].polylineIndex;
  var ptArr = new Array();
  if (gxmlIndex != null && plIndex != null) {
    for (var lindex = 0; lindex < gxmlArr[gxmlIndex].polylines[plIndex].lines.length; lindex++) {
      for (var lptindex = 0; lptindex < gxmlArr[gxmlIndex].polylines[plIndex].lines[lindex].length; lptindex++)
        ptArr.push(gxmlArr[gxmlIndex].polylines[plIndex].lines[lindex][lptindex]);
    }
    var tempBounds = new GBounds(ptArr);
    var tempMinLL = new GLatLng(tempBounds.minY, tempBounds.minX);
    var tempMaxLL = new GLatLng(tempBounds.maxY, tempBounds.maxX);
    return new GLatLngBounds(tempMinLL, tempMaxLL);
  }
  else {
    return null;
  }
}

function getProjIndex(id) {
  var index;
  for (index = 0; index < allProj.length; index++) {
    if (id.toString().toLowerCase() == allProj[index].id.toLowerCase())
      return index;
  }

  return null;


}

function getProjectsWithinDist(point, dist, callback) {
  if (!_gotPolylineIndexes)
    getPolylineIndexes();

  callPageMethod("GetProjectsNearPoint", "{'point':{'X':" + point.lng() + ",'Y':" + point.lat() + "},'dist':" + dist.toString() + "}", function(d) { getProjectsWithinDist_Callback(d, callback); });
}

function getProjectsWithinDist_Callback(d, callback) {
  var retProjList = new Array();
  var rplIndex = 0;
  for (var i = 0; i < d.length; i++) {
    var tempProjIndex = getProjIndex(d[i].Name);
    if (tempProjIndex != null) {
      retProjList[rplIndex] = tempProjIndex;
      rplIndex++;
    }
  }
  retProjList.sort(function(a, b) { return a - b });
  callback(retProjList);
}

// dist in meters
/*function getProjectsWithinDist(point, dist) {
if (!_gotPolylineIndexes)
getPolylineIndexes();
//debugger;
//var index, ptindex;
var rplIndex = 0;
var retProjList = new Array();

for (var index = 0; index < gxmlArr.length; index++) {
for (var plindex = 0; plindex < gxmlArr[index].polylines.length; plindex++) {
for (var ptindex = 0; ptindex < gxmlArr[index].polylines[plindex].lines[0].length; ptindex++) {
if (gxmlArr[index].polylines[plindex].lines[0][ptindex].distanceFrom(point) < dist) {
var tempProjIndex = getProjIndex(gxmlArr[index].polylines[plindex].name);
if (tempProjIndex!=null) {            
retProjList[rplIndex] = tempProjIndex;
rplIndex++;
break;
}
}
}
}
}

return retProjList;
}*/

function getProjectsOnRoute(routePolyline, dist, callback) {
  if (!_gotPolylineIndexes)
    getPolylineIndexes();
  var dataStr = "{route:[";
  // Add all the polyline points
  for (var i = 0; i < routePolyline.getVertexCount(); i++) {
    if (i > 0) dataStr += ", ";
    var temppt = routePolyline.getVertex(i);
    dataStr += "{'X':" + temppt.lng() + ",'Y':" + temppt.lat() + "}";
  }

  dataStr += "],'dist':" + dist.toString() + " }";

  callPageMethod("GetProjectsOnRoute", dataStr, function(d) { getProjectsOnRoute_Callback(d, callback); });
}

function getProjectsOnRoute_Callback(d, callback) {
  var retProjList = new Array();
  var rplIndex = 0;
  for (var i = 0; i < d.length; i++) {
    var tempProjIndex = getProjIndex(d[i].Name);
    if (tempProjIndex != null) {
      retProjList[rplIndex] = tempProjIndex;
      rplIndex++;
    }
  }
  retProjList.sort(function(a, b) { return a - b });
  callback(retProjList);
}

/*function getProjectsOnRoute(routePolyline, dist) {
if (!_gotPolylineIndexes)
getPolylineIndexes();
var index;
var ptindex;
var plptindex;
var rplIndex = 0;
var retProjList = new Array();
var maxLineLength = 300;

for (index = 0; index < gxmlArr.length; index++) {
for (var plindex = 0; plindex < gxmlArr[index].polylines.length; plindex++) {
var numpts = gxmlArr[index].polylines[plindex].lines[0].length;
for (ptindex = 0; ptindex < numpts; ptindex++) {
// if points are too far apart, create "intermediate" points 
var testLen;
if (ptindex < numpts - 1)
testLen = gxmlArr[index].polylines[plindex].lines[0][ptindex].distanceFrom(gxmlArr[index].polylines[plindex].lines[0][ptindex + 1]);
else
testLen = 0;

var tempPtArr = [gxmlArr[index].polylines[plindex].lines[0][ptindex]];
if (testLen > maxLineLength) {
var pt1 = gxmlArr[index].polylines[plindex].lines[0][ptindex];
var pt2 = gxmlArr[index].polylines[plindex].lines[0][ptindex + 1];
for (var i = 1; i < testLen / maxLineLength; i++) {
var rat = (i * maxLineLength) / testLen;
if (rat >= 1) break;
var tempPt = new GLatLng((gxmlArr[index].polylines[plindex].lines[0][ptindex].lat() - gxmlArr[index].polylines[plindex].lines[0][ptindex + 1].lat()) * rat + gxmlArr[index].polylines[plindex].lines[0][ptindex].lat(),
(gxmlArr[index].polylines[plindex].lines[0][ptindex].lng() - gxmlArr[index].polylines[plindex].lines[0][ptindex + 1].lng()) * rat + gxmlArr[index].polylines[plindex].lines[0][ptindex].lng());

tempPtArr[i] = tempPt;
}
}

var successFlag = false;
var numplpts = routePolyline.getVertexCount();
var tempPlPtArr = new Array();
var tempNumPlPts = 0;
for (plptindex = 0; plptindex < numplpts; plptindex++) {
tempPlPtArr[tempNumPlPts] = routePolyline.getVertex(plptindex);
tempNumPlPts++;
var testLen;
if (plptindex < numplpts - 1)
testLen = routePolyline.getVertex(plptindex).distanceFrom(routePolyline.getVertex(plptindex + 1));
else
testLen = 0;

if (testLen > maxLineLength) {
var pt1 = routePolyline.getVertex(plptindex);
var pt2 = routePolyline.getVertex(plptindex + 1);
for (var i = 1; i < testLen / maxLineLength; i++) {
var rat = (i * maxLineLength) / testLen;
if (rat >= 1) break;

var tempPt = new GLatLng((pt1.lat() - pt2.lat()) * rat + pt1.lat(),
(pt1.lng() - pt2.lng()) * rat + pt1.lng());

tempPlPtArr[tempNumPlPts] = tempPt;
tempNumPlPts++;
}
}
}
for (var tempptindex = 0; tempptindex < tempPtArr.length; tempptindex++) {
for (var tempplptindex = 0; tempplptindex < tempPlPtArr.length; tempplptindex++) {
//if (gxmlArr[index].polylines[plindex].lines[0][ptindex].distanceFrom(routePolyline.getVertex(plptindex)) < dist) {
if (tempPtArr[tempptindex].distanceFrom(tempPlPtArr[tempplptindex]) < dist) {
var tempProjIndex = getProjIndex(gxmlArr[index].polylines[plindex].name);
if (tempProjIndex!=null) {            
retProjList[rplIndex] = tempProjIndex;
rplIndex++;
successFlag = true;
break;
}
}
}
if (successFlag)
break;
}
if (successFlag)
break;
}
}
}

return retProjList;
}*/

function isMediaAvailable(projID) {
  var mediaFound = false;
  var i = 0;

  for (i = 0; i < allImgSrc.length; i++) {
    if (allImgProjId[i] == projID) {
      mediaFound = true;
      break;
    }
  }

  if (!mediaFound) {
    for (i = 0; i < allVideoSrc.length; i++) {
      if (allVideoProjId[i] == projID) {
        mediaFound = true;
        break;
      }
    }
  }

  if (!mediaFound) {
    for (i = 0; i < allDocSrc.length; i++) {
      if (allDocProjId[i] == projID) {
        mediaFound = true;
        break;
      }
    }
  }

  return mediaFound;
}
