// Namespace utility function
function defineNamespace( namespace )
{
	var names = namespace.split( '.' );
   	var subspace = window;
	for( var i = 0; i < names.length; i++ ) {
    	subspace = subspace[ names[ i ] ] = subspace[ names[ i ] ] || {};
	}
}

// Define namespace
defineNamespace( "ontario.mnr.maps" );


// Define SBEC mapping module
ontario.mnr.maps.flood = function()
{
	// Approximate bounds of Ontario (minus northern extremes)
	var ONTARIO_BOUNDS = new google.maps.LatLngBounds( new google.maps.LatLng( 42, -95 ),
														new google.maps.LatLng( 53, -74 ) );

	var map = null;
	var resources = {};


	// Get resource value for ID
	function getResource( resourceId )
	{
		return resources[ resourceId ];
	}


	// Call this function when the page has been loaded
	function initializeMap()
	{
		var caOverlay = null;
		var districtOverlay = null;
		var caListener = null;
		var districtListener = null;
		var loadingControl = null;

		// Handle loading overlays
		function addOverlays()
		{
			if( caOverlay !== null    && districtOverlay !== null
			&&  caOverlay.hasLoaded() && districtOverlay.hasLoaded() ) {
				google.maps.Event.removeListener( caListener ); 
				google.maps.Event.removeListener( districtListener ); 

				if( caOverlay.loadedCorrectly() && districtOverlay.loadedCorrectly() ) {
					var overlayControl = new ontario.maps.OverlaySelector( [ caOverlay, districtOverlay ] );
					map.addControl( overlayControl );
					loadingControl.setVisible( false );
				}
				else {
					alert( getResource( "dataError" ) );
				}
			}
		}


		var mapDiv = document.getElementById( getResource( "mapDivId" ) );
		if( google.maps.BrowserIsCompatible() && mapDiv ) {
			mapDiv.style.height = "400px";
			mapDiv.style.border = "1px solid black";

			map = new google.maps.Map2( mapDiv );
			map.setMapType( google.maps.NORMAL_MAP );
			map.addControl( new google.maps.LargeMapControl() );
			map.addControl( new google.maps.MapTypeControl( true ) );
			map.addControl( new google.maps.ScaleControl() );
			map.setCenter( ONTARIO_BOUNDS.getCenter(), map.getBoundsZoomLevel( ONTARIO_BOUNDS ) );

			loadingControl = new ontario.maps.MessageControl( getResource( "dataLoading" ) );
			map.addControl( loadingControl );

			google.maps.Event.addDomListener( window, "unload", google.maps.Unload );

			// Catch info window opening and add nice styling to KML content.
			// This uses the undocumented 'infowindowprepareopen' event,
			// which may not work in the future.
			google.maps.Event.addListener( map, "infowindowprepareopen", function( infoWindowTabs )
				{
					var pTags = infoWindowTabs[ 0 ].contentElem.getElementsByTagName( "p" ); 
					for( var i = 0; i < pTags.length; i++ ) {
						pTags[ i ].style.marginTop = "0.7em";
					}
				}
			);
			
			// Setup CA/district overlays
			caOverlay = new google.maps.GeoXml( getResource( "caKmlUrl" ) +
				   											"?nocache=" + ( new Date() ).valueOf() );
			caOverlay.buttonCaption = getResource( "caButtonCaption" );
			caOverlay.buttonWidth = getResource( "caButtonWidth" );
			caListener = google.maps.Event.addListener( caOverlay, "load", addOverlays ); 

			districtOverlay = new google.maps.GeoXml( getResource( "districtKmlUrl" ) +
				   											"?nocache=" + ( new Date() ).valueOf() );
			districtOverlay.buttonCaption = getResource( "districtButtonCaption" );
			districtOverlay.buttonWidth = getResource( "districtButtonWidth" );
			districtListener = google.maps.Event.addListener( districtOverlay, "load", addOverlays ); 
		}
	}


	// Return "public" interface
	return {
		initialize: function( resourcesMap )
			{
				resources = resourcesMap;
				google.maps.Event.addDomListener( window, "load", initializeMap );
			}
	};

} (); // Execute ontario.mnr.maps.flood module definition



