// Data Query Vars
var addressRequest = null;
var zoomRequest = null;
var addressCallback = null;
var zoomCallback = null;
var mapClickCallback = null;

// Mapping Vars
var map     = null;
var markers = null;
var pinpos  = null;
var size    = new MetroNet.Size(32,32);
var offset  = new MetroNet.Pixel(-(size.w/2), -size.h/2);
var icon    = new MetroNet.Icon('http://www.metroview.com.au/metronet/icon.png',size,offset);

function getDocumentElementById( id )
{
    if( document.getElementById )
        return document.getElementById( id );   // DOM
    else if( document.all )
        return document.all[id];                // MSIE
    else
        return document[id];                    // old NS
}

function PinPosition(lon, lat)
{
    this.longitude = lon;
    this.latitude  = lat;
}

function AddressObject(text, match, latitude, longitude)
{
    this.address   = text;
    this.match     = match;
    this.latitude  = latitude;
    this.longitude = longitude;
}

function SpeedObject(street, speed, distance, school)
{
    this.street   = street;
    this.speed    = speed;
    this.distance = distance;
    this.school   = school;
}

function CrossStreetObject(street1, street2, latitude, longitude, distance)
{
    this.street1   = street1;
    this.street2   = street2;
    this.latitude  = latitude;
    this.longitude = longitude;
    this.distance  = distance;
}

function MapDetails(width, height, left, right, top, bottom)
{
    this.topLat      = top;
    this.bottomLat   = bottom;
    this.leftLong    = left;
    this.rightLong   = right;
    this.pixelWidth  = width;
    this.pixelHeight = height;
}

MetroNet.Control.Click = MetroNet.Class(MetroNet.Control, {                
    defaultHandlerOptions: {
        'single': true,
        'double': false,
        'pixelTolerance': 0,
        'stopSingle': false,
        'stopDouble': false
    },

    initialize: function(options) {
        this.handlerOptions = MetroNet.Util.extend(
            {}, this.defaultHandlerOptions
        );
        MetroNet.Control.prototype.initialize.apply(
            this, arguments
        ); 
        this.handler = new MetroNet.Handler.Click(
            this, {
                'click': this.trigger
            }, this.handlerOptions
        );
    }, 

    trigger: function(e) {
        var lonlat = map.getLonLatFromViewPortPx(e.xy);
        var x=parseInt(lonlat.lon*100000)/100000;
        var y=parseInt(lonlat.lat*100000)/100000;
        markers.addMarker(new MetroNet.Marker(new MetroNet.LonLat(lonlat.lon, lonlat.lat),icon));
        pinpos = new PinPosition(x, y);
        if (mapClickCallback != null)
            mapClickCallback();
    }
});

function ReportMapOptions()
{
    var navCtl = new MetroNet.Control.Navigation();
    var argCtl = new MetroNet.Control.ArgParser();
    var kbdCtl = new MetroNet.Control.KeyboardDefaults();
    navCtl.zoomWheelEnabled = false;
    
//    this.controls = [navCtl, argCtl, kbdCtl];
    this.controls = [navCtl, argCtl];
};

function registerLoadEvents(layer) 
{
    layer.events.register("loadstart", layer, 
                          function() 
                          {
                            var loadingDiv = getDocumentElementById('loadingDiv');
                            loadingDiv.style.visibility = "visible";
                          });
    layer.events.register("loadend", layer, 
                          function() 
                          {
                            var loadingDiv = getDocumentElementById('loadingDiv');
                            loadingDiv.style.visibility = "hidden";
                          });
}


function initMap()
{
    MetroNet.ImgPath = '/metronet/img/';
    map = new MetroNet.Map('map', new ReportMapOptions());
    
    var options = {
                    resolutions: [0.087890625, 0.0439453125, 0.02197265625, 0.010986328125, 0.0054931640625, 0.00274658203125, 
                                  0.001373291015625, 0.0006866455078125, 0.00034332275390625, 0.000171661376953125, 0.0000858306884765625, 
                                  0.00004291534423828125, 0.00002145767211914062, 0.00001072883605957031, 
                                  0.00000536441802978515, 0.00000268220901489257],
                    maxExtent: new MetroNet.Bounds(110.0, -44.0, 155.0, -9.0),
                    ratio: 1.5,
                    singleTile: true,
                    transitionEffect: 'resize'
                  };
    //var ol_wms = new MetroNet.Layer.WMS( "WMS ST","http://www.metroview.com.au/mapserver.php",{layers: 'basic'},options);
    var ol_wms     = new MetroNet.Layer.WMS("MetroView Vector","http://www.metroview.com.au/mapserver.php",{layers: 'basic'},options);
    
    registerLoadEvents(ol_wms);
    markers = new MetroNet.Layer.Markers("Markers");
    var click = new MetroNet.Control.Click();

    map.addControl(new MetroNet.Control.PanZoomBar() );
    map.addControl(new MetroNet.Control.MousePosition());
    map.addControl(new MetroNet.Control.ScaleLine());
    
    map.addLayer(ol_wms);
    map.addLayer(markers);
    map.addControl(click);
    click.activate();
    // Set the base layer for zoom calculations
    map.setBaseLayer(ol_wms);
    // Set marker layer resolution
    markers.minResolution = 0.00000268220901489257;
    markers.maxResolution = 0.087890625;
}

