var map = null;

function setupMap()
{
    var mapElement = document.getElementById('map');
    map = new google.maps.Map2(mapElement);

    map.addMapType(G_PHYSICAL_MAP);
    map.setMapType(G_HYBRID_MAP);
    map.disableDoubleClickZoom();
    map.enableContinuousZoom();
    map.enableScrollWheelZoom();

    map.addControl(new google.maps.SmallZoomControl3D());
    map.addControl(new google.maps.MenuMapTypeControl());
    map.addControl(new google.maps.ScaleControl());
    map.setCenter(new google.maps.LatLng(0, 0));

    loadLocation();
}

function loadLocation()
{
    if (window.location.hash != '') {
        toggleSideBar();
        checkHash();
    }
    window.setInterval(checkHash, 300);
}

if (window.google)
{
    google.setOnLoadCallback(setupMap);
}
else
{
    loadLocation();
}

var lastHash = '';
function checkHash()
{
    if (window.location.hash == lastHash)
    {
        return;
    }
    lastHash = window.location.hash;
    // Mozilla doesn't accept '+' as a substitute for space.
    var hash = lastHash.substring(1).replace(/\+/g, '%20');
    hash = decodeURIComponent(hash);

    if (/^\s*</.test(hash))
    {
        var pl = document.getElementById('pidflo');
        pl.value = hash;
        display();
    }
    else if (/^deref=/.test(hash))
    {
        document.getElementById('lis').value = hash.replace(/^deref=/,'');
        heldRequest();
    }
}

function heldRequest()
{
    var url = document.getElementById('lis').value;
    window.location.hash = '#deref=' + encodeURIComponent(url);
    if (/^[a-zA-Z-]+:/.test(url))
    {
        url = 'deref.php?url=' + encodeURIComponent(url);
    }
    var held = new HeldLocationRequest(url, success_cb, error_cb);
    held.send();
}

function display()
{
    try
    {
        var pl = document.getElementById('pidflo');
        try {
            window.location.hash = '#' + encodeURIComponent(pl.value);
        } catch (err2) {}
        var parser = new DOMParser();
        var xml = parser.parseFromString(pl.value, "application/xml");
        var loc = new PidfLocation(xml);
        success_cb(loc);
    }
    catch (err)
    {
        error_cb('displaying location', err);
    }
}

var loadTime = new Date();
function fuzz(shape)
{
    var fz = document.getElementById('fuzz');
    // This "fuzzes" the result for display only,
    // using a fixed seed that only changes on page load
    shape = shape.fuzz(parseInt(fz.value), loadTime.getTime());
    return shape;
}

function success_cb(loc)
{
    document.getElementById('success').style.display = 'block';
    document.getElementById('error').style.display = 'none';
    if (loc.pidf && XMLSerializer)
    {
        document.getElementById('pidflo').value = new XMLSerializer().serializeToString(loc.pidf);
    }
    if (loc.geodetic)
    {
        setElementText(document.getElementById('geodetic'), loc.geodetic.toString());
        document.getElementById('geodetic').style.display = 'block';
    }
    else
    {
        document.getElementById('geodetic').style.display = 'none';
    }
    var cive = document.getElementById('civic');
    if (loc.civic)
    {
        setElementText(cive, loc.civic.toString());
        cive.style.display = 'block';
    }
    else
    {
        cive.style.display = 'none';
    }
    var rulese = document.getElementById('rules');
    if (loc.rules)
    {
        setElementText(rulese, loc.rules.toString());
        rulese.style.display = 'block';
    }
    else
    {
        rulese.style.display = 'none';
    }
    var u = document.getElementById('uris');
    if (loc.locationURIs.length > 0)
    {
        var dds = u.getElementsByTagName('dd');
        for (var i = 0; i < dds.length; ++i)
        {
            u.removeChild(dds[i]);
        }

        for (var i in loc.locationURIs)
        {
            i = parseInt(i); if (isNaN(i)) { continue; }

            var urie = document.createElement('dd');
            var uria = document.createElement('a');
            uria.setAttribute('href', '#deref=' + encodeURIComponent(loc.locationURIs[i]));
            uria.setAttribute('title', 'Dereference Location URI');
            setElementText(uria, loc.locationURIs[i]);
            urie.appendChild(uria);
            u.appendChild(urie);
        }
        u.style.display = 'block';
    }
    else
    {
        u.style.display = 'none';
    }

    if (map)
    {
        if (loc.geodetic)
        {
            loc.geodetic.shape = fuzz(loc.geodetic.shape);
            mapGeodetic(map, loc.geodetic);
        }
        else if (loc.civic)
        {
            mapCivic(map, loc.civic);
        }
    }
}

function error_cb(code, txt)
{
    document.getElementById('success').style.display = 'none';
    var err = document.getElementById('error');
    err.style.display = 'block';
    err.textContent = 'Error ' + code + ': ' + txt;
}

var sideBarVisible = true;
function toggleSideBar()
{
    var c;
    if (map)
    {
        c = map.getCenter();
    }

    var input = document.getElementById("input");
    var results = document.getElementById("results");
    var toggle = document.getElementById("toggle");
    if (sideBarVisible)
    {
        input.style.display = 'none';
        results.style.marginLeft = '15px';
        toggle.style.left = '5px';
    }
    else
    {
        input.style.display = 'block';
        results.style.marginLeft = '325px';
        toggle.style.left = '315px';
    }
    sideBarVisible = !sideBarVisible;

    if (map)
    {
        map.checkResize();
        map.panTo(c);
    }
}
