function Init() {
	movieName = "myFlash";
	inDebug = false;
	showGroups = true;
//	 debugWin;
//	 drawtimer;
//	 icon;
//	 iconcluster;
	 currentView=GBounds(0,0,0,0);
	 CancelMove = false;
//	 arrHouses;
	 FoldZoomLevel = 0;
	 FnewZoomLevel = 0;
	 factors = Array(101138.377393795,
						50569.1886968976,
						25284.5943484488,
						12642.2971742244,
						6321.1485871122,
						3160.5742935561,
						1580.28714677805,
						790.143573389025,
						395.071786694513,
						197.535893347256,
						98.7679466736282,
						49.3839733368141,
						24.691986668407,
						12.3459933342035,
						6.17299666710176,
						3.08649833355088,
						1.54324916677544,
						0.77162458338772);
	FirstAddCall=true;
	
//debug - set indebug at the top of the library
	if (inDebug) debugWin = window.open("", "", "width=500,height=400");

//hook events 
	GEvent.addListener(map, "moveend", moveEnd);
	GEvent.addListener(map, "zoom", Zoom);
	GEvent.addListener(map, "movestart", moveStart);
	GEvent.addListener(map, "move", move);	

// Create the house icons
	icon = new GIcon();
	icon.image = "/images/marker2.png";
//	icon.image = "/images/marker2.png";
	//icon.shadow = "http://www.google.com/mapfiles/shadow50.png";
	icon.iconSize = new GSize(14, 18);
//	icon.shadowSize = new GSize(37, 34);
//	icon.image = "/images/marker.png";
	//icon.shadow = "/images/blank.png";
//	icon.iconSize = new GSize(30,34);
	//icon.shadowSize = new GSize(1, 1);
	icon.iconAnchor = new GPoint(6, 5);
	icon.infoWindowAnchor = new GPoint(6, 1);
	iconcluster = new GIcon();
	iconcluster.image = "/images/iconcluster.png";
//	iconcluster.image = "/images/iconcluster.php";
	//iconcluster.shadow = "/images/blank.png";
	iconcluster.iconSize = new GSize(14, 18);
//	iconcluster.shadowSize = new GSize(1, 1);
	iconcluster.iconAnchor = new GPoint(6, 5);
	iconcluster.infoWindowAnchor = new GPoint(6, 1); 
}

GMap.prototype.addOverlays=function(a){ // still in use but deprecated after google 1.7
        var b=this;
        for (i=0;i<a.length;i++) {
                try {
                        this.overlays.push(a[i]);
                        a[i].initialize(this);
                        a[i].redraw(true);
                } catch(ex) {
                        alert('err: ' + i + ', ' + ex.toString());
                }
        }
        this.reOrderOverlays();

}; 


function thisMovie(movieName) {
  // IE and Netscape refer to the movie object differently.
  // This function returns the appropriate syntax depending on the browser.
  if (navigator.appName.indexOf ("Microsoft") !=-1) {
    return window[movieName]
  } else {
    return document[movieName]
  }
}

function startFlash() {
	setFlashVar('agent',agent);
	thisMovie('myFlash').TGotoFrame("/", 1);
//	thisMovie('myFlash').Play();
}

function setFlashVar(aVar,Value) {
	thisMovie('myFlash').SetVariable(aVar,Value);
}

function addOverlays(arr) {
	for (i=0;i<arr.length;i++) {	
		map.addOverlay(arr[i]);
	}
}

function ClearLog() {
		if (!inDebug) return;
		debugWin.document.open();
		debugWin.document.write("");


}
function Log(msg) {
		if (!inDebug) return;
		debugWin.document.write(msg);
		debugWin.document.write('<BR>');
		//debugWin.document.close();
}

