/**
 * GmapManager Object
 * Developed for Mootools v1.2.4 and Gmap V3
 *
 * @class GmapManager
 * @author Nicolas Grandgirard <ngrandgirard@agenceinteractive.com>
 * @classDescription append a gmap in a div element
 * @copy Agence Interactive
 */

var MapManager = new Class({

	Implements: [Options, Events],

	/**
	 * Options
	 *
	 */
	options : {
		oGPSCenter			: {
			iLatitude	: 0,
			iLongitude	: 0
		},
		iZoomValue		: 12,
		iMapTypeID		: google.maps.MapTypeId.ROADMAP,
		bScrollWheel	: false
	},

	/**
	 * Constructor
	 *
	 */
	initialize: function( element, options ) {

		this.setOptions(options);

		// set element container
		if( $type(element) == 'element' )
            this.element = element;
        else if( $(element) )
            this.element = $(element);
		else
			throw ('The element use for display map is not valid');

		// set latitude default value
		this.iLatitude = this.options.oGPSCenter.iLatitude;

		// set longitude default value
		this.iLongitude = this.options.oGPSCenter.iLongitude;

		// set zoom default value
		this.iZoomValue = this.options.iZoomValue;

		// set map type
		this.iMapTypeID = this.options.iMapTypeID;

		//Enable or disable scroll on map
		this.bScrollWheel = this.options.bScrollWheel;

		// set hash events
		this.oMapEvents = new Hash();
	},

	/**
	 * Init google map and append it with default value in element
	 *
	 */
	initMap: function()
	{
		// test on div element container for gmap
		if( this.element )
		{
			// instance LatLng object with latitude, longitude value
			var oLatlng = new google.maps.LatLng(
				this.iLatitude,
				this.iLongitude
			);

			// init object with options for gmap
			var aMapOptions = {
				zoom: this.iZoomValue,
				center: oLatlng,
				mapTypeId: this.options.iMapTypeID,
				scrollwheel: this.bScrollWheel
			};

			// instance gmap
			this.oMap = new google.maps.Map(
				this.element,
				aMapOptions
			);

			// add fire event when map loaded ( for gmap V3 we must use bounds_changed event )
			this.oMapEvents.bounds_changed = google.maps.event.addListener(
				this.oMap,
				'bounds_changed',
				this.fireEventMapLoaded.bind(this)
			);
		}
	},

	/**
	 * extend bounds object properties with new marker position
	 *
	 * @param oBoundsMarkers -> google Marker object
	 *
	 * @return void
	 */
	extendBounds: function( oMarkers )
	{
		// set bound with marker
		if( !this.oBounds )
			this.oBounds = new google.maps.LatLngBounds();

		// add marker to oBounds
		this.oBounds.extend( oMarkers.getPosition() );
	},
	
	/**
	 * extend bounds object properties with Lat Lng bound
	 *
	 * @param oLatLngBound -> google Lat Lng bound object
	 *
	 * @return void
	 */
	extendBoundsFromLatLng: function( oLatLngBound )
	{
		// set bound with marker
		if( !this.oBounds )
			this.oBounds = new google.maps.LatLngBounds();

		// add oLatLngBound to oBounds
		if( oLatLngBound instanceof google.maps.LatLng )
			this.oBounds.extend( oLatLngBound );
	},

	/**
	 * set bounds object properties with new marker position
	 *
	 * @param oBounds -> google LatLngBound object
	 * @return void
	 */
	setBounds: function( oLatLngBound )
	{
		// set bound with marker
		if( !oLatLngBound instanceof google.maps.LatLngBounds )
			this.oBounds = new google.maps.LatLngBounds();
		else
			this.oBounds = oLatLngBound;
	},

	/**
	 * reinitialize bounds collection
	 *
	 * @return void
	 */
	reinitializeBounds: function()
	{
		// set bound with marker
		if( this.oBounds )
			this.oBounds = null;
	},

	/**
	 * Sets the maps to fit to the given bounds.
	 *
	 * @return void
	 */
	setCenterWidthBounds: function()
	{
		if( this.oBounds )
			this.oMap.fitBounds( this.oBounds );
	},

	/**
	 * fire event mapLoaded when fireEventMapLoaded is called
	 *
	 */
	fireEventMapLoaded: function()
	{
		google.maps.event.removeListener( this.oMapEvents.bounds_changed );
		this.fireEvent('mapLoaded');
	},

	/**
	 * accessors
	 *
	 */
	getMap: function()
	{
		mReturn = null;

		if( this.oMap )
			mReturn = this.oMap;

		return mReturn	;
	}

});


