/* 
09.06.2016, barwicki@iz.de 
This module is a self-contained, local dependency-free gmap module. 
It loads dynamically the google-map library, can manage multiple google maps objects
and allows simple operations on the map. It also allows to embed google maps in an iframe.
*/

(function(){
 'use strict';
  
  angular
	.module("iz.gmap", [])
    .constant("GOOGLE_MAPS_API_KEY","AIzaSyCipseDfZUkKPiLN7oNL0wz0idUW49oknQ")
    .run(loadGoogleMapScript)
    .service("LocationService",LocationService)

    
loadGoogleMapScript.$inject=['GOOGLE_MAPS_API_KEY'];
function loadGoogleMapScript(GOOGLE_MAPS_API_KEY){
	 // load google maps when the module is injected
    	var scriptElement = document.createElement("script");	
    	scriptElement.type = "application/javascript";
		scriptElement.src = "https://maps.googleapis.com/maps/api/js?key="+GOOGLE_MAPS_API_KEY;
		scriptElement.id = "googlemapsapiscript";
		document.body.appendChild(scriptElement);
}  
  
  
/* Inject*/
LocationService.$inject = ["$timeout","$window","GOOGLE_MAPS_API_KEY"];
function LocationService($timeout,$window,GOOGLE_MAPS_API_KEY){

  // 10.06.2016, barwicki@iz.de, each google map object will reside in the gmaps object.
  // the key is id of the DOM element, value contains the map.
  var gmaps = {};
  var geocoder;

  
  return {
    geocodeAndPinToGmap : geocodeAndPinToGmap,
    geocodeAddress : geocodeAddress,
  	renderEmbededMap : renderEmbededMap,
    initMap : initMap
  };
  
  
 function initGeocoder(){
    if(geocoder){
  		return geocoder;
  	}	
 	geocoder = new google.maps.Geocoder();
   	return geocoder;
 }
  
  

  
 function setMarkerOnGMap(mapContainerId,lat,lng){
    	var LatLng = { lat: lat, lng: lng };
    	var map = getMap(mapContainerId);
    	map.setCenter(LatLng);
	     var marker = new google.maps.Marker({
       		map: map,
       		position: LatLng,
		 });
 }
  
 function geocodeAndPinToGmap(mapContainerId,addressString){
 	geocodeAddress(addressString,function(err,result){
	  if(err){
	  	return console.error(err);
	  }
		setMarkerOnGMap(mapContainerId,result.lat,result.lng);
	});
 }
  
function geocodeAddress(address,callback){
    if(!callback){
		return console.error("Callback not provided");
	} 
   
   
    if(!address){
		return console.error("Keine Addresse!");
	}
   
    // make url friendly
    address =  makeAddressStringGmapFriendly(address);
   
 	initGeocoder().geocode({'address': address}, function(results, status) {
    if (status === google.maps.GeocoderStatus.OK) {
	  
	  var geoloc = results[0].geometry.location;
      callback(null,{lat: geoloc.lat(), lng:geoloc.lng(), location : geoloc});

    } else {
	  callback('Geocode was not successful for the following reason: ' + status);
    }
  });
   
 } 
  
function createMapInstance(mapContainerElementId) {

	var mapProp = {
    	center:new google.maps.LatLng(51.508742,-0.120850),
    	zoom:15,
	    streetViewControl : false,
	    mapTypeControl : false,
	    panControl : false,
	    scrollwheel: false,
    	mapTypeId:google.maps.MapTypeId.ROADMAP
  	};  
	 
	var mapElement=document.getElementById(mapContainerElementId);
    
  if( null === mapElement ) {
	console.log("map element not found with id",mapContainerElementId)
    return null;
  }
   
    gmaps[mapContainerElementId] = new google.maps.Map(mapElement,mapProp);
	return gmaps[mapContainerElementId];
 }
  
function getMap(mapContainerElementId){
  		return gmaps[mapContainerElementId];
} 
 
function initMap(mapContainerElementId){


  	if(gmaps[mapContainerElementId]){
  		return gmaps[mapContainerElementId];
  	}	
 
  	
	return createMapInstance(mapContainerElementId);
}
 
  
function renderEmbededMap(mapContainerId,addressString){
    if(!addressString){
		return console.error("Keine Addresse für GMAP!");
	}
    addressString =  makeAddressStringGmapFriendly(addressString);
	var embededMapIframe = document.createElement('iframe');
    //var encodedAddressString = encodeURI(addressString);
  	var iframeSrc = 'https://www.google.com/maps/embed/v1/place?q='+addressString+'&key='+GOOGLE_MAPS_API_KEY;
	embededMapIframe.setAttribute('src',iframeSrc);
    embededMapIframe.setAttribute('style',"border:0" );
  	embededMapIframe.setAttribute('width',"100%");
	embededMapIframe.setAttribute('height',400);
  	embededMapIframe.setAttribute('frameborder', 0);
    embededMapIframe.setAttribute("allowfullscreen","");
  	document.getElementById(mapContainerId).appendChild(embededMapIframe);
}  
  
// helper functions
  
 function englishifyGermanSigns(text){
  	return text.replace(/ä/g,"ae").replace(/ö/g,"oe").replace(/ü/g,"ue").replace(/Ä/g,"Ae").replace(/Ö/g,"Oe").replace(/Ü/g,"Ue").replace(/ß/g,"ss");
 }


 function makeAddressStringGmapFriendly(addressString){
	
	if(!addressString){
		return console.error("[iz.gmap] Keine Addresse!");
	}
	
	//addressString =  addressString.split(' ').join('-');
	addressString = englishifyGermanSigns(addressString);

	// for url encoding, barwicki@iz.de
	var specialChars = "!@#$^&%*()=[]\/{}|:<>?,.";
	for (var i = 0; i < specialChars.length; i++) {
    	addressString = addressString .replace(new RegExp("\\" + specialChars[i], 'gi'), '');
	}	
	// remove trimming "-"
   	addressString = addressString.replace(/^-+/g, "");
   
 	return addressString;
  } 
  

}


}());