/*jslint browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, bitwise: true, newcap: true, immed: true */
/*global window, $, google */

(function()
{
    "use strict";
    
    /** Assert jQuery */
    if (!$) { $ = jQuery; }
    
    /**
     * A simple, positionable overlay for Google Maps v3. 
     * @constructor
     * @param map (google.maps.Map)
     * @param point (google.maps.LatLng)
     * @param contents (string or jQuery)
     */
    function Overlay(map, position, contents) 
    {
        this.map = map;
        this.position = position || {x: 0, y: 0};
        
        // Wrap the contents in a div:
        this.contents = $("<div class='overlay'/>").append(contents || "");
        
        // Make the protoype aware of the map:
        this.setMap(map);
    }
    Overlay.prototype = new google.maps.OverlayView();

    
    /**
     * Includes the overlay in the map. 
     * NOTE: This happens automatically; you should only call this 
     *       if you've previously removed it.
     */
    Overlay.prototype.add = function() 
    {
        this.setMap(this.map);
    };    
    
    
    /**
     * Invoked from the map API when the overlay needs to be added to the DOM.
     */
    Overlay.prototype.onAdd = function() 
    {
        var panes = this.getPanes(),
            css = 
            {
                display: "none",
                margin: "0",
                position: "absolute",
                "z-index": "9999"
            };
        
        // Override the important CSS attributes that are required
        // for the overlay to render correctly:
        this.contents.css(css);
        
        // Add the container to the map:
        $(panes.overlayImage).append(this.contents);
    };

    
    /**
     * Invoked from the map API when the overlay should reposition itself.
     */
    Overlay.prototype.draw = function() 
    {
        var contents = this.contents,
            projection = this.getProjection(),
            position = projection.fromLatLngToDivPixel(this.position),
            height = contents.height(),
            width = contents.width(),
            css = 
            {
                left: position.x,
                top: position.y  
            };
    
        // Move the overlay to the correct position.
        // (the default position centers the bubble over the pin):
        contents.css(css);
        
        // If the overlay is not visible, show it now:
        if (contents.css("display") === "none")
        {
            this.show();
        }
    };
    

    /**
     * Toggles the overlay's inclusion in the map's DOM. 
     */
    Overlay.prototype.remove = function() 
    {
        this.contents.hide();
        this.setMap(null);
    };
    
    
    /**
     * Invoked from the map API when the overlay should be removed.
     */
    Overlay.prototype.onRemove = function() 
    {
        this.contents.remove();
    };
    

    /**
     * Hides the overlay.
     */
    Overlay.prototype.hide = function() 
    {
        if (this.contents) 
        {
            this.contents.hide();
        }
    };

    /**
     * Shows the overlay.
     */
    Overlay.prototype.show = function() 
    {
        if (this.contents) 
        {
            this.contents.show();
        }
    };

    /**
     * Toggles the visibility of the overlay.
     */
    Overlay.prototype.toggle = function() 
    {
        if (this.contents) 
        {
            this.contents.toggle();
        }
    };

    
    // Make the Overlay available globally:
    window.Overlay = Overlay;
    
}());

