function ClusterManager( gmap ) {
	this.map = gmap;	
	this.DRAW_TILES = false;
}

ClusterManager.prototype.init = function( tileDimensions ) {
		
	this.tileDimensions = tileDimensions;
	this.calculateTileSize();	
	
	this.clusters = new Array();
	
	this.tiles = new Array();
		
	this.lastClustersHere = new Array();
	this.lastClustersIndex = 0;
	
	this.clear();
}


ClusterManager.prototype.calculateTileSize = function() {
	var mapSize = this.map.getSize();	
	var austrianLatLangStart = new GLatLng( 47.34687159, 14.216308 );
	var pixel = this.map.fromLatLngToDivPixel( austrianLatLangStart );
	pixel.x += mapSize.width;
	pixel.y -= mapSize.height;
	var austrianLatLangEnd = this.map.fromDivPixelToLatLng( pixel );	
	var austianMap = new GLatLngBounds( austrianLatLangStart, austrianLatLangEnd );	
	this.stepx = austianMap.toSpan().lng() / this.tileDimensions.x; 
	this.stepy = austianMap.toSpan().lat() / this.tileDimensions.y;
	this.latBoundary = 0; 
	this.lngBoundary = 0;	
}


ClusterManager.prototype.getGridParametersObject = function() {
	return { gridWidth: this.stepx, 
			 gridHeight: this.stepy, 
			 gridX: this.lngBoundary, 
			 gridY: this.latBoundary };
}

ClusterManager.prototype.addDestination = function( dest, latlang ) {
	if( latlang == null ) {
		latlang = new GLatLng( dest.latitude, dest.longitude );
	}
	
	var clu = this.createClusterForCoordinates( latlang );
	if( !clu.addConditionally( dest, latlang ) ) {
		return false;
	}
	
	return true;
};

ClusterManager.prototype.createClusterForCoordinates = function( latlng ) {	

	var lat = latlng.lat();
	var lng = latlng.lng();	
	var bounds = new GLatLngBounds(
		new GLatLng( lat, lng ), // SW
		new GLatLng( lat, lng )  // NE
	);	
	var clu = new Cluster( bounds, 0, 0 );
	this.addCluster( clu );	
	
	
	
	// this is for cluster-grid ie: 3x3
	x = latlng.lng() - this.lngBoundary;
	x /= this.stepx;
	x = Math.floor(x);
	 
	y = latlng.lat() - this.latBoundary;
	y /= this.stepy;
	y = Math.floor(y);
	
	lat = this.latBoundary + ( y * this.stepy );
	lng = this.lngBoundary + ( x * this.stepx );
	bounds = new GLatLngBounds(
			new GLatLng( lat, lng ), // SW
//			new GLatLng( lat, lng )  // NE
			new GLatLng( lat + this.stepy, lng + this.stepx )	 // NE
	);
	var tile = new Cluster( bounds, 0, 0 );
	this.addTile( tile );
	
	return clu;
}

// tileStuff
ClusterManager.prototype.addTile = function( tile ) {
	if( tile instanceof Cluster ) {
		if( !this.getTileAt( tile.getCenter() ) ) {
			this.tiles.push( tile )

			if( this.DRAW_TILES ) {
				// draw lines arround the tile
				var myBounds = tile.getBounds();
				var sw = this.map.fromLatLngToDivPixel(myBounds.getSouthWest());
				var ne = this.map.fromLatLngToDivPixel(myBounds.getNorthEast());
				
				var top = ne.y;
				var left = sw.x;
				var width = ne.x - sw.x;
				var height = sw.y - ne.y;
				
				var narf = $j( "<div />" );
				narf.addClass( "crazyBox" );
				narf.css( "border", "1px solid #f00" );
				narf.css( "position", "absolute" );
				narf.css( "top", top );
				narf.css( "left", left );
				narf.css( "width", width );
				narf.css( "height", height );
				$j( map.getPane( G_MAP_MAP_PANE ) ).after( narf );	
			}
		
		}		
	}
};

ClusterManager.prototype.getTileAt = function( latlng ) {
	for( var i = 0; i < this.tiles.length; i++ ) { if( this.tiles[i].getBounds().containsLatLng( latlng ) ) { return this.tiles[i]; } }	
	return null; 
};


// clusterStuff
ClusterManager.prototype.addCluster = function( clu ) {
	if( clu instanceof Cluster ) {
		if( !this.getClusterAt( clu.getCenter() ) ) {
			this.clusters.push( clu ); 
		}		
	}
};

ClusterManager.prototype.clusterArraysEqual = function( arr1, arr2 ) {
	if( !( arr1 instanceof Array && arr2 instanceof Array ) ) { return false; }
	if( arr1.length != arr2.length ) { return false; }
	if( arr1.length == 0 ) { return true; }
	if( !( arr1[0] instanceof Cluster && arr2[0] instanceof Cluster ) ) { return false; }
	for( var i = 0; i < arr1.length; i++ ) { if( !( arr1[i].getBounds().equals( arr2[i].getBounds() ) ) ) return false; }	
	return true;
}

ClusterManager.prototype.getClusterButtonAt = function( latlng ) {
	var clustersHere = new Array();
	for( var i = 0; i < this.clusters.length; i++ ) { 
		if( this.clusters[i].isPointInsideButton( latlng ) ) { 
			clustersHere.push( this.clusters[i] ); 
		} 
	}
	if( !this.clusterArraysEqual( this.lastClustersHere, clustersHere ) ) { 
		this.lastClustersHere = clustersHere; 
		this.lastClustersIndex = 0; 
	}
	if( this.lastClustersIndex > ( this.lastClustersHere.length - 1 ) ) { 
		this.lastClustersIndex = 0; 
	}
	if( this.lastClustersHere.length > 0 ) { 		
		var currentClusterIndex = this.lastClustersIndex;
		if( this.lastClustersHere.length > 1 ) { this.lastClustersIndex++; }
		return this.lastClustersHere[currentClusterIndex];
	}
	else { return null; }
}

ClusterManager.prototype.getClusterAt = function( latlng ) {
	for( var i = 0; i < this.clusters.length; i++ ) { if( this.clusters[i].getBounds().containsLatLng( latlng ) ) { return this.clusters[i]; } }	
	return null; 
};

ClusterManager.prototype.getClusters = function() {
	return this.clusters;
};

ClusterManager.prototype.clear = function() { 
	this.clusters = [];
	this.tiles = []; 
	$j( "div.crazyBox" ).remove();
}


