/*
 YyMarker version 0.2
 (C)opyright 2006 SWX

 SYNOPSIS
    This implements YyMarkers for YelloYello.com. Based on gxmarker.2.js.
    This version is compatible with Google Maps API Version 2

    A more full-featured marker that supports tooltips and hover events.
    Tooltips are implemented 'outside' the mapping zone. They are child
    of the body element instead of the map element (as is the case with
    all other marker implementation (GxMarker / PdMarker).
   
    Example:
        var marker = new YyMarker(new GLatLng(lat,lng), {options} );

    options are the same as with GMarkers but added:
        tooltip : the div content shown on a mouseover (div gets appended to document.body)
        linkTo : the url to show on marker click
        linkToTarget : _self, _blank, etc..

    TESTED PLATFORMS:
        Linux: Firefox
        Windows: Firefox, IE6
        Mac OS X (Panther): Safari

    There is no warranty of functionality of this code, if you wish to use it
    and it does not work for you, I recommend you submit a patch.  This software
    is licensed under the GNU Lesser General Public License (LGPL):
    the full text at: http://opensource.org/licenses/lgpl-license.php
	
*/

function YyMarkerNamespace() {

var n4=(document.layers);
var n6=(document.getElementById&&!document.all);
var ie=(document.all);
var o6=(navigator.appName.indexOf("Opera") != -1);
var safari=(navigator.userAgent.indexOf("Safari") != -1);
var currentSpan = new GBounds();

function YyMarker( a, b ) {
    // Get the YyMarker options from b
    if (typeof b["tooltip"] != "undefined") {
        this.setTooltip(b["tooltip"]);
        delete(b["tooltip"]);
    }

    if (typeof b["linkTo"] != "undefined") {
        this.setLinkTo(b["linkTo"], b["linkToTarget"]);
        delete(b["linkToTarget"]);
        delete(b["linkTo"]);
    }

    this.inheritFrom = GMarker;
    this.inheritFrom(a,b);
    this.markerlatlng = a;
    if ( !currentSpan.minX || a.x < currentSpan.minX ) currentSpan.minX = a.x;
    if ( !currentSpan.maxX || a.x > currentSpan.maxX ) currentSpan.maxX = a.x;
    if ( !currentSpan.minY || a.y < currentSpan.minY ) currentSpan.minY = a.y;
    if ( !currentSpan.maxY || a.y > currentSpan.maxY ) currentSpan.maxY = a.y;
}

YyMarker.prototype = new GMarker(new GLatLng(1, 1));

YyMarker.prototype.setTooltip = function( string ) {
    this.removeTooltip();
    this.tooltip = new Object();
    //this.tooltip.opacity  = 70;
    this.tooltip.contents = string;
};

YyMarker.prototype.setLinkTo = function( url, target ) {
    this.clickURL = url
	if (typeof target == "undefined") { this.target = '_self'; } else { this.target = target }
}

YyMarker.prototype.onClick = function() {
	if (this.clickURL)
	{
		window.open(this.clickURL, this.target);
	}
}

YyMarker.prototype.initialize = function( a ) {
    // Check if we're using GMap v2
	if (typeof a == "GMap")
	{
		GLog.write("YyMarker requires GMap2");
		return;
	}

    try {
        GMarker.prototype.initialize.call(this, a);
        
        this.map = a;
        // Setup the mouse over/out events
		GEvent.bind(this, "mouseover", this, this.onMouseOver);
		GEvent.bind(this, "mouseout", this, this.onMouseOut);
		GEvent.bindDom(this, "click",  this, this.onClick);
    } catch(e) {
		alert("YyMarker initialize error: " + e);
    }
}

YyMarker.prototype.remove = function( a ) {
    this.removeTooltip();
    GMarker.prototype.remove.call(this);
}

YyMarker.prototype.removeTooltip = function() {
    if ( this.tooltipObject ) {
        document.body.removeChild(this.tooltipObject);
        this.tooltipObject = null;
    }
}

YyMarker.prototype.onInfoWindowOpen = function() {
    this.hideTooltip();
    GMarker.prototype.onInfoWindowOpen.call(this);
}

var inMouseOver = false;

YyMarker.prototype.onMouseOver = function() {
    if (inMouseOver)
		return;
    inMouseOver = true;
    this.showTooltip();
    GEvent.trigger(this, "mouseover");
	inMouseOver = false;
};

YyMarker.prototype.onMouseOut = function() {
    this.hideTooltip();
};

YyMarker.prototype.showTooltip = function() {
    if ( this.tooltip ) {
        if ( !this.tooltipObject ) {
            var opacity = this.tooltip.opacity / 100;
            this.tooltipObject = document.createElement("div");
            this.tooltipObject.style.display    = "none";
            this.tooltipObject.style.position   = "absolute";
            this.tooltipObject.style.background = "#fff";
            this.tooltipObject.style.padding    = "0";
            this.tooltipObject.style.margin     = "0";
            this.tooltipObject.style.MozOpacity = opacity;
            this.tooltipObject.style.filter     = "alpha(opacity=" + this.tooltip.opacity + ")";
            this.tooltipObject.style.opacity    = opacity;
            this.tooltipObject.style.zIndex     = 50000;
            this.tooltipObject.innerHTML        = "<div class=\"markerTooltip\">" + this.tooltip.contents + "</div>";

            document.body.appendChild(this.tooltipObject); // Append the tooltip div to the body
		}
		
		// Following requires a findPosition function (which returns an array with [0]=X-position, [1]=Y-position)
        var mapPos = findPosition(this.map.getContainer());

        /*
            For more information look at the messages in the following thread:
            http://groups.google.nl/group/Google-Maps-API/tree/browse_frm/thread/5f3073449e9446d7/2e04d9e8a1dddbe9?rnum=11&hl=nl&q=pixel+of+marker+after+drag+google+map&_done=%2Fgroup%2FGoogle-Maps-API%2Fbrowse_frm%2Fthread%2F5f3073449e9446d7%2F2e04d9e8a1dddbe9%3Ftvc%3D1%26q%3Dpixel+of+marker+after+drag+google+map%26hl%3Dnl%26#doc_b2fa2182a9efd39c
            
            The way it works is:

            (1) It gets the Lat/Lng of the top left corner of the container
            (2) Converts that Lat/Lng to a DivPixel.
                That gives us the pixel positioning difference between the Div and
                the Container
            (3) Obtain the DivPixel position of the point
            (4) Subtract the offset we obtained in (2) from that DivPixel GPoint. 
        */

		var tlcLatLng = this.map.fromContainerPixelToLatLng(new GPoint(0,0), true);
		var tlcDivPixel = this.map.fromLatLngToDivPixel(tlcLatLng);
		var pointDivPixel = this.map.fromLatLngToDivPixel(this.getPoint());
		var c = new GPoint(pointDivPixel.x-tlcDivPixel.x, pointDivPixel.y-tlcDivPixel.y);

		// Place the tooltip somewhere we can't see.
		this.tooltipObject.style.left = "-1000px";
        this.tooltipObject.style.top = "-1000px";
        this.tooltipObject.style.display = "block";

        // Now start calculating the final position, taking into account:
        // - the size of the tip
        // - the size of the marker icon
        // - the size of the document body
        // - FIXME: top / bottom of body
        var tipLeft = c.x - this.getIcon().iconAnchor.x + mapPos[0];
        if (tipLeft > (document.body.offsetWidth/2)) {
        	// Show the tip on the left side of the marker
        	tipLeft -= this.tooltipObject.offsetWidth;
        } else {
        	// Show the tip on the right side of the marker
        	tipLeft += this.getIcon().iconSize.width;
        }

        // this.map.getContainer().offsetHeight - The height of the map
        var tipTop = c.y - this.getIcon().iconAnchor.y + mapPos[1];
        // This was: c.y + this.map.getContainer().offsetTop
        if (c.y > (this.map.getContainer().offsetHeight/2)) {
        	// Show the tip on the top side of the marker
        	tipTop -= this.tooltipObject.offsetHeight;
        } else {
        	// Show the tip on the bottom side of the marker
        	tipTop += this.getIcon().iconSize.height;
        }

        this.tooltipObject.style.left = tipLeft + "px";
        this.tooltipObject.style.top = tipTop + "px";
    }
}

YyMarker.prototype.hideTooltip = function() {
    if ( this.tooltipObject ) {
        this.tooltipObject.style.display = "none";
    }
}

GMap.prototype.flushOverlays = function() {
    currentSpan = new GBounds();
    this.clearOverlays();
}

GMap.prototype.zoomToMarkers = function() {
    var span = new GSize( currentSpan.maxX - currentSpan.minX, currentSpan.maxY - currentSpan.minY );
    for ( var zoom = 0; zoom < this.spec.numZoomLevels; zoom++ ) {
        var ppd = this.spec.getPixelsPerDegree(zoom);
        var pixelSpan = new GSize(
            Math.round(span.width * ppd.x), Math.round(span.height * ppd.y));
        if ( pixelSpan.width  <= this.viewSize.width &&
             pixelSpan.height <= this.viewSize.height )
        { break; }
    }
    this.centerAndZoom( new GPoint( currentSpan.minX + (span.width/2), currentSpan.minY + (span.height/2) ), zoom);
}

function makeInterface(a) {
    var b = a || window;
    b.YyMarker = YyMarker;
}

makeInterface();
}

