import * as d3 from './d3-custom';
import { round, typeset } from './utilities';

export function createSelectionList(options) {

    //dimensions
    let width, height;
    let x, y;
    // common
    let font;
    let colours;
    let controller;
    let lang;
    let labels;

    //svg element
    let selectedGroup;

    let transitionDuration;
    let maxEntries;

    // hand picked magic numbers for alignment to comma position for ASAP Condensed
    let trailingSpace = {
        small: '-6.8',
        large: '-15.4'
    };

    function selectionList(selection) {

        selectedGroup = selection.append('g')
            .attr('class', 'selection')
            .style('font-size', font.ratio.small + 'em')
            .attr('transform', 'translate(' + x + ',' + y + ')');

        let listheading = selectedGroup.append('g')
            .attr('fill', colours.text)
            .attr('class', 'list-heading');
        listheading.append('rect')
            .attr('fill', colours.translucent)
            .attr('stroke', colours.text)
            .attr('x', '-6em')
            .attr('y', '-1em')
            .attr('width', width)
            .attr('height', height);

        listheading.append('text')
            .attr('text-anchor', 'end')
            .attr('transform', 'translate(' + trailingSpace.large + ',0)')
            .text(labels.per[lang] + ' ' + labels.referenceGroup.size);
        listheading.append('text')
            .attr('text-anchor', 'start')
            .attr('dx', '1.5em')
            .attr('class', 'counter');
    }


    selectionList.update = function (selectedEntries, ifilter) {

        if(selectedEntries.length === 0) {  // show / hide list heading
            selectedGroup.classed('hidden', true);
        } else {
            selectedGroup.classed('hidden', false);
        }

        selectedGroup.select('.counter')
            .text(selectedEntries.length + ' ' + labels.of[lang] + ' ' + maxEntries + ' ' + labels.selected[lang]);

        let eselected = selectedGroup.selectAll('g.selected')
            .data(selectedEntries, function(d) { return d.reason.title; });  // title as key

        // EXIT
        eselected.exit()
            .transition()
            .duration(transitionDuration)
            .attr('opacity', 0)
            .remove();

        // UPDATE
        eselected
            .attr('opacity', function(d) {
                if(ifilter && ifilter !== d.reason.cat) {
                    return 0.8;
                } else {
                    return 1;
                }
            })
            .transition()
            .duration(transitionDuration)
            .attr('transform', function(d,i) { return 'translate(0,' + ((i + 1) * font.ratio.medium * font.baseSize) + ')'; });

        eselected.each(function(d){
            d3.select(this).select('text.list-value')
                .text(function(d) { return typeset(round(d.value), lang); });

            let rect = d3.select(this).select('rect');
            rect.classed('clickable', function(d) {
                if(ifilter && ifilter !== d.reason.cat) {
                    return false;
                } else {
                    return true;
                }
            });
            if(!ifilter || ifilter === d.reason.cat) {  // remove click event listener when corresponding entry is not visible
                rect.on('click', function(e, d) { controller.scrollToEntry(d); });
            } else {
                rect.on('click', null);
            }
        });

        eselected.each(function(){
            d3.select(this).select('.delete')
                .on('click', function(e, d) { controller.deleteEntryFromSelection(d); });
        });

        // ENTER
        let egroup = eselected.enter()
            .append('g')
            .attr('class', 'selected')
            .attr('transform', function(d,i) { return 'translate(0,' + ((i + 1) * font.ratio.medium * font.baseSize) + ')'; })
            .attr('fill', colours.bright);

        let rect = egroup.append('rect');

        egroup.append('text')
            .attr('text-anchor', 'end')
            .attr('class', 'list-value')
            .attr('transform', function(d) {
                let cssval = 'translate(';
                let p = Math.log(d.value) / Math.log(10);
                if(p < 0) { 
                    cssval += '0';
                } else if (p < 1) {
                    cssval += trailingSpace.small;
                } else {
                    cssval += trailingSpace.large;
                }
                return cssval += ', 0)';
            })
            .text(function(d) { return typeset(round(d.value), lang); });

        egroup.append('text')
            .attr('text-anchor', 'start')
            .attr('class', 'list-title')
            .attr('dx', '1.5em')
            .text(function(d) { return d.reason.title; });

        rect.attr('fill', colours.text)
            .attr('class', 'clickable')
            .attr('opacity', 0.9)
            .attr('x', '-6em')
            .attr('y', '-1em')
            .attr('width', width)
            .attr('height', height)
            .on('mouseover', function () {
                let el = d3.select(this);
                if (el.classed('clickable')) {
                    el.attr('fill', colours.highlight);
                }
            })
            .on('mouseout', function () { d3.select(this).attr('fill', colours.text); })
            .on('click', function(e, d) { controller.scrollToEntry(d); });

        let deleteButton = egroup.append('g')
            .attr('transform', 'translate(' +
                (0.25 * font.ratio.medium * font.baseSize) + ',' +
                (- 0.45 * font.ratio.medium * font.baseSize) + ') scale(0.5,0.5)')
            .attr('class', 'delete button')
            .attr('opacity', 0.5)
            .on('mouseover', function () { 
                let t = d3.select(this);
                t.select('circle').attr('fill', colours.bright);
                t.select('use').attr('fill', colours.highlight);
            })
            .on('mouseout', function () {
                let t = d3.select(this);
                t.select('circle').attr('fill', colours.text);
                t.select('use').attr('fill', colours.bright);
            })
            .on('click', function(e, d) { controller.deleteEntryFromSelection(d); });

        deleteButton.append('circle')
            .attr('r', font.ratio.medium * font.baseSize * 0.6)
            .attr('cx', font.ratio.medium * font.baseSize * 0.5)
            .attr('cy', font.ratio.medium * font.baseSize * 0.5)
            .attr('fill', colours.text);

        deleteButton.append('use')
            .attr('xlink:href', '#circle-x')
            .attr('fill', colours.bright)
            .attr('width', font.ratio.medium * font.baseSize)
            .attr('height', font.ratio.medium * font.baseSize);
    };

    selectionList.controller = function(val) {
        if(!arguments.length) {
            return controller;
        }
        controller = val;
        return selectionList;
    };

    selectionList.labels = function(val) {
        if(!arguments.length) {
            return labels;
        }
        labels = val;
        return selectionList;
    };

    selectionList.lang = function(val) {
        if(!arguments.length) {
            return lang;
        }
        lang = val;
        return selectionList;
    };

    selectionList.x = function(val) {
        if(!arguments.length) {
            return x;
        }
        x = val;
        return selectionList;
    };

    selectionList.y = function(val) {
        if(!arguments.length) {
            return y;
        }
        y = val;
        return selectionList;
    };

    selectionList.font = function(obj) {
        if(!arguments.length) {
            return font;
        }
        font = obj;
        return selectionList;
    };

    selectionList.colours = function(obj) {
        if(!arguments.length) {
            return colours;
        }
        colours = obj;
        return selectionList;
    };

    selectionList.maxEntries = function(val) {
        if (!arguments.length) {
            return maxEntries;
        }
        maxEntries = val;
        return selectionList;
    };

    selectionList.width = function(val) {
        if (!arguments.length) {
            return width;
        }
        width = val;
        return selectionList;
    };

    selectionList.height = function(val) {
        if (!arguments.length) {
            return height;
        }
        height = val;
        return selectionList;
    };

    selectionList.transitionDuration = function(val) {
        if (!arguments.length) {
            return transitionDuration;
        }
        transitionDuration = val;
        return selectionList;
    };

    selectionList.controller(options.common.controller);
    selectionList.colours(options.common.colours);
    selectionList.font(options.common.font);
    selectionList.labels(options.common.labels);
    selectionList.lang(options.common.lang);
    selectionList.maxEntries(options.maxEntries);
    selectionList.x(options.x);
    selectionList.y(options.y);
    selectionList.width(options.width);
    selectionList.height(options.height);
    selectionList.transitionDuration(options.common.durations.listUpdate);
    return selectionList;
}
