function MapHandler(od, isSatellite, mapOptions) {
	var ZOOM_LEVEL = 13;
	var outputDiv = od;
	var oThis = this;
	var currentLocation;
	var latlng = new google.maps.LatLng(-34.397, 150.644);
	var geocoder = new google.maps.Geocoder();
	var myOptions
	
	if(mapOptions){
		
		myOptions = mapOptions;
	}else{
		if(isSatellite){
			 myOptions = {
				zoom: 2,
				center: latlng,
				mapTypeId: google.maps.MapTypeId.HYBRID
			};
		}else{
			myOptions = {
					zoom: 2,
					center: latlng,
					mapTypeId: google.maps.MapTypeId.ROADMAP
			}
		}
	}
	
	var map ;
	if(outputDiv){
		map= new google.maps.Map(outputDiv, myOptions);
	}
	
	this.addMapEventListener= function (eventName,callbackFun ){
		google.maps.event.addListener(map, eventName, function(event) {	  
			if(event){
			callbackFun(event.latLng)
			}else{
				callbackFun()
			}
			
		})	
}
	
	
	var externalCallback;
	var enddragCallbak; 
	
	var markers = new Array();
	var infoWindows = new Array();
	var zoom_in = false;

	function geocodeCallback(results, status) {

		if (status == google.maps.GeocoderStatus.OK && results.length) {
		
			// You should always check that a result was returned, as it is
			// possible to return an empty results object.
			if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
				currentLocation = results[0];
				if(outputDiv){
					
					map.setCenter(results[0].geometry.location);
					if(zoom_in) {
						map.setZoom(ZOOM_LEVEL);
					}
					else {
						map.fitBounds(results[0].geometry.bounds);
					}
				}
					if(externalCallback) {
			//	alert(currentLocation)
						externalCallback(currentLocation);
						
					}
				
			}
		}
		if(externalCallback) {
			externalCallback(null);
		}
	}
	

	function updateMarkerPosition(latLng) {
		alert( latLng.lat() + " " +   latLng.lng())
	  
	  
	}
	
	
	this.codeAddress = function(address, z, level) {
		
		zoom_in = z;
		if(level){
			ZOOM_LEVEL = level;
		}
		geocoder.geocode( { address: address}, geocodeCallback);
	}
	this.show = function() {
		outputDiv.style.visibility = 'visible';
		if(document.getElementById('mydiv')){
		document.getElementById('mydiv').style.display = "none";
		}
		
	}

	this.hide = function() {
		outputDiv.style.visibility = 'hidden';
		if(document.getElementById('mydiv')){
		document.getElementById('mydiv').style.display = "block";
		}
	}

	this.getCurrentLocation = function() {
		return currentLocation;
	}

	this.setCallback = function(func) {
		externalCallback = func;
	}

	
	this.SetEnddragCallbak = function(func) {
		enddragCallbak = func;
	}
	
	this.setZoomLevel= function (level){
		
		ZOOM_LEVEL = level;
	}
	
	this.addMarker = function(lat, lng, contentString, openInfoWindow, markerImg) {
		
		
		var point = new google.maps.LatLng(lat, lng);
		if(markerImg){
			marker = null;
			marker = new google.maps.Marker({
				position: point,
				map: map,
				icon: markerImg
			
			});
			
			
		}else{
			
			var marker = new google.maps.Marker({
				position: point,
				map: map
			
			});
			
		}
		
		
		markers.push(marker);
	
		var infowindow = new google.maps.InfoWindow({
			content: contentString
		});
		if(openInfoWindow){
			infowindow.open(map,marker);
		}
		infoWindows.push(infowindow);
		
		/*google.maps.event.addListener(infowindow, 'closeclick', function() {
			
			alert(88)
		});*/
		
		google.maps.event.addListener(marker, 'mouseover', function() {
			
			
			for(var i=0; i < infoWindows.length; i++) {
				infoWindows[i].close();
			}
			
			infowindow.open(map,marker);
			
			
		});
		

		google.maps.event.addListener(marker, 'click', function() {
			
			
			for(var i=0; i < infoWindows.length; i++) {
				infoWindows[i].close();
			}
			
			infowindow.open(map,marker);
			
		});
		
		
	}

	
	this.checkResize = function(NotSetOneMarkerCenter){
		
		google.maps.event.trigger(map, 'resize') 
		
		var bounds = new google.maps.LatLngBounds();
		for(var i=0; i < markers.length; i++) {
			bounds.extend(markers[i].position);
		}
		
		if(!NotSetOneMarkerCenter ){
			if(markers.length>0){
				map.setCenter(bounds.getCenter());
			}else{
				map.setCenter(map.getCenter())
			}
			
		}else{
			map.setCenter(map.getCenter())
		}
		
	}
	this.addDragableMarker = function(lat, lng, contentString, markerImage) {
		var point = new google.maps.LatLng(lat, lng);
		
		if(markerImage){
			
			marker = new google.maps.Marker({
				position: point,
				map: map,
				draggable: true,
				title: 'Drag to new location',
				icon: markerImage
			});
		}else{
		
			 marker = new google.maps.Marker({
				position: point,
				map: map,
				draggable: true,
				title: 'Drag to new location'
			});
		}
		
		
		markers.push(marker);
	
		var infowindow = new google.maps.InfoWindow({
			content: contentString
		});

		infoWindows.push(infowindow);

		google.maps.event.addListener(marker, 'click', function() {
			
			
			for(var i=0; i < infoWindows.length; i++) {
				infoWindows[i].close();
			}
			
			infowindow.open(map,marker);
		});
		
		
		  google.maps.event.addListener(marker, 'dragend', function() {
	
			  if(enddragCallbak!=null){
		 
				  enddragCallbak(marker.getPosition());
			  
			  	}
			  });
		
		
		
	}
	
	
	this.selectMarker = function(num) {
		
			//alert(num)
			//alert(infoWindows[num])
		infoWindows[num].open(map,markers[num]);
		
	}

	this.clearMarkers = function() {
		
		for(var i=0; i < infoWindows.length; i++) {
			infoWindows[i].close();
		}
		
		for(var i=0; i < markers.length; i++) {
			markers[i].setMap(null);
		}
		markers = new Array();
		infoWindows=new Array();
	}
	
	if(outputDiv){
		this.hide();
	}

	this.zoomToMarkers = function(notCenter, notResetZoomLevel) {
		
		if(markers.length == 0)
			return;
		var bounds = new google.maps.LatLngBounds();
		for(var i=0; i < markers.length; i++) {
			bounds.extend(markers[i].position);
		}
		if(!notCenter)
		map.setCenter(bounds.getCenter());
		
		if(markers.length == 1) {
			if(!notResetZoomLevel){
				map.setZoom(ZOOM_LEVEL);
			}
		}
		else {
			
			map.fitBounds(bounds);
		}
		
	
	}
	this.setZoom= function (level){
		map.setZoom(level)
	}
	