function AddressRequest_Callback()
{
    if (addressRequest.readyState == 4)
    {
        if (addressRequest.status == 200)
        {
            // Parse the XML
            var xmlDoc = addressRequest.responseXML;
            var addresses = xmlDoc.getElementsByTagName('address');
            var resultsArray = new Array(addresses.length);
            for (var i = 0; i < addresses.length; i++)
            {
                var addrText  = addresses[i].getAttribute("text");
                var addrMatch = addresses[i].getAttribute("match");
                var addrLat   = addresses[i].getAttribute("latitude");
                var addrLong  = addresses[i].getAttribute("longitude");
                
                resultsArray[i] = new AddressObject(addrText, addrMatch, addrLat, addrLong);
            }
            addressCallback("OK", resultsArray);
        }
        else
        {
            // Error occurred!
            addressCallback("ERROR", addressRequest.status);
        }
    }
}

function ZoomRequest_Callback()
{
    if (zoomRequest.readyState == 4)
    {
        if (zoomRequest.status == 200)
        { 
            // Parse the XML
            var xmlDoc = zoomRequest.responseXML;
            var zoomLevels = xmlDoc.getElementsByTagName('rectangle');
            if (zoomLevels.length > 0)
            {
                top_left_lat      = zoomLevels[0].getAttribute("topleftlat");
                top_left_long     = zoomLevels[0].getAttribute("topleftlong");
                bottom_right_lat  = zoomLevels[0].getAttribute("bottomrightlat");
                bottom_right_long = zoomLevels[0].getAttribute("bottomrightlong");
                zoomCallback("OK", top_left_lat, top_left_long, bottom_right_lat, bottom_right_long);
            }
        }
        else
        {
            // Error occurred!
            zoomCallback("ERROR", zoomRequest.status, '', '', '');
        }
    }
}

function createRequest()
{
    try
    {
        return new XMLHttpRequest();
    }
    catch (error)
    {
        try
        {
            return new ActiveXObject("Microsoft.XMLHTTP");
        }
        catch (error)
        {
            return null;
        }
    }
}

function GetPinDetails()
{
    return pinpos;
}

function GetMapDetails()
{
    if (map == null)
    {	return null; }
    else
    {
        var dims   = map.getCurrentSize();
        var bounds = map.calculateBounds();
        return new MapDetails(dims.w, dims.h, bounds.left, bounds.right, bounds.top, bounds.bottom);
    }
}

function GetAddressDetails(addressText, crossStreetText, callbackFunc)
{
    if (addressRequest != null && addressRequest.readyState != 0 && addressRequest.readyState != 4)
    {
        addressRequest.abort();
    }
    
    // Create the Address Request
    addressRequest = createRequest();
    if (addressRequest == null)
    {	return false; }
    
    // Initialise & send the address match query
    addressCallback = callbackFunc;
    addressRequest.onreadystatechange = AddressRequest_Callback;
    addressRequest.open("GET", queryURL + "?Action=1&Address=\"" + addressText + "\"&CrossStreet=\"" + crossStreetText + "\"");
    addressRequest.send(null);

    return true;
}

function GetZoomLevel(latitude, longitude, numVectors, callbackFunc)
{
    if (zoomRequest != null && zoomRequest.readyState != 0 && zoomRequest.readyState != 4)
    {
        zoomRequest.abort();
    }
    
    // Create the Address Request
    zoomRequest = createRequest();
    if (zoomRequest == null)
    {	return false; }
    
    // Initialise & send the address match query
    zoomCallback = callbackFunc;
    zoomRequest.onreadystatechange = ZoomRequest_Callback;
    // NOTE: Width & height below should match those used for the map DIV style
    zoomRequest.open("GET", queryURL + "?Action=3&Latitude=" + latitude + "&Longitude=" + longitude + "&Width=650&Height=550&NumVectors=" + numVectors);
    zoomRequest.send(null);
    
    return true;
}

function GetAddressDetailsWithStreet(streetText, streetTypeText, suburbText, crossStreetText, callbackFunc)
{
    if (addressRequest != null && addressRequest.readyState != 0 && addressRequest.readyState != 4)
    {
        addressRequest.abort();
    }
    
    // Create the Address Request
    addressRequest = createRequest();
    if (addressRequest == null)
    {	return false; }
    
    // Initialise & send the address match query
    addressCallback = callbackFunc;
    addressRequest.onreadystatechange = AddressRequest_Callback;
    addressRequest.open("GET", queryURL + "?Action=1&State=WA&StreetName=\"" + streetText + 
                               "\"&StreetType=\"" + streetTypeText + "\"&Suburb=\"" + suburbText + 
                               "\"&CrossStreet=\"" + crossStreetText + "\"");
    addressRequest.send(null);

    return true;
}

function SetMapPosition(latitude, longitude)
{
    mapDiv = getDocumentElementById('map');
    mapDiv.style.display = "block";
    if (map == null)
    {	initMap(); }
    map.setCenter(new MetroNet.LonLat(longitude, latitude), 12);
}

function SetMapPositionWithExtents(latitude, longitude, top_left_lat, top_left_long, bottom_right_lat, bottom_right_long)
{
    mapDiv = getDocumentElementById('map');
    mapDiv.style.display = "block";
    if (map == null)
    {	initMap(); }
    
    bounds  = new MetroNet.Bounds(top_left_long, top_left_lat, bottom_right_long, bottom_right_lat);
    zoomLevel = map.getZoomForExtent(bounds, true);
    map.setCenter(new MetroNet.LonLat(longitude, latitude), zoomLevel);
}
