var g_map;

function onLoad() {
    if (typeof window.__php_showSpotMap == "function") {
        __php_showSpotMap();
        var e = document.getElementsByTagName("A");
        var onMouseOver = function(event) { if (g_map) g_map.locateOnMapTimeout(Utilities.getEventTarget(event).id.substr(1), 500); }
        var onMouseOut = function(event) { if (g_map) g_map.clearLocateOnMapTimeout(); }
        for (var i = 0; i < e.length; i++) {
            if (e[i].id.length > 0 && e[i].id.match(/^s\d+$/)) {
                Utilities.addEvent(e[i], "mouseover", onMouseOver);
                Utilities.addEvent(e[i], "mouseout", onMouseOut);
            }
        }

        var sl = new SpotLinkSelector("cSelectedSpot");
        g_map.locateCallback = function(id) { sl.select(document.getElementById(g_map.idPrefixSpot + id)); }
        google.maps.event.addListener(g_map.infoWindow, "closeclick", function() { sl.select(null); });
    }
    if (typeof window.__php_showTownMap == "function") {
        __php_showTownMap();
    }
}


//
// SpotLinkSelector
//

function SpotLinkSelector(selectClass) {
    this.selectClass = selectClass;
    this.lastElement = null;
    this.lastClass = null;
}

SpotLinkSelector.prototype.select = function(e) {
    if (this.lastElement) {
        this.lastElement.className = this.className;
    }
    if (e) {
        this.lastElement = e;
        this.lastClass = e.className;
        e.className = this.selectClass;
    }
}

//
// TownMap
//

function TownMap(containerId, imageAccommodation, imageSpot, zoomDefault) {
    this.containerId = containerId;
    this.imageAccommodation = imageAccommodation;
    this.imageSpot = imageSpot;
    this.infoWindow = new google.maps.InfoWindow();
    this.items = [];
    this.length = 0;
    this.latitude = 0;
    this.longitude = 0;
    this.centerType = TownMap.CenterType.Auto;
    this.mapType = google.maps.MapTypeId.ROADMAP;
    this.zoomDefault = zoomDefault;
    this.idPrefixAccommodation = "h";
    this.idPrefixSpot = "s";
    this.map = null;
}

TownMap.MarkerType = {
    Accmmodation           : 0,
    Spot                    : 1
}

TownMap.CenterType = {
    Custom                  : 0,
    Auto                    : 1
}

TownMap.prototype.addMarkerPosition = function(oid, lat, lng, type) {
    var id;
    if (!isNaN(id = parseInt(oid.substring(1), 10))) {
        this.length++;
        this.items[id] = {lat:lat, lng:lng, type:type};
    }
}

TownMap.prototype.showMap = function() {
    if (this.map) {
        return;
    }

    var options = null, bounds = null, id;
    if (this.centerType == TownMap.CenterType.Custom) {
        options = { zoom:this.zoomDefault, center:new google.maps.LatLng(this.latitude, this.longitude), mapTypeId: this.mapType };
    } else {
        if (this.length > 1) {
            bounds = new google.maps.LatLngBounds();
            for (id in this.items) {
                bounds.extend(new google.maps.LatLng(this.items[id].lat, this.items[id].lng));
            }
            options = {mapTypeId: this.mapType}
        } else { // only 1 anchor
            for (id in this.items) {
                options = { zoom:this.zoomDefault, center:new google.maps.LatLng(this.items[id].lat, this.items[id].lng), mapTypeId: this.mapType };
            }
        }
    }

    this.map = new google.maps.Map(document.getElementById(this.containerId), options);
    if (bounds != null) {
        this.map.fitBounds(bounds);
    }
    for (id in this.items) {
        this.items[id].marker = this.createMarker(id, this.map, this.items[id].type == TownMap.MarkerType.Accommodation ? this.imageAccommodation : this.imageSpot, this.items[id].lat, this.items[id].lng, this.items[id].type);
    }
}

TownMap.prototype.createMarker = function(id, map, image, lat, lng, type) {
    var _this = this;
    var marker = new google.maps.Marker({
        position: new google.maps.LatLng(lat, lng),
        map: map,
        icon: image,
        clickable: true
    });
    google.maps.event.addListener(marker, "click", function(event) {
        _this.locateOnMap(id, type);
    });
    return marker;
}

TownMap.prototype.locateOnMap = function(id, type) {
    this.infoWindow.setContent(this.getInfoWindowHTML(id, type));
    this.infoWindow.open(this.map, this.items[id].marker);
}

TownMap.prototype.getInfoWindowHTML = function(id, type) {
    var maxPhones = 2;
    var html = document.getElementById((type == TownMap.MarkerType.Accommodation ? this.idPrefixAccommodation : this.idPrefixSpot) + id).innerHTML;
    html = html.replace(/<span.*<\/span>/i, "").replace(/([+\d\s,]{10,})/, function(match) {
        var array = match.split(",");
        if (array.length > maxPhones) { 
            array.splice(maxPhones);
            return array.join(",");
        }
        return match;
    });
    return "<div style=\"width:400px;\">" + html + "</div>";
}


