var g_map = null;
function OLMapInit(idDiv, bEditable)
{
    g_map = OLMapCreate(idDiv, bEditable);
    if (g_map == null)
        return;
    
    g_map.SetEventHandler("DistanceChanged", OnDistanceChanged);
    g_map.SetEventHandler("ElevationChanged", OnElevationChanged);

    var select = document.getElementById(MapCtrlID + "lstMapTypes");
    if (select != null)
    {
        var vecTypes = g_map.GetMapSources();
        for (var i = 0; i < vecTypes.length; ++i)
        {
            var opt = document.createElement('OPTION');
            opt.text = vecTypes[i];
            opt.value = i;
            try
            {
                select.add(opt, null);
            }
            catch(ex)
            {
                select.add(opt, i);
            }
        }
    }
    var unit = GetElement('MapUnit');
    if (unit != null && unit.value == '1')
        OLMapChangeDistanceUnits('Mi');
    else
    {
        OLMapChangeDistanceUnits('km');
        unit = GetElement(MapCtrlID + "lstUnits");
        unit.selectedIndex = 1;
        OnDistanceChanged(g_map);
    }

    var data = GetElement('MapData');
    if (data == null || data.value.length == 0)
    {
        var center;
        var nZoom = 4;

        var pLocaleData = GetElement('LocaleData');

        var pNorth = GetElement('LatNorth');
        var pSouth = GetElement('LatSouth');
        var pEast = GetElement('LonEast');
        var pWest = GetElement('LonWest');

        if (pLocaleData != null && pLocaleData.value.length > 0)
        {
            var vecLocale = pLocaleData.value.split(",");
            if (vecLocale.length != 3)
                return;

            var lon = parseFloat(vecLocale[0]);
            var lat = parseFloat(vecLocale[1]);
            var range = parseFloat(vecLocale[2]);

            var size = g_map.m_map.getSize();
            var halfWidth = size.width * range / 2.0;
            var halfHeight = 0.000000001;
    
            var sw = new GLatLng(lat - halfHeight, lon - halfWidth);
            var ne = new GLatLng(lat + halfHeight, lon + halfWidth);
            var bounds = new GLatLngBounds(sw, ne);
            nZoom = g_map.m_map.getBoundsZoomLevel(bounds);
            center = new GLatLng(lat, lon);
        }
        else if (pNorth != null && pSouth != null && pEast != null
                 && pWest != null
                 && pNorth.value.length > 0 && pSouth.value.length > 0
                 && pEast.value.length > 0 && pWest.value.length > 0)
        {
            var north = parseFloat(pNorth.value);
            var south = parseFloat(pSouth.value);
            var east = parseFloat(pEast.value);
            var west = parseFloat(pWest.value);
            var bounds = new GLatLngBounds(new GLatLng(south, west),
                                           new GLatLng(north, east));
            var nZoom = g_map.m_map.getBoundsZoomLevel(bounds);

            center = new GLatLng((north + south) / 2.0, (east + west) / 2.0);
        }
        else
        {
            center = new GLatLng(39.842286020743394, -95.9765625);
            nZoom = 4;
        }
        g_map.CenterAndZoom(center, nZoom);
    }
    else
    {
        g_map.Load(unescape(data.value));
        if (g_map.HasElevation())
        {
            var btn = GetElement("mapCtrl_btnElevation");
            OLMapToggleElevation(btn);
        }
    }
}

function OnDistanceChanged(map)
{
    var span = GetElement(MapCtrlID + "txtRouteDistance");
    var distance = g_map.GetDistance(g_map.GetDistanceUnit());
    span.innerHTML = Math.round(distance * 100) / 100
        + " " + (g_map.GetDistanceUnit() == OLDistanceUnit.Mile
                 ? "miles" : "km");
}

function OnElevationChanged(map)
{
    var div = GetElement("ElevationTally");
    if (div != null)
    {
        var unit = map.GetElevationUnit();
        var strUnit = map.GetElevationUnitStr();
        var gain = Math.round(OLMap.ConvertDistance(g_map.GetElevationGain(),
                                                  OLDistanceUnit.Meter, unit));
        var loss = Math.round(OLMap.ConvertDistance(g_map.GetElevationLoss(),
                                                  OLDistanceUnit.Meter, unit));
        var net = Math.round(OLMap.ConvertDistance(g_map.GetElevationChange(),
                                                  OLDistanceUnit.Meter, unit));
        if (gain == 0.0 && loss == 0.0 && net == 0.0)
            div.innerHTML = "";
        else
            div.innerHTML = 'Elevation: +' + gain + ' ' + strUnit + ' / -'
                + loss + ' ' + strUnit + ' / net ' + net + ' ' + strUnit;
    }
}

