﻿/// <reference path="googlemaps-intellisense.js" />
/// <reference path="GoogleStreetViewControl.js" />
/// <reference path="PolygonDrawerPrototype.js" />
/// <reference path="Identify.js" />
/// <reference path="Measure.js" />
/// <reference path="LocalLayerController.js" />

//----------------------------------Constant Decleration------------------------------------------------------
var GISP_MAPMODE_MAP = "MAP";
var GISP_MAPMODE_POLY = "POLY";
var GISP_MAPMODE_STREET = "STREET";
var GISP_MAPMODE_IDENTIFY = "IDENTIFY";
var GISP_MAPMODE_MEASURE = "MEASURE";
var GISP_MAPMODE_POINT = "POINT";
var GISP_MAPMODE_POINT = "LOCAL";

var GISP_ZOOMCONTROLS_SMALL = "SMALL";
var GISP_ZOOMCONTROLS_LARGE = "LARGE";

//var GISP_LOCATION_SCRIPTS = "http://www.eightfootscrews.com/common/scripts/mapping/";
//var GISP_LOCATION_IMAGES = "http://www.eightfootscrews.com/common/images/mapping/";
//var GISP_LOCATION_CSS = "http://www.eightfootscrews.com/common/styles/mapping/";

//var GISP_LOCATION_SCRIPTS = "http://www.gisplanning.net/gadmin/gmapping/scripts/";
var GISP_LOCATION_IMAGES = "http://www.gisplanning.net/gadmin/gmapping/images/";
var GISP_LOCATION_CSS = "http://www.gisplanning.net/gadmin/gmapping/styles/";

var GISP_LOCATION_SCRIPTS = "/common/scripts/";
//var GISP_LOCATION_IMAGES = "/common/images/";
//var GISP_LOCATION_CSS = "/common/styles/";

var GISP_TIME_TO_WAIT_WHEN_CHECKING_LOAD_OF_SCRIPT = 25;

var GISP_STREETVIEW_CONTROLLER = "StreetViewController.js";
var GISP_MEAUSRE_TOOL = "measure.js";
var GISP_IDENTIFY_TOOL = "identify.js";
var GISP_LOCAL_LAYER_CONTROLLER = "locallayercontroller.js";
var GISP_POLYGON_DRAWER_TOOL = "polygondrawer.js";
var GISP_UTILITIES = "Utilities.js";






//----------------------------------Map Bar Object Definition------------------------------------------------------



