REM     The Standart GNU Personal ANSI Text Viewer.
REM     Copyright (C) Sandul Yura Valentinovich.
REM     (R) Wednesday, 5 March 2003 year.
REM     This program is free software; you can redistribute it and/or modify
REM it under the terms of the GNU General Public License as published by the
REM Free Software Foundation; either version 2 of the License, or (at your
REM option) any later version.
REM     This program is distributed in the hope that it will be useful, but
REM WITHOUT ANY WARRANTY; without even the implied warranty of
REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
REM Public License for more details.
REM     You should have received a copy of the GNU General Public License
REM along with this program; if not, write to the Free Software Foundation,
REM Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
REM
REM $DYNAMIC
DECLARE SUB ScratchScreen ()
DECLARE SUB OutBox (Title$, Message$)
DECLARE SUB ClearANSI ()
DECLARE SUB ANSIOut (ANSISymbol$)
DECLARE SUB MakeBox (BoxColumn%, BoxRow%, BoxWidth%, BoxHeight%)
DECLARE SUB WorkOutANSIText ()
DECLARE FUNCTION CurrentDateTime$ ()
DECLARE FUNCTION DayName$ (DayNumber%)
DECLARE FUNCTION DayOfWeek% (DayValue%, MonthValue%, YearValue%)
DECLARE FUNCTION DayOfWeekName$ (DayValue%, MonthValue%, YearValue%)
DECLARE FUNCTION DaysCount& (DayValue%, MonthValue%, YearValue%)
DECLARE FUNCTION InputBox% (Title$, Message$, InputTextLine$)
DECLARE FUNCTION IsLeapYear% (YearValue%)
DECLARE FUNCTION MenuBox% (ItemsCount%)
DECLARE FUNCTION MessageBox% (Title$, Message$)
DECLARE FUNCTION MonthDays% (MonthValue%, YearValue%)
DECLARE FUNCTION MonthDaysCount% (MonthValue%, YearValue%)
DECLARE FUNCTION MonthName$ (MonthNumber%)
OPTION BASE 1
CONST False% = 0
CONST True% = NOT False%
CONST ANSITextLinesCount% = 128
CONST ANSIParametersCountValue% = 4
CONST ANSICursorCountValue% = 4
DIM SHARED MenuItems$(3)
DIM SHARED CursorRows%(ANSICursorCountValue%)
DIM SHARED CursorColumns%(ANSICursorCountValue%)
DIM SHARED CursorCount%
DIM SHARED Parameters%(ANSIParametersCountValue%)
DIM SHARED ParametersCount%
DIM SHARED ANSIMode%
DIM SHARED NumberLine$
DIM SHARED ANSITextOutPut$(ANSITextLinesCount%)
DIM SHARED ANSIColorOutPut$(ANSITextLinesCount%)
DIM SHARED ANSIOutColumn%
DIM SHARED ANSIOutRow%
DIM SHARED ANSIOutBackColor%
DIM SHARED ANSIOutForeColor%
DIM SHARED ANSITextLinePosition%
DIM SHARED ANSITextOutLinePosition%
DIM SHARED ANSITextPosition%
DIM SHARED ANSIOutPosition%
DIM OldSecond%
DIM Index%
DIM ANSIText$
DIM WorkKey$
DIM WorkLine$
SCREEN 0, 1, 0, 0
ANSIText$ = "Ansi.ans"
DO
 CALL ScratchScreen
 MenuItems$(1) = "Change help file name (" + ANSIText$ + ".)."
 MenuItems$(2) = "Show ANSI text."
 MenuItems$(3) = "Quit."
 SELECT CASE MenuBox%(3)
 CASE 0
   EXIT DO
 CASE 1
   CALL ScratchScreen
   WorkLine$ = ""
   IF InputBox%("ANSI Out.", "Please enter name of exist ANSI text file.", WorkLine$) THEN
    CALL ScratchScreen
    WorkLine$ = UCASE$(LEFT$(LTRIM$(RTRIM$(WorkLine$)), 1)) + LCASE$(MID$(LTRIM$(RTRIM$(WorkLine$)), 2))
    IF (WorkLine$ = "") OR (LEN(WorkLine$) > 12) OR (INSTR(WorkLine$, ":") > 0) OR (INSTR(WorkLine$, "/") > 0) OR (INSTR(WorkLine$, "\") > 0) OR (INSTR(WorkLine$, "?") > 0) OR (INSTR(WorkLine$, "*") > 0) THEN CALL OutBox("ANSI Out.", "You input the invalid file name.") ELSE ANSIText$ = WorkLine$
   END IF
 CASE 2
   CALL ScratchScreen
   CALL ClearANSI
   FOR Index% = 1 TO ANSITextLinesCount%
    ANSITextOutPut$(Index%) = SPACE$(80)
    ANSIColorOutPut$(Index%) = STRING$(80, CHR$((0 * &H10) + 7))
   NEXT Index%
   ANSIOutColumn% = 1
   ANSIOutRow% = 1
   ANSIOutBackColor% = 0
   ANSIOutForeColor% = 7
   ON ERROR GOTO CannotOpenANSIFile
   OPEN ANSIText$ FOR RANDOM AS #1 LEN = 1
   ON ERROR GOTO 0
   FIELD #1, 1 AS ANSIData$
   WHILE NOT EOF(1)
    ON ERROR GOTO CannotReadFromANSIFile
    GET #1
    ON ERROR GOTO 0
    IF NOT EOF(1) THEN CALL ANSIOut(ANSIData$)
   WEND
   CLOSE #1
   ANSITextLinePosition% = 1
   ANSITextOutLinePosition% = 1
   ANSITextPosition% = 1
   ANSIOutPosition% = 1
   OldSecond% = NOT VAL(MID$(TIME$, 7, 2))
   CALL MakeBox(1, 1, 77, 22)
   CALL WorkOutANSIText
   DO
    IF OldSecond% <> VAL(MID$(TIME$, 7, 2)) THEN
     OldSecond% = VAL(MID$(TIME$, 7, 2))
     CALL WorkOutANSIText
    END IF
    WorkKey$ = INKEY$
    IF WorkKey$ = CHR$(27) THEN EXIT DO
    IF LEN(WorkKey$) = 2 THEN
     WorkKey$ = MID$(WorkKey$, 2)
     SELECT CASE WorkKey$
     CASE CHR$(75)
       ANSITextLinePosition% = ANSITextLinePosition% - 1
       ANSITextOutLinePosition% = ANSITextOutLinePosition% - 1
       IF ANSITextLinePosition% < 1 THEN ANSITextLinePosition% = 1
       IF ANSITextOutLinePosition% < 1 THEN ANSITextOutLinePosition% = 1
       CALL WorkOutANSIText
     CASE CHR$(77)
       ANSITextLinePosition% = ANSITextLinePosition% + 1
       ANSITextOutLinePosition% = ANSITextOutLinePosition% + 1
       IF ANSITextLinePosition% > 80 THEN ANSITextLinePosition% = 80
       IF ANSITextOutLinePosition% > 77 THEN ANSITextOutLinePosition% = 77
       CALL WorkOutANSIText
     CASE CHR$(71)
       ANSITextLinePosition% = 1
       ANSITextOutLinePosition% = 1
       CALL WorkOutANSIText
     CASE CHR$(79)
       ANSITextLinePosition% = 80
       ANSITextOutLinePosition% = 77
       CALL WorkOutANSIText
     CASE CHR$(72)
       ANSITextPosition% = ANSITextPosition% - 1
       ANSIOutPosition% = ANSIOutPosition% - 1
       IF ANSITextPosition% < 1 THEN ANSITextPosition% = 1
       IF ANSIOutPosition% < 1 THEN ANSIOutPosition% = 1
       CALL WorkOutANSIText
     CASE CHR$(80)
       ANSITextPosition% = ANSITextPosition% + 1
       ANSIOutPosition% = ANSIOutPosition% + 1
       IF ANSITextPosition% > ANSITextLinesCount% THEN ANSITextPosition% = ANSITextLinesCount%
       IF ANSIOutPosition% > 20 THEN ANSIOutPosition% = 20
       CALL WorkOutANSIText
     CASE CHR$(73)
       ANSITextPosition% = ANSITextPosition% - 20
       ANSIOutPosition% = ANSIOutPosition% - 20
       IF ANSITextPosition% < 1 THEN ANSITextPosition% = 1
       IF ANSIOutPosition% < 1 THEN ANSIOutPosition% = 1
       CALL WorkOutANSIText
     CASE CHR$(81)
       ANSITextPosition% = ANSITextPosition% + 20
       ANSIOutPosition% = ANSIOutPosition% + 20
       IF ANSITextPosition% > ANSITextLinesCount% THEN ANSITextPosition% = ANSITextLinesCount%
       IF ANSIOutPosition% > 20 THEN ANSIOutPosition% = 20
       CALL WorkOutANSIText
     END SELECT
    END IF
   LOOP
 CASE 3
   EXIT DO
 END SELECT
ANSIWorkRepeat:
LOOP
COLOR 7, 0
CLS
LOCATE 1, 1, 1, 7, 8
END
CannotOpenANSIFile:
 IF MessageBox%("ANSI Out.", "Cannot open ANSI file. Retry opening?") THEN
  CALL ScratchScreen
  RESUME
 ELSE
  RESUME ANSIWorkRepeat
 END IF
CannotReadFromANSIFile:
 IF MessageBox%("ANSI Out.", "Cannot read from ANSI file. Retry reading?") THEN
  CALL ScratchScreen
  RESUME
 ELSE
  CLOSE #1
  RESUME ANSIWorkRepeat
 END IF

REM  ANSI.SYS Ü
REM   ßßßßßßßßß
REM
REM Defines functions that change display graphics, control cursor movement,
REM and reassign keys. The ANSI.SYS device driver supports the use of ANSI
REM escape sequences to control the systemREM s screen and keyboard.
REM
REM Syntax: DEVICE=[drive:][path]ansi.sys [/X] [/K]
REM   [drive:][path]
REM       Specifies the location of the ANSI.SYS file.
REM   /X  Remaps extended keys independtly on 101-key keyboards.
REM   /K  Ignores extended keys on 101-key keyboards.
REM
REM Parameters used in ANSI escape sequences
REM Pn  Numeric paramter. Specifies a decimal number.
REM
REM Ps  Selective parameter. Specifies a decimal number that you use to
REM     select a function. You can specify more than one function by
REM     separating the parameters with semicolons.
REM
REM PL  Line parameter. Specifies a decimal number that represents one of
REM     the lines on your display or on another device.
REM
REM Pc  Column parameter. Specifies a decimal number that represents one
REM     of the columns on your screen or on another device.
REM
REM ANSI escape sequences
REM In the following list of ANSI escape sequences, the abbreviate ESC
REM represents the ASCII escape character 27 (1Bh), which appears at the
REM beginning of each escape sequence.
REM
REM ESC[PL;PcH or ESC[PL;Pcf
REM   Cursor Position. Moves the cursor to the specified location
REM   (coordinates). If you do not specify a position, the cursor moves
REM   to the home position (home 0, column 0).
REM
REM ESC[PnA
REM   Cursor Up. Moves the cursor up by the specified number of lines
REM   without changing columns.
REM
REM ESC[PnB
REM   Cursor Down. Moves the cursor down by the sepcified number of lines
REM   without changing columns.
REM
REM ESC[PnC
REM   Cursor Forward. Moves the cursor forward by the specified number of
REM   columns without changing lines.
REM
REM ESC[PnD
REM   Cursor Backward. Moves the cursor back by the specified number of
REM   columns without changing lines.
REM
REM ESC[s
REM   Save Cursor Position. Saves the current position. You can move the
REM   cursor to the saved cursor position by using the Restore Cursor
REM   Position sequence.
REM
REM ESC[u
REM   Restore Cursor Position. Returns the cursor to the position saved by
REM   the Save Cursor Position sequence.
REM
REM ESC[2J
REM   Erase Display. Clears the screen and moves the cursor to the home
REM   position (line 0, column 0).
REM
REM ESC[K
REM   Erase Line. Clears all characters from the cursor position to the
REM   end of the line.
REM
REM ESC[Ps;...;Psm
REM   Set Graphics Mode. Calls the graphics functions specified by the
REM   following values. These functions remain active until the next
REM   occurrence of this escape sequence.
REM
REM   Text attributes
REM          0    All attributes off
REM          1    Bold on
REM          4    Underscore (on monochrome display adapter only)
REM          5    Blink on
REM          7    Reverse video on
REM          8    Concealed on
REM
REM   Foreground colors
REM          30   Black
REM          31   Red
REM          32   Green
REM          33   Yellow
REM          34   Blue
REM          35   Magenta
REM          36   Cyan
REM          37   White
REM
REM   Background colors
REM          40   Black
REM          41   Red
REM          42   Green
REM          43   Yellow
REM          44   Blue
REM          45   Magenta
REM          46   Cyan
REM          47   White
REM
REM   Parameters 30 through 47 meet the ISO 6429 standard.
REM
REM ESC[=Psh
REM   Set Mode. Changes the screen width or type to the mode specified
REM   by one of the following values:
REM
REM    0   40x25 monochrome (text)
REM    1   40x25 color (text)
REM    2   80x25 monochrome (text)
REM    3   80x25 color (text)
REM    4   320x200 4-color (graphics)
REM    5   320x200 monochrome (graphics)
REM    6   640x200 monochrome (graphics)
REM    7   Enables line wrapping
REM   13   320x200 color (graphics)
REM   14   640x200 color (16-color graphics)
REM   15   640x350 monochrome (2-color graphics)
REM   16   640x350 color (16-color graphics)
REM   17   640x480 monochrome (2-color graphics)
REM   18   640x480 color (16-color graphics)
REM   19   320x200 color (256-color graphics)
REM
REM ESC[Psl
REM   Reset Mode. Resets the mode by using the same values that Set Mode
REM   uses, except for 7, which disables line wrapping.
REM
REM Examples:
REM To exchange backslash and question-mark keys by using literal strings,
REM type the following sequence:
REM
REM    ESC["\";"?"pESC["?";"\"p
REM
REM To exchange the backslash and question-mark keys by using each keyREM s
REM ASCII value, type the following escape sequence:
REM
REM    ESC[92;63pESC[63;92p
REM
REM To restore the backslash and question-mark keys to their original
REM meanings, type the following sequence:
REM
REM    ESC[92;92pESC[63;63p
SUB ANSIOut (ANSISymbol$)
 DIM Index%
 SELECT CASE ANSIMode%
 CASE 0
   SELECT CASE ANSISymbol$
   CASE CHR$(10)
     IF ANSIOutRow% < ANSITextLinesCount% THEN
      ANSIOutRow% = ANSIOutRow% + 1
      ANSIOutColumn% = 1
     END IF
   CASE CHR$(27)
     ANSIMode% = 1
   CASE ELSE
     IF ANSISymbol$ <> "" THEN
      IF ASC(ANSISymbol$) > (ASC(SPACE$(1)) - 1) THEN
       IF ANSIOutColumn% = 80 THEN
        IF ANSIOutRow% < ANSITextLinesCount% THEN
         ANSITextOutPut$(ANSIOutRow%) = MID$(ANSITextOutPut$(ANSIOutRow%), 1, ANSIOutColumn% - 1) + ANSISymbol$ + MID$(ANSITextOutPut$(ANSIOutRow%), ANSIOutColumn% + 1)
         ANSIColorOutPut$(ANSIOutRow%) = MID$(ANSIColorOutPut$(ANSIOutRow%), 1, ANSIOutColumn% - 1) + CHR$((ANSIOutBackColor% * &H10) + ANSIOutForeColor%) + MID$(ANSIColorOutPut$(ANSIOutRow%), ANSIOutColumn% + 1)
         ANSIOutRow% = ANSIOutRow% + 1
         ANSIOutColumn% = 1
        END IF
       ELSE
        ANSITextOutPut$(ANSIOutRow%) = MID$(ANSITextOutPut$(ANSIOutRow%), 1, ANSIOutColumn% - 1) + ANSISymbol$ + MID$(ANSITextOutPut$(ANSIOutRow%), ANSIOutColumn% + 1)
        ANSIColorOutPut$(ANSIOutRow%) = MID$(ANSIColorOutPut$(ANSIOutRow%), 1, ANSIOutColumn% - 1) + CHR$((ANSIOutBackColor% * &H10) + ANSIOutForeColor%) + MID$(ANSIColorOutPut$(ANSIOutRow%), ANSIOutColumn% + 1)
        ANSIOutColumn% = ANSIOutColumn% + 1
       END IF
      END IF
     END IF
   END SELECT
 CASE 1
   SELECT CASE ANSISymbol$
   CASE "["
     ANSIMode% = 2
   CASE ELSE
     CALL ClearANSI
     CALL ANSIOut(ANSISymbol$)
   END SELECT
 CASE 2
   SELECT CASE ANSISymbol$
   CASE "H"
     SELECT CASE ParametersCount%
     CASE 0
       ANSIOutRow% = 1
       ANSIOutColumn% = 1
     CASE 1
       IF Parameters%(1) < 1 THEN Parameters%(1) = 1
       IF Parameters%(1) > ANSITextLinesCount% THEN Parameters%(1) = ANSITextLinesCount%
       ANSIOutRow% = Parameters%(1)
       ANSIOutColumn% = 1
     CASE ELSE
       IF Parameters%(1) < 1 THEN Parameters%(1) = 1
       IF Parameters%(1) > ANSITextLinesCount% THEN Parameters%(1) = ANSITextLinesCount%
       IF Parameters%(2) < 1 THEN Parameters%(2) = 1
       IF Parameters%(2) > 80 THEN Parameters%(2) = 80
       ANSIOutRow% = Parameters%(1)
       ANSIOutColumn% = Parameters%(2)
     END SELECT
     CALL ClearANSI
   CASE "f"
     SELECT CASE ParametersCount%
     CASE 0
       ANSIOutRow% = 1
       ANSIOutColumn% = 1
     CASE 1
       IF Parameters%(1) < 1 THEN Parameters%(1) = 1
       IF Parameters%(1) > ANSITextLinesCount% THEN Parameters%(1) = ANSITextLinesCount%
       ANSIOutRow% = Parameters%(1)
       ANSIOutColumn% = 1
     CASE ELSE
       IF Parameters%(1) < 1 THEN Parameters%(1) = 1
       IF Parameters%(1) > ANSITextLinesCount% THEN Parameters%(1) = ANSITextLinesCount%
       IF Parameters%(2) < 1 THEN Parameters%(2) = 1
       IF Parameters%(2) > 80 THEN Parameters%(2) = 80
       ANSIOutRow% = Parameters%(1)
       ANSIOutColumn% = Parameters%(2)
     END SELECT
     CALL ClearANSI
   CASE "A"
     IF Parameters%(1) < 1 THEN Parameters%(1) = 1
     IF (ANSIOutRow% - Parameters%(1)) > 0 THEN ANSIOutRow% = ANSIOutRow% - Parameters%(1)
     CALL ClearANSI
   CASE "B"
     IF Parameters%(1) < 1 THEN Parameters%(1) = 1
     IF (ANSIOutRow% + Parameters%(1)) < (ANSITextLinesCount% + 1) THEN ANSIOutRow% = ANSIOutRow% + Parameters%(1)
     CALL ClearANSI
   CASE "C"
     IF Parameters%(1) < 1 THEN Parameters%(1) = 1
     IF (ANSIOutColumn% + Parameters%(1)) < 81 THEN ANSIOutColumn% = ANSIOutColumn% + Parameters%(1)
     CALL ClearANSI
   CASE "D"
     IF Parameters%(1) < 1 THEN Parameters%(1) = 1
     IF (ANSIOutColumn% - Parameters%(1)) > 0 THEN ANSIOutColumn% = ANSIOutColumn% - Parameters%(1)
     CALL ClearANSI
   CASE "s"
     IF CursorCount% < ANSICursorCountValue% THEN
      CursorCount% = CursorCount% + 1
      CursorRows%(CursorCount%) = ANSIOutRow%
      CursorColumns%(CursorCount%) = ANSIOutColumn%
     END IF
     CALL ClearANSI
   CASE "u"
     IF CursorCount% > 0 THEN
      ANSIOutRow% = CursorRows%(CursorCount%)
      ANSIOutColumn% = CursorColumns%(CursorCount%)
      CursorRows%(CursorCount%) = 0
      CursorColumns%(CursorCount%) = 0
      CursorCount% = CursorCount% - 1
     END IF
     CALL ClearANSI
   CASE "J"
     FOR Index% = 1 TO ANSITextLinesCount%
      ANSITextOutPut$(Index%) = SPACE$(80)
      ANSIColorOutPut$(Index%) = STRING$(80, CHR$((ANSIOutBackColor% * &H10) + ANSIOutForeColor%))
     NEXT Index%
     ANSIOutColumn% = 1
     ANSIOutRow% = 1
     CALL ClearANSI
   CASE "K"
     ANSITextOutPut$(Index%) = MID$(ANSITextOutPut$(Index%), 1, ANSIOutColumn% - 1) + SPACE$(80 - LEN(MID$(ANSITextOutPut$(Index%), 1, ANSIOutColumn% - 1)))
     ANSIColorOutPut$(Index%) = MID$(ANSIColorOutPut$(Index%), 1, ANSIOutColumn% - 1) + STRING$(80 - LEN(MID$(ANSITextOutPut$(Index%), 1, ANSIOutColumn% - 1)), CHR$((ANSIOutBackColor% * &H10) + ANSIOutForeColor%))
     CALL ClearANSI
   CASE "m"
     IF ParametersCount% > 0 THEN
      FOR Index% = 1 TO ParametersCount%
       SELECT CASE Parameters%(Index%)
       CASE 0
         ANSIOutForeColor% = 7
         ANSIOutBackColor% = 0
       CASE 1
         ANSIOutForeColor% = 15
       CASE 4
         ANSIOutForeColor% = 1
       CASE 5
         ANSIOutForeColor% = 7
       CASE 7
         ANSIOutForeColor% = 0
         ANSIOutBackColor% = 7
       CASE 8
         ANSIOutForeColor% = 0
         ANSIOutBackColor% = 0
       CASE 30
         ANSIOutForeColor% = 0
       CASE 31
         ANSIOutForeColor% = 4
       CASE 32
         ANSIOutForeColor% = 2
       CASE 33
         ANSIOutForeColor% = 6
       CASE 34
         ANSIOutForeColor% = 1
       CASE 35
         ANSIOutForeColor% = 5
       CASE 36
         ANSIOutForeColor% = 3
       CASE 37
         ANSIOutForeColor% = 15
       CASE 40
         ANSIOutBackColor% = 0
       CASE 41
         ANSIOutBackColor% = 4
       CASE 42
         ANSIOutBackColor% = 2
       CASE 43
         ANSIOutBackColor% = 6
       CASE 44
         ANSIOutBackColor% = 1
       CASE 45
         ANSIOutBackColor% = 5
       CASE 46
         ANSIOutBackColor% = 3
       CASE 47
         ANSIOutBackColor% = 7
       END SELECT
      NEXT Index%
     ELSE
      ANSIOutForeColor% = 7
      ANSIOutBackColor% = 0
     END IF
     CALL ClearANSI
   CASE "0" TO "9"
     ANSIMode% = 3
     CALL ANSIOut(ANSISymbol$)
   CASE ";"
     ParametersCount% = 1
   CASE ELSE
     CALL ClearANSI
     CALL ANSIOut(ANSISymbol$)
   END SELECT
 CASE 3
   SELECT CASE ANSISymbol$
   CASE "0" TO "9"
     IF LEN(NumberLine$) < 2 THEN NumberLine$ = NumberLine$ + ANSISymbol$
   CASE ";"
     IF ParametersCount% < ANSIParametersCountValue% THEN
      ParametersCount% = ParametersCount% + 1
      Parameters%(ParametersCount%) = VAL(NumberLine$)
     END IF
     NumberLine$ = ""
   CASE ELSE
     IF ParametersCount% < ANSIParametersCountValue% THEN
      ParametersCount% = ParametersCount% + 1
      Parameters%(ParametersCount%) = VAL(NumberLine$)
     END IF
     ANSIMode% = 2
     CALL ANSIOut(ANSISymbol$)
   END SELECT
 END SELECT
END SUB

SUB ClearANSI
 DIM Index%
 FOR Index% = 1 TO ANSIParametersCountValue%
  Parameters%(Index%) = 0
 NEXT Index%
 ParametersCount% = 0
 ANSIMode% = 0
 NumberLine$ = ""
END SUB

FUNCTION CurrentDateTime$
 CurrentDateTime$ = "Date: " + DayOfWeekName$(VAL(MID$(DATE$, 4, 2)), VAL(MID$(DATE$, 1, 2)), VAL(MID$(DATE$, 7, 4))) + ", " + LTRIM$(STR$(VAL(MID$(DATE$, 4, 2)))) + " " + MonthName$(VAL(MID$(DATE$, 1, 2))) + " " + LTRIM$(STR$(VAL(MID$(DATE$, 7, 4)))) + " year. Time: " + TIME$ + "."
END FUNCTION

FUNCTION DayName$ (DayNumber%)
 SELECT CASE DayNumber%
 CASE 1
   DayName$ = "Monday"
 CASE 2
   DayName$ = "Tuesday"
 CASE 3
   DayName$ = "Wednesday"
 CASE 4
   DayName$ = "Thursday"
 CASE 5
   DayName$ = "Friday"
 CASE 6
   DayName$ = "Saturday"
 CASE 7
   DayName$ = "Sunday"
 END SELECT
END FUNCTION

FUNCTION DayOfWeek% (DayValue%, MonthValue%, YearValue%)
 SELECT CASE DaysCount&(DayValue%, MonthValue%, YearValue%) - (INT(DaysCount&(DayValue%, MonthValue%, YearValue%) / 7) * 7)
 CASE 0
   DayOfWeek% = 6
 CASE 1
   DayOfWeek% = 7
 CASE 2
   DayOfWeek% = 1
 CASE 3
   DayOfWeek% = 2
 CASE 4
   DayOfWeek% = 3
 CASE 5
   DayOfWeek% = 4
 CASE 6
   DayOfWeek% = 5
 CASE 7
   DayOfWeek% = 6
 END SELECT
END FUNCTION

FUNCTION DayOfWeekName$ (DayValue%, MonthValue%, YearValue%)
 DayOfWeekName$ = DayName$(DayOfWeek%(DayValue%, MonthValue%, YearValue%))
END FUNCTION

FUNCTION DaysCount& (DayValue%, MonthValue%, YearValue%)
 DaysCount& = (YearValue% * 365#) + INT(YearValue% / 100) + INT(YearValue% / 4) + MonthDaysCount%(MonthValue%, YearValue%) + DayValue%
END FUNCTION

FUNCTION InputBox% (Title$, Message$, InputTextLine$)
 DIM OutMessage$
 DIM OutIndex%
 DIM WorkKey$
 DIM InputTextCursorColumn%
 DIM InputTextCursorPosition%
 DIM InputText$
 IF LEN(Message$) < 256 THEN OutMessage$ = Message$ + SPACE$(256 - LEN(Message$)) ELSE OutMessage$ = LEFT$(Message$, 256)
 CALL MakeBox(7, 8, 64, 7)
 PRINT LEFT$(Title$, 64) + SPACE$(64 - LEN(LEFT$(Title$, 64)));
 COLOR 1, 7
 FOR OutIndex% = 1 TO 4
  LOCATE 9 + OutIndex%, 8, 0
  PRINT LEFT$(OutMessage$, 64);
  OutMessage$ = MID$(OutMessage$, 65)
 NEXT OutIndex%
 COLOR 14, 7
 LOCATE 15, 8, 0
 PRINT "Please press key is equalient to your answer: ENTER=Yes, ESC=No.";
 InputTextCursorColumn% = 1
 InputTextCursorPosition% = 1
 InputText$ = InputTextLine$
 GOSUB OutInputLine
 DO
  WorkKey$ = INKEY$
  SELECT CASE LEN(WorkKey$)
  CASE 1
    SELECT CASE WorkKey$
    CASE CHR$(8)
      IF InputTextCursorColumn% > 1 THEN
       InputTextCursorColumn% = InputTextCursorColumn% - 1
       InputTextCursorPosition% = InputTextCursorPosition% - 1
       IF InputTextCursorColumn% < 1 THEN InputTextCursorColumn% = 1
       IF InputTextCursorPosition% < 1 THEN InputTextCursorPosition% = 1
       InputText$ = MID$(InputText$, 1, InputTextCursorColumn% - 1) + MID$(InputText$, InputTextCursorColumn% + 1)
       GOSUB OutInputLine
      END IF
    CASE CHR$(13)
      InputTextLine$ = InputText$
      EXIT DO
    CASE CHR$(27)
      EXIT DO
    CASE ELSE
      IF (LEN(InputText$) < 256) AND (ASC(WorkKey$) > (ASC(SPACE$(1)) - 1)) THEN
       InputText$ = MID$(InputText$, 1, InputTextCursorColumn% - 1) + WorkKey$ + MID$(InputText$, InputTextCursorColumn%)
       InputTextCursorColumn% = InputTextCursorColumn% + 1
       InputTextCursorPosition% = InputTextCursorPosition% + 1
       IF InputTextCursorColumn% > LEN(InputText$) + 1 THEN InputTextCursorColumn% = LEN(InputText$) + 1
       IF LEN(InputText$) > 63 THEN IF InputTextCursorPosition% > 64 THEN InputTextCursorPosition% = 64
       IF LEN(InputText$) < 65 THEN IF InputTextCursorPosition% > LEN(InputText$) + 1 THEN InputTextCursorPosition% = LEN(InputText$) + 1
       GOSUB OutInputLine
      END IF
    END SELECT
  CASE 2
    WorkKey$ = MID$(WorkKey$, 2)
    SELECT CASE WorkKey$
    CASE CHR$(75)
      IF InputTextCursorColumn% > 1 THEN
       InputTextCursorColumn% = InputTextCursorColumn% - 1
       InputTextCursorPosition% = InputTextCursorPosition% - 1
       IF InputTextCursorColumn% < 1 THEN InputTextCursorColumn% = 1
       IF InputTextCursorPosition% < 1 THEN InputTextCursorPosition% = 1
       GOSUB OutInputLine
      END IF
    CASE CHR$(77)
      IF InputTextCursorColumn% < LEN(InputText$) + 1 THEN
       InputTextCursorColumn% = InputTextCursorColumn% + 1
       InputTextCursorPosition% = InputTextCursorPosition% + 1
       IF InputTextCursorColumn% > LEN(InputText$) + 1 THEN InputTextCursorColumn% = LEN(InputText$) + 1
       IF LEN(InputText$) > 63 THEN IF InputTextCursorPosition% > 64 THEN InputTextCursorPosition% = 64
       IF LEN(InputText$) < 65 THEN IF InputTextCursorPosition% > LEN(InputText$) + 1 THEN InputTextCursorPosition% = LEN(InputText$) + 1
       GOSUB OutInputLine
      END IF
    CASE CHR$(71)
      IF InputTextCursorColumn% <> 1 THEN
       InputTextCursorColumn% = 1
       InputTextCursorPosition% = 1
       GOSUB OutInputLine
      END IF
    CASE CHR$(79)
      IF InputTextCursorColumn% <> LEN(InputText$) + 1 THEN
       InputTextCursorColumn% = LEN(InputText$) + 1
       InputTextCursorPosition% = LEN(InputText$) + 1
       IF LEN(InputText$) > 63 THEN IF InputTextCursorPosition% > 64 THEN InputTextCursorPosition% = 64
       IF LEN(InputText$) < 65 THEN IF InputTextCursorPosition% > LEN(InputText$) + 1 THEN InputTextCursorPosition% = LEN(InputText$) + 1
       GOSUB OutInputLine
      END IF
    CASE CHR$(83)
      IF InputText$ <> "" THEN
       InputText$ = MID$(InputText$, 1, InputTextCursorColumn% - 1) + MID$(InputText$, InputTextCursorColumn% + 1)
       GOSUB OutInputLine
      END IF
    END SELECT
  END SELECT
 LOOP
 LOCATE , , 0
 InputBox% = WorkKey$ = CHR$(13)
 EXIT FUNCTION
OutInputLine:
 COLOR 4, 7
 LOCATE 14, 8, 0
 PRINT MID$(InputText$, (InputTextCursorColumn% - InputTextCursorPosition%) + 1, 64) + SPACE$(64 - LEN(MID$(InputText$, (InputTextCursorColumn% - InputTextCursorPosition%) + 1, 64)));
 LOCATE 14, 7 + InputTextCursorPosition%, 1, 7, 8
 RETURN
END FUNCTION

FUNCTION IsLeapYear% (YearValue%)
 IsLeapYear% = ABS((INT(YearValue% / 4) * 4) = YearValue%)
END FUNCTION

SUB MakeBox (BoxColumn%, BoxRow%, BoxWidth%, BoxHeight%)
 DIM BoxWorkIndex%
 IF (BoxColumn% < 1) OR (BoxRow% < 1) OR (BoxWidth% < 1) OR (BoxHeight% < 1) OR (BoxWidth% > 77) OR (BoxHeight% > 22) OR (((BoxColumn% - 1) + BoxWidth%) > 77) OR (((BoxRow% - 1) + BoxHeight%) > 22) THEN EXIT SUB
 COLOR 0, 7
 LOCATE BoxRow%, BoxColumn%, 0
 PRINT CHR$(201) + STRING$(BoxWidth%, CHR$(205)) + CHR$(187);
 FOR BoxWorkIndex% = 1 TO BoxHeight% + 1
  LOCATE BoxRow% + BoxWorkIndex%, BoxColumn%, 0
  PRINT CHR$(186) + SPACE$(BoxWidth%) + CHR$(186);
  COLOR 0, 0
  PRINT SPACE$(1);
  COLOR 0, 7
 NEXT BoxWorkIndex%
 LOCATE BoxRow% + BoxHeight% + 1, BoxColumn%, 0
 PRINT CHR$(200) + STRING$(BoxWidth%, CHR$(205)) + CHR$(188);
 COLOR 0, 0
 LOCATE BoxRow% + BoxHeight% + 2, BoxColumn% + 1, 0
 PRINT SPACE$(BoxWidth% + 2);
 COLOR 15, 2
 LOCATE BoxRow% + 1, BoxColumn% + 1, 0
END SUB

FUNCTION MenuBox% (ItemsCount%)
 DIM MenuIndex%
 DIM MenuLineLength%
 DIM CurrentItem%
 DIM WorkKey$
 IF (ItemsCount% < 1) OR (ItemsCount% > UBOUND(MenuItems$)) OR (UBOUND(MenuItems$) > 20) THEN
  MenuBox% = 0
  EXIT FUNCTION
 END IF
 MenuLineLength% = 0
 FOR MenuIndex% = 1 TO ItemsCount%
  IF LEN(MenuItems$(MenuIndex%)) > MenuLineLength% THEN MenuLineLength% = LEN(MenuItems$(MenuIndex%))
 NEXT MenuIndex%
 IF MenuLineLength% < 56 THEN MenuLineLength% = 56
 IF MenuLineLength% > 75 THEN MenuLineLength% = 75
 CurrentItem% = 1
 GOSUB OutMenu
 DO
  WorkKey$ = UCASE$(INKEY$)
  SELECT CASE LEN(WorkKey$)
  CASE 1
    SELECT CASE WorkKey$
    CASE CHR$(13)
      MenuBox% = CurrentItem%
      EXIT DO
    CASE CHR$(27)
      MenuBox% = 0
      EXIT DO
    CASE ELSE
      IF (ASC(WorkKey$) > (ASC("A") - 1)) AND (ASC(WorkKey$) < (ASC("A") + ItemsCount%)) THEN
       CurrentItem% = (ASC(WorkKey$) - ASC("A")) + 1
       GOSUB OutMenu
      END IF
    END SELECT
  CASE 2
    WorkKey$ = MID$(WorkKey$, 2)
    SELECT CASE WorkKey$
    CASE CHR$(72)
      IF CurrentItem% > 1 THEN
       CurrentItem% = CurrentItem% - 1
       GOSUB OutMenu
      END IF
    CASE CHR$(80)
      IF CurrentItem% < ItemsCount% THEN
       CurrentItem% = CurrentItem% + 1
       GOSUB OutMenu
      END IF
    CASE CHR$(73)
      IF CurrentItem% <> 1 THEN
       CurrentItem% = 1
       GOSUB OutMenu
      END IF
    CASE CHR$(81)
      IF CurrentItem% <> ItemsCount% THEN
       CurrentItem% = ItemsCount%
       GOSUB OutMenu
      END IF
    CASE CHR$(71)
      IF CurrentItem% <> 1 THEN
       CurrentItem% = 1
       GOSUB OutMenu
      END IF
    CASE CHR$(79)
      IF CurrentItem% <> ItemsCount% THEN
       CurrentItem% = ItemsCount%
       GOSUB OutMenu
      END IF
    END SELECT
  END SELECT
 LOOP
 EXIT FUNCTION
OutMenu:
 CALL MakeBox(INT((80 - (MenuLineLength% + 5)) / 2) + 1, INT((25 - (ItemsCount% + 5)) / 2) + 1, MenuLineLength% + 2, ItemsCount% + 2)
 FOR MenuIndex% = 1 TO ItemsCount%
  COLOR 14, 7
  LOCATE INT((25 - (ItemsCount% + 5)) / 2) + (MenuIndex% + 1), INT((80 - (MenuLineLength% + 5)) / 2) + 2, 0
  PRINT CHR$(ASC("A") + (MenuIndex% - 1));
  COLOR 12, 7
  PRINT "=";
  IF MenuIndex% = CurrentItem% THEN COLOR 15, 6 ELSE COLOR 8, 7
  PRINT LEFT$(MenuItems$(MenuIndex%), MenuLineLength%) + SPACE$(MenuLineLength% - LEN(LEFT$(MenuItems$(MenuIndex%), MenuLineLength%)));
 NEXT MenuIndex%
 COLOR 0, 7
 LOCATE INT((25 - (ItemsCount% + 5)) / 2) + 2 + ItemsCount%, INT((80 - (MenuLineLength% + 5)) / 2) + 1, 0
 PRINT CHR$(204) + STRING$(MenuLineLength% + 2, CHR$(205)) + CHR$(185);
 COLOR 14, 7
 LOCATE INT((25 - (ItemsCount% + 5)) / 2) + 3 + ItemsCount%, INT((80 - (MenuLineLength% + 5)) / 2) + 2, 0
 PRINT SPACE$(INT((MenuLineLength% - 56) / 2) + 1) + "Please press ENTER to select menu item or ESC to cancel."
 RETURN
END FUNCTION

FUNCTION MessageBox% (Title$, Message$)
 DIM OutMessage$
 DIM OutIndex%
 DIM WorkKey$
 IF LEN(Message$) < 256 THEN OutMessage$ = Message$ + SPACE$(256 - LEN(Message$)) ELSE OutMessage$ = LEFT$(Message$, 256)
 CALL MakeBox(7, 9, 64, 6)
 PRINT LEFT$(Title$, 64) + SPACE$(64 - LEN(LEFT$(Title$, 64)));
 COLOR 1, 7
 FOR OutIndex% = 1 TO 4
  LOCATE 10 + OutIndex%, 8, 0
  PRINT LEFT$(OutMessage$, 64);
  OutMessage$ = MID$(OutMessage$, 65)
 NEXT OutIndex%
 COLOR 14, 7
 LOCATE 15, 8, 0
 PRINT "Please press key is equalient to your answer: ENTER=Yes, ESC=No.";
 WorkKey$ = ""
 WHILE (WorkKey$ <> CHR$(13)) AND (WorkKey$ <> CHR$(27))
  WorkKey$ = INKEY$
 WEND
 MessageBox% = WorkKey$ = CHR$(13)
END FUNCTION

FUNCTION MonthDays% (MonthValue%, YearValue%)
 SELECT CASE MonthValue%
 CASE 1
   MonthDays% = 31
 CASE 2
   MonthDays% = 28 + IsLeapYear%(YearValue%)
 CASE 3
   MonthDays% = 31
 CASE 4
   MonthDays% = 30
 CASE 5
   MonthDays% = 31
 CASE 6
   MonthDays% = 30
 CASE 7
   MonthDays% = 31
 CASE 8
   MonthDays% = 31
 CASE 9
   MonthDays% = 30
 CASE 10
   MonthDays% = 31
 CASE 11
   MonthDays% = 30
 CASE 12
   MonthDays% = 31
 END SELECT
END FUNCTION

FUNCTION MonthDaysCount% (MonthValue%, YearValue%)
 SELECT CASE MonthValue%
 CASE 1
   MonthDaysCount% = 0
 CASE 2
   MonthDaysCount% = 31
 CASE 3
   MonthDaysCount% = 59 + IsLeapYear%(YearValue%)
 CASE 4
   MonthDaysCount% = 90 + IsLeapYear%(YearValue%)
 CASE 5
   MonthDaysCount% = 120 + IsLeapYear%(YearValue%)
 CASE 6
   MonthDaysCount% = 151 + IsLeapYear%(YearValue%)
 CASE 7
   MonthDaysCount% = 181 + IsLeapYear%(YearValue%)
 CASE 8
   MonthDaysCount% = 212 + IsLeapYear%(YearValue%)
 CASE 9
   MonthDaysCount% = 243 + IsLeapYear%(YearValue%)
 CASE 10
   MonthDaysCount% = 273 + IsLeapYear%(YearValue%)
 CASE 11
   MonthDaysCount% = 304 + IsLeapYear%(YearValue%)
 CASE 12
   MonthDaysCount% = 334 + IsLeapYear%(YearValue%)
 END SELECT
END FUNCTION

FUNCTION MonthName$ (MonthNumber%)
 SELECT CASE MonthNumber%
 CASE 1
   MonthName$ = "January"
 CASE 2
   MonthName$ = "February"
 CASE 3
   MonthName$ = "March"
 CASE 4
   MonthName$ = "April"
 CASE 5
   MonthName$ = "May"
 CASE 6
   MonthName$ = "June"
 CASE 7
   MonthName$ = "July"
 CASE 8
   MonthName$ = "August"
 CASE 9
   MonthName$ = "September"
 CASE 10
   MonthName$ = "October"
 CASE 11
   MonthName$ = "November"
 CASE 12
   MonthName$ = "December"
 END SELECT
END FUNCTION

SUB OutBox (Title$, Message$)
 DIM OutMessage$
 DIM OutIndex%
 IF LEN(Message$) < 256 THEN OutMessage$ = Message$ + SPACE$(256 - LEN(Message$)) ELSE OutMessage$ = LEFT$(Message$, 256)
 CALL MakeBox(7, 9, 64, 6)
 PRINT LEFT$(Title$, 64) + SPACE$(64 - LEN(LEFT$(Title$, 64)));
 COLOR 1, 7
 FOR OutIndex% = 1 TO 4
  LOCATE 10 + OutIndex%, 8, 0
  PRINT LEFT$(OutMessage$, 64);
  OutMessage$ = MID$(OutMessage$, 65)
 NEXT OutIndex%
 COLOR 14, 7
 LOCATE 15, 8, 0
 PRINT "       Please press the ENTER key to quit from this box.";
 WHILE INKEY$ <> CHR$(13)
 WEND
END SUB

SUB ScratchScreen
 COLOR 0, 2
 CLS
 PRINT "********************************************************************************"
 PRINT "                   The Standart GNU Personal ANSI Text Viewer."
 PRINT "                     Copyright (C) Sandul Yura Valentinovich."
 PRINT "                        (R) Wednesday, 5 March 2003 year."
 PRINT
 PRINT "    This program is free software; you can redistribute it and/or modify it"
 PRINT "under the terms of the GNU General Public License as published by the Free"
 PRINT "Software Foundation; either version 2 of the License, or (at your option) any"
 PRINT "later version."
 PRINT "    This program is distributed in the hope that it will be useful, but WITHOUT"
 PRINT "ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS"
 PRINT "FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details."
 PRINT "    You should have received a copy of the GNU General Public License along with"
 PRINT "this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave,"
 PRINT "Cambridge, MA 02139, USA."
END SUB

SUB WorkOutANSIText
 DIM ANSITextLine$
 DIM ANSIColorLine$
 DIM Index%
 COLOR 4, 7
 LOCATE 22, 2, 0
 PRINT SPACE$(77);
 LOCATE 22, 2, 0
 PRINT "Row=" + LTRIM$(STR$(ANSITextPosition%)) + ". Column=" + LTRIM$(STR$(ANSITextLinePosition%)) + ".";
 LOCATE 23, 2, 0
 PRINT SPACE$(77);
 LOCATE 23, 2, 0
 PRINT CurrentDateTime$;
 FOR Index% = 1 TO 20
  COLOR 7, 7
  LOCATE Index% + 1, 2, 0
  PRINT SPACE$(77);
  LOCATE Index% + 1, 2, 0
  ANSITextLine$ = MID$(ANSITextOutPut$((ANSITextPosition% - ANSIOutPosition%) + Index%), (ANSITextLinePosition% - ANSITextOutLinePosition%) + 1, 77)
  ANSIColorLine$ = MID$(ANSIColorOutPut$((ANSITextPosition% - ANSIOutPosition%) + Index%), (ANSITextLinePosition% - ANSITextOutLinePosition%) + 1, 77)
  WHILE ANSITextLine$ <> ""
   COLOR ASC(ANSIColorLine$) - (INT(ASC(ANSIColorLine$) / &H10) * &H10), INT(ASC(ANSIColorLine$) / &H10)
   PRINT LEFT$(ANSITextLine$, 1);
   ANSITextLine$ = MID$(ANSITextLine$, 2)
   ANSIColorLine$ = MID$(ANSIColorLine$, 2)
  WEND
 NEXT Index%
 LOCATE ANSIOutPosition% + 1, ANSITextOutLinePosition% + 1, 1, 7, 8
END SUB

