google.maps.Map.prototype.markers = new Array();
google.maps.Map.prototype.getMarkers = function() {
    return this.markers
};
google.maps.Map.prototype.addMarker = function(marker) {
	this.markers[this.markers.length] = marker;
};
google.maps.Map.prototype.clearMarkers = function() {
	alert(this.markers.length)
	for ( var i = 0; i < this.markers.length; i++) {
			this.markers[i].setMap(null);
	}
	this.markers = new Array();
};
/**
* @param {google.maps.LatLng} newLatLng
* @returns {number}
*/
google.maps.LatLng.prototype.distanceFrom = function(newLatLng) {
    var lat1 = this.lat() * Math.PI / 180.0;
    var lat2 = newLatLng.lat() * Math.PI / 180.0;
    var lngDiff = (newLatLng.lng() - this.lng()) * Math.PI / 180.0;
    return Math.acos(Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos(lngDiff)) * 20902231.0029;
} 

function TrimString(aString) {
    var aSource = "" + aString
    return (aSource.replace(/^\s*/, "")).replace(/\s*$/, "")
}

function CP(a, b, c, e, f, g, h, i, j, k, m, n, o) {
	this.latitude = a
	this.longitude = b
	this.title = c
	this.sabbr = e
	this.paradelocation = f
	this.address1 = g
	this.address2 = h
	this.suburb = i
	this.postcode = j
	this.email = k
	this.phonenumbers = m
	this.uabbr = n,
	this.parading = o
}

var map = null;
var geocoder = null;
var shadow = null;
var clickIcon = null;
var clickMarker = null;
var markers = null;
var selected = null;
var infowindow = null;
var boundsOverlay = null;
var viewportOverlay = null;
var initialized = false;
var hashFragment = "";
var infowindow = new google.maps.InfoWindow();
var geocoder = new google.maps.Geocoder();
var fluster = null;
var markerClusterer = null;
var pathPrefix = "";
var zoomlevelonfind = 15;
var maxzoombeforecluser = 14;
var infoBox = null;

var i0 = "images/collapse.gif"
var i1 = "images/expand.gif"
var closeimg = "images/icon-close.gif"
var flipimg = "images/flip.png"

var gicons = [];

var clusterstyles = [{
	url: 'images/m1.png',
	height: 47,
	width: 47,
	opt_matchpoints: 0,
	opt_anchor: [16, 0],
	opt_textColor: '#000000',
	opt_textSize: 10
  }, {
	url: 'images/m2.png',
	height: 47,
	width: 47,
	opt_matchpoints: 25,
	opt_anchor: [24, 0],
	opt_textColor: '#000000',
	opt_textSize: 11
  }, {
	url: 'images/m3.png',
	height: 47,
	width: 47,
	opt_matchpoints: 50,
	opt_anchor: [32, 0],
	opt_textColor: '#FFFFFF',
	opt_textSize: 12
  }, {
    url: 'images/m4.png',
    height: 69,
    width: 69,
    opt_matchpoints: 100,
    opt_anchor: [32, 0],
    opt_textColor: '#FFFFFF',
    opt_textSize: 12
}]

function BuildMarkerIcons() {
    //image,size,origin,anchor
    gicons["AAFC"] = new google.maps.MarkerImage(pathPrefix + 'images/mp_aafc.png', new google.maps.Size(37, 47), new google.maps.Point(0, 0), new google.maps.Point(18, 44));
    gicons["AAC"] = new google.maps.MarkerImage(pathPrefix + 'images/mp_aac.png', new google.maps.Size(36, 47), new google.maps.Point(0, 0), new google.maps.Point(18, 44));
    gicons["ANC"] = new google.maps.MarkerImage(pathPrefix + 'images/mp_anc.png', new google.maps.Size(37, 47), new google.maps.Point(0, 0), new google.maps.Point(18, 44));
}

