// ###################################################################################
//  purpose:  This module contains all the entry point code for the application
//
//
//  functions:
//      <-- Functions dealing with initializing the map and the layers -->
//      application_onStartup: called on page load -- initilizes the map 
//      onBaseMapLayerLoaded: called after the base layer is loaded, gets the parcel layer id from the base layer and initialized all the searches that require the parcels to be in the map
//      mapLoaded: connects all the other stuff on the map, ie pans, zooms, extent history.  requires the map be loaded first
//      
//      <-- event handler functions -->    
//      onMapMouseMove: triggered on mouse moving over the map - starts the event for getting map coordinates
//      onMapMouseOut: triggered when mouse leaves the map area - reset the coords to nothing
//      onMapExtentChange: tiggered when the extent of the map changes - recalculates the scale
//      calcScale: recacluates the scale of the map
//      resizeMap: resizes the map when the browser resizes
//      map_onclick: Event triggered when a user clicks the map canvas
//          identify--> triggers the 'doIdentify' function
//          select -->  triggers the printing of the tax card 'doSelect' function in taxcard.js
//          zoomout --> map to zoom out
//
//      <-- user functions -->
//      printLegend_onClick: user clicks the legend button on toolbar,app goes to server for the legend
//      printLegend_onComplete: retrieves the response for the legend and renders it in the side panel.
//
//      <-- Toolbar Functions -->
//      setToolImage: changes the tool image in the toolbar   
//
//      <-- Map Functions -->
//      zoomToInitialExtent: zooms to the initial extent of the map
//      zoomMap: zooms maps to a feature geometry
//      centerMap: centers map on feature's extent
//      zoomOut: zooms the map out by x percent
//      zoomIn: zooms the map in by x percent
//      zoomToAllGraphics: zooms to all the graphics in the map
//      clearAllGraphics: clear the graphics and graphic containers in the map
//
//      <-- General functions -->
//      showConfigurationError: show the error panel
//      showError: shows an error panel
//      showLoading: starts the time on the a layer load or visibility change
//      hideLoading: end the timer on layer load or visibility change
//
//      <-- Functions dealing with hiding & showing Side panels
//      showPanel: show & initializes the targeted side panel
//      hidePanels: hides all the side panels
// ####################################################################################


      dojo.require("dijit.dijit");
      dojo.require("dojo.parser");
      dojo.require("dijit._Widget");
      dojo.require("dijit._Templated");
      dojo.require("dijit._Container");
      dojo.require("esri.map");
      dojo.require("dijit.layout.BorderContainer");
      dojo.require("dijit.layout.ContentPane");
      dojo.require("dijit.layout.TabContainer");
      dojo.require("dijit.Toolbar");
      dojo.require("esri.tasks.geometry");
	  dojo.require("esri.tasks.query");
	  dojo.require("esri.tasks.find");
	  dojo.require("dijit.Dialog");
	  dojo.require("dijit.TitlePane");
	  dojo.require("dijit.form.Button");
	  dojo.require("dijit.form.TextBox");
	  dojo.require("dijit.form.Slider");

	  dojo.require("dojox.data.QueryReadStore");
	  dojo.require("dijit.form.FilteringSelect");
	  dojo.require("dojo.data.ItemFileReadStore");
	  dojo.require("dojo.data.ItemFileWriteStore");
	  dojo.require("dijit.form.CheckBox");
	  dojo.require("dijit.form.RadioButton");
	  dojo.require("dijit.form.ComboBox");
	  
	  dojo.require("dijit.ProgressBar");
	  dojo.require("dijit.Menu");
	  dojo.require("dijit.ColorPalette"); 
	  dojo.require("dijits.overview.OverviewMap");
	  dojo.require("dijits.tools.ZoomToBtn");
	  dojo.require("dijits.custom.ZoomToCoords");
	  dojo.require("dijits.tools.draw.DrawTools");
	  dojo.require("dijits.tools.taskProcessing");

	  
	  dojo.require("dijits.tools.Scalebar");
	  dojo.require("dijits.tools.MapCoords");
	  dojo.require("dijits.tools.LoadingDialog");
	  dojo.require("dijits.toc.SimpleTOC");
	 
	  dojo.require("dijit.form.Slider");
	  dojo.require("dijit.form.HorizontalSlider");
	  dojo.require("dijits.tools.LastUpdateControl");
	  dojo.require("dijits.tools.MapViewButtons");
	  dojo.require("dijits.tools.MeasureToolbar");
	  dojo.require("dijits.tools.SelectToolbar");
	  dojo.require("dijits.tools.ZoomToCoords");

	  // Map Panels - these are located in the side bar
	  var mapPanels = ["find", "toc-panel", "measure", "identify", "zoomtocoords", "drawtools"];

	  var searchPanels = ["about", "results", "locator", "adjoiners", "info" ];

	  // Map Tools - These can be listed in the map_click event
	  var mapTools = ["MapZoomIn", "MapZoomOut", "MapPan", "MapIdentify"];

	  var map, mapScales;
      var resizeTimer;
      var navToolbar;

      // toc global parameters
	  var visible = [];
	  var agsLayers = [];

	  var overviewMapLayer;
	 
	  var useToolbar;
      var queryString;
      var idHandle;

      var advancedSearch;
      var collapsed = false;

      var currentTool = "MapPan"
      var loading;
      var layersLoaded = 0;  //varible to keep track of when all layers have been loaded.
      var initialExtent;
      var parcelStore;

      var tocIsInitialize = false;

      var currentImagery = "Imagery08";

      var modalDijit = null;

      function application_startup() {

          try {

              
              console.debug("Starting the application");
              initialExtent = new esri.geometry.Extent(initialXmin, initialYmin, initialXmax, initialYmax, new esri.SpatialReference({ wkid: 2264 }));
             
              // show the loading layer...
              layersLoaded = 0;
              loading = dojo.byId("loading");
              hideLoading();

              modalDijit = dijit.byId("loadingDialog");

              modalDijit.show();
              modalDijit.setMessage("Initializing Map...");
              

              esriConfig.defaults.map.slider = { right: "10px", top: "60px", width: null, height: "200px" };

              // MAIN MAP

              var o = document.getElementById("mapDiv");
              if (o == null)
                  alert("cannot find MapDiv");

              map = new esri.Map("mapDiv", { nav: false, slider: true });
              
              dojo.connect(map, "onLoad", mapLoaded);

              modalDijit.setMessage("Initializing Map...");
              
              loadLayer(mapLayers[0]);

              
              initGeometryService();
              navToolbar = new esri.toolbars.Navigation(map);

              showPanel('find');
              

              console.debug("ending start up for the application #2");

              
          } catch (Error) {
                console.warn("An error occurred in the application", Error);
                //modalDijit.setMessage("An error occurred in application startup");
                document.location = "ApplicationError.aspx?error=" + Error.message;
          }
          
 
      }


      
      // ########################################################
      // Toolbar Functions
      // ########################################################
      function ToolbarStartUp() {

          try {
              // Connect all the mouse down events...
              dojo.connect(dojo.byId("MapZoomIn"), "onmousedown", function() { ToolbarMouseDown('MapZoomIn', 'Tool'); });
              dojo.connect(dojo.byId("MapZoomOut"), "onmousedown", function() { ToolbarMouseDown('MapZoomOut', 'Command'); });
              dojo.connect(dojo.byId("MapZoomNext"), "onmousedown", function() { ToolbarMouseDown('MapZoomNext', 'Command'); });
              dojo.connect(dojo.byId("MapZoomPrevious"), "onmousedown", function() { ToolbarMouseDown('MapZoomPrevious', 'Command'); });
              dojo.connect(dojo.byId("MapFullExtent"), "onmousedown", function() { ToolbarMouseDown('MapFullExtent', 'Command'); });
              dojo.connect(dojo.byId("MapPan"), "onmousedown", function() { ToolbarMouseDown('MapPan', 'Tool'); });
              dojo.connect(dojo.byId("MapIdentify"), "onmousedown", function() { ToolbarMouseDown('MapIdentify', 'Tool'); });
              dojo.connect(dojo.byId("MapMeasure"), "onmousedown", function() { ToolbarMouseDown('MapMeasure', 'Command'); });
              dojo.connect(dojo.byId("MapZoomCoords"), "onmousedown", function() { ToolbarMouseDown('MapZoomCoords', 'Command'); });
              dojo.connect(dojo.byId("MapSelect"), "onmousedown", function() { ToolbarMouseDown('MapSelect', 'Command'); });
              dojo.connect(dojo.byId("MapDraw"), "onmousedown", function() { ToolbarMouseDown('MapDraw', 'Command'); });
              dojo.connect(dojo.byId("ClearSelection"), "onmousedown", function() { ToolbarMouseDown('ClearSelection', 'Command'); });

              // connect the mouse over events
              mapTools = dojo.query(".toolicon");
              dojo.forEach(mapTools, function(t) {
                    dojo.connect(t, "onmouseover", function() { ToolbarMouseOver(t); });
                    dojo.connect(t, "onmouseout", function() { ToolbarMouseOut(t); });
                });
              
  
          } catch (Error) {
          console.warn("An error occurred in ToolBarStartUp function", Error);
          }     

      }
      
      function ToolbarMouseOut(tool) {

          if (tool != currentTool) {
              dojo.style(tool,{ borderStyle: "none" } );
          }

      }

      function ToolbarMouseOver(tool) {
          dojo.style(tool, { borderStyle: "Solid", borderColor: "red", borderWidth: "1px" } );  
      }


      function ToolbarMouseDown(tool, tooltype) {

          map.infoWindow.hide();

          dojo.style("selectToolbarPane", { display: "none" }); 

         // example: 'ClearSelection', 'Command'
         // Tools are: MapZoomIn, MapZoomOut, MapPan, MapMeasure, MapIdentify, MapSelect
          if (tooltype === "Tool") {
              clearCurrentTool();

              dojo.style(tool, { backgroundColor: "white", borderStyle: "inset", borderColor: "white", borderWidth: "1px" });
              currentTool = tool;

              changeMapCursors(tool);
              
              
              switch (tool) {
                  case "MapZoomIn":
                      navToolbar.activate(esri.toolbars.Navigation.ZOOM_IN);
                      break;
                  case "MapZoomOut":
                      navToolbar.activate(esri.toolbars.Navigation.ZOOM_OUT);
                      break;
                  case "MapPan":
                      navToolbar.activate(esri.toolbars.Navigation.PAN);
                      break;
                  case "MapIdentify":
                      showPanel("identify");
                      navToolbar.activate(esri.toolbars.Navigation.PAN);
                      break;
                  case "MapSelect":
                      navToolbar.activate(esri.toolbars.Navigation.PAN);
                      break;
                  default:
                      navToolbar.activate(esri.toolbars.Navigation.PAN);
                      break;
              }
              
          } else {

              switch (tool) {
                  case "MapFullExtent":
                      zoomToInitialExtent();
                      break;
                  case "MapZoomOut":
                      //Zoom map out
                      var levelID = map.getLevel();
                      if (levelID == -1)
                          map.centerAndZoom(map.extent.getCenter(), 2.5)
                      else {
                          if (levelID > 0)
                              map.setLevel(levelID - 1);
                      }
                      break;
                  case "MapZoomNext":
                      navToolbar.zoomToNextExtent();
                      break;
                  case "MapZoomPrevious":
                      navToolbar.zoomToPrevExtent();
                      break;
                  case "MapMeasure":
                      dijit.byId("measureTools").activate();
                      showPanel("measure");
                      break;
                  case "MapZoomCoords":
                      showPanel("zoomtocoords");
                      break;
                  case "MapDraw":
                      clearCurrentTool();
                      currentTool = "MapDraw";
                      navToolbar.activate(esri.toolbars.Navigation.PAN);
                      showPanel("drawtools");
                      break;
                  case "MapSelect":
                      clearCurrentTool();
                      navToolbar.activate(esri.toolbars.Navigation.PAN);
                      dojo.style("selectToolbarPane", { display: "block" });
                      currentTool = "MapSelect";
                      changeMapCursors("MapSelect");
                      dijit.byId("selectToolbar").setTool("point");                  
                      break;                  
                  case "ClearSelection":
                      clearAllGraphics();
                      //showPanel(returnToPanel);
                      break;
                   default:
                      break;
              }
          }
      }

      function clearCurrentTool() {
          try {
              // clear selected tools
              currentTool = "";

              //deactivateSelectToolbar();
              dijit.byId("drawToolbar").deactivate();

              //deactivateMeasureToolbar();
              dijit.byId("measureTools").deactivate();

              // deactivate the coords zoom tool
              dijit.byId("zoomcoords").deactivate();

              // deactivate the select tools
              dijit.byId("selectToolbar").deactivate();
              
              dojo.forEach(mapTools, function(t) {
                  dojo.style(t, { backgroundColor: "transparent", borderStyle: "none" });
              });
          } catch (Error) {


          }

      }

      function deactivateMapClick() {
          // change the tool reference in app...
          clearCurrentTool();
          changeMapCursors("");
          map.infoWindow.hide();
          navToolbar.activate(esri.toolbars.Navigation.PAN);
      }

      function changeMapCursors(tool) {
          switch (tool) {
              case "MapZoomIn":
                  dojo.byId("mapDiv_layers").style.cursor = "url('images/cursors/i_zoomin.cur'),crosshair";
                  break;
              case "MapSelect":
                  dojo.byId("mapDiv_layers").style.cursor = "pointer";
                  break;
              case "MapIdentify":
                  dojo.byId("mapDiv_layers").style.cursor = "pointer";
                  break;
              case "MapPan":
                  dojo.byId("mapDiv_layers").style.cursor = "url('images/cursors/i_pan.cur'),crosshair";
                  break;
              default:
                  dojo.byId("mapDiv_layers").style.cursor = "default";
                  break;
          }

      }
 


      // ###############################################
      // Map Click Event
      // ###############################################
      
      function map_onclick(evt) {
          map.infoWindow.hide();
          switch (currentTool) {
              case "MapIdentify":
                  doIdentify(evt);
                  break;
              case "MapZoomOut":
                  map.centerAndZoom(evt.mapPoint, 2.5)
                  break;
              default:
                  // do nothing at all
          }
      }
      
      // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      // Tool - menu functions
      // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      function showPanel(name) {
          hidePanels();
          dojo.style(name, { 'display': 'block' });
          
          // open the sibe bar if it is closed
          if (collapsed)
              resize();
                
          // do any additional stuff
          switch (name) {
              case "find":
                  dojo.byId("back").innerHTML = "";
                  break;
               case "toc-panel":
                  refreshTOC();
                  break;
              case "advanced":
                  dijit.byId("advancedDialog").show();
                  dojo.style('find', { 'display': 'block' });
                  break;
              default:
                  break;
          }
                
          
      }



      function showSearchPanel(name) {

          // first hide the search panels...
          dojo.forEach(searchPanels, function(panel) {
              dojo.style(panel, { "display": "none" });
          });

          dojo.style(name, { 'display': 'block' });


      }


    function clearAllGraphics() {
        try {

            map.graphics.clear();
            clearSearchResultsPanel();
            clearAdjoiners();
            showPanel("find");
            showSearchPanel("about");

            // hide the map info window.
            map.infoWindow.hide();

	    dijit.byId("txtFind").reset();
            return;
        } catch (Error) {
        console.warn("An Error Occurred in application: 'ClearAllGraphics'", Error);
        }
    }

    dojo.addOnLoad(application_startup);

    // ########################################################
    // Loading Functions
    // ########################################################
    function mapLoaded(thisMap) {

        try {
        
            
            ToolbarStartUp();

            modalDijit.setMessage("loading additional layers...");
            loadLayers();
       
            dojo.connect(map, "onMouseMove", onMapMouseMove);
            dojo.connect(map, "onMouseOut", onMapMouseOut);
            dojo.connect(map, "onExtentChange", onMapExtentChange);
            dojo.connect(window, 'onresize', function() { resizeMap([map]); });
            dojo.connect(map, "onZoomStart", showLoading);
            dojo.connect(map, "onPanStart", showLoading);
            
            
            dojo.connect(window, 'onresize', function() { resizeMap([map]); });
            
            // disable the map navigation
            map.enableScrollWheelZoom();
            map.disableShiftDoubleClickZoom();
            map.disableRubberBandZoom();
            map.disablePan();
            map.disableClickRecenter();
            map.disableKeyboardNavigation();
            map.disableMapNavigation();
            map.disableDoubleClickZoom()
            map.disableMapNavigation();
            
            idHandle = dojo.connect(map, "onClick", map_onclick);           

            searchResultsStartup();
            //initSelectToolbar(map);
            
            // create the parcel search url string...
            parcelSearchLayerURL = searchURL + "/" + parcels_layerID;

            // init the searches and queries dealing with parcels
            modalDijit.setMessage("Initializing searches...");
            initIdentifyFunctionality();
            initSearch();
            
            adjoiners_startup();



            modalDijit.setMessage("Creating map tools...");
            // initialize the overview map...
            overviewMapLayer = new esri.layers.ArcGISDynamicMapServiceLayer(overviewMapServiceURL, { id: "map", visible: true });
            dojo.connect(overviewMapLayer, "onLoad", function() {
                try {
                    overviewMapDijit = new dijits.overview.OverviewMap({
                        baseLayer: overviewMapLayer,
                        id: "overview-map",
                        expandFactor: 3,
                        attachTo: "bottom-right",
                        color: "#FF0000",
                        opacity: 0.55,
                        map: map
                    });


                    overviewMapDijit.startup();
                } catch (Error) { console.warn("Error loading overview map", Error); }
            });

            // measure toolbar
            var mtbParams = { map: map };
            var mtb = new dijits.tools.MeasureToolbar(mtbParams, "measureTools");
            mtb.startup();


            // select a parcel toolbar
            var spParams = { map: map, searchURL: parcelSearchLayerURL, outFields: parcels_return_fields };
            var sp = new dijits.tools.SelectToolbar(spParams, "selectToolbar");
            sp.startup();
            
            // zoom to coords control
            var zc = new dijits.custom.ZoomToCoords(null, "zoomcoords");
            zc.init(map);
            zc.startup();

            // zoom to State plane coordinates

            var zc2 = new dijits.tools.ZoomToCoords(null, "zoomcoordsncsp");
            zc2.init(map);
            zc2.startup();

//            // map legend
//            var mapLegend = new dijits.tools.Legend({ map: map, legends: legends }, "legend");
//            mapLegend.startup();

            var mapScalebar = new dijits.tools.Scalebar({ map: map }, "mapScale");
            mapScalebar.startup();

            var mapCoords = new dijits.tools.MapCoords({ map: map }, "mapPosition");
            mapCoords.startup();

            //mapViewButtonsStartUp();
            addMapViewbuttons();
         
            esriConfig.defaults.io.proxyUrl = "proxy.ashx";
            esriConfig.defaults.io.alwaysUseProxy = false;
            
            dijit.byId("drawToolbar").setMap(map);

            console.debug("ending start up for the application");

            // handle initial extent...
            if (handleQueryString()== false)
                zoomToInitialExtent();

            modalDijit.setMessage("Map Loaded Successfully...");
            modalDijit.hide();

        } catch (Error) {
            console.warn("An error occurred in the application", Error);
            modalDijit.setMessage("An error occurred while starting the application...");
        }
    }


    function loadLayers() {
        console.debug("loading layers");
        dojo.forEach(mapLayers, function(l, indx) {
            if (indx > 0)
                loadLayer(l);
        });
    }

    function loadLayer(mapServiceInfo) {
        try {
            console.debug(mapServiceInfo);
            var layer = null;
            if (mapServiceInfo.type === "tiled") {
                layer = new esri.layers.ArcGISTiledMapServiceLayer(mapServiceInfo.url, {
                    id: mapServiceInfo.label,
                    opacity: parseFloat(mapServiceInfo.alpha),
                    visible: mapServiceInfo.visible
                });
            }
            else
                if (mapServiceInfo.type === "dynamic") {
                layer = new esri.layers.ArcGISDynamicMapServiceLayer(mapServiceInfo.url, {
                    id: mapServiceInfo.label,
                    opacity: parseFloat(mapServiceInfo.alpha),
                    visible: mapServiceInfo.visible
                });

               

                if ((mapServiceInfo.layerIDs !== undefined))  {
                    layer.setVisibleLayers(mapServiceInfo.layerIDs);
                }
                
            }

            if (layer != null) {
                map.addLayer(layer);
                //dojo.connect(layer, "onLoad", function(l) { alert("layer loaded " + l.id); });
                dojo.connect(layer, "onUpdate", hideLoading);
                dojo.connect(layer, "onVisibilityChange", refreshTOC)
                console.debug("Layer is valid");
            } else {
                console.debug("Layer is invalid");
            }
        }
        catch (err) {
            console.error("Loading map service at url: " + mapServiceInfo.url);
            alert(err.message);
        }
    }

    function refreshTOC() {

        if (!tocIsInitialize) {

            var params = { items: null };
            var toc = new dijits.toc.SimpleTOC(params, "toc");
            toc.startup();

            dojo.forEach(tocLayerList, function(item, indx) {

                if (item.isService) {

                    var params = { text: item.text, map: map, mapservice: item.mapname, opacity: item.opacity, url: item.url, layerIDs: item.layerIDs }
                    var item = new dijits.toc.tocServiceNode(params);
                    toc.addService(item);

                } else {

                    try {

                        if (item.layers.length == 0)
                            item.layers = [item.text];

                        var params = { text: item.text, mapservice: item.mapname, layers: item.layers, map: map };
                        var item = new dijits.toc.tocNode(params);
                        toc.add(item);
                    } catch (Error) {
                        console.error("Error when adding layer to TOC", Error);
                    }

                }
            });

            tocIsInitialize = true;
        } else {
             window.setTimeout("dijit.byId('toc').refresh();", 1000) 
        }

    }


    function addMapViewbuttons() {

        dojo.forEach(mapViewButtons, function(item) {
            var params = { map: map, label: item.label, turnOff: item.turnOff, turnOn: item.turnOn };
            var btn = new dijits.tools.MapViewButton(params);
            btn.startup();


            // ###################################################
            // the following code is custom to Caldwell County, nc 
            //  since they have multiple imagery
            switch (btn.label) {
                case "Hybrid":
                    btn.onBeforeClick = function() {

                        var layers = [];

                        dojo.forEach(this.layer2TurnOn, function(layerName, indx) {
                           // try {

					
switch(layerName) {

   case "Imagery08":
   case "Imagery04":
   case "Imagery2010":
	layers.push(currentImagery);
   	break;
   default:
     layers.push(layerName);
     break;	

}

//                               if ((layerName == "Imagery08") || (layerName == "Imagery04")) {layers.push(currentImagery); }    
//                               else { layers.push(layerName); }
//                            } catch (Error) {
//                                console.warn("problem parsing layer: ", Error);
//                            }
                        });
                        
                        this.setLayersToTurnOn(layers);

                    };
                    break;
                case "Imagery 2010":
                    btn.onClickCompleted = function() { currentImagery = "Imagery2010"; };
                    break;
                case "Imagery 08":
                    btn.onClickCompleted = function() { currentImagery = "Imagery08"; };
                    break;
                case "Imagery 04":
                    btn.onClickCompleted = function() { currentImagery = "Imagery04"; };
                    break;
            }
            // ###################################################
            

            dijit.byId("mapViewToolbar").add(btn);
        });

    }

    function handleQueryString() {

        // on startup check for url query parameters and use extent and optionally featureID
        // executeQueryTask will be called if there is a featureID so the app behaves just like a mouse click
        var url = esri.urlToObject(window.location.toString());
        if (url.query && url.query != null) {
            if (url.query.pid && url.query.pid != null) {
                var pid = url.query.pid;
                sWhere = dojo.string.substitute("${0} = '${1}'", [fields.ncpin, pid ]);
                ExecuteParcelSearch(sWhere);
                return true;
            }
        }

        return false;
    }



    
    
