import { displayLength } from '../util/units';
import { geoLonToMeters, geoMetersToLon } from '../geo';
import { localizer } from '../core/localizer';
import type { Vec2 } from '../geo/vector';


export function uiScale(context: iD.Context) {
    var projection = context.projection,
        isImperial = !localizer.usesMetric(),
        maxLength = 180,
        tickHeight = 8;


    function scaleDefs(loc1: Vec2, loc2: Vec2) {
        var lat = (loc2[1] + loc1[1]) / 2,
            conversion = (isImperial ? 3.28084 : 1),
            dist = geoLonToMeters(loc2[0] - loc1[0], lat) * conversion,
            scale = { dist: 0, px: 0, text: '' },
            buckets, i, val, dLon;

        if (isImperial) {
            buckets = [5280000, 528000, 52800, 5280, 500, 50, 5, 1];
        } else {
            buckets = [5000000, 500000, 50000, 5000, 500, 50, 5, 1];
        }

        // determine a user-friendly endpoint for the scale
        for (i = 0; i < buckets.length; i++) {
            val = buckets[i];
            if (dist >= val) {
                scale.dist = Math.floor(dist / val) * val;
                break;
            } else {
                scale.dist = +dist.toFixed(2);
            }
        }

        dLon = geoMetersToLon(scale.dist / conversion, lat);
        scale.px = Math.round(projection([loc1[0] + dLon, loc1[1]])[0]);

        scale.text = displayLength(scale.dist / conversion, isImperial);

        return scale;
    }


    function update(selection: d3.Selection) {
        // choose loc1, loc2 along bottom of viewport (near where the scale will be drawn)
        var dims = context.map().dimensions(),
            loc1 = projection.invert([0, dims[1]]),
            loc2 = projection.invert([maxLength, dims[1]]),
            scale = scaleDefs(loc1, loc2);

        selection.select('.scale-path')
            .attr('d', 'M0.5,0.5v' + tickHeight + 'h' + scale.px + 'v-' + tickHeight);

        selection.select('.scale-text')
            .style(localizer.textDirection() === 'ltr' ? 'left' : 'right', (scale.px + 16) + 'px')
            .text(scale.text);
    }


    return function(selection: d3.Selection) {
        function switchUnits() {
            isImperial = !isImperial;
            selection.call(update);
        }

        var scalegroup = selection.append('svg')
            .attr('class', 'scale')
            .on('click', switchUnits)
            .append('g')
            .attr('transform', 'translate(10,11)');

        scalegroup
            .append('path')
            .attr('class', 'scale-path');

        selection
            .append('div')
            .attr('class', 'scale-text');

        selection.call(update);

        context.map().on('move.scale', function() {
            update(selection);
        });
    };
}