/*
centerPoint is a GLatLng object
zoomLevel is an integer between 1-18
options;
name: "NameOfTheInstanceOfTheObject"
MapBarColor: #HTMLCOLOR
SearchBar : true|false
StreetView: true|false
Satellite: true|false
Terrain: true|false
Hybrid: true|false
PolySelect: true|false
Identify:true|false
LocalData: true|false
Pinpoint: true|false
Distance: true|false
DragZoom: true|false
ScrollWheelZoom: true
ZoomControls: GISP_ZOOMCONTROLS_SMALL|GISP_ZOOMCONTROLS_LARGE
PolyOptions:{}
GMapOptions
StreetOptions:{}
GGoogleBarOptions:{showOnLoad : true}
ClickHandler: ClickHandler
PolySelectedHandler: function(markers){}
*/
function MapBar(pMapDIV, pOptions) {

    var me = this;
    this._map = null;
    this._markers = [];
    this._streetViewController = null;
    this._localLayerController = null;
    this._mapDIV = pMapDIV;
    this._dragZoomControl = null;
    this._polySelectControl = null;
    this._PolySelectedHandler = (pOptions.PolySelectedHandler != undefined ? pOptions.PolySelectedHandler : null);
    this._PolyStartedHandler = (pOptions.PolyStartedHandler != undefined ? pOptions.PolyStartedHandler : null);
    this._identifyControl = null;
    this._measureControl = null;
    this._googleEarth = null;
    this._googleEarthAdded = false;
    this._googleEarthMode = false;


    //component options
    this._mapOptions = (pOptions.GMapOptions != undefined ? pOptions.GMapOptions : null);
    this._googleSearchBarOptions = (pOptions.GGoogleBarOptions != undefined ? pOptions.GGoogleBarOptions : null);
    this._streetViewOptions = (pOptions.StreetOptions != undefined ? pOptions.StreetOptions : null);
    this._localOptions = (pOptions.LocalOptions != undefined ? pOptions.LocalOptions : null);

    //map options
    this._zoomControls = (pOptions.ZoomControls != undefined ? pOptions.ZoomControls : "NONE");

    //feature flags
    this._isGoogleSearchBarEnabled = (pOptions.SearchBar != undefined ? pOptions.SearchBar : false);
    this._isStreetViewEnabled = (pOptions.StreetView != undefined ? pOptions.StreetView : false);
    this._isPolySelectEnabled = (pOptions.PolySelect != undefined ? pOptions.PolySelect : false);
    this._isIdentifyEnabled = (pOptions.Identify != undefined ? pOptions.Identify : false);
    this._isLocalDataEnabled = (pOptions.LocalData != undefined ? pOptions.LocalData : false);
    this._isPinpointEnabled = (pOptions.Pinpoint != undefined ? pOptions.Pinpoint : false);
    this._isMeasureEnabled = (pOptions.Distance != undefined ? pOptions.Distance : false);
    this._isDragZoomEnabled = (pOptions.DragZoom != undefined ? pOptions.DragZoom : false);
    this._isScrollWheelEnabled = (pOptions.ScrollWheelZoom != undefined ? pOptions.ScrollWheelZoom : false);

    //map types
    this._isSatelliteEnabled = (pOptions.Satellite != undefined ? pOptions.Satellite : false);
    this._isTerrainEnabled = (pOptions.Terrain != undefined ? pOptions.Terrain : false);
    this._isHybridEnabled = (pOptions.Hybrid != undefined ? pOptions.Hybrid : false);
    this._isEarthEnabled = (pOptions.Earth != undefined ? pOptions.Earth : false);

    //mapbar options
    this._mapBarColor = (pOptions.MapBarColor != undefined ? pOptions.MapBarColor : '#5c5c5c');

    //handlers
    this._externalClickHandler = (pOptions.ClickHandler != undefined ? pOptions.ClickHandler : null);

    //the actual mapBar control
    this._mapBarControl = null;

    //the mapBarFunction Buttons
    this._functionControls = null;


    //Tooltip service
    this._tooltipService = null;

    //events
    this._loadedEvent = {};


    this._Initialize = function() {
        //register CSS
        GISPlanning_MapUtilities_RegisterCSSFile(GISP_LOCATION_CSS + "MapBar.css");


        //set map properties
        //NOTE: This function has been disabled because in production, this fires after the rest of the page sets the map center. I would prefer to see 
        //this set as options. To be implemented at a later time
        //me._map.setCenter(me._centerPoint, me._zoomLevel);

        //enable search bar
        if (me._isGoogleSearchBarEnabled) { me._map.enableGoogleBar(); };

        //enable zooming with scroll wheel
        if (me._isScrollWheelEnabled) { me._map.enableScrollWheelZoom(); };

       

        //Create the MapBar
        me._mapBarControl = new GISPlanning_MapUtilities_MapBarControl(me._mapBarColor, me);
        me._map.addControl(me._mapBarControl);


        //manager = new MarkerManager(map, {trackMarkers:true});

        //add click listener to the map
        GEvent.addListener(me._map, "click", me._HandleMapClicks);


        //Setup the function buttons*******************************************
        me._functionControls = new MapBar_FunctionControlCollection(me._map);


        //add the hand button if any of the functions are enabled
        if (me._isPolySelectEnabled || me._isIdentifyEnabled || me._isLocalDataEnabled || me._isPinpointEnabled || me._isMeasureEnabled) {
            var myHandControl = MapBar_CreateFunctionControl(GISP_LOCATION_IMAGES + "pan_active.png", GISP_LOCATION_IMAGES + "pan_inactive.png", "Normal Map Mode", null, null);
            me._functionControls.AddControl(myHandControl, "HAND");
            me._functionControls.ResetHandAsActiveButton();
        }; //end if other options are selecting


        //add the tooltip service
        me._tooltipService = new GISPlanning_MapUtilities_TooltipService(me._map);

        //set up streetview
        if (me._isStreetViewEnabled) {
            var myScriptLoader = new GISPlanning_MapUtilities_ScriptLoader(
             GISP_LOCATION_SCRIPTS + GISP_STREETVIEW_CONTROLLER,
            "GISPlanning_MapUtilities_StreetViewController", GISPlanning_MapUtilities_AssociateObjWithEvent(me, "_AddStreetViewWhenLoaded"));
            myScriptLoader.Load();
        }; //end if streetview enabled


        //Add in Drag Zoom
        if (me._isDragZoomEnabled) {
            var myScriptLoader = new GISPlanning_MapUtilities_ScriptLoader(
            "http://gmaps-utility-library.googlecode.com/svn/trunk/dragzoom/release/src/dragzoom.js",
            "DragZoomControl", GISPlanning_MapUtilities_AssociateObjWithEvent(me, "_AddDragZoomControlWhenLoaded"));
            myScriptLoader.Load();
        };


        //Add in poly Zoom
        if (me._isPolySelectEnabled) {
            var myScriptLoader = new GISPlanning_MapUtilities_ScriptLoader(
            GISP_LOCATION_SCRIPTS + GISP_POLYGON_DRAWER_TOOL,
            "GISPlanning_MapUtilities_PolygonDrawer", GISPlanning_MapUtilities_AssociateObjWithEvent(me, "_AddPolyZoomControlWhenLoaded"));
            myScriptLoader.Load();
        };

        //add in local
        if (me._isLocalDataEnabled) {
            var myScriptLoader = new GISPlanning_MapUtilities_ScriptLoader(
            "http://serverapi.arcgisonline.com/jsapi/gmaps/?v=1.4",
            "esri", GISPlanning_MapUtilities_AssociateObjWithEvent(me, "_AddLocalWhenESRILoaded"));
            myScriptLoader.Load();
        };

        //add in identify
        if (me._isIdentifyEnabled) {
            var myScriptLoader = new GISPlanning_MapUtilities_ScriptLoader(
            GISP_LOCATION_SCRIPTS + GISP_IDENTIFY_TOOL,
            "GISPlanning_MapUtilities_Identify", GISPlanning_MapUtilities_AssociateObjWithEvent(me, "_AddIdentifyControlWhenLoaded"));
            myScriptLoader.Load();
        };

        //add in measure
        if (me._isMeasureEnabled) {
            var myScriptLoader = new GISPlanning_MapUtilities_ScriptLoader(
            GISP_LOCATION_SCRIPTS + GISP_MEAUSRE_TOOL,
            "GISPlanning_MapUtilities_Ruler", GISPlanning_MapUtilities_AssociateObjWithEvent(me, "_AddMeasureControlWhenLoaded"));
            myScriptLoader.Load();
        };

        //add the print button
        var myPrintFunction = function() {
            GISP_MapUtilities_PrintMap();
            me._functionControls.ResetHandAsActiveButton();
        };
        var myPrintControl = MapBar_CreateFunctionControl(GISP_LOCATION_IMAGES + "print_active.png", GISP_LOCATION_IMAGES + "print_inactive.png", "Print Current Map", myPrintFunction, null);
        me._functionControls.AddControl(myPrintControl, "PRINT");

        //raise the loaded event
        GEvent.trigger(me._loadedEvent, "Raised");
    };         //end function initializeMap


    this._HandleMapClicks = function(pOverlay, pPoint) {

        //determine what was clicked on
        var myClickObjectType = null;

        if (pOverlay) {
            if (pOverlay instanceof GMarker) {
                myClickObjectType = "MARKER";
            } else if (pOverlay instanceof GPolygon) {
                myClickObjectType = "POLYGON";
            } else if (pOverlay instanceof GPolyline) {
                myClickObjectType = "POLYLINE";
            };
        };
        if (!pOverlay && pPoint) {
            myClickObjectType = "MAP";
        }; //end if not overlay and point

        //if you click on a polygon, its possible the point is null, check the second argument
        if (pPoint == null && myClickObjectType == "POLYGON") {
            if (arguments.length >= 3) {
                if (arguments[2].x != null && arguments[2].y != null) {
                    pPoint = arguments[2];
                }; //end if argument 2 is a point
            }; //end if there is a third argument
        }; //end if point is null

        //based on the map mode, process the click event
        if (me._GetMapMode() == 'IDENTIFY' && (myClickObjectType == "MAP" || myClickObjectType == "POLYGON")) {
            me._identifyControl.Identify(pOverlay, pPoint);
        } //end if mode polydraw
        else if (me._GetMapMode() == 'STREET') {
            if (myClickObjectType == "MAP") {
                me._streetViewController.MapClicked(pOverlay, pPoint);
            }; //end if object type map
        }; //end if mode street
    };     //end click handler function


    this._SetMarkers = function(pMarkers) {
        me._markers = pMarkers;
        if (me._polySelectControl != null) {
            me._polySelectControl.SetFilterMarkers(pMarkers);
        }; //end if poly control not null
    }; //end set markers

    this._GetMarkers = function() {
        return me._markers;
    }; //end get markers

    this._GetMap = function() {
        return me._map;
    }; //end function get map

    this._GetPolySelectControl = function() {
        return me._polySelectControl;
    }; //end function

    this._GetFunctionControl = function() {
        return me._functionControls;
    }; //end method

    //CONSTRUCTOR**************************************************************
    return new function() {
        //create the map opject
        me._map = new GMap2(me._mapDIV, { googleBarOptions: me._googleSearchBarOptions });
        
        //set the default UI options
        var myUIOptions = me._map.getDefaultUI();
        myUIOptions.zoom.scrollwheel = false;
        myUIOptions.controls.maptypecontrol = false;
        me._map.setUI(myUIOptions);


        this.map = me._map;
        this.SetMarkers = me._SetMarkers;
        this.GetMarkers = me._GetMarkers;
        this.LoadedEvent = me._loadedEvent;

        this.PolygonDrawer = me._GetPolySelectControl;
        this.FunctionControl = me._GetFunctionControl;


        var myScriptLoader = new GISPlanning_MapUtilities_ScriptLoader(GISP_LOCATION_SCRIPTS + GISP_UTILITIES, "GISPlanning_MapUtilities_AssociateObjWithEvent", me._Initialize);
        myScriptLoader.Load();

    };   //end constructor
}; //end mapbar definition


