/*
 * Creates a marker at the given point with the given text
 * @param GLatLng latlng The point to use
 * @param string title The marker header title
 * @param string body The body (can contain raw html)
 * @param string address The address to use for directions
 * @param string icon The icon to use for the location
 * @return GMarker The marker
 */
function createChildMarker(latlng, title, body, address, icon)
{
    var marker = new GMarker(latlng, {draggable:false,icon:icon});
    var text = '<h2 class="markerheader">' + title + '<\/h2>' + '<div class="markerbody">' + body + '<\/div>';

    if (address) {
        // add route form
        text = text + '<form class="route" onsubmit="return submitRouteForm(this)">' + getText('RouteDepartureLocation') + '<input type="text" name="departure"\/><input class="submit" type="submit" value="' + getText('RouteExecute') + '"\/><\/form>';
    }

    marker.address = address;

    GEvent.addListener(marker, "click", function() { marker.openInfoWindowHtml(text); });
    GEvent.addListener(marker, "infowindowopen", function() {
        this.opened = true;
    });
    GEvent.addListener(marker, "infowindowclose", function() {
        this.opened = false;
    });
    return marker;
}

/**
 * Process route form
 * @return boolean false (to prevent form actually being submitted)
 */
function submitRouteForm(form)
{
    var sm = getSelectedMarker();

    if (sm) {

        var dir = new GDirections(window.map, document.getElementById('route'));

        GEvent.addListener(dir, "load", processRouteLoad);
        GEvent.addListener(dir, "addoverlay", processRouteResult);

        dir.loadFromWaypoints([form.departure.value,sm.address], {locale:"nl_NL"});

    }

    return false;
}

/**
 * Process route form
 * @return boolean false (to prevent form actually being submitted)
 */
function submitExternalRouteForm(form)
{
    if (window.address) {

        var dir = new GDirections(window.map, document.getElementById('route'));

        GEvent.addListener(dir, "load", processRouteLoad);
        GEvent.addListener(dir, "addoverlay", processRouteResult);

        dir.loadFromWaypoints([form.departure.value,window.address], {locale:"nl_NL"});

    }

    return false;
}

/**
 *
 */
function loadRouteForm()
{
    if (formobject = document.getElementById('routeform')) {
        formobject.innerHTML = '<h2>' + getText('RouteHeader') + '</h2><form class="route" onsubmit="return submitExternalRouteForm(this)">' + getText('RouteDepartureLocation') + '<input type="text" name="departure"\/><input class="button" type="submit" value="' + getText('RouteExecute') + '"\/><\/form>';
    }
}

/**
 * Event handler for route request
 * @return void
 */
function processRouteLoad()
{
    // this method gets called when a user submits a route request
}

/**
 * Event handler for route response
 * @return void
 */
function processRouteResult()
{
    // TODO test if any route was found
    var sm = getSelectedMarker();
    if (sm) {
        sm.closeInfoWindow();
    }

    // enable print-button
    var print = document.getElementById('printroute');
    print.className = '';
    // TODO adjust margins for route
    // TODO add 'clear route' link
}

/**
 * Apply view on a map
 * @param Object view The view must hold: (x,y,z) for setting center and zoom level and/or (m) for map type
 * @param GMap2 map The map to apply view on
 * @return void
 */
function applyMapView(view, map)
{
    if (view.m) {
        mapTypes = map.getMapTypes();
        map.setMapType(mapTypes[view.m]);
    }

    if (view.x && view.y) {
        map.setCenter(new GLatLng(view.x, view.y));
    }

    if (view.z) {
        map.setZoom(parseInt(view.z));
    }

    if (view.sm) {
        // apply selected marker
        if (window.markers[view.sm]) {
            GEvent.trigger(window.markers[view.sm], 'click');
        }
    }

    map.savePosition();

}

/**
 * Initializes 'link to this page' on the <a> node with the map
 * @param DOMNode node The <a> node
 * @param GMap2 map The map to get state from
 * @param string label The text to show in the link
 */
function showMapLink(node, map, label)
{
    var labelNode = document.createTextNode(label);
    var a = document.createElement('a');
    a.setAttribute('id', 'maplink');
    a.setAttribute('class', 'permalink');
    a.setAttribute('href', window.location.toString());
    a.appendChild(labelNode);
    a.map = map;
    a.onfocus = function ()
//    node.onclick = function ()
    {
        var url = window.location.toString();
        var currentFragment = getFragment(url);
        if (currentFragment.length > 0) {
            url = url.substring(0, url.length - currentFragment.length);
        }
        url = url + '#';

        // determine selected map type
        var m = -1;
        if ((mapTypes = this.map.getMapTypes()) && (mapType = this.map.getCurrentMapType())) {
            for (var i = 0; i < mapTypes.length; i++) {
                if (mapTypes[i] == mapType) m = i;
            }
        }
        if (m > -1) {
            url = url + (url.substr(url.length - 1, 1) != '#' ? ';' : '') + 'm=' + m.toString();
        }

        // get selected center
        center = this.map.getCenter();
        if (center) {
            url = url + (url.substr(url.length - 1, 1) != '#' ? ';' : '') + 'x=' + center.lat() + ';y=' + center.lng();
        }

        // determine selected zoom level
        z = this.map.getZoom();
        if (z) {
            url = url + (url.substr(url.length - 1, 1) != '#' ? ';' : '') + 'z=' + z.toString();
        }

        // determine selected marker
        var el = getSelectedMarkerName();
        if (el) {
            url = url + (url.substr(url.length - 1, 1) != '#' ? ';' : '') + 'sm=' + el;
        }

        if (url.substr(url.length - 1, 1) == '#') url = url.substr(0, url.length - 1);

        this.setAttribute('href', url);
        return true;
    }
    a.onmouseover = a.onfocus;

    insertAfter(a, node);
}

/**
 * Returns selected marker name (if any selected)
 * @return String
 */
function getSelectedMarkerName()
{
    if (window.markers) {
        for (el in window.markers) {
            if (window.markers[el].opened == true) {
                return el;
                break;
            }
        }
    }
    return null;
}

/**
 * Returns selected marker (if any selected)
 * @return GMarker
 */
function getSelectedMarker()
{
    var el = getSelectedMarkerName();
    if (el && window.markers[el]) {
        return window.markers[el];
    }
    return null;
}

/**
 * Prepares an html element for Google maps by adding styles to it
 * @param id The id of the html element
 * @param width The width of the map
 * @param height The height of the map
 */
function prepareMap(id, width, height)
{
    var map = document.getElementById(id);
    map.style.width = width + 'px';
    map.style.height = height + 'px';
}

addUnloadEvent(GUnload);