function setFilter(args) {
	MM_showHideLayers('loading','','show')
	arr = args.split(",");
	minBeds = parseInt(arr[0]);
	maxBeds = parseInt(arr[1]);
	minPrice = parseInt(arr[2]);
	maxPrice = parseInt(arr[3]);
	DestroyGroups();
	arrHouses = null;
	arrHouses = Array();
	arrHouses["groups"] = Array();
	count = 0
	for (i=0;i<arrAllHouses.length;i++) {
		if ( (arrAllHouses[i][4]>=minPrice) && (arrAllHouses[i][4]<=maxPrice) && (arrAllHouses[i][5]>=minBeds) && (arrAllHouses[i][5]<=maxBeds) ) { 
			arrHouses.push(arrAllHouses[i]);			
			count++;
		} else {		
			if(arrAllHouses[i][3].visible)	showMarker(arrAllHouses[i][3],false);
		}
	}
	BuildGroups();
	drawtimer = window.setTimeout(addHouses, 100);
}

function loadHouses(args) { //this is the entry point from flash
	Init();
	MM_showHideLayers('loading','','show')
	FnewZoomLevel = map.getZoomLevel();	
	arrHouses = null;
	arrHouses = Array();
	arrHouses["groups"] = Array();

	//alert(args);	
	// array structure
		//[0] - long, [1]-lat, [2]-houseref, [3]-marker pointer, [4] - price, [5] - beds, [6] - initial visibility
		arrAllHouses=eval(args);	
		arrAllHouses["groups"] = Array();	
		var i =0;
		for (i=0; i<arrAllHouses.length; ++i) {
			var point = new GPoint(arrAllHouses[i][0],arrAllHouses[i][1]);		
			var marker = new GMarker(point,icon);		
			marker.visible = false; // if it's showing overlay
			marker.hasOverlay  = false; // if the overlay has been created
			marker.houseref = arrAllHouses[i][2];
			arrAllHouses[i][3] = marker;
			GEvent.addListener(marker, "click", onHouseClick);					
			if (arrAllHouses[i][6]) {
				arrHouses.push(arrAllHouses[i]);
			}	
		}

//	arrHouses = arrAllHouses;
	
	BuildGroups();
	drawtimer = window.setTimeout(addHouses, 100);
}

function onHouseClick(a) {
//	alert(this.point.x);
	html = '<iframe src="prop.php?houseref='+this.houseref+'&agent='+agent+'" scrolling="no" width="200" height="160" FRAMEBORDER=0 style="border:none"></iframe>';
	this.openInfoWindowHtml(html);
}

function onGroupClick(a) {
	//alert(FnewZoomLevel);
	level = FnewZoomLevel-1;
	if (level<0) return;
	map.centerAndZoom(new GPoint(this.point.x, this.point.y), level);
}

function MarkerToOverlay(marker) {
for(var a=0;a<map.overlays.length;a++){
	if (map.overlays[a] == arrHouses[i][3])  return ;
}

}

function CreateGroup(i,j) {
	var group = new tgroup;					
	group.id = arrHouses["groups"].push(group) - 1;
	//Log('Created Group: '+group.id);
	arrHouses[j][3].groupid = group.id;
	arrHouses[i][3].groupid = group.id;	
	group.minX = Math.min(arrHouses[i][3].point.x,arrHouses[j][3].point.x);
	group.maxX = Math.max(arrHouses[i][3].point.x,arrHouses[j][3].point.x);					
	group.minY = Math.min(arrHouses[i][3].point.y,arrHouses[j][3].point.y);
	group.maxY = Math.max(arrHouses[i][3].point.y,arrHouses[j][3].point.y);					
	//Log('min X'+arrHouses[i][3].point.x+' and ' +arrHouses[j][3].point.x+' = '+ group.minX );	
	//Log('min Y'+arrHouses[i][3].point.y+' and ' +arrHouses[j][3].point.y+' = '+ group.minY );						
	//Log('New group: '+arrHouses[i][4]+' and ' +arrHouses[j][4]);							
	return group	
}