// singleton operations
var pPrevActionButton = null;
var CssButton = "SiteButton";
var CssButtonDepressed = "SiteButtonDepressed";
var CssButtonHighlight = "SiteButtonHighlight";
function OLMapSetClickAction(but, act)
{
    if (but.id == MapCtrlID + "btnEditNode")
    {
        if (g_map.InNodeEditingMode())
        {
            OLMapEnableButtons(true);
            act = OLMapClickMode.AddPoint;
            but = document.getElementById(MapCtrlID + "AddRoute");
        }
        else
            OLMapEnableButtons(false);
    }
    else
        OLMapEnableButtons(true);

    g_map.SetClickMode(act);
    if (pPrevActionButton == null)
        pPrevActionButton = GetElement(MapCtrlID + "AddRoute");
    pPrevActionButton.className = CssButton;
    but.className = CssButtonDepressed;
    pPrevActionButton = but;
}
function OLMapUndo()
{
    g_map.Undo();
}
function OLMapClear()
{
    var okay = confirm("Den här funktionen tar bort alla punkterna från kartan. Vill du fortsätta?");
    if (!okay)
		return;
    g_map.Clear();
}
function OLMapToggleMileMarkers(btn)
{
    showMileMarkers = btn.className == CssButtonDepressed;
    btn.className = showMileMarkers ? CssButton : CssButtonDepressed;

    g_map.ToggleMileMarkers();
}
function OLMapFitToView()
{
    g_map.FitToView();
}
function OLMapCreateOutAndBackRoute()
{
    g_map.CreateOutAndBackRoute();
}
function OLMapReverseRoute()
{
    g_map.Reverse();
}
function OLMapToggleElevation()
{
    var btn = GetElement(MapCtrlID + "btnElevation");

    g_map.ToggleElevation();
    btn.className = g_map.EnabledElevation()
        ? CssButtonDepressed : CssButtonHighlight;
}
function OLMapChangeMapType(type)
{
    g_map.SetMapSource(type);
}
function OLMapChangeDistanceUnits(unit)
{
    g_map.SetUnitSystem(unit == 'Mi' ? 'english' : 'metric');
}
function OLMapSetAutoCenter(bAutoCenter)
{
    g_map.SetAutoCenter(bAutoCenter);
}
function OLMapSaveRoute()
{
    var ctrl = GetElement('MapData');
    if (ctrl != null)
        ctrl.value = escape(g_map);
}
function OLMapCreateReturnRoute()
{
    g_map.CreateReturnRoute();
}
function OLMapChangeLocation()
{
    // looking for "Boston, MA" or "Boston,MA"
    var city = GetElement('City');
    var state = GetElement('State');
    var country = GetElement('Country');
    if (city == null || country == null)
        return false;

    var strCountry = country.value;
    var strLocation = city.value;
    if (state != null)
    {
        if (state.value.length == 0
            && (strCountry == "USA" || strCountry == "CAN"))
            return;
        var strState = state.value.toUpperCase();
        strLocation += ', ' + strState;
    }
    g_map.ShowDialog("map", "wait", "Finding Location: " + strLocation);

    var url = OLMap.CommandFile + "?cmd=gd";
    if (city.value.length > 0)
        url += "&city=" + city.value;
    if (state != null && state.value.length > 0)
        url += "&state=" + state.value;
    url += "&country=" + strCountry;
    getXml(url);
}

var g_ajaxRequest = null;
function getXml(url)
{
    // Using XML and Asynchronous RPC ("AJAX") with Maps
    //
    // In this example, we download a static file ("data.xml") that contains a
    // list of lat/lng coordinates in XML. When the download completes,
    // we parse the XML and create a marker at each of those lat/lngs.
    
    
    // Download the data in xml and load it on the map. The format we
    // expect is:
    //<rdf:RDF>
    //    <geo:Point>
    //        <geo:long>-0.15</geo:long>
    //        <geo:lat>50.8333333</geo:lat>
    //    </geo:Point>
    //</rdf:RDF>

    // request = new XMLHttpRequest();
    g_ajaxRequest = GXmlHttp.create();
    g_ajaxRequest.onreadystatechange = processXML;
    g_ajaxRequest.open("GET", url, true);
    g_ajaxRequest.send(null);
}

