
# menus.pl -- Copyright (c) 1990, Henk P. Penning.
# You may distribute under the terms of the GNU General Public License
# as specified in the README file that comes with the Jinx 2.0 kit.

sub addMenu
  { return 0 if $menuError ;
    local(*Menu,$entry,$choice,$tag,$help) = @_ ;
    local($a) ;
    push(@Menu,$entry) ;
    if ( $entry !~ /arrow=/ )
      { $Menu{$choice} = $tag ;
        $Menu{"help_$choice"} = $help ;
	if ( $entry =~ /TAB=/ )
          { $Menu{'KEY_TAB'} = $choice ;
            $Menu{"help_KEY_TAB"} = $help ;
	  }
      }
    else
      { if ( $entry =~ /^arrow=/ )
          { $Menu{'h'}      = $Menu{'KEY_LEFT'}       = 'left' ;
            $Menu{'j'}      = $Menu{'KEY_DOWN'}       = 'down' ;
            $Menu{'k'}      = $Menu{'KEY_UP'}         = 'up' ;
	    $Menu{'l'}      = $Menu{'KEY_RIGHT'}      = 'right' ;
            $Menu{'help_h'} = $Menu{'help_KEY_LEFT'}  = 'move view left' ;
            $Menu{'help_j'} = $Menu{'help_KEY_DOWN'}  = 'move cursor down' ;
            $Menu{'help_k'} = $Menu{'help_KEY_UP'}    = 'move cursor up' ;
            $Menu{'help_l'} = $Menu{'help_KEY_RIGHT'} = 'move view right' ;
          }
        if ( $entry =~ /left.*arrow=/ )
          { $Menu{'h'}      = $Menu{'KEY_LEFT'}       = 'left' ;
            $Menu{"help_h"} = $Menu{"help_KEY_LEFT"}  = $choice ;
	  }
        if ( $entry =~ /down.*arrow=/ )
          { $Menu{'j'}      = $Menu{'KEY_DOWN'}       = 'down' ;
            $Menu{"help_j"} = $Menu{"help_KEY_DOWN"}  = $choice ;
	  }
        if ( $entry =~ /up.*arrow=/ )
          { $Menu{'k'}      = $Menu{'KEY_UP'}         = 'up' ;
            $Menu{"help_k"} = $Menu{"help_KEY_UP"}    = $choice ;
	  }
        if ( $entry =~ /right.*arrow=/ )
          { $Menu{'l'}      = $Menu{'KEY_RIGHT'}      = 'right' ;
            $Menu{"help_l"} = $Menu{"help_KEY_RIGHT"} = $choice ;
	  }
      }
  }