// Generic map controls
ontario.maps = function()
{
	// Shared position function
	function positionLeftOfMapTypes()
	{
      return new google.maps.ControlPosition( google.maps.ANCHOR_TOP_RIGHT,
			  									new google.maps.Size( 159, 7 ) );
	}



	// Overlay control object
	OverlaySelector = function( overlays )
	{
		this.overlays = overlays;
	};


	// Prototyped from Google Maps Control
	OverlaySelector.prototype = new google.maps.Control( false, true );


	// Implement initialize routine
	OverlaySelector.prototype.initialize = function( map )
	{
		var currentOverlayIndex = -1;
		var overlays = this.overlays;
		var innerButtons = [];

		// Function closure for handling button clicks
		function addClickHandler( button, overlayIndex )
		{
			google.maps.Event.addDomListener( button, "click", function()
				{
					if( currentOverlayIndex != overlayIndex ) {
						for( var i = 0; i < innerButtons.length; i++ ) {
							innerButtons[ i ].style.borderColor = ( i == overlayIndex ?
								"#345684 #6C9DDF #6C9DDF #345684" : "white #B0B0B0 #B0B0B0 white" );
							innerButtons[ i ].style.fontWeight = ( i == overlayIndex ? "bold" : "normal" );
						}
						if( currentOverlayIndex != -1 ) {
							map.removeOverlay( overlays[ currentOverlayIndex ] );
						}
						map.addOverlay( overlays[ overlayIndex ] );
						currentOverlayIndex = overlayIndex;
					}
				}
			);
		}


		var control = document.createElement( "div" );
		control.style.fontFamily = "Arial, sans-serif";
		control.style.fontSize = "small";
		control.style.height = "18px";

		var i;
		var cummulativeWidths = [ 0 ];
		for( i = 1; i <= this.overlays.length; i++ ) {
			cummulativeWidths[ i ] = cummulativeWidths[ i - 1 ] +
										this.overlays[ this.overlays.length - i ].buttonWidth + 0.1;
		}
		control.style.width = cummulativeWidths[ this.overlays.length ] + "em";


		var firstButton = null;
		for( i = 0; i < this.overlays.length; i++ ) {
			var outerButton = document.createElement( "div" );
			outerButton.style.position = "absolute";
			outerButton.style.right = cummulativeWidths[ this.overlays.length - 1 - i ] + "em";
			outerButton.style.width = this.overlays[ i ].buttonWidth + "em";
			outerButton.style.border = "1px solid black";
			outerButton.style.backgroundColor = "white";
			outerButton.style.textAlign = "center";
			outerButton.style.cursor = "pointer";

			addClickHandler( outerButton, i );
			if( i === 0 ) {
				firstButton = outerButton;
			}


			innerButtons[ i ] = document.createElement( "div" );
			innerButtons[ i ].innerHTML = this.overlays[ i ].buttonCaption;
			innerButtons[ i ].style.borderStyle = "solid";
			innerButtons[ i ].style.borderWidth = "1px";
			innerButtons[ i ].style.borderColor = "white #B0B0B0 #B0B0B0 white";
			innerButtons[ i ].style.fontSize = "12px";

			outerButton.appendChild( innerButtons[ i ] );
			control.appendChild( outerButton );
		}

		google.maps.Event.trigger( firstButton, "click" );

		map.getContainer().appendChild( control );

		return control;
	};


	// Implement default position
	OverlaySelector.prototype.getDefaultPosition = positionLeftOfMapTypes;

	

	// Generic map message box control
	MessageControl = function( content )
	{
		this.content = content;

		this.setVisible = function( visible )
			{
				this.control.style.display = ( visible ? "" : "none" );
			};
	};


	// Prototyped from Google Maps Control
	MessageControl.prototype = new google.maps.Control( false, true );


	// Implement initialize routine
	MessageControl.prototype.initialize = function( map )
	{
		var control = document.createElement( "div" );
		control.style.fontFamily = "Arial, sans-serif";
		control.style.fontSize = "small";
		control.style.height = "18px";

		var container = document.createElement( "div" );
		container.style.border = "1px solid black";
		container.style.color = "black";
		container.style.backgroundColor = "white";

		var content = document.createElement( "div" );
		content.style.border = "1px solid #FFEE99";
		content.style.fontSize = "12px";
		container.style.backgroundColor = "#FFEE99";
		content.style.padding = "0 15px";
		content.innerHTML = this.content;
		
		container.appendChild( content );
		control.appendChild( container );
		map.getContainer().appendChild( control );

		// Store for member functions
		this.control = control;

		return control;
	};


	// Implement default position
	MessageControl.prototype.getDefaultPosition = positionLeftOfMapTypes;



	// Return "public" interface
	return {
		OverlaySelector: OverlaySelector,
		MessageControl: MessageControl
	};

} (); // Execute ontario.maps module definition