//declare prototype methods****************************************************
MapBar.prototype._GetMapMode = function() {
    return this._functionControls.GetActiveFunction();
};
MapBar.prototype._SetMapMode = function(pMapMode) {
    this._functionControls.SetActiveFunction(pMapMode);
};
MapBar.prototype._SetMapType = function(sender, e, args) {
    //reset the map mode
    this._SetMapMode("MAP");


    //remove streetview if it is there
        if (args != "STREET" && this._streetViewController != null) {
        this._streetViewController.StopStreetView();
    }; //end if streetview Controller not null


    //figure out what to do.....
    if (args == "STREET") {
        this._SetMapMode("STREET");
        this._streetViewController.ToggleStreetViewOverlay();
    }
    else if (args.getName() == "Earth") {
        this._StartEarth();
    }
    else {
        this._map.setMapType(args);
    }; //end if elseif else block
}; //end function SetMapType



MapBar.prototype._SetGoogleEarthObject = function(obj) {
    this._googleEarth = obj;
    this._googleEarthAdded = true;
    this._StartEarth();
};

MapBar.prototype._StartEarth = function() {
    if(this._googleEarthAdded == false){
        this._map.addMapType(G_SATELLITE_3D_MAP);
        this._googleEarth = this._map.getEarthInstance(GISPlanning_MapUtilities_AssociateObjWithEvent(this, "_SetGoogleEarthObject"));
    }
    else{
        this._map.setMapType(G_SATELLITE_3D_MAP);
        //this._localLayerController.UIControl.Hide();
        this._googleEarthMode = true;
    }
    
};  //end method start earch






