REM     The Standart GNU Personal Dialog Library for QBasic.
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 MakeBox (BoxColumn%, BoxRow%, BoxWidth%, BoxHeight%)
DECLARE SUB OutBox (Title$, Message$)
DECLARE SUB ScratchScreen ()
DECLARE SUB SecondsToDateAndTime (SecondsCount#, HourValue%, MinuteValue%, SecondValue%, DayValue%, MonthValue%, YearValue%, DayOfWeekValue%)
DECLARE SUB SetBit (ValueData&, BitNumber%, BitValue%)
DECLARE FUNCTION CalendarBox% (Title$, Message$, DayValue%, MonthValue%, YearValue%)
DECLARE FUNCTION CurrentDateTime$ ()
DECLARE FUNCTION DateAndTimeToSeconds# (HourValue%, MinuteValue%, SecondValue%, DayValue%, MonthValue%, YearValue%)
DECLARE FUNCTION DayName$ (DayNumber%)
DECLARE FUNCTION DayOfWeek% (DayValue%, MonthValue%, YearValue%)
DECLARE FUNCTION DayOfWeekName$ (DayValue%, MonthValue%, YearValue%)
DECLARE FUNCTION DaysCount& (DayValue%, MonthValue%, YearValue%)
DECLARE FUNCTION GetBit% (ValueData&, BitNumber%)
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%)
DECLARE FUNCTION NumberToString$ (Value#, SystemBase$)
DECLARE FUNCTION PasswordInputBox% (Title$, Message$, InputTextLine$)
DECLARE FUNCTION Power& (Value%)
DECLARE FUNCTION StringToNumber# (Value$, SystemBase$)
DECLARE FUNCTION WeekNumber% (DayValue%, MonthValue%, YearValue%)
OPTION BASE 1
CONST False% = 0
CONST True% = NOT False%
DIM SHARED MenuItems$(20)
DIM Errors$(77)
SCREEN 0, 1, 0, 0
CALL ScratchScreen
CALL OutBox("The Standart GNU Personal Dialog Library for QBasic.", "Welkome to GNU freeware BASIC dialog system library!")
COLOR 7, 0
CLS
LOCATE 1, 1, 1, 7, 8
END
Errors$(1) = "NEXT without FOR"
Errors$(2) = "Syntax error"
Errors$(3) = "RETURN without GOSUB"
Errors$(4) = "Out of DATA"
Errors$(5) = "Illegal function call"
Errors$(6) = "Overflow"
Errors$(7) = "Out of memory"
Errors$(8) = "Label not defined"
Errors$(9) = "Subscript out of range"
Errors$(10) = "Duplicate definition"
Errors$(11) = "Division by zero"
Errors$(12) = "Illegal in direct mode"
Errors$(13) = "Type mismatch"
Errors$(14) = "Out of string space"
Errors$(16) = "String formula too complex"
Errors$(17) = "Cannot continue"
Errors$(18) = "Function not defined"
Errors$(19) = "No RESUME"
Errors$(20) = "RESUME without error"
Errors$(24) = "Device timeout"
Errors$(25) = "Device fault"
Errors$(26) = "FOR without NEXT"
Errors$(27) = "Out of paper"
Errors$(29) = "WHILE without WEND"
Errors$(30) = "WEND without WHILE"
Errors$(33) = "Duplicate label"
Errors$(35) = "Subprogram not defined"
Errors$(37) = "Argument-count mismatch"
Errors$(38) = "Array not defined"
Errors$(40) = "Variable required"
Errors$(50) = "FIELD overflow"
Errors$(51) = "Internal error"
Errors$(52) = "Bad file name or number"
Errors$(53) = "File not found"
Errors$(54) = "Bad file mode"
Errors$(55) = "File already open"
Errors$(56) = "FIELD statement active"
Errors$(57) = "Device I/O error"
Errors$(58) = "File already exists"
Errors$(59) = "Bad record length"
Errors$(61) = "Disk full"
Errors$(62) = "Input past end of file"
Errors$(63) = "Bad record number"
Errors$(64) = "Bad file name"
Errors$(67) = "Too many files"
Errors$(68) = "Device unavailable"
Errors$(69) = "Communication-buffer overflow"
Errors$(70) = "Permission denied"
Errors$(71) = "Disk not ready"
Errors$(72) = "Disk-media error"
Errors$(73) = "Feature unavailable"
Errors$(74) = "Rename across disks"
Errors$(75) = "Path/File access error"
Errors$(76) = "Path not found"
'ErrorHandler:
' PRINT "ERROR: " + Errors$(ERR) + "."
'RESUME NEXT

FUNCTION CalendarBox% (Title$, Message$, DayValue%, MonthValue%, YearValue%)
 DIM OutMessage$
 DIM OutIndex%
 DIM Value%
 DIM Days%(37)
 DIM CalendarLine$
 DIM WorkDay%
 DIM WorkMonth%
 DIM WorkYear%
 DIM WorkKey$
 IF LEN(Message$) < 256 THEN OutMessage$ = Message$ + SPACE$(256 - LEN(Message$)) ELSE OutMessage$ = LEFT$(Message$, 256)
 CALL MakeBox(7, 5, 64, 14)
 PRINT LEFT$(Title$, 64) + SPACE$(64 - LEN(LEFT$(Title$, 64)));
 COLOR 1, 7
 FOR OutIndex% = 1 TO 4
  LOCATE 6 + OutIndex%, 8, 0
  PRINT LEFT$(OutMessage$, 64);
  OutMessage$ = MID$(OutMessage$, 65)
 NEXT OutIndex%
 COLOR 14, 7
 LOCATE 19, 8, 0
 PRINT "Please press key is equalient to your answer: ENTER=Yes, ESC=No.";
 WorkDay% = DayValue%
 WorkMonth% = MonthValue%
 WorkYear% = YearValue%
 COLOR 15, 7
 LOCATE 11, 31, 0
 PRINT "Mo Tu We Th Fr Sa Su";
 GOSUB OutCalendar
 DO
  WorkKey$ = INKEY$
  SELECT CASE LEN(WorkKey$)
  CASE 1
    SELECT CASE WorkKey$
    CASE CHR$(13)
      DayValue% = WorkDay%
      MonthValue% = WorkMonth%
      YearValue% = WorkYear%
      EXIT DO
    CASE CHR$(27)
      EXIT DO
    END SELECT
  CASE 2
    WorkKey$ = MID$(WorkKey$, 2)
    SELECT CASE WorkKey$
    CASE CHR$(72)
      WorkDay% = WorkDay% - 1
      IF WorkDay% < 1 THEN
       WorkMonth% = WorkMonth% - 1
       IF WorkMonth% < 1 THEN
        IF WorkYear% = 1980 THEN
         WorkMonth% = 1
         WorkDay% = 1
        ELSE
         WorkYear% = WorkYear% - 1
         WorkMonth% = 12
         WorkDay% = 31
        END IF
       ELSE
        WorkDay% = MonthDays%(WorkMonth%, WorkYear%)
       END IF
      END IF
      GOSUB OutCalendar
    CASE CHR$(80)
      WorkDay% = WorkDay% + 1
      IF WorkDay% > MonthDays%(WorkMonth%, WorkYear%) THEN
       WorkMonth% = WorkMonth% + 1
       IF WorkMonth% > 12 THEN
        IF WorkYear% = 2010 THEN
         WorkMonth% = 12
         WorkDay% = 31
        ELSE
         WorkYear% = WorkYear% + 1
         WorkMonth% = 1
         WorkDay% = 1
        END IF
       ELSE
        WorkDay% = 1
       END IF
      END IF
      GOSUB OutCalendar
    CASE CHR$(75)
      WorkDay% = WorkDay% - 1
      IF WorkDay% < 1 THEN
       WorkMonth% = WorkMonth% - 1
       IF WorkMonth% < 1 THEN
        IF WorkYear% = 1980 THEN
         WorkMonth% = 1
         WorkDay% = 1
        ELSE
         WorkYear% = WorkYear% - 1
         WorkMonth% = 12
         WorkDay% = 31
        END IF
       ELSE
        WorkDay% = MonthDays%(WorkMonth%, WorkYear%)
       END IF
      END IF
      GOSUB OutCalendar
    CASE CHR$(77)
      WorkDay% = WorkDay% + 1
      IF WorkDay% > MonthDays%(WorkMonth%, WorkYear%) THEN
       WorkMonth% = WorkMonth% + 1
       IF WorkMonth% > 12 THEN
        IF WorkYear% = 2010 THEN
         WorkMonth% = 12
         WorkDay% = 31
        ELSE
         WorkYear% = WorkYear% + 1
         WorkMonth% = 1
         WorkDay% = 1
        END IF
       ELSE
        WorkDay% = 1
       END IF
      END IF
      GOSUB OutCalendar
    CASE CHR$(73)
      WorkMonth% = WorkMonth% - 1
      IF WorkMonth% < 1 THEN
       IF WorkYear% = 1980 THEN
        WorkMonth% = 1
       ELSE
        WorkYear% = WorkYear% - 1
        WorkMonth% = 12
       END IF
      END IF
      IF WorkDay% > MonthDays%(WorkMonth%, WorkYear%) THEN WorkDay% = MonthDays%(WorkMonth%, WorkYear%)
      GOSUB OutCalendar
    CASE CHR$(81)
      WorkMonth% = WorkMonth% + 1
      IF WorkMonth% > 12 THEN
       IF WorkYear% = 2010 THEN
        WorkMonth% = 12
       ELSE
        WorkYear% = WorkYear% + 1
        WorkMonth% = 1
       END IF
      END IF
      IF WorkDay% > MonthDays%(WorkMonth%, WorkYear%) THEN WorkDay% = MonthDays%(WorkMonth%, WorkYear%)
      GOSUB OutCalendar
    CASE CHR$(71)
      IF WorkYear% > 1980 THEN
       WorkYear% = WorkYear% - 1
       IF WorkDay% > MonthDays%(WorkMonth%, WorkYear%) THEN WorkDay% = MonthDays%(WorkMonth%, WorkYear%)
       GOSUB OutCalendar
      END IF
    CASE CHR$(79)
      IF WorkYear% < 2010 THEN
       WorkYear% = WorkYear% + 1
       IF WorkDay% > MonthDays%(WorkMonth%, WorkYear%) THEN WorkDay% = MonthDays%(WorkMonth%, WorkYear%)
       GOSUB OutCalendar
      END IF
    END SELECT
  END SELECT
 LOOP
 CalendarBox% = WorkKey$ = CHR$(13)
 EXIT FUNCTION
OutCalendar:
 COLOR 8, 7
 LOCATE 12, 31, 0
 PRINT MonthName$(WorkMonth%) + ", " + LTRIM$(STR$(WorkYear%)) + " year." + SPACE$(21 - LEN(MonthName$(WorkMonth%) + ", " + LTRIM$(STR$(WorkYear%)) + " year."));
 FOR OutIndex% = 1 TO 37
  Days%(OutIndex%) = 0
 NEXT OutIndex%
 Value% = 1
 FOR OutIndex% = DayOfWeek%(1, WorkMonth%, WorkYear%) TO 37
  Days%(OutIndex%) = Value%
  Value% = Value% + 1
  IF Value% = MonthDays%(WorkMonth%, WorkYear%) + 1 THEN EXIT FOR
 NEXT OutIndex%
 CalendarLine$ = ""
 Value% = 1
 FOR OutIndex% = 1 TO 37
  IF Days%(OutIndex%) > 0 THEN
   IF Days%(OutIndex%) = WorkDay% THEN
    CalendarLine$ = CalendarLine$ + "*" + SPACE$(2 - LEN(LTRIM$(STR$(Days%(OutIndex%))))) + LTRIM$(STR$(Days%(OutIndex%)))
   ELSE
    CalendarLine$ = CalendarLine$ + SPACE$(3 - LEN(LTRIM$(STR$(Days%(OutIndex%))))) + LTRIM$(STR$(Days%(OutIndex%)))
   END IF
  ELSE
   CalendarLine$ = CalendarLine$ + SPACE$(3)
  END IF
  IF LEN(CalendarLine$) = 21 THEN
   COLOR 6, 7
   LOCATE 12 + Value%, 30, 0
   WHILE CalendarLine$ <> ""
    SELECT CASE LEFT$(CalendarLine$, 1)
    CASE "*"
      COLOR 14, 6
      CalendarLine$ = MID$(CalendarLine$, 2)
      PRINT SPACE$(1) + LEFT$(CalendarLine$, 3);
      CalendarLine$ = MID$(CalendarLine$, 4)
      COLOR 6, 7
    CASE ELSE
      PRINT LEFT$(CalendarLine$, 1);
      CalendarLine$ = MID$(CalendarLine$, 2)
    END SELECT
   WEND
   Value% = Value% + 1
  END IF
 NEXT OutIndex%
 IF CalendarLine$ <> "" THEN
  COLOR 6, 7
  LOCATE 12 + Value%, 30, 0
  WHILE CalendarLine$ <> ""
   SELECT CASE LEFT$(CalendarLine$, 1)
   CASE "*"
     COLOR 14, 6
     CalendarLine$ = MID$(CalendarLine$, 2)
     PRINT SPACE$(1) + LEFT$(CalendarLine$, 3);
     CalendarLine$ = MID$(CalendarLine$, 4)
     COLOR 6, 7
   CASE ELSE
     PRINT LEFT$(CalendarLine$, 1);
     CalendarLine$ = MID$(CalendarLine$, 2)
   END SELECT
  WEND
 END IF
 RETURN
END FUNCTION

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 DateAndTimeToSeconds# (HourValue%, MinuteValue%, SecondValue%, DayValue%, MonthValue%, YearValue%)
 DateAndTimeToSeconds# = (YearValue% * (416 * 86400#)) + (MonthValue% * (32 * 86400)) + (DayValue% * 86400) + (HourValue% * 3600!) + (MinuteValue% * 60) + SecondValue%
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 GetBit% (ValueData&, BitNumber%)
 GetBit% = Power&(BitNumber%) AND ValueData&
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

FUNCTION NumberToString$ (Value#, SystemBase$)
 DIM OutLineNumber$
 DIM Fractional$
 DIM Alphabet$
 DIM Meaning#
 DIM NumberBase#
 DIM Number&
 DIM Signed%
 OutLineNumber$ = ""
 Fractional$ = ""
 Alphabet$ = "0123456789ABCDEFGHIJKLMNOPQRSTUV"
 SELECT CASE LTRIM$(RTRIM$(UCASE$(SystemBase$)))
 CASE "BINARY"
   NumberBase# = 2#
 CASE "QUADRE"
   NumberBase# = 4#
 CASE "OCTAL"
   NumberBase# = 8#
 CASE "DECIMAL"
   NumberBase# = 10#
 CASE "HEXADECIMAL"
   NumberBase# = 16#
 CASE "DUOTRICENARY"
   NumberBase# = 32#
 CASE ELSE
   NumberToString$ = ""
   EXIT FUNCTION
 END SELECT
 IF INT(Value#) <> Value# THEN
  IF INT(Value#) < 0 THEN
   Value# = ABS(Value#)
   Number& = ABS(INT(Value#))
   Signed% = True%
  ELSE
   Number& = INT(Value#)
   Signed% = False%
  END IF
  WHILE Number& <> 0
   OutLineNumber$ = MID$(Alphabet$, (Number& MOD NumberBase#) + 1, 1) + OutLineNumber$
   Number& = INT(Number& / NumberBase#)
  WEND
  Meaning# = (Value# - INT(Value#)) * NumberBase#
  WHILE Meaning# <> 0#
   Fractional$ = Fractional$ + MID$(Alphabet$, INT(Meaning#) + 1, 1)
   Meaning# = (Meaning# - INT(Meaning#)) * NumberBase#
  WEND
  IF Signed% THEN NumberToString$ = "-" + OutLineNumber$ + "." + Fractional$ ELSE NumberToString$ = OutLineNumber$ + "." + Fractional$
 ELSE
  IF INT(Value#) < 0 THEN
   Value# = ABS(Value#)
   Number& = ABS(INT(Value#))
   Signed% = True%
  ELSE
   Signed% = False%
   Number& = INT(Value#)
  END IF
  WHILE Number& <> 0
   OutLineNumber$ = MID$(Alphabet$, (Number& MOD NumberBase#) + 1, 1) + OutLineNumber$
   Number& = INT(Number& / NumberBase#)
  WEND
  IF Signed% THEN NumberToString$ = "-" + OutLineNumber$ ELSE NumberToString$ = OutLineNumber$
 END IF
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

FUNCTION PasswordInputBox% (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 PasswordOutInputLine
 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 PasswordOutInputLine
      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 PasswordOutInputLine
      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 PasswordOutInputLine
      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 PasswordOutInputLine
      END IF
    CASE CHR$(71)
      IF InputTextCursorColumn% <> 1 THEN
       InputTextCursorColumn% = 1
       InputTextCursorPosition% = 1
       GOSUB PasswordOutInputLine
      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 PasswordOutInputLine
      END IF
    CASE CHR$(83)
      IF InputText$ <> "" THEN
       InputText$ = MID$(InputText$, 1, InputTextCursorColumn% - 1) + MID$(InputText$, InputTextCursorColumn% + 1)
       GOSUB PasswordOutInputLine
      END IF
    END SELECT
  END SELECT
 LOOP
 LOCATE , , 0
 PasswordInputBox% = WorkKey$ = CHR$(13)
 EXIT FUNCTION
PasswordOutInputLine:
 COLOR 4, 7
 LOCATE 14, 8, 0
 PRINT STRING$(LEN(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 Power& (Value%)
 DIM Index%
 DIM Meaning&
 Meaning& = 1&
 FOR Index% = 1 TO Value%
  Meaning& = Meaning& * 2&
 NEXT Index%
 Power& = Meaning&
END FUNCTION

SUB ScratchScreen
 COLOR 0, 2
 CLS
 PRINT "********************************************************************************"
 PRINT "               The Standart GNU Personal Dialog Library for QBasic."
 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 SecondsToDateAndTime (SecondsCount#, HourValue%, MinuteValue%, SecondValue%, DayValue%, MonthValue%, YearValue%, DayOfWeekValue%)
 DIM WorkValue#
 WorkValue# = SecondsCount#
 YearValue% = INT(WorkValue# / (416 * 86400))
 WorkValue# = WorkValue# - (YearValue% * (416 * 86400#))
 MonthValue% = INT(WorkValue# / (32 * 86400))
 WorkValue# = WorkValue# - (MonthValue% * (32 * 86400))
 DayValue% = INT(WorkValue# / 86400)
 WorkValue# = WorkValue# - (DayValue% * 86400)
 HourValue% = INT(WorkValue# / 3600)
 WorkValue# = WorkValue# - (HourValue% * 3600!)
 MinuteValue% = INT(WorkValue# / 60)
 SecondValue% = WorkValue# - (MinuteValue% * 60)
 DayOfWeekValue% = DayOfWeek%(DayValue%, MonthValue%, YearValue%)
END SUB

SUB SetBit (ValueData&, BitNumber%, BitValue%)
 IF BitValue% THEN ValueData& = ValueData& OR Power&(BitNumber%) ELSE ValueData& = ValueData& AND NOT Power&(BitNumber%)
END SUB

FUNCTION StringToNumber# (Value$, SystemBase$)
 DIM WholeLine$
 DIM FractionalLine$
 DIM Fractional#
 DIM NumberBase&
 DIM Whole&
 DIM NumBase&
 DIM Signed%
 DIM IsFractional%
 WholeLine$ = ""
 FractionalLine$ = ""
 Whole& = 0&
 NumBase& = 1&
 Fractional# = 0#
 IsFractional% = False%
 Value$ = LTRIM$(RTRIM$(Value$))
 IF Value$ = "" THEN
  StringToNumber# = 0#
  EXIT FUNCTION
 END IF
 Alphabet$ = "0123456789ABCDEFGHIJKLMNOPQRSTUV"
 SELECT CASE LTRIM$(RTRIM$(UCASE$(SystemBase$)))
 CASE "BINARY"
   NumberBase& = 2
 CASE "QUADRE"
   NumberBase& = 4
 CASE "OCTAL"
   NumberBase& = 8
 CASE "DECIMAL"
   NumberBase& = 10
 CASE "HEXADECIMAL"
   NumberBase& = 16
 CASE "DUOTRICENARY"
   NumberBase& = 32
 CASE ELSE
   StringToNumber# = 0#
   EXIT FUNCTION
 END SELECT
 IF LEFT$(Value$, 1) = "-" THEN
  Signed% = True%
  Value$ = LTRIM$(MID$(Value$, 2))
  IF Value$ = "" THEN
   StringToNumber# = 0#
   EXIT FUNCTION
  END IF
 END IF
 IF INSTR(Value$, ".") > 0 THEN
  IsFractional% = True%
  WholeLine$ = RTRIM$(MID$(Value$, 1, INSTR(Value$, ".") - 1))
  FractionalLine$ = LTRIM$(MID$(Value$, INSTR(Value$, ".") + 1))
  IF WholeLine$ = "" THEN
   StringToNumber# = 0#
   EXIT FUNCTION
  END IF
  IF FractionalLine$ = "" THEN
   StringToNumber# = 0#
   EXIT FUNCTION
  END IF
 ELSE
  WholeLine$ = Value$
 END IF
 WHILE WholeLine$ <> ""
  IF INSTR(Alphabet$, RIGHT$(UCASE$(WholeLine$), 1)) = 0 THEN
   StringToNumber# = 0#
   EXIT FUNCTION
  ELSE
   Whole& = Whole& + ((INSTR(Alphabet$, RIGHT$(UCASE$(WholeLine$), 1)) - 1) * NumBase&)
  END IF
  NumBase& = NumBase& * NumberBase&
  WholeLine$ = MID$(WholeLine$, 1, LEN(WholeLine$) - 1)
 WEND
 IF Signed% THEN Whole& = Whole& - (Whole& * 2)
 IF IsFractional% THEN
  WHILE FractionalLine$ <> ""
   IF INSTR(Alphabet$, RIGHT$(UCASE$(FractionalLine$), 1)) = 0 THEN
    StringToNumber# = 0#
    EXIT FUNCTION
   ELSE
    Fractional# = Fractional# + (INSTR(Alphabet$, RIGHT$(UCASE$(FractionalLine$), 1)) - 1)
   END IF
   FractionalLine$ = MID$(FractionalLine$, 1, LEN(FractionalLine$) - 1)
   Fractional# = Fractional# / NumberBase&
  WEND
 END IF
 StringToNumber# = Whole& + Fractional#
END FUNCTION

FUNCTION WeekNumber% (DayValue%, MonthValue%, YearValue%)
 WeekNumber% = INT((MonthDaysCount%(MonthValue%, YearValue%) + DayValue%) / 7) + 1
END FUNCTION

