package TUI;

use strict;
use warnings;
use diagnostics;

use Curses::UI;

# Singleton
my $_cui;

sub init_cui {
    if ( !defined $_cui ) {
        $_cui = new Curses::UI(
            -color_support => 1,
            -mouse_support => 1,

            # -clear_on_exit => 1,
        );
    }

    return $_cui;
}

sub select_from_list {
    my ( $title, $multiselect, @items ) = @_;
    die "No items to choose from" unless @items;

    my @values = $multiselect ? ( '__ALL__', @items ) : @items;
    my %labels =
      $multiselect
      ? ( '__ALL__' => '[ALL]', map { $_ => $_ } @items, )
      : map { $_ => $_ } @items;

    my @selection;
    my @selection_order;    # multiselect only: items in toggle order

    my $cui = init_cui();
    my $win = $cui->add( 'root', 'Window', );

    my $listbox;
    $listbox = $win->add(
        'item_list',
        'Listbox',
        -title     => $title,
        -border    => 1,
        -values    => \@values,
        -labels    => \%labels,
        -multi     => $multiselect == 1,
        -radio     => $multiselect == 0,
        -padbottom => 1,
        -onchange  => sub {
            return unless $multiselect;
            my %now = map { $_ => 1 } $listbox->get();

            # Append newly selected items in toggle order
            for my $item (@items) {
                if ( $now{$item} && !grep { $_ eq $item } @selection_order ) {
                    push @selection_order, $item;
                }
            }

            # Drop deselected items
            @selection_order = grep { $now{$_} } @selection_order;
        },
    );

    $win->add(
        'info', 'Label',
        -y    => -1,
        -text => "Space/Enter = toggle, C = confirm, Q = quit",
    );

    $listbox->clear_binding('loose-focus');

    $listbox->set_binding(
        sub {
            my @picked = $listbox->get();
            if ( $multiselect && grep { $_ eq '__ALL__' } @picked ) {
                @selection = @items;
            }
            elsif ($multiselect) {
                @selection = @selection_order;
            }
            else {
                @selection = @picked;
            }
            $cui->mainloopExit();
        },
        'c',
    );

    $listbox->set_binding(
        sub {
            @selection = ();
            $cui->mainloopExit();
        },
        'q',
    );

    $listbox->focus();
    $cui->mainloop();

    $cui->leave_curses();
    $cui->delete('root');

    return @selection;
}

1;