function BuildMarkerPoints() {
    if (markerClusterer) {
        markerClusterer.clearMarkers();
    } else {
        BuildMarkerIcons()
        for (var style in clusterstyles) {
            clusterstyles[style].url = pathPrefix + clusterstyles[style].url;
        }
    }
	
	var markers = [];

	var sabbr = jQuery('#unitfinderservice').val();
	for (var i=0;i<CM.length;i++) {
	    if ((sabbr == '') || (CM[i].sabbr == sabbr)) {
			//create the map point
			var marker = new google.maps.Marker({
			  position: new google.maps.LatLng(CM[i].latitude,CM[i].longitude), 
			  map: map, 
			  title:CM[i].title,
			  icon: gicons[CM[i].sabbr],
			  id: i
			});
			//add the click handler
			google.maps.event.addListener(marker, 'click', (function(marker, i) {
			    return function() {
			        var options = {
			            latlng: marker.getPosition(),
			            map: map,
			            content: BuildInfoHTML(i, true),
			            'closeimg': pathPrefix + closeimg,
			            'flipimg': pathPrefix + flipimg
			        }
			        closeAllInfoBoxes()
			        infoBox = new InfoBox(options);
			        infoBox.draw()

			        toggleListInfo(document.getElementById("listinfoimg_" + i), i);
			        CM[i].toggle = true;
			    }
			})(marker, i));
			markers.push(marker);
		}
    }
    markerClusterer = new MarkerClusterer(map, markers, { gridSize: 40, maxZoom: maxzoombeforecluser, styles: clusterstyles, useMatchPoints: true });
}

function BuildInfoHTML(i,showtitle) {
    var sa = new Array();
    if (TrimString(CM[i].address1) != "") {
        sa.push(TrimString(CM[i].address1));
    }
    if (TrimString(CM[i].address2) != "") {
        sa.push(TrimString(CM[i].address2));
    }
    var sb = new Array()
    sb.push("<table class='unitfindertable'>");
    if (showtitle) {
        sb.push("<tr><td colspan='2' class='uftitle'>" + CM[i].sabbr + ": " + CM[i].title + "</td></tr>");
    } else {
        sb.push("<tr><td class='uflabel'>Service:</td><td class='ufdata'>" + CM[i].sabbr + "</td></tr>");
    }
    sb.push("<tr><td class='uflabel'>Location: </td><td class='ufdata'>" + CM[i].paradelocation + "</td></tr>");
    sb.push("<tr><td class='uflabel'>Address: </td><td class='ufdata'>" + sa.join(", ") + "</td></tr>");
    sb.push("<tr><td class='uflabel'>Suburb: </td><td class='ufdata'>" + CM[i].suburb + "</td></tr>");
    sb.push("<tr><td class='uflabel'>Postcode: </td><td class='ufdata'>" + CM[i].postcode + "</td></tr>");
    if (CM[i].phonenumbers != null) {
        for (var idx = 0; idx < CM[i].phonenumbers.length; ) {
            sb.push("<tr><td class='uflabel'>" + CM[i].phonenumbers[idx++] + ": </td><td class='ufdata'>" + CM[i].phonenumbers[idx++] + "</td></tr>");
        }
    }
    sb.push("<tr><td class='uflabel'>Email: </td><td class='ufdata'><a href='mailto:" + CM[i].email + CM_emaildomain + "'>" + CM[i].email + CM_emaildomain + "</a></td></tr>");
    sb.push("<tr><td class='uflabel'>Parading: </td><td class='ufdata'>" + CM[i].parading + "</td></tr>");
    sb.push("<tr><td class='uflabel'>Website: </td><td class='ufdata'><a href='" + CM_baseurl + CM[i].sabbr + "/" + CM[i].uabbr + "'>View unit website</a></td></tr>");
    sb.push("</table>");
    return sb.join("");
}