//
// SpotMap
//

function SpotMap(containerId, imageUrlFormat, markerUrlFormat, linkUrlFormat, linkText, zoomDefault) {
    this.containerId = containerId;
    this.imageUrlFormat = imageUrlFormat;
    this.markerUrlFormat = markerUrlFormat;
    this.linkUrlFormat = linkUrlFormat;
    this.linkText = linkText;
    this.zoomDefault = zoomDefault;
    this.infoWindow = new google.maps.InfoWindow();
    this.items = [];
    this.length = 0;
    this.latitude = 0;
    this.longitude = 0;
    this.centerType = SpotMap.CenterType.Auto;
    this.mapType = google.maps.MapTypeId.ROADMAP;
    this.idPrefixSpot = "s";
    this.map = null;
    this.lastLocatedId = null;
    this.timeoutId = null;
    this.zIndexOnTop = 100000;
    this.locateCallback = null;
}

SpotMap.CenterType = {
    Custom                  : 0,
    Auto                    : 1
}

SpotMap.prototype.addMarkerPosition = function(oid, lat, lng) {
    var id;
    if (!isNaN(id = parseInt(oid.substring(1), 10))) {
        this.length++;
        this.items[id] = {lat:lat, lng:lng};
    }
}

SpotMap.prototype.showMap = function() {
    if (this.map) {
        return;
    }

    var options = null, bounds = null, id;
    if (this.centerType == SpotMap.CenterType.Custom) {
        options = { zoom:this.zoomDefault, center:new google.maps.LatLng(this.latitude, this.longitude), mapTypeId: this.mapType };
    } else {
        if (this.length > 1) {
            bounds = new google.maps.LatLngBounds();
            for (id in this.items) {
                bounds.extend(new google.maps.LatLng(this.items[id].lat, this.items[id].lng));
            }
            options = {mapTypeId: this.mapType}
        } else { // only 1 anchor
            for (id in this.items) {
                options = { zoom:this.zoomDefault, center:new google.maps.LatLng(this.items[id].lat, this.items[id].lng), mapTypeId: this.mapType };
            }
        }
    }

    this.map = new google.maps.Map(document.getElementById(this.containerId), options);
    if (bounds != null) {
        this.map.fitBounds(bounds);
    }
    for (id in this.items) {
        this.items[id].marker = this.createMarker(id, this.map, this.imageSpot, this.items[id].lat, this.items[id].lng);
    }
}

SpotMap.prototype.createMarker = function(id, map, image, lat, lng) {
    var _this = this;
    var marker = new google.maps.Marker({
        position: new google.maps.LatLng(lat, lng),
        map: map,
        icon: this.markerUrlFormat.replace(/\[id\]/gi, id),
        clickable: true
    });
    google.maps.event.addListener(marker, "click", function(event) {
        _this.locateOnMap(id);
    });
    return marker;
}

SpotMap.prototype.locateOnMapTimeout = function(id, msec) {
    var _this = this;
    this.timeoutId = setTimeout(function() { _this.locateOnMap(id); }, msec);
}

SpotMap.prototype.clearLocateOnMapTimeout = function() {
    clearTimeout(this.timeoutId);
}

SpotMap.prototype.locateOnMap = function(id) {
    this.setMarkerOnTop(id);
    this.infoWindow.setContent(this.getInfoWindowHTML(id));
    this.infoWindow.open(this.map, this.items[id].marker);
    if (this.locateCallback) {
        this.locateCallback(id);
    }
}

SpotMap.prototype.setMarkerOnTop = function(id) {
    if (this.lastLocatedId != null) {
        this.items[this.lastLocatedId].marker.setZIndex(undefined);
    }
    this.lastLocatedId = id;
    this.items[id].marker.setZIndex(this.zIndexOnTop);
}

SpotMap.prototype.getInfoWindowHTML = function(id) {
    var name = document.getElementById(this.idPrefixSpot + id).innerHTML;
    var link = "<a href=\"" + this.linkUrlFormat.replace(/\[id\]/gi, id) + "\" class=\"cListingLink\">" + this.linkText + "</a>";
    return "<div><div style=\"float:left; width:68px; height:68px; background-image:url(" + this.imageUrlFormat.replace(/\[id\]/gi, id) + "); background-repeat:no-repeat; margin-right:8px;\" /></div><div style=\"float:left; width:250px;\"><b>" + name + "<br />" + link + "<b/></div></div>";
}


//
// Utilities
//

function Utilities() {
}

Utilities.addEvent = function(o, e, h) {
    if (o.addEventListener) {
        o.addEventListener(e, h, false);
    } else if (o.attachEvent) {
        o.attachEvent("on" + e, h);
    }
}

Utilities.getEventTarget = function(e) {
    return (window.event) ? window.event.srcElement : e.target;
}
