/**
 * Creates Infowindow. The InfoWindow markup is defined in medela.locationfinder.gmap.map.js
 * @author tjunghans, Namics AG, www.namics.com
 * @class Infowindow
 * @namespace MEDELA.locationfinder.gmap
 * @requires jQuery
 */

/* JSLint Stuff */
/*globals jQuery, GOverlay, G_MAP_FLOAT_PANE, GSize */

var MEDELA = MEDELA || {};
MEDELA.locationfinder = MEDELA.locationfinder || {};
MEDELA.locationfinder.gmap = MEDELA.locationfinder.gmap || {};
(MEDELA.locationfinder.gmap.infowindow = function (marker, html) {

    var getHtmlFragmentDimensions = null,
        proto = null;
    /**
     * Method takes html string as parameter and calculates the width and height
     * @method getHtmlFragmentDimensions
     * @param {String} html
     * @return {Object} {w:int, h:int}
     */
    getHtmlFragmentDimensions = function (html) {
		
		
        var $tmp = null,
            h = 0,
            w = 0;

     	//$tmp = jQuery(html);
		jQuery('body').append('<div id="tmp"></div>');
		jQuery('#tmp').html(html);
		$tmp = jQuery('#infowin');
		
        $tmp.css({
            'position' : 'absolute',
            'left' : '-5000px',
            'top' : '-5000px'
        });
        
        h = $tmp.height();
        w = $tmp.width();

        // remove temporary infowindow
        jQuery('#tmp').remove();

        return {'width' : w, 'height' : h };
    };



    

    /**
     * @method InfoWindow (Constructor)
     * @param {GMarker} marker
     * @param {String} html
     */
    function InfoWindow(marker, html) {

        this.map = null;
        this.div_ = null;
        this.marker = marker;
        this.html = html;
        this.dimensions = getHtmlFragmentDimensions(html);
        this.latlng = null;

    }

    /**
     * Holds InfoWindow.prototype which in turn holds GOverlay
     * @property proto
     */
    proto = InfoWindow.prototype = new GOverlay();

    /**
     * @method initialize
     * @param {GMap2} map
     */
    proto.initialize = function (map) {
        var coord = null,
            div = null,
            mapContainer = null,
            offsetLeft = 0,
            offsetRight = 0,
            offsetTop = 0,
            infowindowContainer = null,
            markerDistanceFromMapContainer = null,
            padding = null,
            panByHeight = 0,
            panByWidth = 0;

        div = document.createElement('div');
        div.style.position = 'absolute';
        div.innerHTML = this.html;


        map.getPane(G_MAP_FLOAT_PANE).appendChild(div);

        // coord gets marker position relative to containing div (pane)
        coord = map.fromLatLngToDivPixel(marker.getLatLng());

        // markerDistanceFromMapContainer gets marker position relative to map container
        markerDistanceFromMapContainer = map.fromLatLngToContainerPixel(marker.getLatLng());
        offsetLeft = -1 * Math.round(this.dimensions.width / 2);
        offsetTop = -1 * this.dimensions.height + 4;

        
        // position infowindow relative to marker
        div.style.top = (coord.y + offsetTop) + 'px';
        div.style.left = (coord.x + offsetLeft) + 'px';

        /**
         * To make sure, the infowindow is not hidden or overlapping map controls it needs to be
         * repositioned, according to paddings and map and infowindow dimensions
         */
        infowindowContainer = {};

        // padding makes sure none of the GMap controls (incl. logo and copyright) are covered
        padding = {
            'left' : 56,
            'top' : 27,
            'bottom' : 15,
            'right' : 7
        };

        mapContainer = {
            'left' : 0,
            'top' : 0,
            'bottom' : map.getSize().height,
            'right' : map.getSize().width
        };

        infowindowContainer.left = (markerDistanceFromMapContainer.x - Math.round(this.dimensions.width / 2));
        infowindowContainer.top = (markerDistanceFromMapContainer.y - (this.dimensions.height + 4));
        infowindowContainer.bottom = infowindowContainer.top + this.dimensions.height;
        infowindowContainer.right = infowindowContainer.left + this.dimensions.width;

        if (infowindowContainer.top < padding.top) {
            panByHeight = padding.top - infowindowContainer.top; // positive
        } else if (infowindowContainer.bottom > (mapContainer.bottom - padding.bottom)) {
            panByHeight =  (mapContainer.bottom - padding.bottom) - infowindowContainer.bottom; // negative
        }

        if (infowindowContainer.left < padding.left) {
            panByWidth = padding.left - infowindowContainer.left; // positive
        } else if (infowindowContainer.right > (mapContainer.right - padding.right)) {
            panByWidth =  (mapContainer.right - padding.right) - infowindowContainer.right; // negative
        }

        map.panBy(new GSize(panByWidth, panByHeight));

        this.map = map;
        this.div_ = div;
    };

    /**
     * @method remove
     */
    proto.remove = function () {
        jQuery(this.div_).remove();
    };

    /**
     * method redraw
     */
    proto.redraw = function () {
        // not needed  
    };

    /**
     * method getHeight
     */
    proto.getHeight = function () {
        return this.height;
    };

    return new InfoWindow(marker, html);
});