#!/usr/bin/env raku

use Termbox;

my @chars = <
    n n n n n n n n n
    b b b b b b b b b
    u u u u u u u u u
    B B B B B B B B B
>;

my @all-attributes = (
    0,
    Termbox::BOLD,
    Termbox::UNDERLINE,
    Termbox::BOLD +| Termbox::UNDERLINE,
);

sub draw-line ( $x is copy, $y, $bg ) {
    for @all-attributes -> $attribute {
        for Termbox::DEFAULT .. Termbox::WHITE -> $color {
            my $fg = $attribute +| $color;
            my $c = @chars.shift;
            Termbox::change-cell( $x++, $y, $c.encode.first, $fg, $bg );
            @chars.push: $c;
        }
    }
}

sub print-combinations-table ( $x, $y is copy, *@attributes ) {
    for @attributes -> $attribute {
        for Termbox::DEFAULT .. Termbox::WHITE -> $color {
            draw-line( $x, $y++, $attribute +| $color );
        }
    }
}

sub draw-all {
    Termbox::clear;

    Termbox::select-output-mode(Termbox::OUTPUT_NORMAL);

    print-combinations-table( 1, 1, 0, Termbox::BOLD  );
    print-combinations-table( 2 + @chars.elems, 1, Termbox::REVERSE );

    Termbox::present;

    Termbox::select-output-mode(Termbox::OUTPUT_GRAYSCALE);

    my $y = 23;
    for ^24 -> $x {
        Termbox::change-cell( $x,      $y, '@'.encode.first, $x, 0  );
        Termbox::change-cell( $x + 25, $y, ' '.encode.first, 0,  $x );
    }

    Termbox::present;

    Termbox::select-output-mode(Termbox::OUTPUT_216);

    $y++;
    for ^216 -> $c {
        state $x = 0;

        if $x %% 24 {
            $x = 0;
            $y++;
        }

        Termbox::change-cell( $x,      $y, '@'.encode.first, $c, 0  );
        Termbox::change-cell( $x + 25, $y, ' '.encode.first, 0,  $c );

        $x++;
    }

    Termbox::present;

    Termbox::select-output-mode(Termbox::OUTPUT_256);

    $y++;
    for ^256 -> $c {
        state $x = 0;

        if $x %% 24 {
            $x = 0;
            $y++;
        }

        my $a = $y +& 1 ?? Termbox::UNDERLINE !! 0;
        Termbox::change-cell( $x,      $y, '+'.encode.first, $c +| $a, 0  );
        Termbox::change-cell( $x + 25, $y, ' '.encode.first, 0,        $c );

        $x++;
    }

    Termbox::present;
}

sub MAIN {
    use Termbox :subs, :events, :keys;

    if tb-init() -> $ret {
        note "tb-init failed with error code $ret";
        return 1;
    }

    LEAVE tb-shutdown;

    draw-all;

    my $events = Supplier.new;
    start {
        while tb-poll-event( my $ev = Termbox::Event.new ) { $events.emit: $ev }
    }

    react whenever $events.Supply -> $ev {
        given $ev.type {
            when TB_EVENT_KEY {
                given $ev.key {
                    when TB_KEY_ESC { done }
                }
            }
            when TB_EVENT_RESIZE {
                draw-all;
            }
        }
    }
}