function DestroyGroups() {
	for (i=0; i<arrHouses["groups"].length; ++i) {	
		map.removeOverlay(arrHouses["groups"][i].marker);					
		//GEvent.removeListener(arrHouses["groups"][i].marker.listener);		
	}
	arrHouses["groups"] = null;
	arrHouses["groups"]=Array();

}
function BuildGroups () {
	Log('Building groups');
	
	DestroyGroups();
	var zoom = map.getZoomLevel();	

	var view = map.getBoundsLatLng();
	a = (view.maxY - view.minY);//* Math.pow(2, (17-zoom));
	Log('A='+map.container.offsetHeight);
	Log('MinY='+view.minY* Math.pow(2, (17-zoom)));
	Log('MaxY='+view.maxY);
	for (i=0;i<arrHouses.length;++i) {	// init grouping
		arrHouses[i][3].groupid=-1;
		if ( (i>0) && (arrHouses[i-1][3].point.x==arrHouses[i][3].point.x) && (zoom<2)) // on last zoom split houses with same postcode 
		{
//			arrHouses[i-1][3].posX -=5; 
			arrHouses[i][3].point.x +=0.0001; 
		} 		
		arrHouses[i][3].posX = arrHouses[i][3].point.x * factors[zoom]; // pixel coordinates from longitude
		arrHouses[i][3].posY = arrHouses[i][3].point.y * Math.pow(2, (17-zoom)); // pixel coordinates form latitude
	}
	
	var tloops=0; var breakedloops=0;
	for (i=0;i<arrHouses.length;++i) {
	//Log('check:'+i);
	if (arrHouses[i][3].groupid>-1) continue // if already in a group		
			for (c=-1; c<2; c=c+2 ) {
				j=i+c;
				if (j<0 || j>arrHouses.length-1) continue; //reach bounderies
				if (arrHouses[i][3].groupid>-1) continue // if already in a group - joined in previously om the loop
				//Log(j);	
				while (Math.abs(arrHouses[i][3].posX - arrHouses[j][3].posX) < 6)
				{
					if (Math.abs(arrHouses[i][3].posY - arrHouses[j][3].posY) < 6)  
					{ //if close enough to other house																			
						if (arrHouses[j][3].groupid==-1) {  // the matching house doesn't belong to a group create one and join both to it
							CreateGroup(i,j);					
						} else { // if mathing house belongs to a group then join the house to that group
							arrHouses[i][3].groupid = arrHouses[j][3].groupid;
							arrHouses["groups"][arrHouses[j][3].groupid].minX = Math.min(arrHouses[i][3].point.x,arrHouses["groups"][arrHouses[j][3].groupid].minX);
							//Log('GID = '+arrHouses[j][3].groupid);
							//Log('min '+arrHouses[i][3].point.x+' and ' +arrHouses["groups"][arrHouses[j][3].groupid].minX+' = '+ arrHouses["groups"][arrHouses[j][3].groupid].minX );
							//Log('Joining  '+arrHouses[i][4]+':'+i+ 'to ' + arrHouses[j][4]+':'+j);					
							arrHouses["groups"][arrHouses[j][3].groupid].maxX = Math.max(arrHouses[i][3].point.x,arrHouses["groups"][arrHouses[j][3].groupid].maxX);					
							arrHouses["groups"][arrHouses[j][3].groupid].minY = Math.min(arrHouses[i][3].point.y,arrHouses["groups"][arrHouses[j][3].groupid].minY);
							arrHouses["groups"][arrHouses[j][3].groupid].maxY = Math.max(arrHouses[i][3].point.y,arrHouses["groups"][arrHouses[j][3].groupid].maxY);					
						}		
					break;  //house formed a group with the overlaping house or joined it's group				
					}
				j=j+c;	
				if (j<0 || j>arrHouses.length-1) break; //reach boundries					
				} 						  	
			}	
	}
	Log('loops:'+tloops+' breaked '+breakedloops);
	createGroupsOverlay();
}

