﻿/*global Microsoft */
Cwo.RegisterNamespace("Cwo.MapProvider");

Cwo.MapProvider = function (BingKey) {
    var bingKey = BingKey;
    this.RenderMap = function (htmlControl, settings) {
        var baseSettings = { bingKey: bingKey };

        $.extend(baseSettings, settings);

        return new Cwo.Map(htmlControl, baseSettings);
    }
    //get a rectange cords for an array of points
    this.GetRectFromBounds = function (bounds) {
        var localbounds = new Microsoft.Maps.LocationRect.fromLocations(bounds);
        //localbounds.height = bounds.height - 10;
        //localbounds.width = bounds.width - 10;
        return localbounds;
    }
    //returns a typed point from a lat long
    this.CreatePoint = function (lat, lon) {
        return new Microsoft.Maps.Location(lat, lon);
    }

}

Cwo.Map = function (control, settings) {
    var basesettings = {
        mapType: Microsoft.Maps.MapTypeId.road
    },
    map = null,
    htmlControl = control,
    mapProvider = this,
    entities = [],
    polygonLayerIndex = null,
    markers = new Array(),
    infoBoxes = new Array(),
    POIAlert = null;


    function ResetMarkers() {
        markers = new Array();
    }

    //extend the base settings
    $.extend(basesettings, settings);

    //returns a color
    this.getColor = function (a, r, g, b) {
        return new Microsoft.Maps.Color(a, r, g, b);
    }



    //Adds a market to them map
    this.AddMarker = function (lat, lon, settings) {
        var basesettings = { toolTip: false, toolTiptext: "" };
        $.extend(basesettings, settings);


        var pin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(lat, lon), basesettings);
        map.entities.push(pin);
        markers.push(pin);

        if (basesettings.toolTip) {
            pin.ToolTip = basesettings.toolTiptext;
            Microsoft.Maps.Events.addHandler(pin, "mouseover", function (e) {
                if (POIAlert === null) {
                    var infoboxOptions = { htmlContent: "<div class='mapToolTip'>" + e.target.ToolTip + "</div>" };
                    POIAlert = new Microsoft.Maps.Infobox(map.tryPixelToLocation(new Microsoft.Maps.Point(e.getX() + 10, e.getY() + 10)), infoboxOptions);
                    map.entities.push(POIAlert);
                }
            });
            Microsoft.Maps.Events.addHandler(pin, "mouseout", function () {
                setTimeout(function () {
                    map.entities.remove(POIAlert);
                    POIAlert = null;
                }, 50);
            });
        }
        return pin;
    }


    this.ClearMarkers = function () {
        for (var i = 0; i < markers.length; i++) {
            map.entities.removeAt(map.entities.indexOf(markers[i]));
        }
        ResetMarkers();
    }


    this.AddInfoBox = function (lat, lon, html, settings) {

        var location = new Microsoft.Maps.Location(lat, lon);
        var infoboxOptions = { htmlContent: html };
        var infoBox = new Microsoft.Maps.Infobox(location, infoboxOptions);
        infoBoxes.push(infoBox);
        map.entities.push(infoBox);
        return infoBox;
    }


    this.Remove = function (entity) {
        map.entities.remove(entity)
    }

    this.PixelToLatLong = function (x, y) {
        var location = map.tryPixelToLocation(new Microsoft.Maps.Point(x, y))
        return { latitude: location.latitude, longitude: location.longitude }
    }

    this.LatLongToPixel = function (lat, lon) {
        var pixel = map.tryLocationToPixel(new Microsoft.Maps.Location(lat, lon), Microsoft.Maps.PixelReference.viewport);
        return { x: pixel.x, y: pixel.y };
    }

    this.AttachEvent = function (event, callback) {
        Microsoft.Maps.Events.addHandler(map, event, callback);
    }

    //draws a polygon on the map
    this.DrawPolygon = function (Points, settings) {
        var baseSettings = {
            fillColor: new Microsoft.Maps.Color(100, 100, 0, 100),
            strokeColor: new Microsoft.Maps.Color(200, 0, 100, 100),
            strokeThickness: 1
        }

        var polygon = new Microsoft.Maps.Polygon(Points, settings);
        map.entities.push(polygon);
        polygonLayerIndex = map.entities.indexOf(polygon);
    }


    this.ClearPolygon = function () {
        map.entities.removeAt(polygonLayerIndex);
    }

    //move the map to the lat long
    this.MoveTo = function (lat, lon) {
        map.setView({ center: new Microsoft.Maps.Location(lat, lon) });
    }

    //return the top left cord of the map
    this.GetTopLeft = function () {
        return map.getTargetBounds().getNorthwest();
    }

    //return the bottom right cord of the map
    this.GetBottomRight = function () {
        return map.getTargetBounds().getSoutheast();
    }

    //return the current zoom level of the map
    this.GetZoom = function () {
        return Math.round(map.getZoom());
    }

    //set the zoom level of the map
    this.SetZoom = function (zoomLevel) {
        map.setView({ zoom: zoomLevel });
    }


    //Move all markers and shapes from the map
    this.DeleteAllShapeLayers = function () {
        map.entities.clear();
    }

    this.GetWidth = function () {
        return map.getWidth();
    }

    this.GetHeight = function () {
        return map.getHeight();
    }


    this.GetBounds = function () {
        return map.getBounds();
    }


    //set the display to the bounds of the the rect
    this.SetView = function (rect) {
        map.setView({ bounds: rect });
    }

    this.GetCenter = function () {
        return map.getCenter();
    }

    var init = function () {
        var mapsettings;

        //If we send the map the bounds we dont want a centerpoint
        if (basesettings.bounds !== undefined) {
            mapsettings = {
                credentials: basesettings.bingKey,
                mapTypeId: basesettings.mapType,
                bounds: basesettings.bounds,
                showScalebar: true,
                showCopyright: false,
                showMapTypeSelector: true,
                showBreadcrumb: false,
                enableSearchLogo: false,
                disableKeyboardInput: true
            }
        } else {
            mapsettings = {
                credentials: basesettings.bingKey,
                mapTypeId: basesettings.mapType,
                center: new Microsoft.Maps.Location(basesettings.centerLat, basesettings.centerLong),
                showScalebar: true,
                showCopyright: false,
                showMapTypeSelector: true,
                showBreadcrumb: false,
                enableSearchLogo: false,
                zoom: basesettings.zoom,
                disableKeyboardInput: true
            }
        }


        map = new Microsoft.Maps.Map(
            htmlControl,
            mapsettings
        );
        Cwo.Page.EventController.FireEvent("Maps.MapRendered");
    }

    init();
}



