/**
 * create marker for google map V3
 *
 * @author ngrandgirard@agenceinteractive.com
 * @version 1.0 - 2010-05-05
 * Use mootools 1.2.4
 */
var MapMarker = new Class({

	Implements: [Events, Options],

	/**
	 * Options
	 */
	options : {

		// name of adress
		sAddress : null,

		// GPS coord
		oGPSCoord: {
			iLatitude	: null,
			iLongitude	: null
		},

		// data for custom icon
		oIcon: {
			sIconPath	: null,
			oIconSize	: {
				iWidth 	: null,
				iHeight	: null
			}
		}
	},


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

		// set option
		this.setOptions(options);

		// set icon object
		this.oIcon = this.options.oIcon;

		// set GPS coord in object
		this.oGPSCoord = this.options.oGPSCoord;

		// set adress
		if( this.options.sAddress != null )
			this.sAddress = this.options.sAddress;

		// set marker
		this.oMarker = null;

		// set oIconCustom
		this.oCustomIcon = null;

		// set hash events
		this.oMarkerEvents = new Hash();

		// set unique id from gMarker
		this.iUid = null;

		return this;
	},

	/**
	 * init marker with gmap, custom icon and create marker
	 *
	 * @param oMap -> google map which display marker
	 *
	 * @return void
	 */
	initMarker: function ( oMap )
	{
		if( oMap == null || oMap == 'undefined' )
			throw ('Gmap specified is not valid.');
		if( this.oIcon.sIconPath  != null )
			this.oCustomIcon = this.getCustomMarkerImage();
		this.createMarker( oMap );
	},

	/**
	 * instanciate google marker with value of latitude and longitude or adress
	 * append marker on google map oMap
	 *
	 * @param oMap -> google map which display marker
	 *
	 * @return void
	 */
	createMarker : function( oMap )
	{
		// build marker only when LatLng is ok
		this.addEvent('GPSCoordLoaded', function buildMarker( oLatLng )
		{
			this.removeEvent('GPSCoordLoaded', buildMarker);

			this.oMarker = new google.maps.Marker(
			{
				position: oLatLng,
				map: oMap,
				icon: this.oCustomIcon
			});
			// update id from gmarker
			if( this.iUid == null )
				this.iUid = this.oMarker.__gm_id;
			else
				throw ( 'error unique id for marker with icon ' + this.oMarker.getIcon().Qa );

			this.fireEvent('MarkerAppended');
		});

		// get LatLng object
		if( this.options.oGPSCoord.iLatitude != null && this.options.oGPSCoord.iLongitude != null )
			this.getLatLngByValues(
				this.options.oGPSCoord.iLatitude,
				this.options.oGPSCoord.iLongitude
			);
		else if( this.sAddress != null )
			this.getLatLngCoordByAddress( this.sAddress );
		else
			throw ('Latitude, Longitude and adress name are required.');
	},

	/**
	 * instance google markerImage for custom icon
	 *
	 * @return MarkerImage
	 */
	getCustomMarkerImage: function ()
	{
		// init Size object
		var oSize = null;
		if( this.oIcon.oIconSize.iWidth != null && this.oIcon.oIconSize.iHeight != null )
			oSize = new google.maps.Size(
				this.oIcon.oIconSize.iWidth,
				this.oIcon.oIconSize.iHeight,
				'px', 'px'
			);

		//type du marqueur
		var oReturn = new google.maps.MarkerImage(
			this.oIcon.sIconPath,
			oSize
		);

		return oReturn;
	},

	/**
	 * instance google LatLng
	 *
	 * @param iLatitude -> value of latitude
	 * @param iLongitude -> value of longitude
	 *
	 * @return LatLng google object
	 */
	getLatLngByValues : function( iLatitude, iLongitude )
	{
		oReturn = null;

		if( iLatitude != null && iLongitude != null )
			oReturn = new google.maps.LatLng( iLatitude, iLongitude );
		else
			throw ('Latitude and Longitude values are required.');

		this.fireEvent('GPSCoordLoaded', oReturn);
	},

	/**
	 * get GPScoord with adress
	 *
	 * @return LatLng google object
	 */
	getLatLngCoordByAddress: function ( sAddress )
	{
		var oReturn = null;
		var oGeocoder = new google.maps.Geocoder();

		if( sAddress != null)
			oGeocoder.geocode({address:sAddress}, function( aGeocoderResult, sGeocoderStatus ){

				if( sGeocoderStatus == 'OK')
				{
					if( aGeocoderResult.length > 0 && aGeocoderResult[0] != '' )
						oReturn = aGeocoderResult[0].geometry.location;

					this.fireEvent('GPSCoordLoaded', oReturn);
				}
				else
					throw ( 'error with geocoder ' + sGeocoderStatus );

			}.bind(this));
		else
			throw ('Adress is required.');
	},

	/**
	 * accessor
	 *
	 */
	getGMarker : function()
	{
		return this.oMarker;
	},

	getUid : function()
	{
		return this.iUid;
	}
});