sub makeMenu
  { return () if $menuError ;
    local($cnt,$curlen) = (-1,$COLS) ;
    local(@res,$i,$strlen,$_) ;

    for ( @_ )
      { if ( $i == $#_ )
	  { $_ = "or $_" ; }
	else
	  { $_ .= ',' ; }
	$strlen = length ;
	$menuError = 1 if $strlen > $COLS ;
        if ( $curlen + $strlen >= $COLS )
          { $cnt++ ;
            push(@res,$_) ;
            $curlen = $strlen ;
          }
        else
          { $curlen += ($strlen+1) ;
            $res[$cnt] .= ( ' ' . $_ ) ;
          }
	$i++ ;
      }
    return @res ;
  }

sub mkMetaMenu {
%metaMenu = () ;
@metaMenu = () ;
&addMenu(*metaMenu,"arrow=scroll") ;
&addMenu(*metaMenu,"n)ext",'n','next','show next data page') ;
&addMenu(*metaMenu,"p)rev",'p','prev','show previous data page') ;
&addMenu(*metaMenu,"g)oto",'g','goto','ask record number; show record') ;
&addMenu(*metaMenu,"/=search",'/','search','ask regexp; show matching record') ;
&addMenu(*metaMenu,";=re-search",';','re-search',
  'search with previous regexp; show matching record') ;
&addMenu(*metaMenu,"i)nspect",'i','inspect','show data record by record') ;
&addMenu(*metaMenu,"D)escr",'D','Descr','inspect and change descriptor') ;
&addMenu(*metaMenu,"P)roject",'P','Project','select columns by name') ;
&addMenu(*metaMenu,"J)oin",'J','Join','join database on cols with same name') ;
&addMenu(*metaMenu,"O)rder",'O','Order','sort on specific keys' ) ;
&addMenu(*metaMenu,"T)est all",'T','Test','test if records match the cpats') ;
&addMenu(*metaMenu,"A)dd field",'A','Add field','add a field to the database') ;
&addMenu(*metaMenu,"s)ave",'s','save','save current database') ;
&addMenu(*metaMenu,"S)ave as",'S','Save as','save db under specific name') ;
&addMenu(*metaMenu,"o)pen",'o','open','open a new database') ;
&addMenu(*metaMenu,"G)uess",'G','Guess','ask file and separator, build db') ;
&addMenu(*metaMenu,"C)lear",'C','Clear','Forget about current database') ;
&addMenu(*metaMenu,"TAB=q)uit",'q','quit','leave jinx') ;
&addMenu(*metaMenu,"Q)uit without save",'Q','QUIT','leave jinx; no update') ;
@metaMenu = &makeMenu(@metaMenu) ;
return $#metaMenu ;
}

sub mkMainMenu {
%mainMenu = () ;
@mainMenu = () ;
&addMenu(*mainMenu,'arrow=scroll') ;
&addMenu(*mainMenu,"n)ext",'n','next','show next record') ;
&addMenu(*mainMenu,"p)rev",'p','previous','show previous record') ;
&addMenu(*mainMenu,"g)oto",'g','goto','ask number; show record') ;
&addMenu(*mainMenu,"/=search",'/','search','ask pattern; search record') ;
&addMenu(*mainMenu,";=re-search",';','re-search',
  'search with previous regexp; show matching record') ;
&addMenu(*mainMenu,"u)pdate",'u','update','edit current record') ;
&addMenu(*mainMenu,"a)dd",'a','add','add empty record; edit') ;
&addMenu(*mainMenu,"c)opy",'c','copy','copy current record; edit') ;
&addMenu(*mainMenu,"d)elete",'d','delete','delete current record') ;
&addMenu(*mainMenu,"U)ndo",'U','Undo','put back deleted records') ;
&addMenu(*mainMenu,"C)ompute",'C','Compute',
  'compute new values for one or more columns') ;
&addMenu(*mainMenu,"E)xtract",'E','Extract','Extract selection') ;
&addMenu(*mainMenu,"D)elete",'D','Delete','Delete selection') ;
&addMenu(*mainMenu,"P)eek",'P','Peek',
  'ask for database; present records to select') ;
&addMenu(*mainMenu,"R)ead",'R','Read',
  'ask for database; present only new records to select') ;
&addMenu(*mainMenu,"K)ey test",'K','Key test',
  'ask key-fields; test if keys are unique (if no keys, uniq records)') ;
&addMenu(*mainMenu,"O)rder",'O','Order','sort on specific keys' ) ;
&addMenu(*mainMenu,"t)est",'t','test','test if fields match cpats') ;
&addMenu(*mainMenu,"T)est all",'T','Test','test if all records match cpats') ;
&addMenu(*mainMenu,"TAB=q)uit",'q','quit','leave inspect mode') ;
&addMenu(*mainMenu,"Q)uit without save",'Q','QUIT','leave jinx; no update') ;
@mainMenu = &makeMenu(@mainMenu) ;
return $#mainMenu ;
}

sub mkSelectFromMenu {
%selectFromMenu = () ;
@selectFromMenu = () ;
&addMenu(*selectFromMenu,"arrow=scroll") ;
&addMenu(*selectFromMenu,"n)ext",'n','next','show next record') ;
&addMenu(*selectFromMenu,"p)rev",'p','previous','show previous record') ;
&addMenu(*selectFromMenu,"g)oto",'g','goto','ask number; show record') ;
&addMenu(*selectFromMenu,"/=search",'/','search','ask pattern; search record') ;
&addMenu(*selectFromMenu,";=re-search",';','re-search',
  'search with previous regexp; show matching record') ;
&addMenu(*selectFromMenu,">=next mark",'>','next mark',
  'goto next marked record') ;
&addMenu(*selectFromMenu,"<=prev mark",'<','previous mark',
  'goto previous marked record') ;
&addMenu(*selectFromMenu,")=next unmark",')','next unmark',
  'goto next unmarked record') ;
&addMenu(*selectFromMenu,"(=prev unmark",'(','previous unmark',
  'goto previous unmarked record') ;
&addMenu(*selectFromMenu,"t)oggle",'t','toggle','toggle marking') ;
&addMenu(*selectFromMenu,"T)oggle",'T','Toggle all',
  'toggle marking of all records') ;
&addMenu(*selectFromMenu,"C)lear",'C','Clear marks',
  'unmark all records') ;
&addMenu(*selectFromMenu,"M)ark",'M','Mark subset','ask patterns; mark') ;
&addMenu(*selectFromMenu,"U)nmark",'U','Unmark subset','ask patterns; unmark') ;
&addMenu(*selectFromMenu,"s)elect one",'s','select',
  'select only the current record') ;
&addMenu(*selectFromMenu,"S)elect marked",'S','select marked',
  'select all marked records') ;
&addMenu(*selectFromMenu,"TAB=q)uit select",'q','quit',
  'back to previous menu; no changes') ;
@selectFromMenu = &makeMenu(@selectFromMenu) ;
return $#selectFromMenu ;
}

sub mkUpdateMenu {
@updateMenu= () ;
%updateMenu= () ;
&addMenu(*updateMenu,"arrow=move cursor") ;
&addMenu(*updateMenu,"TAB=finish",'','','finish update') ;
@updateMenu = &makeMenu(@updateMenu) ;
return $#updateMenu ;
}

sub mkUpdateAddMenu {
@updateAddMenu= () ;
%updateAddMenu= () ;
&addMenu(*updateAddMenu,"arrow=move cursor") ;
&addMenu(*updateAddMenu,"TAB=finish",'','','finish update') ;
@updateAddMenu = &makeMenu(@updateAddMenu) ;
return $#updateAddMenu ;
}

sub mkUpdateXMenu {
@updateXMenu= () ;
%updateXMenu= () ;
&addMenu(*updateXMenu,"a)ccept",'a','accept','confirm this update') ;
&addMenu(*updateXMenu,"TAB=f)orget",'f','forget','leave it as it was') ;
&addMenu(*updateXMenu,"e)dit",'e','edit','edit it again') ;
@updateXMenu = &makeMenu(@updateXMenu) ;
return $#updateXMenu ;
}

sub mkUpdMatchMenu {
@updMatchMenu= () ;
%updMatchMenu= () ;
&addMenu(*updMatchMenu,"e)dit",'e','edit','edit it again') ;
&addMenu(*updMatchMenu,"a)ccept",'a','accept','confirm this update') ;
&addMenu(*updMatchMenu,"f)orget",'f','forget','leave it as it was') ;
&addMenu(*updMatchMenu,"TAB=q)uit",'q','quit','abandon all changes') ;
@updMatchMenu = &makeMenu(@updMatchMenu) ;
return $#updMatchMenu ;
}

sub mkUpdReMenu {
@updReMenu= () ;
%updReMenu= () ;
&addMenu(*updReMenu,"e)dit",'e','edit','edit it again') ;
&addMenu(*updReMenu,"f)orget",'f','forget','leave it as it was') ;
&addMenu(*updReMenu,"TAB=q)uit",'q','quit','abandon all changes') ;
@updReMenu = &makeMenu(@updReMenu) ;
return $#updReMenu ;
}

sub mkDirtyMenu {
@dirtyMenu= () ;
%dirtyMenu= () ;
&addMenu(*dirtyMenu,"y)es",'y','yes','confirm') ;
&addMenu(*dirtyMenu,"TAB=n)o",'n','no','deny') ;
@dirtyMenu = &makeMenu(@dirtyMenu) ;
return $#dirtyMenu ;
}

sub mkNoKeyMenu {
@noKeyMenu= () ;
%noKeyMenu= () ;
&addMenu(*noKeyMenu,"a)dd empty data",'a','add',
  'add empty join-data for this record') ;
&addMenu(*noKeyMenu,"d)elete this record",'d','delete',
  'don\'t join with this record') ;
&addMenu(*noKeyMenu,"A)dd empty data for all undefined keys",'A','Add',
  'add empty join-data for all records that don\'t join with anything') ;
&addMenu(*noKeyMenu,"D)elete all undefined keys",'D','Delete',
  'don\'t join with any record that can\'t be joined with properly') ;
&addMenu(*noKeyMenu,"TAB=q)uit",'q','quit','leave Join; no change') ;
@noKeyMenu = &makeMenu(@noKeyMenu) ;
return $#noKeyMenu ;
}

sub mkMultiKeyMenu {
@multiKeyMenu= () ;
%multiKeyMenu= () ;
&addMenu(*multiKeyMenu,"a)dd all",'a','add',
  'join with all records') ;
&addMenu(*multiKeyMenu,"A)lways add all",'A','Always add all',
  'always join with all possible records') ;
&addMenu(*multiKeyMenu,"d)elete this record",'d','delete',
  'leave this record out of the join') ;
&addMenu(*multiKeyMenu,"D)elete Multi's always",'D','Delete',
  'leave out any record which can be joined with more than one record') ;
&addMenu(*multiKeyMenu,"s)how to select",'s','show',
  'show which records can be joined with') ;
&addMenu(*multiKeyMenu,"TAB=q)uit",'q','quit','leave Join; no change') ;
@multiKeyMenu = &makeMenu(@multiKeyMenu) ;
return $#multiKeyMenu ;
}

sub mkKeyTestMenu {
@keyTestMenu= () ;
%keyTestMenu= () ;
&addMenu(*keyTestMenu,"n)ext",'n','next',
  'skip current record; test following records') ;
&addMenu(*keyTestMenu,"s)how to delete",'s','show',
  'show records; delete selection') ;
&addMenu(*keyTestMenu,"q)uit",'q','quit',
  'leave Keytest; make changes indicated sofar') ;
&addMenu(*keyTestMenu,"TAB=ex)it",'x','exit','leave Keytest; no change') ;
@keyTestMenu = &makeMenu(@keyTestMenu) ;
return $#keyTestMenu ;
}

sub mkSearchMenu {
@searchMenu= () ;
%searchMenu= () ;
&addMenu(*searchMenu,"up/down-arrow=previous entries",
  'scroll through previous entries') ;
&addMenu(*searchMenu,"RET=finish",'','') ;
&addMenu(*searchMenu,"TAB=quit",'','') ;
@searchMenu = &makeMenu(@searchMenu) ;
return $#searchMenu ;
}

sub mkTestMenu {
@testMenu= () ;
%testMenu= () ;
&addMenu(*testMenu,"n)ext",'n','next','search next mismatch') ;
&addMenu(*testMenu,"N)ext",'N','Next','search next record with mismatch') ;
&addMenu(*testMenu,"u)pdate",'u','update','update current record') ;
&addMenu(*testMenu,"TAB=q)uit",'q','quit','leave testing') ;
@testMenu = &makeMenu(@testMenu) ;
return $#testMenu ;
}

sub mkGetNamesMenu {
@getNamesMenu= () ;
%getNamesMenu= () ;
&addMenu(*getNamesMenu,"up/down-arrow=move cursor",'move cursor') ;
&addMenu(*getNamesMenu,"right-arrow=select",'select/de-select') ;
$getNamesMenu{'KEY_RIGHT'} = 'select' ;
$getNamesMenu{'help_KEY_RIGHT'} = 'select current name' ;
$getNamesMenu{'l'} = 'select' ;
$getNamesMenu{'help_l'} = 'select current name' ;
&addMenu(*getNamesMenu,"left-arrow=delete") ;
$getNamesMenu{'KEY_LEFT'} = 'delete' ;
$getNamesMenu{'help_KEY_LEFT'} = 'de-select current name' ;
$getNamesMenu{'h'} = 'delete' ;
$getNamesMenu{'help_h'} = 'de-select current name' ;
&addMenu(*getNamesMenu,"i)ncr",'i','increment',
  'move current name up in the list') ;
&addMenu(*getNamesMenu,"d)ecr",'d','decrement',
  'move current name down in the list') ;
&addMenu(*getNamesMenu,"s)how",'s','show',
  'show the current list by name') ;
&addMenu(*getNamesMenu,"q)uit",'q','quit',
  'leave select mode') ;
&addMenu(*getNamesMenu,"TAB=ex)it",'x','exit',
  'abandon select; no change') ;
@getNamesMenu = &makeMenu(@getNamesMenu) ;
return $#getNamesMenu ;
}

sub mkDoDescrMenu {
@doDescrMenu= () ;
%doDescrMenu= () ;
&addMenu(*doDescrMenu,"up/down-arrow=move cursor",'move cursor') ;
&addMenu(*doDescrMenu,"p)at edit",'p','pat edit','edit patterns') ;
&addMenu(*doDescrMenu,"n)ame edit",'n','name edit','update names') ;
&addMenu(*doDescrMenu,"q)uit",'q','quit','finish updating') ;
&addMenu(*doDescrMenu,"TAB=ex)it",'x','exit','leave; no updates') ;
@doDescrMenu = &makeMenu(@doDescrMenu) ;
return $#doDescrMenu ;
}

sub initMenus {
$maxMenuSize = &max(&mkMetaMenu,&mkMainMenu,&mkUpdateMenu,&mkUpdateAddMenu,
		    &mkUpdateXMenu,&mkUpdReMenu,&mkUpdMatchMenu,&mkSearchMenu,
		    &mkDirtyMenu,&mkNoKeyMenu,&mkMultiKeyMenu,&mkKeyTestMenu,
		    &mkSelectFromMenu,&mkTestMenu,&mkGetNamesMenu,
		    &mkDoDescrMenu) ;

&QUIT('terminal not wide enough for menu.') if $menuError ;
}

1;