//DRAG ZOOM********************************************************************
MapBar.prototype._AddDragZoomControlWhenLoaded = function() {

    var myDragEndCallback = GISPlanning_MapUtilities_AssociateObjWithEvent(this._functionControls, "ResetHandAsActiveButton");

    //create the control and add it to the page and mapbar function collection
    var myDragZoomControl = new DragZoomControl({ opacity: .2, border: "2px solid red" }, { buttonZoomingHTML: "Click and drag to outline a region on the map.", buttonStartingStyle: { display: 'none' }, buttonZoomingStyle: { display: 'block', background: '#ff0', padding: '5px', height: '24px' }, overlayRemoveTime: 500 }, { dragend: myDragEndCallback });
    this._dragZoomControl = myDragZoomControl
    //here we need to create an event handler bound to the actual instance of the control, this is done with a little magic...
    var myDragZoomInstanceOfInitiateZoom = GISPlanning_MapUtilities_AssociateObjWithEvent(this._dragZoomControl, "initiateZoom")

    var myDragFunctionControl = new MapBar_CreateFunctionControl(GISP_LOCATION_IMAGES + "search_active.png",
            GISP_LOCATION_IMAGES + "search_inactive.png",
            "Zoom to a selected area", myDragZoomInstanceOfInitiateZoom, null);

    //because this is special control initself, we need to add it to the map (it should not physically look like anything until its activated)
    this._map.addControl(myDragZoomControl, new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(0, 0)));

    //now add the function button
    this._functionControls.AddControl(myDragFunctionControl, "DRAG");

}; //end add drag zoom when loaded


//POLY SELECT******************************************************************
MapBar.prototype._AddPolyZoomControlWhenLoaded = function() {

    //create a new polydrawer object and associate it with the bar
    var myPolyCancelEventhandler = GISPlanning_MapUtilities_AssociateObjWithEvent(this._functionControls, "ResetHandAsActiveButton"); //lets the bar reset the hand
    var myPolyDrawer = new GISPlanning_MapUtilities_PolygonDrawer(this._map, this._markers,
           this._tooltipService, this._PolySelectedHandler, myPolyCancelEventhandler, this._PolyStartedHandler);
    this._polySelectControl = myPolyDrawer;

    //create a closure around the start and stop methods
    var myInstanceOfStartShape = GISPlanning_MapUtilities_AssociateObjWithEvent(this._polySelectControl, "StartShape")
    var myInstanceOfStopShape = GISPlanning_MapUtilities_AssociateObjWithEvent(this._polySelectControl, "StopEditing")

    var myPolyFunctionControl = new MapBar_CreateFunctionControl(GISP_LOCATION_IMAGES + "shape_active.png",
            GISP_LOCATION_IMAGES + "shape_inactive.png",
            "Filter an area by drawing a shape around it", myInstanceOfStartShape, myInstanceOfStopShape);

    //now add the function button
    this._functionControls.AddControl(myPolyFunctionControl, "POLY");

};   //end add poly when loaded


//LOCAL LAYER CONTROLLER*******************************************************
MapBar.prototype._AddLocalWhenESRILoaded = function() {
    var myScriptLoader = new GISPlanning_MapUtilities_ScriptLoader(
            GISP_LOCATION_SCRIPTS + GISP_LOCAL_LAYER_CONTROLLER,
            "GISPlanning_MapUtilities_LocalLayerController", GISPlanning_MapUtilities_AssociateObjWithEvent(this, "_AddLocalDataWhenLoaded"));
    myScriptLoader.Load();
};  //end add api when loaded

MapBar.prototype._AddLocalDataWhenLoaded = function() {
    this._localLayerController = new GISPlanning_MapUtilities_LocalLayerController(this._map, this._localOptions);
    this._map.addControl(this._localLayerController.UIControl);
};    //end add local when loaded


//IDENTIFY*********************************************************************
MapBar.prototype._AddIdentifyControlWhenLoaded = function() {
    this._identifyControl = new GISPlanning_MapUtilities_Identify(this._map, this._tooltipService);

    var myActivateCallback = GISPlanning_MapUtilities_AssociateObjWithEvent(this._identifyControl, "Start");
    var myDeactivateCallback = GISPlanning_MapUtilities_AssociateObjWithEvent(this._identifyControl, "Stop");
    var activeImage = GISP_LOCATION_IMAGES + "info_active.png";
    var inactiveImage = GISP_LOCATION_IMAGES + "info_inactive.png";
    var tootip = "Get information about a point on the map including lat, lng, reverse geocode and local information";

    var myFunctionControl = new MapBar_CreateFunctionControl(activeImage, inactiveImage, tootip, myActivateCallback, myDeactivateCallback);

    //now add the function button
    this._functionControls.AddControl(myFunctionControl, "IDENTIFY");
};    //end add identify control when loaded


