import * as d3 from 'd3';
import { geoRoundCoords } from '../geo/index';
import { uiTooltipHtml } from './tooltipHtml';


export function uiRadialMenu(context, operations) {
    var menu,
        center = [0, 0],
        tooltip;


    var radialMenu = function(selection) {
        if (!operations.length) return;

        selection.node().parentNode.focus();

        function click(operation) {
            d3.event.stopPropagation();
            if (operation.disabled()) return;
            operation();
            radialMenu.close();
        }

        menu = selection
            .append('g')
            .attr('class', 'radial-menu')
            .attr('transform', 'translate(' + center + ')')
            .attr('opacity', 0);

        menu
            .transition()
            .attr('opacity', 1);

        var r = 50,
            a = Math.PI / 4,
            a0 = -Math.PI / 4,
            a1 = a0 + (operations.length - 1) * a;

        menu
            .append('path')
            .attr('class', 'radial-menu-background')
            .attr('d', 'M' + r * Math.sin(a0) + ',' +
                             r * Math.cos(a0) +
                      ' A' + r + ',' + r + ' 0 ' + (operations.length > 5 ? '1' : '0') + ',0 ' +
                             (r * Math.sin(a1) + 1e-3) + ',' +
                             (r * Math.cos(a1) + 1e-3)) // Force positive-length path (#1305)
            .attr('stroke-width', 50)
            .attr('stroke-linecap', 'round');

        var button = menu.selectAll()
            .data(operations)
            .enter()
            .append('g')
            .attr('class', function(d) { return 'radial-menu-item radial-menu-item-' + d.id; })
            .classed('disabled', function(d) { return d.disabled(); })
            .attr('transform', function(d, i) {
                return 'translate(' + geoRoundCoords([
                        r * Math.sin(a0 + i * a),
                        r * Math.cos(a0 + i * a)]).join(',') + ')';
            });

        button
            .append('circle')
            .attr('r', 15)
            .on('click', click)
            .on('mousedown', mousedown)
            .on('mouseover', mouseover)
            .on('mouseout', mouseout);

        button
            .append('use')
            .attr('transform', 'translate(-10,-10)')
            .attr('width', '20')
            .attr('height', '20')
            .attr('xlink:href', function(d) { return '#operation-' + d.id; });

        tooltip = d3.select(document.body)
            .append('div')
            .attr('class', 'tooltip-inner radial-menu-tooltip');

        function mousedown() {
            d3.event.stopPropagation(); // https://github.com/openstreetmap/iD/issues/1869
        }

        function mouseover(d, i) {
            var rect = context.surfaceRect(),
                angle = a0 + i * a,
                top = rect.top + (r + 25) * Math.cos(angle) + center[1] + 'px',
                left = rect.left + (r + 25) * Math.sin(angle) + center[0] + 'px',
                bottom = rect.height - (r + 25) * Math.cos(angle) - center[1] + 'px',
                right = rect.width - (r + 25) * Math.sin(angle) - center[0] + 'px';

            tooltip
                .style('top', null)
                .style('left', null)
                .style('bottom', null)
                .style('right', null)
                .style('display', 'block')
                .html(uiTooltipHtml(d.tooltip(), d.keys[0]));

            if (i === 0) {
                tooltip
                    .style('right', right)
                    .style('top', top);
            } else if (i >= 4) {
                tooltip
                    .style('left', left)
                    .style('bottom', bottom);
            } else {
                tooltip
                    .style('left', left)
                    .style('top', top);
            }
        }

        function mouseout() {
            tooltip.style('display', 'none');
        }
    };


    radialMenu.close = function() {
        if (menu) {
            menu
                .style('pointer-events', 'none')
                .transition()
                .attr('opacity', 0)
                .remove();
        }

        if (tooltip) {
            tooltip.remove();
        }
    };


    radialMenu.center = function(_) {
        if (!arguments.length) return center;
        center = _;
        return radialMenu;
    };


    return radialMenu;
}
