/*
 * SearchInput : jQuery JavaScript Plugin
 * Copyright (c) 2010 PSA Peugeot Citroën
 * Author: Cedrick HATCHI
 * Date: 2010-05-19
 *
 * Version : 3.0 
 * -> Modification du positionnement de la liste déroulante du MultiAddress
 * -> Ajout du texte par default
 * -> Pas de recherche effectuer quand la zone de saisie est vide ou par defaut
 * -> Ajout du zindex à incrementer dans le cas de popIn
 * -> Modification de la gestion du nombre d'adresse afficher
 * -> Fonctionne avec la version 3 de l'API google
 */
(function($){
    var geocoder ;
    
    var _defaultParameters = {
		culture				:"fr-FR",
        country				:"FR",
        mapCountry			:"Europe",
        addressNotFoundMsg	:"sorry Address not found.",
        classOverEntry		:"on",
        styleEntry			:"overflow-y:scroll;margin-bottom:0px",
        timeLoad			:209,
        defaultText			:"",
        searchInclass		:"",
        addWidth			:0,
        zindex				:'100',
        closeOnClick		:"",
        displayNotFoundMsg  :true,
        replaceAdresse		:true,
        replaceAdresseOnclick:true,
        wrap				:"<span></span>",
        mapBound			:{SWLat:0,SWLng:0,NELat:0,NELng:0},
        nbAddrDisplay		:5,
        callEvent			:'click',
        callback			:function(latitude,longitude){alert(latitude+','+longitude);}
    };
    
    $.fn.searchInput = function(callAction,parameters){
        
        var $e = $(this);
        parameters = $.extend({},_defaultParameters,parameters);
        
        $e.each(function(){
			var $_e = $(this);
			if(parameters.wrap)
			{
				$_e.wrap(parameters.wrap);
            }
            $('#Psa-src-pl-searchIn-multipleAddress').remove();
            $('<div id="Psa-src-pl-searchIn-multipleAddress"></div>').appendTo($('body'));
            var $multipleAddress = $("#Psa-src-pl-searchIn-multipleAddress");
            if(parameters.searchInclass)
            {
				$multipleAddress.addClass(parameters.searchInclass);
            }
            $multipleAddress.attr('style',parameters.styleEntry);
            
            $(document).click(function(){
				$multipleAddress.hide();
				if(parameters.wrap)
				{
					$_e.parent().css('height',null);
				}
				else
				{
					$multipleAddress.css('height',null);
				}
            });
        });
        
        function Contains(Container,value)
        {
			var returnvalue = false;
			
			for( var i =0;i<Container.length;i++)
			{
				
				if(Container[i] == value)
				{
					returnvalue = true;
					break;
				}
			}
			
			return returnvalue;
        }
        
        function GetLocationsForAddressv3(townOrZipCode)
        {
			var $_e = $(this);
			if(!geocoder){geocoder = new google.maps.Geocoder();}
			var addr = townOrZipCode+', '+parameters.mapCountry;
			var geolocRequest = {
				address : addr,
				bounds  : new google.maps.LatLngBounds(new google.maps.LatLng(parameters.mapBound.SWLat,parameters.mapBound.SWLng),new google.maps.LatLng(parameters.mapBound.NELat,parameters.mapBound.NELng)),
				language : parameters.culture
			};
			geocoder.geocode(geolocRequest, function(geocoderResult, geocoderStatus){
				if (geocoderStatus == google.maps.GeocoderStatus.OK) 
				{
					var firstCity = null;
                    var nbCities  = 0;
                    var $multipleAddress = $('#Psa-src-pl-searchIn-multipleAddress');
                    $multipleAddress.empty();
                    $multipleAddress.hide();
                    $_e.parent().css('height',null);
                    function attachEntryClickEvent($entry, latitude, longitude){
                        $entry.mouseover(function() {	
                            $entry.addClass(parameters.classOverEntry);
                        });
                        $entry.mouseout(function() {
                            $entry.removeClass(parameters.classOverEntry);
                        });
                        $entry.click(function() {
							if($("#loadfiltera")!=null){
								$("#loadfiltera").show();
                            }
                            $multipleAddress.css('display', 'none');
                            if(parameters.replaceAdresseOnclick)
                            {
								$_e.val($entry.text());
							}
                            if(parameters.wrap)
							{
								$_e.parent().css('height',null);
							}
							else
							{
								$multipleAddress.css('height',null);
							}
                            parameters.callback(latitude,longitude);
                            
                        });
                    }
					if(geocoderResult.length>1)
					{//Plusieurs résultats retournés pour l'adresse
						var nbCities=0;
						for (var i = 0; i < geocoderResult.length; i++) 
						{ 
							var _country; 
							var _country_name; 
							var _postal_code;
							
							for (j=0;j<geocoderResult[i].address_components.length;j++)
							{
								for (k=0;k<geocoderResult[i].address_components[j].types.length;k++)
								{
									if(geocoderResult[i].address_components[j].types[k]=="country")
									{
										_country = geocoderResult[i].address_components[j].short_name; 
										_country_name= geocoderResult[i].address_components[j].long_name; 
									}
									if(geocoderResult[i].address_components[j].types[k]=="postal_code")
									{
										_postal_code = geocoderResult[i].address_components[j].short_name;
									}
								}
							}
							var location = geocoderResult[i].geometry.location;
							var lat = location.lat();
							var lng = location.lng();				
							if ((_country && _country.toLowerCase() == parameters.country.toLowerCase()) || 
							(!_country && lat >= parameters.mapBound.SWLat && lng >= parameters.mapBound.SWlng && lat <= parameters.mapBound.NElat && lng <= parameters.mapBound.NElng))
							{
									$multipleAddress.append('<p class="Psa-src-pl-entryAddress">'+geocoderResult[i].formatted_address+'</p>');
									attachEntryClickEvent($multipleAddress.children('p:last'), lat, lng);
									nbCities++;
							}
						}
						if(nbCities == 0)
						{
							//pas d'adresse valid.
                            alert(parameters.addressNotFoundMsg);
						}
						else
						{
							var maxHeightParent = $_e.parent().innerHeight();
							var top		= $_e.parent().offset().top;
							var left	= $_e.parent().offset().left;
							var innerWidth	= $_e.parent().innerWidth();
							var width	= $_e.parent().width();
							if(!parameters.wrap)
							{
								maxHeightParent = $_e.innerHeight();
								top				= $_e.offset().top;
								left			= $_e.offset().left;
								innerWidth		= $_e.innerWidth();
								width			= $_e.width();
							}
							if(parameters.addWidth)
							{
								innerWidth += parameters.addWidth;
								width += parameters.addWidth;
							}
                            $multipleAddress.show();
                            if($("#loadfiltera")!=null){
								$("#loadfiltera").hide();
                            }
                            if(parameters.closeOnClick)
							{
								$(parameters.closeOnClick).click(function(){
									$multipleAddress.hide();
									if(parameters.wrap)
									{
										$_e.parent().css('height',null);
									}
									else
									{
										$multipleAddress.css('height',null);
									}
								});
							}
                            //Positionnement
                            $multipleAddress.css('position','absolute');
                            $multipleAddress.css('margin-top',maxHeightParent+'px');
                            $multipleAddress.css('top',''+top+'px');
                            $multipleAddress.css('left',''+left+'px');
                            $multipleAddress.css('width',''+innerWidth+'px');
                            $multipleAddress.css('z-index',parameters.zindex);
                            $multipleAddress.children('p').css('width',''+(width-17)+'px');
                            
                            
                            //var maxHeightEntry = $multipleAddress.children('p:first').innerHeight();
                            var maxHeightEntry = 0;
                            $multipleAddress.children('p').each(function(){
								maxHeightEntry=maxHeightEntry+$(this).innerHeight()+2;
							});
                            var width = $multipleAddress.children('p:first')
                            
                            if(nbCities > parameters.nbAddrDisplay)
							{
								maxHeightEntry	= Math.ceil((maxHeightEntry/nbCities)*parameters.nbAddrDisplay)+10;
								maxHeightParent = ''+(maxHeightParent+maxHeightEntry)+'px';
								maxHeightEntry	= ''+maxHeightEntry+'px';
								$multipleAddress.css('height',maxHeightEntry);
								if(parameters.wrap)
								{
									$_e.parent().css('height',maxHeightParent);
								}
								
							}
							else
							{
								
								maxHeightEntry	= maxHeightEntry+10;
								maxHeightParent = ''+(maxHeightParent+maxHeightEntry)+'px';
								maxHeightEntry	= ''+maxHeightEntry+'px';
								$multipleAddress.css('height',maxHeightEntry);
								if(parameters.wrap)
								{
									$_e.parent().css('height',maxHeightParent);
								}
								
							}
						}		
					}
					else if(geocoderResult.length==1)
					{//un résultat retourné
						var _country; 
						for (var j=0;j<geocoderResult[0].address_components.length;j++)
						{
							for (var k=0;k<geocoderResult[0].address_components[j].types.length;k++)
							{
								if(geocoderResult[0].address_components[j].types[k]=="country")
								{
									_country = geocoderResult[0].address_components[j].short_name; 
								}
							}
						}
				
						var lat = geocoderResult[0].geometry.location.lat();
						var lng = geocoderResult[0].geometry.location.lng();
						if ((_country && _country.toLowerCase() == parameters.country.toLowerCase()) || 
						(!_country && lat >= parameters.mapBound.SWLat 
						&& lng >= parameters.mapBound.SWlng 
						&& lat <= parameters.mapBound.NElat 
						&& lng <= parameters.mapBound.NElng))
						{
							if(parameters.replaceAdresse)
                            {
								$_e.val(geocoderResult[0].formatted_address);
                            }
                            parameters.callback(lat,lng);
						}
						else
						{
							// Pas de ville (globalement ou pour le pays en cours).
                            alert(parameters.addressNotFoundMsg);
						}
					}
					else
					{
						// Pas de ville (globalement ou pour le pays en cours).
                           alert(parameters.addressNotFoundMsg);
					}
				}
				else
				{
					// Pas de ville (globalement ou pour le pays en cours).
                    alert(parameters.addressNotFoundMsg);
				}
			});
		}
        
        function GetLocationsForAddressv2(addr){
            var $_e = $(this);
            if(!geocoder){geocoder = new GClientGeocoder()}
            addr = addr+','+parameters.country+','+parameters.mapCountry;
            //alert('addr: ' + addr);
            if (GBrowserIsCompatible()) {
                geocoder.getLocations(addr,function(response){
                    if(response.Status.code == 200){
                        var firstCity = null;
                        var nbCities  = 0;
                        var $multipleAddress = $('#Psa-src-pl-searchIn-multipleAddress');
                        $multipleAddress.empty();
                        $multipleAddress.hide();
                        $_e.parent().css('height',null);
                        function attachEntryClickEvent($entry, latitude, longitude){
                            $entry.mouseover(function() {	
                                $entry.addClass(parameters.classOverEntry);
                            });
                            $entry.mouseout(function() {
                                $entry.removeClass(parameters.classOverEntry);
                            });
                            $entry.click(function() {
								if($("#loadfiltera")!=null){
									$("#loadfiltera").show();
								}
                                $multipleAddress.css('display', 'none');
                                if(parameters.replaceAdresseOnclick)
                                {
									$_e.val($entry.text());
								}
                                if(parameters.wrap)
								{
									$_e.parent().css('height',null);
								}
								else
								{
									$multipleAddress.css('height',null);
								}
                                parameters.callback(latitude,longitude);
                                
                            });
                        }
                        var ArrayPlaceAddress = new Array();
                        for(var i = 0;i < response.Placemark.length; i++){
							
                            var place = response.Placemark[i];
                            if (place.AddressDetails.Country !=null)
                            {
								if (place.AddressDetails.Country.CountryNameCode.toUpperCase() == parameters.country.toUpperCase()) {
									if (firstCity == null) {
										firstCity = place.address + ';' + place.Point.coordinates[1] + ';' + place.Point.coordinates[0];
									}
									if(!Contains(ArrayPlaceAddress,place.address))
									{
										
										ArrayPlaceAddress.push(place.address);
										nbCities++;
										$multipleAddress.append('<p class="Psa-src-pl-entryAddress">'+place.address+'</p>');
										attachEntryClickEvent($multipleAddress.children('p:last'), place.Point.coordinates[1], place.Point.coordinates[0]);
									}
								}
                            }
                            else
                            {
								//CHA : Google Maps ne renvoie pas les informations Pays pour ce point
								//On compare les coordonées du point retourné par rapport aux limites fixées pour la carte
								if(place.Point !=null &&  place.Point.coordinates != null)
								{
									var lng = place.Point.coordinates[0];
									var lat = place.Point.coordinates[1];
									
									if(lat >= parameters.mapBound.SWLat 
									&& lng >= parameters.mapBound.SWLng 
									&& lat <= parameters.mapBound.NELat 
									&& lng <= parameters.mapBound.NELng)
									{
										//Le point est dans les limites de la cartes
										if (firstCity == null) {
											firstCity = place.address + ';' + place.Point.coordinates[1] + ';' + place.Point.coordinates[0];
										}
										if(!Contains(ArrayPlaceAddress,place.address))
										{
											
											ArrayPlaceAddress.push(place.address);
											nbCities++;
											$multipleAddress.append('<p class="Psa-src-pl-entryAddress">'+place.address+'</p>');
											attachEntryClickEvent($multipleAddress.children('p:last'), place.Point.coordinates[1], place.Point.coordinates[0]);
										}
									}
									
								}
                            }
                        }
                         if (nbCities == 0 && parameters.displayNotFoundMsg) {
                        // Pas de ville (globalement ou pour le pays en cours).
                            alert(parameters.addressNotFoundMsg);
                        }else if(nbCities == 1){
                            var firstCityArgs = firstCity.split(';');
                            if(parameters.replaceAdresse)
                            {
								$_e.val(firstCityArgs[0]);
                            }
                            parameters.callback(firstCityArgs[1], firstCityArgs[2]);
                        }else{
							var maxHeightParent = $_e.parent().innerHeight();
							var top		= $_e.parent().offset().top;
							var left	= $_e.parent().offset().left;
							var innerWidth	= $_e.parent().innerWidth();
							var width	= $_e.parent().width();
							if(!parameters.wrap)
							{
								maxHeightParent = $_e.innerHeight();
								top				= $_e.offset().top;
								left			= $_e.offset().left;
								innerWidth		= $_e.innerWidth();
								width			= $_e.width();
							}
							if(parameters.addWidth)
							{
								innerWidth += parameters.addWidth;
								width += parameters.addWidth;
							}
                            $multipleAddress.show();
                            if($("#loadfiltera")!=null){
								$("#loadfiltera").hide();
                            }
                            if(parameters.closeOnClick)
							{
								$(parameters.closeOnClick).click(function(){
									$multipleAddress.hide();
									if(parameters.wrap)
									{
										$_e.parent().css('height',null);
									}
									else
									{
										$multipleAddress.css('height',null);
									}
								});
							}
                            //Positionnement
                            $multipleAddress.css('position','absolute');
                            $multipleAddress.css('margin-top',maxHeightParent+'px');
                            $multipleAddress.css('top',''+top+'px');
                            $multipleAddress.css('left',''+left+'px');
                            $multipleAddress.css('width',''+innerWidth+'px');
                            $multipleAddress.css('z-index',parameters.zindex);
                            $multipleAddress.children('p').css('width',''+(width-17)+'px');
                            /*.each(function(){
								$(this)
                            });*/
                            
                            //var maxHeightEntry = $multipleAddress.children('p:first').innerHeight();
                            var maxHeightEntry = 0;
                            $multipleAddress.children('p').each(function(){
								maxHeightEntry=maxHeightEntry+$(this).innerHeight()+2;
							});
                            var width = $multipleAddress.children('p:first')
                            
                            if(nbCities > parameters.nbAddrDisplay)
							{
								maxHeightEntry	= Math.ceil((maxHeightEntry/nbCities)*parameters.nbAddrDisplay)+10;
								maxHeightParent = ''+(maxHeightParent+maxHeightEntry)+'px';
								maxHeightEntry	= ''+maxHeightEntry+'px';
								$multipleAddress.css('height',maxHeightEntry);
								if(parameters.wrap)
								{
									$_e.parent().css('height',maxHeightParent);
								}
								/*else
								{
									$_e.next(".Psa-src-pl-multipleAddress").css('height',maxHeightEntry);
								}*/
							}
							else
							{
								
								maxHeightEntry	= maxHeightEntry+10;
								maxHeightParent = ''+(maxHeightParent+maxHeightEntry)+'px';
								maxHeightEntry	= ''+maxHeightEntry+'px';
								$multipleAddress.css('height',maxHeightEntry);
								if(parameters.wrap)
								{
									$_e.parent().css('height',maxHeightParent);
								}
								/*else
								{
									$_e.next(".Psa-src-pl-multipleAddress").css('height',maxHeightEntry);
								}*/
							}
                        }
                    }
                });
            }  
        }  
        if(callAction != null && typeof callAction =='string'){
			$(callAction).each(function(){
				$call = $(this);
				$call.preventDefault();
				$call.bind(parameters.callEvent,function(){
					$e.each(function(){
						if($e.val()&& $e.val()!= parameters.defaultText)
						{
							// Les versions anterieur à la 3 n'ont pas se parametre google.maps.version
							if(google && google.maps && google.maps.version)
							{
								GetLocationsForAddressv3.call(this,$e.val());
							}
							else
							{
								GetLocationsForAddressv2.call(this,$e.val());
							}
						}
					});
					return false;
				});
            });
        }else if(callAction != null && typeof callAction == 'object'){
            callAction.each(function(){
				$call = $(this);
				$call.bind(parameters.callEvent,function(){					
					$e.each(function(){
						if($e.val()&& $e.val()!= parameters.defaultText)
						{
							// Les versions anterieur à la 3 n'ont pas se parametre google.maps.version
							if(google && google.maps && google.maps.version)
							{
								GetLocationsForAddressv3.call(this,$e.val());
							}
							else
							{
								GetLocationsForAddressv2.call(this,$e.val());
							}
						}
					});
					return false;
				});
            });
        }
        return this;
    }
})(jQuery)

