L.TileLayer.GoogleBase = L.TileLayer.extend({
    getTileUrl: function (coords) {
        return '/Beijing/GetMap?type=47626774&zoom={0}&x={1}&y={2}'.format(coords.z, coords.x, coords.y);
    }
});

L.TileLayer.GoogleDetail = L.TileLayer.extend({
    getTileUrl: function (coords) {
        return '/Beijing/GetMap?type=1024577166&zoom={0}&x={1}&y={2}'.format(coords.z, coords.x, coords.y);
    }
});

L.tileLayer.googleBase = function () {
    return new L.TileLayer.GoogleBase();
};

L.tileLayer.googleDetail = function () {
    return new L.TileLayer.GoogleDetail();
};

var Map = function (parent) {
    this.Parent = parent;
    this.PointsLayer = null;
    this.TimePointLayer = null;
    this.TimeTextLayer = null;

    this.Startup = function () {
        this.CreateMap();
    };

    this.CreateMap = function () {
        this.map = L.map('map', {
            zoomControl: false,
            minZoom: 4,
            maxZoom: 14,
            zoomDelta: 0.05
        }).setView([39.915, 116.404], 9);

        L.tileLayer.googleBase().addTo(this.map);
        L.tileLayer.googleDetail().addTo(this.map);
        $('.leaflet-control-attribution').hide();

        this.icon = L.icon({
            iconSize: [64, 64],
            iconAnchor: [24, 48],
            iconUrl: '../Content/Images/TianAnMen.png'
        });
        L.marker([39.908, 116.396], { icon: this.icon }).addTo(this.map);
    };

    this.ReloadData = function (time) {
        // Create points layer
        if (this.PointsLayer !== null)
            this.map.removeLayer(this.PointsLayer);

        $.getJSON("http://{0}/bj/getdaily/{1}.json".format(Config.ApiRoot, time)).done(function (data) {
            this.PointsLayer = this.CreatePointsLayer(data);
            this.map.addLayer(this.PointsLayer);
        }.bind(this)).fail(function (jqxhr, status, error) {
            swal({
                title: "",
                text: "Json文件加载失败: Status={0}, Error={1}".format(status, error),
                type: "error",
                icon: "error",
                showCancelButton: false,
                confirmButtonText: "确定",
                closeOnConfirm: true
            });
        }.bind(this));

        // Create times layer
        if (this.TimePointLayer !== null)
            this.map.removeLayer(this.TimePointLayer);

        if (this.TimeTextLayer !== null)
            this.map.removeLayer(this.TimeTextLayer);

        //$.getJSON("/Content/2019092300_traj.json".format(Config.ApiRoot, time)).done(function (data) {
        $.getJSON("http://{0}/bj/getdaily/{1}_traj.json".format(Config.ApiRoot, time)).done(function (data) {
            this.TimePointLayer = this.CreateTimePointLayer(data);
            this.map.addLayer(this.TimePointLayer);

            this.TimeTextLayer = this.CreateTimeTextLayer(data);
            this.map.addLayer(this.TimeTextLayer);
        }.bind(this)).fail(function (jqxhr, status, error) {
            swal({
                title: "",
                text: "时间点Json文件加载失败: Status={0}, Error={1}".format(status, error),
                type: "error",
                icon: "error",
                showCancelButton: false,
                confirmButtonText: "确定",
                closeOnConfirm: true
            });
        }.bind(this));
    };

    this.CreateTimePointLayer = function (points) {
        var features = new L.FeatureGroup();

        $(points).each(function (index, point) {
            var circle = L.circleMarker([point.lat, point.lon], {
                opacity: 1,
                weight: 1,
                color: 'black',
                fillColor: '#fff',
                fillOpacity: 1,
                radius: 3.5
            });
            features.addLayer(circle);
        }.bind(this));

        return features;
    };

    this.CreateTimeTextLayer = function (points) {
        var features = new L.FeatureGroup();

        $(points).each(function (index, point) {
            var text = L.marker([point.lat, point.lon], {
                icon: L.divIcon({
                    className: 'forecast-time',
                    html: this.NormalizeTime(point.timepoint)
                })
            });
            features.addLayer(text);
        }.bind(this));

        return features;
    };

    this.NormalizeTime = function (time) {
        var month = time.substr(4, 2);
        var day = time.substr(6, 2);
        var hour = time.substr(9, 2);
        var minutes = time.substr(11, 2);
        return '{0}/{1} {2}:{3}'.format(month, day, hour, minutes);
    };

    this.CreatePointsLayer = function (points) {
        var features = new L.FeatureGroup();

        $(points).each(function (index, point) {
            var color = this.GetPointsColor(point.value);
            var bounds = [[point.lat - 0.005, point.lon - 0.005], [point.lat + 0.005, point.lon + 0.005]];

            var marker = L.rectangle(bounds, {
                color: color,
                fillColor: color,
                fillOpacity: 0.75,
                weight: 0
            });
            features.addLayer(marker);
        }.bind(this));

        return features;
    };

    this.GetPointsColor = function (value) {
        if (value <= 0.0001)
            return 'rgb(255,255,255)';
        if (value <= 0.001)
            return 'rgb(178, 226, 249)';
        if (value <= 0.01)
            return 'rgb(93, 160, 213)';
        if (value <= 0.1)
            return 'rgb(73, 170, 106)';
        if (value <= 1)
            return 'rgb(159, 206, 81)';
        if (value <= 10)
            return 'rgb(248, 171, 67)';
        if (value <= 100)
            return 'rgb(239, 94, 41)';
        if (value <= 1000)
            return 'rgb(192, 28, 36)';
    };
};