/* GNU moe - My Own Editor
   Copyright (C) 2005-2025 Antonio Diaz Diaz.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <cstdio>
#include <string>
#include <vector>

#include "buffer.h"
#include "menu.h"
#include "screen.h"


namespace Menu {

const char * help_line[] = {
  " Help Screen: Keyboard Commands               PAGE_DN next",
  " @bF1@b Help           @bF5@b Prev window     @bF9@b Copy block     ^C  Close window",
  " @bF2@b Save file      @bF6@b Next window    @bF10@b Options menu   ^X  Save and close",
  " @bF3@b Load file      @bF7@b Undo           @bF11@b Buffers menu   ^QX Save all and exit",
  " @bF4@b Zoom window    @bF8@b Redo           @bF12@b Last visited   ^QC Exit without saving",
  " ",
  " @bGO TO@b                  @bSEARCH@b                      @bMISC@b",
  " ^[U Begin of file      ^F  Find                    Ins  Insert/Overwrite",
  " ^[V End of file        ^G  Find next               Tab  File name completion",
  " ^[L Line               ^W  Find word               ^A 1-90AB  Alternative @bFn@b",
  " ^[C Column             ^OF Toggle direction        ^B   Reformat paragraph",
  " ^[O Offset             ^QU update (C)              ^P   Control char",
  " ^[B Begin of block                                 ^Y   Delete line",
  " ^[K End of block       @bINFO@b                        ^OC  Center line",
  " ^[F Match pair ->      ^H   Show help              ^ON  Change buffer name",
  " ^[G Match pair <-      ^[I  Show character info    ^OR  Repaint screen",
  " ^[D Center cursor      ^[T  Show UTF-8 code        ^OS  Split window",
  "                        ^Sn  Show LE multibyte      ^Q@bF2@b Save named buffers",
  " @bSCROLL@b                 ^S@bFn@b Show BE multibyte",
  " ^[W Up                 ^SC  Show character code    @bBOOKMARKS@b",
  " ^[Z Down               ^SG  Show global status     ^[ 0-9  Goto",
  " ^[A Left               ^SP  Show line position     ^K 0-9  Set",
  " ^[S Right              ^SV  Show version           ^KE     Extend",
  "",
  " Help Screen: Block Commands     PAGE_DN next/PAGE_UP prev",
  " ",
  " @bBLOCK@b                     @bENCODE@b                 @bREMOVE@b",
  " ^SPACE Mark begin/end     ^O1 To Base64          ^OD Duplicate lines forwards",
  " ^KB Begin                 ^O3 To Rot-13          ^OE Duplicate lines backwards",
  " ^KK End                   ^O4 To Rot-47          ^OO UTF-8 out of range",
  " ^KC Copy                  ^O5 To ASCII",
  " ^KM Move                  ^O7 To UTF-8",
  " ^KY Delete",
  " ^KR Read                  @bDECODE@b",
  " ^KW Write                 ^O2 Base64",
  " ^KI Indent                ^O6 Quoted-Printable",
  " ^KU Unindent              ^O8 UTF-8",
  " ^OB Reformat paragraphs",
  " ^OK Capitalize words",
  " ^OL To lowercase",
  " ^OU To uppercase",
  " ",
  " ",
  " ",
  " ",
  " ^[X means Alt-X or Esc-X    ^X means Control-X",
  " ",
  " See manual (moe.info) for a complete explanation of moe's commands.",
  "",
  " Help Screen: Search             PAGE_DN next/PAGE_UP prev",
  " ",
  " Special search sequences:",
  "   \\?      matches any single char       \\^  \\$  matches beginning/end of line",
  "   \\*      matches 0 or more chars       \\<  \\>  matches beginning/end of word",
  "   \\[..]   matches one in a set          \\c      matches balanced C expression",
  "   \\[^..]  matches one not in a set      \\T      matches trailing whitespace",
  "   \\s      matches 0 or more whitespace characters",
  "   \\S      matches the longest possible non-empty sequence of whitespace",
  "   \\w      matches any word-constituent character",
  "   \\W      matches any character that is not a word-constituent",
  "   \\=<ch>  matches one in an equivalence class; '\\=e' = '\\[eèéêë]'",
  "   \\+<ch>  matches 0 or more of <ch> (also \\[..], \\w, \\W, or \\=<ch>)",
  " ",
  " Notes",
  "   Ranges of characters may be specified in sets with 'A-Z'",
  "   '-' may be specified in sets by placing it first or last",
  "   ']' may be specified in sets by placing it first",
  "   \\u and \\U may not be specified in sets nor after \\+",
  "   \\+ may precede itself any number of times, matching N-1 chars",
  "",
  " Help Screen: Replace            PAGE_DN next/PAGE_UP prev",
  " ",
  " Special replace sequences:",
  "   \\&      replaced with text which matched search string",
  "   \\c      same as \\& but matched text is capitalized",
  "   \\l  \\u  same as \\& but matched text is lowercased / uppercased",
  "   \\0 - 9  replaced with text which matched the Nth special search sequence",
  " ",
  " Notes",
  "   \\u0 may be specified as \\u\\x30 to avoid ambiguity with \\uhhhh",
  "   Octal escape sequences can't be used in the replacement string",
  " ",
  " Escape sequences for special characters (search or replace (except \\ooo)):",
  "   \\a  BEL (alert)       \\n  LF (newline)           \\\\    '\\' (backslash)",
  "   \\b  BS  (backspace)   \\r  CR (carriage return)   \\dddd decimal code 'ddd'",
  "   \\e  ESC (escape)      \\t  HT (tab)               \\ooo  octal code 'ooo'",
  "   \\f  FF  (form feed)   \\v  VT (vertical tab)      \\xhh  hexadecimal code 'hh'",
  "                                                    \\uhhhh \\Uhhhhhhhh  UTF-8",
  "",
  " Help Screen: Character Set      PAGE_DN next/PAGE_UP prev",
  "  \x20    \x21    \x22    \x23    \x24    \x25    \x26    \x27    \x28    \x29    \x2A    \x2B    \x2C    \x2D    \x2E    \x2F",
  "  32   33   34   35   36   37   38   39   40   41   42   43   44   45   46   47",
  "  \x30    \x31    \x32    \x33    \x34    \x35    \x36    \x37    \x38    \x39    \x3A    \x3B    \x3C    \x3D    \x3E    \x3F",
  "  48   49   50   51   52   53   54   55   56   57   58   59   60   61   62   63",
  "  \x40    \x41    \x42    \x43    \x44    \x45    \x46    \x47    \x48    \x49    \x4A    \x4B    \x4C    \x4D    \x4E    \x4F",
  "  64   65   66   67   68   69   70   71   72   73   74   75   76   77   78   79",
  "  \x50    \x51    \x52    \x53    \x54    \x55    \x56    \x57    \x58    \x59    \x5A    \x5B    \x5C    \x5D    \x5E    \x5F",
  "  80   81   82   83   84   85   86   87   88   89   90   91   92   93   94   95",
  "  \x60    \x61    \x62    \x63    \x64    \x65    \x66    \x67    \x68    \x69    \x6A    \x6B    \x6C    \x6D    \x6E    \x6F",
  "  96   97   98   99  100  101  102  103  104  105  106  107  108  109  110  111",
  "  \x70    \x71    \x72    \x73    \x74    \x75    \x76    \x77    \x78    \x79    \x7A    \x7B    \x7C    \x7D    \x7E",
  " 112  113  114  115  116  117  118  119  120  121  122  123  124  125  126",
  "  \xA0    \xA1    \xA2    \xA3    \xA4    \xA5    \xA6    \xA7    \xA8    \xA9    \xAA    \xAB    \xAC    \xAD    \xAE    \xAF",
  " 160  161  162  163  164  165  166  167  168  169  170  171  172  173  174  175",
  "  \xB0    \xB1    \xB2    \xB3    \xB4    \xB5    \xB6    \xB7    \xB8    \xB9    \xBA    \xBB    \xBC    \xBD    \xBE    \xBF",
  " 176  177  178  179  180  181  182  183  184  185  186  187  188  189  190  191",
  "  \xC0    \xC1    \xC2    \xC3    \xC4    \xC5    \xC6    \xC7    \xC8    \xC9    \xCA    \xCB    \xCC    \xCD    \xCE    \xCF",
  " 192  193  194  195  196  197  198  199  200  201  202  203  204  205  206  207",
  "  \xD0    \xD1    \xD2    \xD3    \xD4    \xD5    \xD6    \xD7    \xD8    \xD9    \xDA    \xDB    \xDC    \xDD    \xDE    \xDF",
  " 208  209  210  211  212  213  214  215  216  217  218  219  220  221  222  223",
  "  \xE0    \xE1    \xE2    \xE3    \xE4    \xE5    \xE6    \xE7    \xE8    \xE9    \xEA    \xEB    \xEC    \xED    \xEE    \xEF",
  " 224  225  226  227  228  229  230  231  232  233  234  235  236  237  238  239",
  "  \xF0    \xF1    \xF2    \xF3    \xF4    \xF5    \xF6    \xF7    \xF8    \xF9    \xFA    \xFB    \xFC    \xFD    \xFE    \xFF",
  " 240  241  242  243  244  245  246  247  248  249  250  251  252  253  254  255",
  "",
  " Help Screen: Character Set (oct)PAGE_DN next/PAGE_UP prev",
  "  \x20    \x21    \x22    \x23    \x24    \x25    \x26    \x27    \x28    \x29    \x2A    \x2B    \x2C    \x2D    \x2E    \x2F",
  " 040  041  042  043  044  045  046  047  050  051  052  053  054  055  056  057",
  "  \x30    \x31    \x32    \x33    \x34    \x35    \x36    \x37    \x38    \x39    \x3A    \x3B    \x3C    \x3D    \x3E    \x3F",
  " 060  061  062  063  064  065  066  067  070  071  072  073  074  075  076  077",
  "  \x40    \x41    \x42    \x43    \x44    \x45    \x46    \x47    \x48    \x49    \x4A    \x4B    \x4C    \x4D    \x4E    \x4F",
  " 100  101  102  103  104  105  106  107  110  111  112  113  114  115  116  117",
  "  \x50    \x51    \x52    \x53    \x54    \x55    \x56    \x57    \x58    \x59    \x5A    \x5B    \x5C    \x5D    \x5E    \x5F",
  " 120  121  122  123  124  125  126  127  130  131  132  133  134  135  136  137",
  "  \x60    \x61    \x62    \x63    \x64    \x65    \x66    \x67    \x68    \x69    \x6A    \x6B    \x6C    \x6D    \x6E    \x6F",
  " 140  141  142  143  144  145  146  147  150  151  152  153  154  155  156  157",
  "  \x70    \x71    \x72    \x73    \x74    \x75    \x76    \x77    \x78    \x79    \x7A    \x7B    \x7C    \x7D    \x7E",
  " 160  161  162  163  164  165  166  167  170  171  172  173  174  175  176",
  "  \xA0    \xA1    \xA2    \xA3    \xA4    \xA5    \xA6    \xA7    \xA8    \xA9    \xAA    \xAB    \xAC    \xAD    \xAE    \xAF",
  " 240  241  242  243  244  245  246  247  250  251  252  253  254  255  256  257",
  "  \xB0    \xB1    \xB2    \xB3    \xB4    \xB5    \xB6    \xB7    \xB8    \xB9    \xBA    \xBB    \xBC    \xBD    \xBE    \xBF",
  " 260  261  262  263  264  265  266  267  270  271  272  273  274  275  276  277",
  "  \xC0    \xC1    \xC2    \xC3    \xC4    \xC5    \xC6    \xC7    \xC8    \xC9    \xCA    \xCB    \xCC    \xCD    \xCE    \xCF",
  " 300  301  302  303  304  305  306  307  310  311  312  313  314  315  316  317",
  "  \xD0    \xD1    \xD2    \xD3    \xD4    \xD5    \xD6    \xD7    \xD8    \xD9    \xDA    \xDB    \xDC    \xDD    \xDE    \xDF",
  " 320  321  322  323  324  325  326  327  330  331  332  333  334  335  336  337",
  "  \xE0    \xE1    \xE2    \xE3    \xE4    \xE5    \xE6    \xE7    \xE8    \xE9    \xEA    \xEB    \xEC    \xED    \xEE    \xEF",
  " 340  341  342  343  344  345  346  347  350  351  352  353  354  355  356  357",
  "  \xF0    \xF1    \xF2    \xF3    \xF4    \xF5    \xF6    \xF7    \xF8    \xF9    \xFA    \xFB    \xFC    \xFD    \xFE    \xFF",
  " 360  361  362  363  364  365  366  367  370  371  372  373  374  375  376  377",
  "",
  " Help Screen: Character Set (hex)             PAGE_UP prev",
  "  \x20    \x21    \x22    \x23    \x24    \x25    \x26    \x27    \x28    \x29    \x2A    \x2B    \x2C    \x2D    \x2E    \x2F",
  "  20   21   22   23   24   25   26   27   28   29   2A   2B   2C   2D   2E   2F",
  "  \x30    \x31    \x32    \x33    \x34    \x35    \x36    \x37    \x38    \x39    \x3A    \x3B    \x3C    \x3D    \x3E    \x3F",
  "  30   31   32   33   34   35   36   37   38   39   3A   3B   3C   3D   3E   3F",
  "  \x40    \x41    \x42    \x43    \x44    \x45    \x46    \x47    \x48    \x49    \x4A    \x4B    \x4C    \x4D    \x4E    \x4F",
  "  40   41   42   43   44   45   46   47   48   49   4A   4B   4C   4D   4E   4F",
  "  \x50    \x51    \x52    \x53    \x54    \x55    \x56    \x57    \x58    \x59    \x5A    \x5B    \x5C    \x5D    \x5E    \x5F",
  "  50   51   52   53   54   55   56   57   58   59   5A   5B   5C   5D   5E   5F",
  "  \x60    \x61    \x62    \x63    \x64    \x65    \x66    \x67    \x68    \x69    \x6A    \x6B    \x6C    \x6D    \x6E    \x6F",
  "  60   61   62   63   64   65   66   67   68   69   6A   6B   6C   6D   6E   6F",
  "  \x70    \x71    \x72    \x73    \x74    \x75    \x76    \x77    \x78    \x79    \x7A    \x7B    \x7C    \x7D    \x7E",
  "  70   71   72   73   74   75   76   77   78   79   7A   7B   7C   7D   7E",
  "  \xA0    \xA1    \xA2    \xA3    \xA4    \xA5    \xA6    \xA7    \xA8    \xA9    \xAA    \xAB    \xAC    \xAD    \xAE    \xAF",
  "  A0   A1   A2   A3   A4   A5   A6   A7   A8   A9   AA   AB   AC   AD   AE   AF",
  "  \xB0    \xB1    \xB2    \xB3    \xB4    \xB5    \xB6    \xB7    \xB8    \xB9    \xBA    \xBB    \xBC    \xBD    \xBE    \xBF",
  "  B0   B1   B2   B3   B4   B5   B6   B7   B8   B9   BA   BB   BC   BD   BE   BF",
  "  \xC0    \xC1    \xC2    \xC3    \xC4    \xC5    \xC6    \xC7    \xC8    \xC9    \xCA    \xCB    \xCC    \xCD    \xCE    \xCF",
  "  C0   C1   C2   C3   C4   C5   C6   C7   C8   C9   CA   CB   CC   CD   CE   CF",
  "  \xD0    \xD1    \xD2    \xD3    \xD4    \xD5    \xD6    \xD7    \xD8    \xD9    \xDA    \xDB    \xDC    \xDD    \xDE    \xDF",
  "  D0   D1   D2   D3   D4   D5   D6   D7   D8   D9   DA   DB   DC   DD   DE   DF",
  "  \xE0    \xE1    \xE2    \xE3    \xE4    \xE5    \xE6    \xE7    \xE8    \xE9    \xEA    \xEB    \xEC    \xED    \xEE    \xEF",
  "  E0   E1   E2   E3   E4   E5   E6   E7   E8   E9   EA   EB   EC   ED   EE   EF",
  "  \xF0    \xF1    \xF2    \xF3    \xF4    \xF5    \xF6    \xF7    \xF8    \xF9    \xFA    \xFB    \xFC    \xFD    \xFE    \xFF",
  "  F0   F1   F2   F3   F4   F5   F6   F7   F8   F9   FA   FB   FC   FD   FE   FF",
  0 };


class Help_index		// index of first lines of each help screen
  {
  std::vector< int > data;
public:
  Help_index()
    {
    data.push_back( 0 );
    for( int i = 0; ; ++i )
      {
      const char * p = help_line[i];
      if( !p || *p == 0 ) { data.push_back( i + 1 ); if( !p ) break; }
      }
    }
  int operator[]( const int i ) const { return data[i]; }
  int size() const { return data.size(); }
  } help_index;


void show_help_screen( const int current )
  {
  int line = 0;
  int i = help_index[current];		// first line of current help screen
  int size = 0;
  char * const buf = Screen::status_line_buf( &size );

  snprintf( buf, size, "%s  %5s  F1 exit help",
            help_line[i], Screen::clock_string() );
  Screen::out_line( buf, line, false, 'i' ); ++line; ++i;

  while( line < Screen::height() &&
         i < help_index[current+1] - 1 && help_line[i] )
    { Screen::out_line( help_line[i], line ); ++line; ++i; }

  while( line < Screen::height() ) { Screen::out_line( "", line ); ++line; }
  }

} // end namespace Menu


void Menu::help_menu( const int abort_key1, const int abort_key2 )
  {
  static int current = 0;
  int old = -1;				// make old != current

  Screen::save_lines_and_cursor( 0, Screen::height() );
  while( true )
    {
    if( old != current )
      {
      old = current;
      show_help_screen( current );
      Screen::move_to( Point( 0, Screen::width() - 1 ) );
      }
    const int key = Screen::wait_kbhit( 1 );	// show clock on line 0 only
    if( key == 3 || key == abort_key1 || key == abort_key2 ) break;	// ^C
    switch( Screen::convert_key( key ) )
      {
      case Screen::key_down :
      case Screen::key_npage:
        if( current + 2 < help_index.size() ) { ++current; } break;
      case Screen::key_up   :
      case Screen::key_ppage: if( current > 0 ) --current; break;
      case Screen::key_home : current = 0; break;
      case Screen::key_end  : current = help_index.size() - 2; break;
      default: break;
      }
    }
  Screen::restore_lines_and_cursor();
  Screen::show_status_lines();
  }