YyMarkerNamespace();

// Following is slightly adapted from: http://www.google.com/apis/maps/documentation/#Custom_Controls

// A TextualZoomControl is a GControl that displays textual "Zoom In"
// and "Zoom Out" buttons (as opposed to the iconic buttons used in
// Google Maps).
function TextualMapTypeControl() {
}
TextualMapTypeControl.prototype = new GControl();

// Creates a one DIV for each of the buttons and places them in a container
// DIV which is returned as our control element. We add the control to
// to the map container and return the element for the map class to
// position properly.
TextualMapTypeControl.prototype.initialize = function(map) {
    var container = document.createElement("div");

    var mapTypeDiv = document.createElement("div");
    this.setButtonStyle_(mapTypeDiv);
    container.appendChild(mapTypeDiv);
    mapTypeDiv.appendChild(document.createTextNode("Map"));
    GEvent.addDomListener(mapTypeDiv, "click", function() {
        map.setMapType(G_NORMAL_MAP);
    });

    var satTypeDiv = document.createElement("div");
    this.setButtonStyle_(satTypeDiv);
    container.appendChild(satTypeDiv);
    satTypeDiv.appendChild(document.createTextNode("Sat"));
    GEvent.addDomListener(satTypeDiv, "click", function() {
        map.setMapType(G_SATELLITE_MAP);
    });

    map.getContainer().appendChild(container);
    return container;
}

// By default, the control will appear in the top left corner of the
// map with 7 pixels of padding.
TextualMapTypeControl.prototype.getDefaultPosition = function() {
    return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(7, 7));
}

// Sets the proper CSS for the given button element.
TextualMapTypeControl.prototype.setButtonStyle_ = function(button) {
//  button.style.textDecoration = "underline";
//  button.style.fontSize = "5pt";
  button.style.color = "black";
  button.style.backgroundColor = "white";
  button.style.font = "8pt Arial";
  button.style.border = "1px solid black";
  button.style.padding = "2px";
  button.style.marginBottom = "3px";
  button.style.textAlign = "center";
//  button.style.width = "6em";
  button.style.cursor = "pointer";
}

//var map = new GMap2(document.getElementById("map"));
//map.addControl(new TextualMapTypeControl());
//map.setCenter(new GLatLng(37.441944, -122.141944), 13);