function processXML()
{
    if (g_ajaxRequest.readyState != 4)
        return;
    try
    {
        var resXml = g_ajaxRequest.responseXML.documentElement;
        var latTag = resXml.getElementsByTagName("lat")[0];
        if (null == latTag)
            latTag = resXml.getElementsByTagName("geo:lat")[0];
        var geoLat = latTag.childNodes[0].nodeValue;
        var longTag = resXml.getElementsByTagName("long")[0];
        if (null == longTag)
            longTag = resXml.getElementsByTagName("geo:long")[0];
        var geoLong = longTag.childNodes[0].nodeValue;
        var gPoint = new GLatLng(geoLat, geoLong);
        g_map.CenterAndZoom(gPoint, 12);
        g_map.HideDialog();
    }
    catch(er)
    {
        g_map.HideDialog(true);
        g_map.ShowAndHideDialog("map", "error", "Kunde inte hitta platsen.", 2);
    }
}

function OLMapOnZipFocus(fld) 
{
    if (fld.value == "< Skriv in postnummer >")
        fld.value="";
}

function OLMapOnZipBlur(fld)
{
    if (fld.value == "")
        fld.value="< Skriv in postnummer >";
}

function OLMapOnZipKeyPress(fld,evt)
{
    var val = fld.value;
    
    var key = evt.which;
    if (key == null)
        key = window.event.keyCode;
        
    var keychar = String.fromCharCode(key);

    if (isControlKey(key))
        return true;

    if (("0123456789").indexOf(keychar) < 0)
        return false;
    
    var selStart = getSelectionStart(fld);
    var selEnd = getSelectionEnd(fld);
    var selected = (selStart != selEnd);
        
    if (val.length == 5 && !selected)
        return false;
        
    if (val.length == 5 && selected)
    {
        // alert("selStart = " + selStart + "\nselEnd = " + selEnd);
        if (Math.abs(selStart - selEnd) != 1)
            return true;
        else
        {
            var newVal = val.substring(0,selStart);
            newVal += keychar;
            newVal += val.substr(selEnd);
            
            showWaitDlg("Hittar postnummer: " + newVal,divMap);
            getZip(newVal);
            return true;
        }
    }
    
    if (val.length == 4 && !selected)
    {
        var newVal = val.substring(0, selStart) + keychar + val.substr(selEnd);
        
        g_map.ShowDialog("map", "wait", "Hittar postnummer: " + newVal);
        getXml("cm.aspx?cmd=gd&zip=" + newVal);
    } 
        
    return true;
}
function isControlKey(key)
{    
    if (key >= 0 && key <= 31)
        return true;
        
    return false;
}
function getSelectionStart(input)
{
    if(input.createTextRange) 
    {
        selectedRange = document.selection.createRange().duplicate();
        selectedRange.moveEnd("character",input.value.length);
        pos=input.value.lastIndexOf(selectedRange.text);
        if (selectedRange.text=="")
            pos=input.value.length;
        return pos;
    }
    else
        return input.selectionStart;
}

function getSelectionEnd(input)
{
    if (input.createTextRange)
    {
        selectedRange = document.selection.createRange().duplicate();
        selectedRange.moveStart("character",-input.value.length);
        pos=selectedRange.text.length;
        return pos;
    } 
    else
        return input.selectionEnd;
}
function OnChangeCountry(ctrl)
{
    if (ctrl.value == "USA" || ctrl.value == "CAN")
    {
        var tb = GetElement("State");

        if (tb != null)
            tb.parentNode.parentNode.removeChild(tb.parentNode);

        var tdParent = ctrl.parentNode;
        var td = document.createElement("TD");
        var strText = ctrl.value == "USA"
            ? "State:&nbsp;" : "Province:&nbsp;";
        var label = document.createElement("B");
        label.innerHTML = strText;
        td.appendChild(label);

        var tb = document.createElement("input");
        tb.maxLength = 2;
        tb.setAttribute("size", 2);
        tb.type = "text";
        tb.name = "State";
        tb.id = "State";
        td.appendChild(tb);
        td.setAttribute("nowrap", 1);
        tdParent.parentNode.insertBefore(td, tdParent);
    }
    else
    {
        var input = GetElement("State");
        if (input == null)
            return;
        var td = input.parentNode;
        td.parentNode.removeChild(td);
    }
}

