function GMap() {
    this.map;
    this.latlng;
    this.itemsUrl = "/kaart/get-items";
    this.getBuurtUrl = "/kaart/get-buurt"; 
    this.setBuurtUrl =  "/kaart/set-buurt";
    this.resetBuurtUrl = "/kaart/reset-buurt";
    this.options = new Array();
    this.items = new Array();
	this.zoom_level;
	this.address;
    this.config = {
    	options: new Array(),
    	types: new Array(),
    	item: new Array(),
        element: 'google_map',
        latitude: 52.37,
        longitude: 4.9,
		zoom_level: 14,  
        max_zoom : 20,
        min_zoom : 10,
		load_items: true,
		load_buurt: false,
		show_pointer: false
    };
    this.markers = new Array();
    this.currentWindow;
    this.buurt; // polygon
}


// Initieer de instellingen
GMap.prototype.init = function(settings) {
	for (att in settings) this.config[att] = settings[att];
    this.loadMap();
}


// Laad de kaart
GMap.prototype.loadMap = function() {
   
    this.latlng = new google.maps.LatLng(this.config.latitude, this.config.longitude);
	this.zoom_level = this.config.zoom_level;

	var myOptions = {
        zoom: this.zoom_level,
        center: this.latlng,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        navigationControl: 0,
        mapTypeControl: 0,
        scaleControl: 0
    };
    
	
    var element = document.getElementById(this.config.element);
 
    this.map = new google.maps.Map(element, myOptions);
    
	var deze = this;

	// Functie om te kijken of de map al klaar is met laden
	var boundsListener = null; 
	boundsListener = new google.maps.event.addListener(this.map,
        'bounds_changed', function() {
            deze.initializeMap();
            new google.maps.event.removeListener(boundsListener);
    }); 
    
};


GMap.prototype.initializeMap = function(){
	var deze = this;
	if (this.config.load_items) {
		this.loadItems();
		google.maps.event.addListener(this.map, "dragend", function(){
			if (deze.checkOutsideBounds()) {
				deze.removeItems();
				deze.loadItems();
			}
		});
	}
    if (this.config.load_buurt) {
        this.loadBuurt();
    }
    if (this.config.show_pointer) {
        this.showPointer();
    }    
    if (this.config.show_address) {
        this.showAddress();
    }    
}	

// Laat een icoontje zien dat ook nog op een ander plek geprikt kan worden.
GMap.prototype.showPointer = function(type) {
    
	var deze = this;
	
    var newItem = {
			"latitude":this.config.latitude,
			"longitude":this.config.longitude,
			"html":"Nieuw item",
			"type":"new",
			"title":"Nieuw"
		};
    this.printItem(newItem);


    var klik;
	klik = new google.maps.event.addListener(this.map, "click", function(point) {
		if (deze.currentWindow) deze.currentWindow.close();
		deze.removeItems();
        newItem.latitude = point.latLng.lat();
        newItem.longitude = point.latLng.lng();
        deze.printItem(newItem);
        $('input[name=latitude]').attr("value",point.latLng.lat());
        $('input[name=longitude]').attr("value", point.latLng.lng());
		return true;
    });
}

// Check of we buiten het gebied komen waar we de punten van hebben geladen
GMap.prototype.checkOutsideBounds = function() {
    if (this.map.getBounds().getSouthWest().lat() < this.bounds.lat1
    || this.map.getBounds().getSouthWest().lng() < this.bounds.lng1
    || this.map.getBounds().getNorthEast().lat() > this.bounds.lat2
    || this.map.getBounds().getNorthEast().lng() > this.bounds.lng2) {
       return true; 
    }

    return false;
};

// Reken een gebied uit iets groter dan de kaart
GMap.prototype.getOverlapBounds = function() {
    var overlap = (0.008 * 5) * Math.pow(2,-(this.map.getZoom() - 13));
	//var overlap = 0;
    this.bounds = new Array();
    this.bounds.lat1 = this.map.getBounds().getSouthWest().lat() - overlap;
    this.bounds.lng1 = this.map.getBounds().getSouthWest().lng() - overlap;
    this.bounds.lat2 = this.map.getBounds().getNorthEast().lat() + overlap;
    this.bounds.lng2 = this.map.getBounds().getNorthEast().lng() + overlap;
    return this.bounds;
};


// Print items op de kaart 
GMap.prototype.printItems = function (items) {
    for (var item in items) {
        this.printItem(items[item]);
    }
}

// Verwijder items zodat we nieuwe kunnen plaatsen
GMap.prototype.removeItems = function() {
    for (i = 0; i < this.markers.length; i++) {
		this.markers[i].setMap(null);
    }
    this.markers = new Array();
};

// Laad items via Ajax
GMap.prototype.loadItems = function() {
    var deze = this;
    var bounds = this.getOverlapBounds();
    $.getJSON(this.itemsUrl, {
            lat1: bounds.lat1,
            lng1: bounds.lng1,
            lat2: bounds.lat2,
            lng2: bounds.lng2,
            zoom_level: this.zoom_level,
            options: this.config.options,
            types: this.config.types,
            item: this.config.item
        },
        function(items){
    		deze.printItems(items);
        }
    );
}

//Laad items via Ajax
GMap.prototype.flyToItem = function(lat, lng, id) {
	this.map.setCenter(new google.maps.LatLng(lat, lng));
	this.config.item = {id: id};
    this.loadItems();
}