function createGroupsOverlay () {
	//create group markers
	Log('Groups count:');
	Log(arrHouses["groups"].length);
	var arrGroups  = Array();		
	for (i=0; i<arrHouses["groups"].length; ++i) {
		GX	= (arrHouses["groups"][i].maxX+arrHouses["groups"][i].minX)/2;
		GY	= (arrHouses["groups"][i].maxY+arrHouses["groups"][i].minY)/2;
		Log('gx'+GX+' gy'+GY);		
		var point = new GPoint( GX, GY );		
		var marker = new GMarker(point,iconcluster);
		marker.id = i;
		arrHouses["groups"][i].marker = marker;
		arrGroups.push(marker);
		 // Show this marker's index in the info window when it is clicked
		GEvent.addListener(marker, "click", onGroupClick);		
	}	
	map.addOverlays(arrGroups); //we can afford to add all groups markers at once while they are far less than houses
}


function showMarker(marker,show) {
	marker.display(show); 
	marker.visible = show;		
}

function addHouses() {
	Log('AddHouses');
	CancelMove = false;
	var zoom = map.getZoomLevel();	
	var view = map.getBoundsLatLng();
	
	var x=0; var showing=0;
	var arrMarkers = Array();
	for (i=0; i<arrHouses.length; ++i) {		
		//if not in view skip if there is no marker assigned or delete marker if assigned already
		if (arrHouses[i][0] < view.minX || arrHouses[i][0] > view.maxX || arrHouses[i][1] < view.minY || arrHouses[i][1] > view.maxY) {
		//not in view
			//.. but show overlay	
			if (arrHouses[i][3].groupid>-1) { // if in group hide the whole group
				arrHouses["groups"][arrHouses[i][3].groupid].marker.display(false); //??
			}

			if (arrHouses[i][3].visible) { 
				arrHouses[i][3].display(false); 
				arrHouses[i][3].visible = false;
			};
			continue; 
		// in view	
		} else { 
			// in view and do not show overlay
			showing++;
			if (arrHouses[i][3].groupid>-1) { //in group
				arrHouses["groups"][arrHouses[i][3].groupid].marker.display(true);
				if (arrHouses[i][3].visible) { 
					arrHouses[i][3].display(false); 
					arrHouses[i][3].visible = false;
				}
			} else {						// not in group	
				if (!arrHouses[i][3].visible) { 
					//Log('marker x:'+map.overlays[arrHouses[i][3]]);
					if (!arrHouses[i][3].hasOverlay) {				
						arrMarkers.push(arrHouses[i][3]);					
						x++;
						//hack to replace the use isObject which still has some problems
						arrHouses[i][3].hasOverlay = true;
					} else {					
							arrHouses[i][3].display(true); 	
					}
					arrHouses[i][3].visible = true;
				} 			
			}
		}

	}
	MM_showHideLayers('loading','','hide')			
	map.addOverlays(arrMarkers);
	setFlashVar('nrploted',arrHouses.length);  
	Log('Showing:'+showing+' Added :'+x+' Removed:');
	currentView= view;
}

function moveEnd() {
	
	CancelMove = true;
	// ignore small movements  0.05 currently
	var bounds = map.getBoundsLatLng();
	var movedY = Math.abs((bounds.minY-currentView.minY) / (currentView.maxY-currentView.minY));
	var movedX = Math.abs((bounds.minX-currentView.minX) / (currentView.maxX-currentView.minX));
	Log('Moved '+movedX+'% on X || '+movedY+'% on Y');
	//draw if moved 5% of map
	if (movedX>0.05 || movedY>0.05) 
	{
		MM_showHideLayers('loading','','show')
		drawtimer = window.setTimeout(addHouses, 100);
	}
}

function moveStart() {
	Log('moveStart');
}

function move() {
	Log('moveStart');
}

function Zoom(oldZoomLevel, newZoomLevel) {
	if (oldZoomLevel == newZoomLevel) return;
	FoldZoomLevel = oldZoomLevel;
	FnewZoomLevel = newZoomLevel;
	MM_showHideLayers('loading','','show')
	ClearLog();
	Log('current zoom:' + newZoomLevel+' old zoom:'+oldZoomLevel);	
	BuildGroups();
	// this one triggers moveStart by default

}



//group of consolidated markers
	function tgroup() {
  		this.minX = 0;
  		this.maxX = 0;  
  		this.minY = 0;  
  		this.maxY = 0; 
  		this.id	= -1; 
		this.marker = false;
	}