//MEASURE**********************************************************************
MapBar.prototype._AddMeasureControlWhenLoaded = function() {
    var myMeasureCancelEventhandler = GISPlanning_MapUtilities_AssociateObjWithEvent(this._functionControls, "ResetHandAsActiveButton"); //lets the bar reset the hand

    this._measureControl = new GISPlanning_MapUtilities_Ruler(this._map, this._tooltipService, myMeasureCancelEventhandler);

    var myActivateCallback = GISPlanning_MapUtilities_AssociateObjWithEvent(this._measureControl, "EnableDrawing");
    var myDeactivateCallback = GISPlanning_MapUtilities_AssociateObjWithEvent(this._measureControl, "StopDrawing");
    var activeImage = GISP_LOCATION_IMAGES + "line_active.png";
    var inactiveImage = GISP_LOCATION_IMAGES + "line_inactive.png";
    var tootip = "Measure distances on the map";

    var myFunctionControl = new MapBar_CreateFunctionControl(activeImage, inactiveImage, tootip, myActivateCallback, myDeactivateCallback);

    //now add the function button
    this._functionControls.AddControl(myFunctionControl, "MEASURE");
};    //end add measure when loaded


//STREET VIEW******************************************************************
MapBar.prototype._AddStreetViewWhenLoaded = function() {
    this._streetViewController = new GISPlanning_MapUtilities_StreetViewController(this._map,
        this._streetViewOptions.PanoDiv, this._streetViewOptions.HideFunction, this._streetViewOptions.ShowFunction, GISPlanning_MapUtilities_AssociateObjWithEvent(this._functionControls, "ResetHandAsActiveButton"));
};  //end add measure when loaded





//--------------------------------------FUNCTION BUTTONS-------------------------------------------
/*
The function buttons appear at the top left of the map and are used for map interaction
versus the mode buttons on the left hand side. The function buttons only provide a 
uniform interface for working with whatever custom functionallity we create. 
*/

///
/// This contains methods for working with the collection of buttons
///
function MapBar_FunctionControlCollection(pMap) {
    var me = this;
    this._map = pMap;
    this._leftCoordinateOfNextAvailableMapFunctionButton = 2;
    this._children = []; //this will hold the collection of butons
    this._activeFunction = "HAND";

    this._OnChildClickHandler = function(pSender, pEvent, pArgs) {
        me._activeFunction = pArgs.ControlID;
        me._SetActiveButton(pArgs.ControlID);
    };

    this._AddControl = function(pControl, pID) {
        //set the position
        pControl.left = me._leftCoordinateOfNextAvailableMapFunctionButton;
        pControl.getDefaultPosition = function() { return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(this.left, -27)) };

        //set the control ID
        pControl.ID = pID;

        //incrament the left counter so the next button is added in the correct position
        me._leftCoordinateOfNextAvailableMapFunctionButton += 25;

        //add the control to the map and the child collection
        me._map.addControl(pControl);
        me._children.push(pControl);

        //add a click handler to the control that will notify the collection that a control has been clicked
        var myHandler = GISPlanning_MapUtilities_AssociateObjWithEvent(me, "_OnChildClickHandler", { ControlID: pID });
        AddClickHandler(pControl.Container, myHandler);

    };  //end method

    this._ResetHandAsActiveButton = function() {
        me._SetActiveButton("HAND");
    }; //end decleration

    //cycles thru all the buttons in the collection and calls the SetInactive of all but the desired button, then calls SetActive on the desired button
    this._SetActiveButton = function(pID) {
        var myActiveControl;
        for (var i_sab = 0; i_sab < me._children.length; i_sab++) {
            if (me._children[i_sab].ID == pID) {
                myActiveControl = me._children[i_sab];
            }
            else {
                me._children[i_sab].SetInactive();
            }; //end determining what to do with each button
        }; //end for each control

        //activate the control
        myActiveControl.SetActive();

    };   //end set active button decleration

    this._GetActiveFunction = function() {
        return me._activeFunction
    };
    this._SetActiveFunction = function(pFunction) {
        me._activeFunction = pFunction
    };


    //CONSTRUCTOR**************************************************************
    return new function() {
        this.AddControl = me._AddControl;
        this.ActivateFunction = me._OnChildClickHandler;
        this.ResetHandAsActiveButton = me._ResetHandAsActiveButton;
        this.SetActiveFunction = me._SetActiveFunction;
        this.GetActiveFunction = me._GetActiveFunction;
    };        //end constructorr


};  //end mapbarfunctioncontrols def

function MapBar_CreateFunctionControl(activeImage, inactiveImage, tooltip, clickHandler, cancelHandler) {
    var myControl = new MapBar_FunctionButton(clickHandler, cancelHandler, activeImage, inactiveImage, tooltip);
    return myControl;
}; //end function CreateControl


//Extension to GControl
function MapBar_FunctionButton(pClickHandler, pCancelHandler, pActiveImageURL, pInactiveImageURL, pTooltip) {
    var me = this;
    this._ClickHandler = pClickHandler;
    this._CancelHandler = pCancelHandler;
    this._activeImageURL = pActiveImageURL;
    this._inactiveImageURL = pInactiveImageURL;
    this._backgroundDIV = document.createElement("div");
    this._isActive = false;
    this._tooltip = pTooltip;

    this._SetActive = function() {
        me._backgroundDIV.style.backgroundImage = "url(" + me._activeImageURL + ")";
        if (me._ClickHandler != null) {
            me._ClickHandler();
        }; //end if click handler not null
    }; //end function setActive

    this._SetInactive = function() {
        me._backgroundDIV.style.backgroundImage = "url(" + me._inactiveImageURL + ")";
        if (me._CancelHandler != null) {
            me._CancelHandler();
        }; //end if cancel handler not null
    }; //end decleration of setinactive function


    //create the control
    this._initialize = function(pMap) {
        GISPlanning_MapUtilities_SetHTMLAttributes(me._backgroundDIV.style, {
            backgroundImage: "url(" + me._inactiveImageURL + ")", zIndex: "110",
            width: "23px", height: "23px", cursor: "hand"
        });
        me._backgroundDIV.title = me._tooltip;
        me._backgroundDIV.className = "nonexportable nonpopup"; //indicates it should not be shown in exports or popups

        //add the control to the map
        var myContainer = pMap.getContainer();
        myContainer.appendChild(me._backgroundDIV);

        return me._backgroundDIV;
    };

    //CONSTRUCTOR**************************************************************
    var myControl = new GControl(true, true);

    myControl.SetActive = me._SetActive;
    myControl.SetInactive = me._SetInactive;
    myControl.ClickHandler = me._ClickHandler;
    myControl.CancelHandler = me._CancelHandler;
    myControl.IsActive = me._isActive;
    myControl.Container = me._backgroundDIV;
    myControl.initialize = me._initialize;

    return myControl;

};