this.inView = function(lat, lng){
	var point = new google.maps.LatLng(lat, lng);
	if(map.getBounds()){
		return map.getBounds().contains(point);
	}
	
	return false;
	
}

this.getCenter = function(){
	
	return map.getBounds().getCenter();
	
	
}

this.getBounds = function(){
	
	return map.getBounds()
	
	
}
this.setCenter = function(lat,lng){
	var latLng = new google.maps.LatLng(lat, lng);
	
	map.setCenter(latLng);
}

this.getMarkerImage = function(placeState, isSmall){
	
	var image	= new google.maps.MarkerImage('/img/LocationaryImgs/icons/icn_place_generic_grey_sml.png',
		      new google.maps.Size(23, 23),
		      new google.maps.Point(0,0),
		      new google.maps.Point(6, 22));
	
	if(placeState==2){
		
		image	= new google.maps.MarkerImage('/img/LocationaryImgs/icons/icn_place_generic_sml.png',
			      new google.maps.Size(23, 23),
			      new google.maps.Point(0,0),
			      new google.maps.Point(6, 22));
		
		return image ;
	}
	if(placeState==1){
		image	= new google.maps.MarkerImage('/img/LocationaryImgs/icons/icn_place_generic_green_sml.png',
			      new google.maps.Size(23, 23),
			      new google.maps.Point(0,0),
			      new google.maps.Point(6, 22));
		
		return image ;
	}
	
	return image;
}



}





