# menu for DCT, by Shiar

# 1.11.0 200410282200 - display-specific code in evals
# 1.10.4 200410151900 - remove explicit call to redraw on error
# 1.10.3 200410150030 - add quit at F10 in main menu (after running other modules)
#                     - don't show undefined menu entries (skippable)
# 1.10.2 200410122345 - addmenu() function to add submenus
# 1.10.1 200410122210 - @menus global; unit+math items added in those modules
# 1.09.1 200410112150 - everything related to menus moved here
# 1.06.1 200409152332 - moved @menus from 1.6 main

use strict;
use warnings;

my %falias = (
	"\033"                         =>  0, # esc
	"\033\117\120"                 =>  1, # f1
	"\033\133\061\061\176"         =>  1, # f1
	"\033\133\061\062\176"         =>  2, # f2
	"\033\133\061\063\176"         =>  3, # f3
	"\033\133\061\064\176"         =>  4, # f4
	"\033\117\121"                 =>  2, # f2
	"\033\117\122"                 =>  3, # f3
	"\033\117\123"                 =>  4, # f4
	"\033\133\061\065\176"         =>  5, # f5
	"\033\133\061\067\176"         =>  6, # f6
	"\033\133\061\070\176"         =>  7, # f7
	"\033\133\061\071\176"         =>  8, # f8
	"\033\133\062\060\176"         =>  9, # f9
	"\033\133\062\061\176"         => 10, # f10
	"\033\133\062\063\176"         => 11, # f11/F1
	"\033\133\062\064\176"         => 12, # f12/F2
	"\033\133\062\065\176"         => 13, # F3
	"\033\133\062\066\176"         => 14, # F4
	"\033\133\062\070\176"         => 15, # F5
	"\033\133\062\071\176"         => 16, # F6
	"\033\133\063\061\176"         => 17, # F7
	"\033\133\063\062\176"         => 18, # F8
	"\033\133\063\063\176"         => 19, # F9
	"\033\133\063\064\176"         => 20, # F10
	"\033\133\062\063\073\062\176" => 21, # F11
	"\033\133\062\064\073\062\176" => 22, # F12
	"\033\061"                     =>  1, # alt+1
	"\033\062"                     =>  2, # alt+2
	"\033\063"                     =>  3, # alt+3
	"\033\064"                     =>  4, # alt+4
	"\033\065"                     =>  5, # alt+5
	"\033\066"                     =>  6, # alt+6
	"\033\067"                     =>  7, # alt+7
	"\033\070"                     =>  8, # alt+8
	"\033\071"                     =>  9, # alt+9
	"\033\060"                     => 10, # alt+0
); # %falias

#our @menus = ([qw(refresh quit)]);
our @menus = (
	[qw(refresh prog> mode>1)], # main
	[qw(main>0 number_format angle_measure coord_system)], #1 mode
); # @menus

sub addmenu {
	my $parent = shift;
	push @menus, ["$parent->[0]>$parent->[1]"];  # create new menu
	my $menuthis = $#menus;
	push @{$menus[$parent->[1]]}, shift(@_).">$menuthis";  # link from parent
	ref $_ ? addmenu([$_->[0], $menuthis], @$_)  # add subsubmenu
		: push @{$menus[$menuthis]}, $_ for @_;  # add menu items
	return $menuthis;
} # addmenu

#my @menu = [];
our @menu;
our $menumin = 0;

push @{$hook{init}}, sub {
	$menus[0][10] = "quit";
	@menu = @{$menus[0]};
	$set{height}--;  # make space for menubar
	$set{menushow} = int($set{width}/(4+$set{width}/20))+1  # menu items to show simultaneously
		unless defined $set{menushow};
}; # init

my %show = (
	curses => q{
		clrtoeol($set{height}+2, 1);
		my $nr = -1;
		for (grep exists $menu[$_], $menumin+1..$menumin+$set{menushow}) {
			$nr++;
			next unless defined $menu[$_];
			my $sub = (my $s = $menu[$_]) =~ s/>\d+$//;
			addstr($set{height}+2, $set{width}/$set{menushow}*$nr, $_);
			attron(A_REVERSE);
			addstr($s);
			attroff(A_REVERSE);
			addch('>') if $sub;  # indicate submenu
		} # display menu txts
	},
	stdout => q{
		my $nr = -1;
		for (grep exists $menu[$_], $menumin+1..$menumin+$set{menushow}) {
			$nr++;
			next unless defined $menu[$_];
			my $sub = (my $s = $menu[$_]) =~ s/>\d+$//;
			print " $_:$s";
			print ">" if $sub;  # indicate submenu
		} # display menu txts
		print "\n> ";
	},
);

sub showmenu() {
	eval $_ if local $_ = $show{$::modules{disp}{name}};
} # showmenu

$action{more} = [-1, sub {
	$menumin += $set{menushow};
	$menumin = 0 if $menumin>=$#menu;
	showmenu();
}]; # tab

push @{$hook{refresh}}, sub {
	showmenu();
}; # refresh

unshift @{$hook{precmd}}, sub {
	return unless exists $falias{$_};  # not a function key
	return if $_ = $menu[$falias{$_}];  # execute found menu item instead
	error("no such menu entry");
	return 1;
}; # precmd

push @{$hook{precmd}}, sub {
	return unless />(\d+)$/;
	@menu = @{$menus[$1]};  # go to submenu
	$menumin = 0;  # reset to first item
	showmenu();  # redraw
	return 1;
}; # precmd

return {
	author  => "Shiar",
	title   => "menu",
	version => "1.11",
};