//-------------------------------MAP BAR CONTROL
GISPlanning_MapUtilities_MapBarControl = function(pBackgroundColor, pMapBarRef) {
    var me = this;
    this._backgroundColor = pBackgroundColor;
    this._mapBarReference = pMapBarRef;


    this._Initialize = function(map) {
        //Define the HTML of the map bar

        var myMapHeaderContainer = document.createElement("div");
        myMapHeaderContainer.className = "nonexportable nonpopup";
        GISPlanning_MapUtilities_SetHTMLAttributes(myMapHeaderContainer.style, { width: "100%", position: "absolute", top: "-34px", left: "-1px", height: "42px", borderLeft: "solid 1px #59595b", borderRight: "solid 1px #59595b", borderTop: "solid 1px #59595b" });

        var myMapHeaderLower = document.createElement("div");
        GISPlanning_MapUtilities_SetHTMLAttributes(myMapHeaderLower.style, { width: "100%", height: "42px", zIndex: "98", position: "absolute", top: "0px" });
        //set style based on the IE version
        jQuery.each(jQuery.browser, function(i) {
            if (!$.browser.msie || ($.browser.msie && $.browser.version.substr(0, 1) > 6)) {
                GISPlanning_MapUtilities_SetHTMLAttributes(myMapHeaderLower.style, { backgroundImage: "url(" + GISP_LOCATION_IMAGES + "MapBarLower.png)" });
            }; //end if greater than IE6
        });

        var myMapHeader = document.createElement("div");
        GISPlanning_MapUtilities_SetHTMLAttributes(myMapHeader.style, { width: "100%", height: "34px", backgroundColor: me._backgroundColor, textAlign: "right", margin: "auto", zIndex: "100" });
        //set style based on the IE version
        jQuery.each(jQuery.browser, function(i) {
            if (!$.browser.msie || ($.browser.msie && $.browser.version.substr(0, 1) > 6)) {
                GISPlanning_MapUtilities_SetHTMLAttributes(myMapHeader.style, { backgroundImage: "url(" + GISP_LOCATION_IMAGES + "MapBarGr.png)", backgroundRepeat: "repeat-x" });
            }; //end if greater than IE6
        });

        myMapHeaderContainer.appendChild(myMapHeaderLower);
        myMapHeaderContainer.appendChild(myMapHeader);




        //add the map styles
        var myMapStyleHolder = document.createElement("div");
        GISPlanning_MapUtilities_SetHTMLAttributes(myMapStyleHolder.style, { position: "relative", top: "0px" });

        if (me._mapBarReference._isStreetViewEnabled) {
            var myMapStyle_Str = document.createElement("span");
            GISPlanning_MapUtilities_SetHTMLAttributes(myMapStyle_Str, { className: "GISPlanning_MapUtilities_MapBar_MapStyleButton", title: "Click here to enable street view" });
            myMapStyle_Str.style.backgroundImage = "url(" + GISP_LOCATION_IMAGES + "MapType_Street.gif)"
            AddClickHandler(myMapStyle_Str, GISPlanning_MapUtilities_AssociateObjWithEvent(me._mapBarReference, "_SetMapType", "STREET"));
            myMapStyleHolder.appendChild(myMapStyle_Str);
        }; //end if street view

        var myMapStyle_map = document.createElement("span");
        //myMapStyle_map.appendChild(document.createTextNode("Map"));
        GISPlanning_MapUtilities_SetHTMLAttributes(myMapStyle_map, { className: "GISPlanning_MapUtilities_MapBar_MapStyleButton", title: "Click to view the basic map" });
        myMapStyle_map.style.backgroundImage = "url(" + GISP_LOCATION_IMAGES + "MapType_Map.gif)"
        AddClickHandler(myMapStyle_map, GISPlanning_MapUtilities_AssociateObjWithEvent(me._mapBarReference, "_SetMapType", G_NORMAL_MAP));
        myMapStyleHolder.appendChild(myMapStyle_map);

        var myMapStyle_sat = document.createElement("span");
        //myMapStyle_sat.appendChild(document.createTextNode("Satellite"));
        myMapStyle_sat.style.backgroundImage = "url(" + GISP_LOCATION_IMAGES + "MapType_Satellite.gif)"
        GISPlanning_MapUtilities_SetHTMLAttributes(myMapStyle_sat, { className: "GISPlanning_MapUtilities_MapBar_MapStyleButton", title: "Click to view satellite data " });
        AddClickHandler(myMapStyle_sat, GISPlanning_MapUtilities_AssociateObjWithEvent(me._mapBarReference, "_SetMapType", G_HYBRID_MAP));
        myMapStyleHolder.appendChild(myMapStyle_sat);

        if (me._mapBarReference._isTerrainEnabled) {
            var myMapStyle_phy = document.createElement("span");
            //myMapStyle_phy.appendChild(document.createTextNode("Physical"));
            GISPlanning_MapUtilities_SetHTMLAttributes(myMapStyle_phy, { className: "GISPlanning_MapUtilities_MapBar_MapStyleButton", title: "Click to view phsyical location data" });
            myMapStyle_phy.style.backgroundImage = "url(" + GISP_LOCATION_IMAGES + "MapType_Terrain.gif)"
            AddClickHandler(myMapStyle_phy, GISPlanning_MapUtilities_AssociateObjWithEvent(me._mapBarReference, "_SetMapType", G_PHYSICAL_MAP));
            myMapStyleHolder.appendChild(myMapStyle_phy);
        }; //end if terrain

        if (me._mapBarReference._isEarthEnabled) {
            var myMapStyle_ert = document.createElement("span");
            //myMapStyle_phy.appendChild(document.createTextNode("Earth"));
            GISPlanning_MapUtilities_SetHTMLAttributes(myMapStyle_ert, { className: "GISPlanning_MapUtilities_MapBar_MapStyleButton", title: "Click to view in google earth" });
            myMapStyle_ert.style.backgroundImage = "url(" + GISP_LOCATION_IMAGES + "MapType_Earth.gif)"
            AddClickHandler(myMapStyle_ert, GISPlanning_MapUtilities_AssociateObjWithEvent(me._mapBarReference, "_SetMapType", G_SATELLITE_3D_MAP));
            myMapStyleHolder.appendChild(myMapStyle_ert);
        }; // end if earth is enabled




        myMapHeader.appendChild(myMapStyleHolder);



        //add the control to the map
        var container = map.getContainer();
        container.appendChild(myMapHeaderContainer);

        return myMapHeader;
    };       //end initialize of the MapBarControl

    this._GetDefaultPosition = function() {
        return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(0, 0));
    };


    //CONSTRUCTOR**************************************************************
    var myControl = new GControl();
    myControl.getDefaultPosition = me._GetDefaultPosition;
    myControl.initialize = me._Initialize;

    return myControl;
};