MarkerClusterer.prototype.done = function() {
    //alert("done")
    var ldiv = jQuery("#map_list");
    if (ldiv) {
        var toggleId = 0;
        var m = new Array();
        for (var i = 0, cluster; cluster = this.clusters_[i]; i++) {
            if (cluster.markers_.length == 1) {
                //alert("found a marker");
                var id = cluster.markers_[0].id;
                m.push("<img class='listinfoimg' src='" + pathPrefix + i1 + "' id='listinfoimg_" + id + "' onclick='toggleListInfo(this," + id + ");' border='0' /><a href='#' onclick='listItemClicked(" + id + ");'>" + CM[id].title + "</a><div class='listinfo' id='listinfo_" + id + "'>" + BuildInfoHTML(id, false) + "</div>");
                if (CM[id].toggle) {
                    toggleId = id;
                }
            }
        }
        ldiv.html(m.join("<br />"));
        if (toggleId > 0) {
            toggleListInfo(document.getElementById("listinfoimg_" + toggleId), toggleId);
        }
    }
}

function toggleListInfo(me, id) {
    if (me) {
        if (me.src.substr(me.src.length - i0.length) != i0) {
            me.src = pathPrefix + i0;
        } else {
            me.src = pathPrefix + i1;
        }
        jQuery("#listinfo_" + id).toggle();
    }
}

function defaultZoom() {
    closeAllInfoBoxes();
    var ne = new google.maps.LatLng(-10.77719, 168)
    var sw = new google.maps.LatLng(-43.0, 112.4)
    var bounds = new google.maps.LatLngBounds(sw, ne);
    map.fitBounds(bounds);
}

function listItemClicked(id) {
    map.setCenter(new google.maps.LatLng(CM[id].latitude, CM[id].longitude));
    map.setZoom(zoomlevelonfind);
}