// Print een item op de kaart
GMap.prototype.printItem = function (item) {

    var image = '';
    image = '/images/kaart/iconen/' + item.type + '.png';

    
	var infowindow = new google.maps.InfoWindow({
//        content: item.html + "<hr/><i>" + item.type + ' : ' + item.id + '</i>'
		content: item.html
    });
    
    var latlng = new google.maps.LatLng(item.latitude, item.longitude);
    
    var marker = new google.maps.Marker({
        icon: image,
        position: latlng,
        map: this.map,
        title: item.tooltip
    });
        
    //functie om item te openen op kaart
	var deze = this;
    google.maps.event.addListener(marker, 'click', function() {
		if (deze.currentWindow) deze.currentWindow.close();
        infowindow.open(deze.map, marker);
		deze.currentWindow = infowindow;
		
    });
    this.markers.push(marker);
}

// Zoom de kaart en haal opnieuw items op
GMap.prototype.zoom = function(amount) {
    if (this.map instanceof google.maps.Map) {
        var z = this.zoom_level + amount;
        if (z <= this.config.max_zoom && z >= this.config.min_zoom) {
            this.zoom_level = z;
            this.map.setZoom(this.zoom_level);
			if (this.config.load_items) {
				this.removeItems();
				this.loadItems();
			}
        }
    }
};


/* Selecteren buurt */

GMap.prototype.getMarkingBounds = function(){
	var size = (0.009 * 1) * Math.pow(2, -(this.zoom_level - 13));
	var bounds = new google.maps.LatLngBounds(
        new google.maps.LatLng(
           (this.map.getCenter().lat() - size), 
           (this.map.getCenter().lng() - size)
        ), 
        new google.maps.LatLng(
	      (this.map.getCenter().lat() + size), 
		  (this.map.getCenter().lng() + size)
        )
	);
	return bounds;
}

GMap.prototype.loadBuurt = function() {
	var deze = this;
    $.getJSON(this.getBuurtUrl, function(data){
        var points = new Array();
        for(p in data) {
            points[p] = new google.maps.LatLng(data[p].lat, data[p].lng);
        }
	
	    // Construct the polygon
	    deze.buurt = new google.maps.Polygon({
            paths: points,
            strokeColor: "#27809F",
            strokeOpacity: 1,
            strokeWeight: 1,
            fillColor: "#3B9DBF",
            fillOpacity: 0.4
	    });
	
	   deze.buurt.setMap(deze.map);
	   //deze.map.addOverlay(deze.buurt);
	   deze.buurt.enableEditing();
    })
};


GMap.prototype.saveMarking = function() {
    this.setBuurtUrl;
	var points = new Array(); 
    for (var i = 0; i < this.buurt.getVertexCount(); i++) {
        //var vertex = this.buurt.getVertex(i);
		points[i][lat] = this.buurt.getVertex(i).lat();
        points[i][lng] = this.buurt.getVertex(i).lng();
        //uri += (i > 0 ? "&" : "?") + "points[" + i +  "][lat]=" + vertex.lat() + "&points[" + i + "][lng]=" + vertex.lng();
    }
    $.getJSON(this.setBuurtUrl, points, function (data) {
		notify(data);
	});
};


//Laat een icoontje zien dat ook nog op een ander plek geprikt kan worden.
GMap.prototype.showAddress = function(type) {
    
	var deze = this;
	
    var newItem = {
			"latitude":this.config.latitude,
			"longitude":this.config.longitude,
			"html":"Nieuw item",
			"type":"bericht",
			"title":"Bericht"
		};
    this.printItem(newItem);


    var klik;
	klik = new google.maps.event.addListener(this.map, "click", function(point) {
		if (deze.currentWindow) deze.currentWindow.close();
		deze.removeItems();
		var address = deze.findAddress(point);
        newItem.latitude = point.latLng.lat();
        newItem.longitude = point.latLng.lng();
        newItem.html = "Stuur een bericht aan de bewoners van deze plek.";
        deze.printItem(newItem);
		return true;
    });
}

GMap.prototype.setAddress = function(address) {
	this.address = address[0].formatted_address;
	var number = '';
	var street = '';
	//print_r(address[0]);
	for(var p in address[0].address_components){
		var type = address[0].address_components[p].types[0];
		var str  = address[0].address_components[p].long_name;
		if (type == 'street_number') number =str;
		if (type == 'route') street = str;
	}
	
	if (!$('#straatbericht').attr('id')) {
		$('#google_map2').before('<div id="straatbericht">Bericht aan: '+address +'</div>');
	}	
    ajax_load('/woning/straatbericht?straat='+street+'&nummers='+number+'&adres='+address, null, true)

}

GMap.prototype.getAddress = function(address) {
	return this.address;
}



GMap.prototype.findAddress = function(point){
	var deze = this;
	var geocoder = new google.maps.Geocoder();
	geocoder.geocode({location: point.latLng}, 
	    function(responses) {
		  	if (responses && responses.length > 0) {
		  		deze.setAddress(responses);
		  	} else {
		  		deze.setAddress("");
		  	}
    	}
	);
	
}


function print_r(theObj){
	  if(theObj.constructor == Array ||
	     theObj.constructor == Object){
	    document.write("<ul>")
	    for(var p in theObj){
	      if(theObj[p].constructor == Array||
	         theObj[p].constructor == Object){
	document.write("<li>["+p+"] => "+typeof(theObj)+"</li>");
	        document.write("<ul>")
	        print_r(theObj[p]);
	        document.write("</ul>")
	      } else {
	document.write("<li>["+p+"] => "+theObj[p]+"</li>");
	      }
	    }
	    document.write("</ul>")
	  }
	}



