/**
 * $Workfile: atolMapSourceManager.js $
 * $Revision: 19 $
 *  $Modtime: 30/10/09 16:43 $
 *   $Author: Peter.goulborn $ 
 * 
 * Class: Astun.iSharemaps.MapSourceManager
 * Provides iSharemaps map source configuration for the extended OpenLayers
 * maps. Instances of this class are created with the 
 * <Astun.iSharemaps.MapSOurceManager> constructor.  
 */

if (!OpenLayers || !Prototype) throw new Error('Dependent library not found');  // Needs to be nicer, possibly iSharemaps-wide library error?

if (!Astun) var Astun = {};
if (!Astun.iSharemaps) Astun.iSharemaps = {};
Astun.iSharemaps.MapSourceManager = Class.create(
{
/**
     * Constructor: Astun.iSharemaps.MapSourceManager
     * Create a new iShareMaps map source manager. This class makes available 
     *    map source configuration information that can be used to configure
     *    other elements in the iSharemaps OpenLayers interfacel.
     *
     * Parameters:
     * url : {String} url of the web service that returns map sources in JSON
     *    format.
     * eventElement: {Object} the HTML element on which custom events will be
     *    fired. 
     */
	'initialize': function( url , eventElement, defaultMapSource ) {
		
		this.url = url;
		this.firstLoad = false;
		this.eventElement = eventElement;
		this.sources = {};
		this.current = {};
		this.sources.ism = $H({});
		this.sources.raster = $H({});
		this.queryHandler = new Astun.JS.Common.QueryHandler ({
			'MapSource': 'ms'
		});
		var urlMapSource = this.queryHandler.getParameter('MapSource');
		var manager = this; //make available in AJAX functions
		
		if ( jQuery ) {		
			this.$eventElement = jQuery( '#' + eventElement.id );
			this.$eventElement.bind('loadMapSource', this, function( evt, name, type, force ) {
				evt.data.loadMapSource( name, type, force );
			})
		}
		
		var successFunc = function (transport) {
			var root =  transport.responseText.evalJSON();
			this.firstLoad = true; //we are loading when page loads
			
			if( this.$eventElement ){
				this.$eventElement.trigger( 'mapSourceLoaded',[ root, 'root', 'iShareMaps' ] );
				jQuery.data(eventElement, "rootMapSource", jQuery.makeArray(root.mapSources));
			}
			
			var msStub = {};
			var mapSources = ( root.logFaultSources && root.logFaultSources.length ) ? root.mapSources.concat( root.logFaultSources ) : root.mapSources;
			while( mapSources.length ) {
					msStub = mapSources.shift();
					this.sources.ism.set(msStub.mapName, Object.extend({'loaded': false}, msStub));
			}
			while( root.baseMapSources.length ) {
					msStub = root.baseMapSources.shift();
					this.sources.raster.set(msStub.mapName, Object.extend({'loaded': false}, msStub));
			}
			var loadMapSourceEvent = function( mapSourceName ) {
				if( !!mapSourceName && this.sources.ism.get( mapSourceName ) ){
					this.loadMapSource( mapSourceName );
				}
				else {
					this.loadMapSource( root.defaultMapSource) ;
				}
			} 
			if( initMapSource = urlMapSource || defaultMapSource ) {
				this.loadMapSource( initMapSource );
			}
			else {
				this.eventElement.fire('astun:loadSetting', {setting: 'mapSource', loadFunction: loadMapSourceEvent.bindAsEventListener(this)});
			}
		
		}
		var options = {
			'method': 'get',
			parameters : {
				'RequestType': 'Json',
				'Type': 'MapSource',
				'ms': 'root'
			},
			onSuccess: successFunc.bindAsEventListener(this)
		};
		var initialRequest = new Ajax.Request(url, options);
		
	},
	'loadMapSource': function( name, type, force ) {
		var type = type || 'ism';
		var mapSource = this.sources[type].get(name);
		
		var loadSuccess = function( mapSource, type, name )
		{
			mapSource.loaded = true;
			this.sources[type].set( mapSource.mapName, mapSource );
			this.current[type] = mapSource;
			if( this.$eventElement ){
				if( type === 'ism' ){
					jQuery.data(this.eventElement, "currentlyActiveMapSource",  name );
				}
				this.$eventElement.trigger( 'mapSourceLoaded',[ mapSource, type, name ] );
			}
			if( type === 'ism' ) {
				this.eventElement.fire('astun:saveSetting', {'setting': 'mapSource', 'value': this.current[type].mapName});
				if( this.firstLoad ) {
					// Old way of doing things, listeners will assume talking about data map source
					this.eventElement.fire('astun:mapSourceLoad', mapSource);
					this.firstLoad = false;
				}
				else {
					var loadBaseMap = function( baseMapName ) {
						var name = mapSource.defaultBaseMap;
						if( baseMapName ) {
							for( var i = 0; i < mapSource.baseMaps.length; i++ ){
								if( mapSource.baseMaps[i] === baseMapName ) {
									name = baseMapName;
									break;
								}
							}
						}
						//load the default base map
						this.loadMapSource( name, 'raster');
						
					}.bind( this );
					
					this.eventElement.fire('astun:loadSetting', {setting: 'baseMap', loadFunction: loadBaseMap});
				}
			} 
			else if( type === 'raster' ) {
				this.eventElement.fire('astun:saveSetting', {'setting': 'baseMap', 'value': this.current[type].mapName});
				
			}
		}.bind(this);
		
		if (!mapSource.loaded && !force) {
			mapSource.loaded = false;
			var successFunc = function (transport) {
				var json =  transport.responseText.evalJSON();
				var mapSource = this.sources[type].get(name);
				Object.extend(mapSource, json);
				loadSuccess( mapSource, type, name );
				
			}
			var failFunc =  function (transport) {
					alert('Failed to load map source!');
					this.eventElement.fire('astun:mapSourceLoadError');
				}
			var options = {
				'method': 'get',
				parameters : {
					'RequestType': 'Json',
					'Type': 'MapSource',
					'ms': name
				},
				onSuccess: successFunc.bindAsEventListener(this),
				onFailure: failFunc.bindAsEventListener(this)
			};
			var msRequest = new Ajax.Request(this.url, options);
		}
		else {
				loadSuccess( mapSource, type, name );
		}
	},
    CLASS_NAME: "Astun.iSharemaps.MapSourceManager"
});
