/*  GNU Moe - My Own Editor
    Copyright (C) 2005-2015 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 Beg of file        ^F  Find                    Ins  Insert/Overwrite",
  " ^[V End of file        ^G  Find next               Tab  File name completion",
  " ^[L Line               ^W  Find word               ^B   Reformat paragraph",
  " ^[C Column             ^OF Toggle direction        ^P   Control char",
  " ^[O Offset             ^QU update (C)              ^Y   Delete line",
  " ^[B Beg of block                                   ^OC  Center line",
  " ^[K End of block       @bINFO@b                        ^ON  Change buffer name",
  " ^[F Match pair ->      ^H   Show help              ^OR  Repaint screen",
  " ^[G Match pair <-      ^[I  Show character info    ^OS  Split window",
  " ^[D Center cursor      ^[T  Show UTF-8 code        ^Q@bF2@b Save named buffers",
  "                        ^Sn  Show LE multibyte",
  " @bSCROLL@b                 ^S@bFn@b Show BE multibyte      @bBOOKMARKS@b",
  " ^[W Up                 ^SC  Show character code    ^[ 0-9 Goto",
  " ^[Z Down               ^SG  Show global status     ^K 0-9 Set",
  " ^[A Left               ^SV  Show version           ^KE    Extend",
  " ^[S Right",
  "",
  " 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 forward",
  " ^KB Begin                 ^O3 To Rot-13          ^OE Duplicate lines backward",
  " ^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",
  " ^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",
  " ",
  " Escape sequences for special characters:",
  "   \\a  BEL (alert)       \\n  LF (newline)           \\\\   '\\' (backslash)",
  "   \\b  BS  (backspace)   \\r  CR (carriage return)   \\ooo  octal code 'ooo'",
  "   \\e  ESC (escape)      \\t  HT (tab)               \\xhh  hexadecimal code 'hh'",
  "   \\f  FF  (form feed)   \\v  VT (vertical tab)",
  " ",
  " 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      \\+<ch>  matches 0 or more of <ch>",
  "   \\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",
  " ",
  " 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",
  "     \\+\\[..] matches 0 or more chars of those in set",
  "     \\+\\w    matches 0 or more word-constituent characters",
  "",
  " 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",
  "",
  " 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::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();
  }