function OnSaveBounds()
{
    var vecMarkers = g_map.m_vecMarkers;

    if (vecMarkers.length < 2)
    {
        alert('inte tiläckligt många punkter');
        return;
    }
    var country = GetElement("Country");
    if (country == null)
    {
        alert("inget land");
        return;
    }

    var north;
    var south;
    var east;
    var west;
    var point;
    for (var i = 0; i < vecMarkers.length; ++i)
    {
        point = vecMarkers[i].getPoint();
        if (i == 0)
        {
            north = point.lat();
            south = north;
            east = point.lng();
            west = east;
        }
        else
        {
            north = Math.max(north, point.lat());
            south = Math.min(south, point.lat());
            east = Math.max(east, point.lng());
            west = Math.min(west, point.lng());
        }
    }

    g_ajaxRequest = GXmlHttp.create();
    g_ajaxRequest.onreadystatechange = ShowStatus;

    var url = OLMap.CommandFile + "?cmd=scb&country=" + country.value
        + "&n=" + north + "&s=" + south + "&e=" + east + "&w=" + west;
    g_ajaxRequest.open("GET", url, true);
    g_ajaxRequest.send(null);
}

function ShowStatus()
{
    if (g_ajaxRequest.readyState != 4)
        return;
    alert(g_ajaxRequest.responseText);
}

function InitPrintableMap(idDiv)
{
    g_map = OLMapCreate(idDiv, false);	
    if (g_map == null)
        return;
    g_map.SetEventHandler("DistanceChanged", OnPrintableDistanceChange);
    
    var data = document.getElementById('MapData');
    if (data != null && data.value.length > 0)
    {
        g_map.Load(unescape(data.value));
        if (g_map.HasElevation())
            g_map.ToggleElevation();
    }
    var unit = document.getElementById("MapUnit");
    if (unit != null && unit.value == '1')
        OLMapChangeDistanceUnits('Mi');
}

function OnPrintableDistanceChange(map)
{

}
function OLMapPrintMap(id)
{
    window.location = id;
}
function OLMapMouseOver(o)
{
    if (o.className != CssButtonDepressed)
        o.className = CssButtonHighlight;
}
function OLMapMouseOut(o)
{
    if (o.className != CssButtonDepressed)
        o.className = CssButton;
}
function OLMapEnableButtons(bEnable)
{
    OLMapEnableButton("btnOutAndBack", bEnable, OLMapCreateOutAndBackRoute);
    OLMapEnableButton("btnBackToStart", bEnable, OLMapCreateReturnRoute);
    OLMapEnableButton("btnReverse", bEnable, OLMapReverseRoute);
    OLMapEnableButton("btnElevation", bEnable, OLMapToggleElevation);
    OLMapEnableButton("btnMileMarkers", bEnable, OLMapToggleMileMarkersWrapper);

    if (bEnable)
    {
        var btn = document.getElementById(MapCtrlID + "btnMileMarkers");
        OLMapToggleMileMarkersWrapper(btn);
    }
}

function OLMapToggleMileMarkersWrapper()
{
    var btn = document.getElementById(MapCtrlID + "btnMileMarkers");
    OLMapToggleMileMarkers(btn);
}

function OLMapEnableButton(btnName, bEnable, func)
{
    var btn = document.getElementById(MapCtrlID + btnName);
    if (btn == null)
        return;

    var img = GetFirstNonTextSiblingNode(btn.firstChild);
    var imgSrc = (typeof(img.oldSrc) == 'undefined' ? img.src : img.oldSrc);
    var strRegex = "";
    var strReplace = "";
    if (bEnable)
    {
        btn.className = "SiteButton";
        btn.onclick = func;
        btn.onmouseover = function() { OLMapMouseOver(this); };
        btn.onmouseout = function() { OLMapMouseOut(this); };

        strRegex = "_g\\.png$";
        strReplace = ".png";
    }
    else
    {
        btn.className = "SiteButtonDisabled";
        btn.onclick = null;
        btn.onmouseover = null;
        btn.onmouseout = null;

        strRegex = "\\.png$";
        strReplace = "_g.png";
    }

    var regex = new RegExp(strRegex, "g");
    imgSrc = imgSrc.replace(regex, strReplace);
    img.src = imgSrc;
}