function GISPlanning_MapUtilities_ScriptLoader(pScriptURL, pType, pCallback) {
    var me = this;
    this._type = pType;
    this._Callback = pCallback;
    this._LoadScript = function() {
        //append the script
        var myHead = document.getElementsByTagName("head").item(0);
        var myLink = document.createElement("script");
        myLink.setAttribute("src", pScriptURL);
        myLink.setAttribute("type", "text/javascript");
        myHead.appendChild(myLink);

        //verify its loaded
        me._ExecuteCallbackWhenScriptLoaded();
    };   //end method LoadScript

    this._ExecuteCallbackWhenScriptLoaded = function() {
        if (eval("typeof(" + me._type + ") == 'undefined'")) {
            setTimeout(me._ExecuteCallbackWhenScriptLoaded, GISP_TIME_TO_WAIT_WHEN_CHECKING_LOAD_OF_SCRIPT);
        }
        else {
            me._Callback();
        }; //end if loaded
    };  //end function execute when loaded

    //CONSTRUCTOR**************************************************************
    return new function() {
        this.Load = me._LoadScript;
    }; //end constructor
}; //end class Script loader



function GISPlanning_MapUtilities_CreateMarker(point, htmltext, markerType, pOptions) {
    var myIcon = new GIcon();
    var myIconSize = null;
    var myShadowSize = null;
    var myIconAnchor = null;
    var myInfoWindowAnchor = null;
    var myIconURL = null;
    var myIconShadowURL = null;
    var myIconHighlightURL = null;

    var myOptions = { hide: false, title: null, ID: "", Modifier: "" };
    pOptions = pOptions != null ? pOptions : {};
    for (var o in myOptions) {
        if (typeof (pOptions[o]) != "undefined" && pOptions[o] != null) {
            myOptions[o] = pOptions[o];
        }; //end if option was passed in
    }; //end for each option

    // property search (building icon)
    switch (markerType) {
        case "BUILDING":
            myIconSize = new GSize(58, 36);
            myIconShadowSize = new GSize(56, 36);
            myIconAnchor = new GPoint(15, 30);
            myIconInfoWindowAnchor = new GPoint(30, 5);
            myIconURL = "/common/images/pins/multi/multiuse_pin" + myOptions.Modifier + myOptions.ID + ".png";
            myIconShadowURL = "/common/images/pins/multi/multiuse_shadow.png";
            myIconHighlightURL = "/common/images/pins/multi/multiuse_pin_over" + myOptions.ID + ".png";
            break;
        case "PINPOINT":
            myIconSize = new GSize(15, 35);
            myIconShadowSize = new GSize(30, 35);
            myIconAnchor = new GPoint(7, 29);
            myIconInfoWindowAnchor = new GPoint(7, 5);
            myIconURL = GISP_LOCATION_IMAGES + "pushpin.png";
            myIconShadowURL = GISP_LOCATION_IMAGES + "pushpin_shadow.png";
            myIconHighlightURL = GISP_LOCATION_IMAGES + "pushpin.png";
            break;
        case "HOUSING":
            myIconSize = new GSize(15, 35);
            myIconShadowSize = new GSize(30, 35);
            myIconAnchor = new GPoint(7, 29);
            myIconInfoWindowAnchor = new GPoint(7, 5);
            myIconURL = "/common/helpers/pushpinsgenerator.ashx?color=00aeef";
            myIconShadowURL = GISP_LOCATION_IMAGES + "pushpin_shadow.png";
            myIconHighlightURL = null;
            break;
        case "BUSINESS":
            myIconSize = new GSize(15, 35);
            myIconShadowSize = new GSize(15, 35);
            myIconAnchor = new GPoint(7, 29);
            myIconInfoWindowAnchor = new GPoint(7, 5);
            myIconURL = "/common/helpers/pushpinsgenerator.ashx?color=" + myOptions.ID;
            myIconShadowURL = GISP_LOCATION_IMAGES + "pushpin_shadow.png";
            myIconHighlightURL = null;
            break;
        case "COMMUNITY":
            myIconSize = new GSize(58, 35);
            myIconShadowSize = new GSize(58, 35);
            myIconAnchor = new GPoint(18, 35);
            myIconInfoWindowAnchor = new GPoint(18, 5);
            myIconURL = "/common/images/pins/community/community_pin" + myOptions.Modifier + myOptions.ID + ".png";
            myIconShadowURL = "/common/images/pins/community/community_shadow.png";
            myIconHighlightURL = "/common/images/pins/community/community_pin_over" + myOptions.ID + ".png";
            break;
        case "OFFICE":
            myIconSize = new GSize(58, 35);
            myIconShadowSize = new GSize(58, 35);
            myIconAnchor = new GPoint(18, 35);
            myIconInfoWindowAnchor = new GPoint(18, 5);
            myIconURL = "/common/images/pins/office/office_pin" + myOptions.Modifier + myOptions.ID + ".png";
            myIconShadowURL = "/common/images/pins/office/office_shadow.png";
            myIconHighlightURL = "/common/images/pins/office/office_pin_over" + myOptions.ID + ".png";
            break;
        case "INDUSTRIAL":
            myIconSize = new GSize(58, 35);
            myIconShadowSize = new GSize(58, 35);
            myIconAnchor = new GPoint(18, 35);
            myIconInfoWindowAnchor = new GPoint(18, 5);
            myIconURL = "/common/images/pins/industrial/industrial_pin" + myOptions.Modifier + myOptions.ID + ".png";
            myIconShadowURL = "/common/images/pins/insustrial/industrial_shadow.png";
            myIconHighlightURL = "/common/images/pins/industrial/industrial_pin_over" + myOptions.ID + ".png";
            break;
        case "WAREHOUSE":
            myIconSize = new GSize(58, 35);
            myIconShadowSize = new GSize(58, 35);
            myIconAnchor = new GPoint(18, 35);
            myIconInfoWindowAnchor = new GPoint(18, 5);
            myIconURL = "/common/images/pins/warehouse/warehouse_pin" + myOptions.Modifier + myOptions.ID + ".png";
            myIconShadowURL = "/common/images/pins/warehouse/warehouse_shadow.png";
            myIconHighlightURL = "/common/images/pins/warehouse/warehouse_pin_over" + myOptions.ID + ".png";
            break;
        case "LAND":
            myIconSize = new GSize(58, 35);
            myIconShadowSize = new GSize(58, 35);
            myIconAnchor = new GPoint(18, 35);
            myIconInfoWindowAnchor = new GPoint(18, 5);
            myIconURL = "/common/images/pins/land/land_pin" + myOptions.Modifier + myOptions.ID + ".png";
            myIconShadowURL = "/common/images/pins/land/land_shadow.png";
            myIconHighlightURL = "/common/images/pins/land/land_pin_over" + myOptions.ID + ".png";
            break;
        case "CALLCENTER":
            myIconSize = new GSize(58, 35);
            myIconShadowSize = new GSize(58, 35);
            myIconAnchor = new GPoint(18, 35);
            myIconInfoWindowAnchor = new GPoint(18, 5);
            myIconURL = "/common/images/pins/callcenter/callcenter_pin" + myOptions.Modifier + myOptions.ID + ".png";
            myIconShadowURL = "/common/images/pins/callcenter/callcenter_shadow.png";
            myIconHighlightURL = "/common/images/pins/callcenter/callcenter_pin_over" + myOptions.ID + ".png";
            break;
    }; //end switch marker type




    myIcon.iconSize = myIconSize;

    if (myIconShadowSize != null) {
        myIcon.shadowSize = myIconShadowSize;
    }; //end if shadow
    myIcon.iconAnchor = myIconAnchor;
    myIcon.infoWindowAnchor = myIconInfoWindowAnchor;

    var myGIcon = new GIcon(myIcon, myIconURL, null, (myIconShadowURL != null ? myIconShadowURL : null));     // building marker for properties
    var myGMarker = new GMarker(point, { icon: myGIcon, title: myOptions.title, hide: myOptions.hide });
    myGMarker.HTML = htmltext;

    myGMarker.ClickEventHandler = GEvent.addListener(myGMarker, "click", function() {
        this.openInfoWindowHtml(this.HTML);
    });

    if (myIconHighlightURL != null) {
        GEvent.addListener(myGMarker, "mouseover", function() {
            this.setImage(myIconHighlightURL);
        });
        GEvent.addListener(myGMarker, "mouseout", function() {
            this.setImage(this.getIcon().image);
        });
    };

    return myGMarker;
}; //end function createMarker