//geocoder
function showaddr() {
    var address = jQuery('#unitfinderlocation').val()
    var found = 0
    var sb = new Array()
    var lastcoords = null
    address = TrimString(address).toLowerCase();
    if (address != "") {
        var sabbr = jQuery('#unitfinderservice').val();
        //scan hash
        for (var idx = 0; idx < CM.length; idx++) {
			var ma = (CM[idx].postcode.toLowerCase().indexOf(address) != -1) || (CM[idx].uabbr.toLowerCase().indexOf(address) != -1) || (CM[idx].title.toLowerCase().indexOf(address) != -1);
            var ms = ((sabbr == '') || (CM[idx].sabbr == sabbr));
            if (ma &&  ms) {
                found++;
                lastcoords = new google.maps.LatLng(CM[idx].latitude, CM[idx].longitude)
                sb.push("<a id='sr" + idx + "' onclick=" + '"' + "zoomToCoords(" + CM[idx].latitude + "," + CM[idx].longitude + ")" + '">' + CM[idx].title + "</a>");
            }
        }
	    //check geocoder
        if (geocoder) {
            var ne = new google.maps.LatLng(-8, 169)
            var sw = new google.maps.LatLng(-46, 110)
            var bounds = new google.maps.LatLngBounds(sw, ne);

            geocoder.geocode({ 'address': address, 'region': 'au', 'bounds': bounds }, function(results, status) {
                if (status == google.maps.GeocoderStatus.OK) {
                    var lfound = false
                    var lb = "";
                    for (var i in results) {
                        if (bounds.contains(results[i].geometry.location)) {
                            found++;
                            lastcoords = results[i].geometry.location;
                            if (sb.length > 0 && !lfound) {
                                lb = "<hr class='map_narrowsearchsep'>";
                            } else {
                                lb = "";
                            }
                            sb.push(lb + "<a id='sr" + i + "' onclick=" + '"' + "zoomToCoordsGeocoder(" + results[i].geometry.location.lat() + "," + results[i].geometry.location.lng() + ")" + '">' + results[i].formatted_address + "</a>");
                            lfound = true;
                            //break;
                        }
                    }
                }
                if (found == 0) {
                    alert("The search returned no results");
                } else if (found == 1) {
                    searchZoomToCoords(lastcoords, zoomlevelonfind);
                } else if (found > 1) {
                    jQuery('#map_narrowsearchcontent').html(sb.join('<br />'));
                    showFloatingDiv('#map_narrowsearch');
                }
            });
        } else {
            if (found == 0) {
                alert("The search returned no results");
            } else if (found == 1) {
                zoomToCoords(lastcoords, zoomlevelonfind);
            } else if (found > 1) {
                jQuery('#map_narrowsearchcontent').html(sb.join('<br />'));
                showFloatingDiv('#map_narrowsearch');
            }
        }
    }
	BuildMarkerPoints()
}
function searchZoomToCoords(coords, defaultzoom) {
    var clat = coords.lat();
    var clng = coords.lng();
    var sdist = { 'distance': 1000000000, 'index': -1 };
	var sabbr = jQuery('#unitfinderservice').val();
    for (var idx = 0; idx < CM.length; idx++) {
        var ms = ((sabbr == '') || (CM[idx].sabbr == sabbr));
        if (ms) {
            var dist = coords.distanceFrom(new google.maps.LatLng(CM[idx].latitude, CM[idx].longitude));
            if (dist < sdist.distance) {
                sdist.distance = dist;
                sdist.index = idx;
            }
        }
    }


    //work out which quadrant we are in for the math.
    var olat = CM[sdist.index].latitude;
    var olng = CM[sdist.index].longitude;
    var quadrant = -1
    if (clat < olat) {
        if (clng > olng) {
            //A
            quadrant = 0           
            var ne = new google.maps.LatLng(olat, (clng - olng) + clng);
            var sw = new google.maps.LatLng((clat - olat) + clat, olng);
        } else {
            //B
            quadrant = 1
            var ne = new google.maps.LatLng(olat, olng);
            var sw = new google.maps.LatLng((clat - olat) + clat, clng - (olng - clng));
        }
    } else {
        if (clng > olng) {
            //D
            quadrant = 3
            var ne = new google.maps.LatLng(clat - (olat - clat), clng - (olng - clng));
            var sw = new google.maps.LatLng(olat, olng);
        } else {
            //C
            quadrant = 2
            var ne = new google.maps.LatLng(clat - (olat - clat), olng);
            var sw = new google.maps.LatLng(olat, clng - (olng - clng));
        }
    }
    //alert(sdist.distance + "\n" + sdist.index + "\nclat:" + clat + "\nclng:" + clng + "\nolat:" + olat + "\nolng:" + olng + "\nquadrant:" + quadrant + "\n\nne:" + ne + "\nsw:" + sw);
    var bounds = new google.maps.LatLngBounds(sw, ne);
    
    //map.setCenter(coords);
    //map.setZoom(defaultzoom);
    map.fitBounds(bounds);
}
function zoomToCoordsGeocoder(lat, lng) {
    //map.setCenter(new google.maps.LatLng(lat, lng));
    //map.setZoom(zoomlevelonfind);
    searchZoomToCoords(new google.maps.LatLng(lat, lng), zoomlevelonfind)
    closeFloatingDiv('#map_narrowsearch')
    BuildMarkerPoints()
}
function zoomToCoords(lat, lng) {
    map.setCenter(new google.maps.LatLng(lat, lng));
    map.setZoom(zoomlevelonfind);
    //searchZoomToCoords(new google.maps.LatLng(lat, lng), zoomlevelonfind)
    closeFloatingDiv('#map_narrowsearch')
    BuildMarkerPoints()
}
function showFloatingDiv(objname) {
    //deal with selects
    jQuery('select').hide();
    jQuery(objname + ' select').show(); 
    //request data for centering  
    var windowWidth = document.documentElement.clientWidth;  
    var windowHeight = document.documentElement.clientHeight;
    var popupHeight = jQuery(objname).height();
    var popupWidth = jQuery(objname).width();  
    //centering
    jQuery(objname).css({  
        "position": "absolute",  
        "top": windowHeight/2-popupHeight/2,  
        "left": windowWidth/2-popupWidth/2
    });  
    
    //only need force for IE6
    //$("#backgroundPopup").css({"height": windowHeight});
    jQuery(objname).show();    
}
function closeFloatingDiv(objname) {
    jQuery(objname).hide()
    jQuery('select').show();
}
function closeAllInfoBoxes() {
    if (infoBox) {
        infoBox.setMap(null);
        for (var j = 0; j < CM.length; j++) {
            if (CM[j].toggle) {
                toggleListInfo(document.getElementById("listinfoimg_" + j), j);
            }
            CM[j].toggle = false;
        }
    }
}
