!--------------------------------------------------------------
!DonsBasicLibrary.bas
!Version: 2017/12/13
!----------------------------
!Purpose: This file pulls all of my functions together into a
! single library file.
!All functions here will begin with L_ to differentiate them from
! other functions and basic commands.
!All data is stored in bundle number B2.
!
!Contents:
!
!  Library Setup:
!    L_DisplaySetup(DisplayBoarder,DisplayORI,DisplayStatus)
!      (Run first.  Sets the bundle data, and the graphics screen.)
!
!  Display:
!    L_addscreen(NumberOfThisType,DisplayMX,DisplayMY,Displaybackground)
!      (Adds a text display screen.)
!    L_ChangeScreen(NewScreen)
!      (Switches the current text display being used.)
!    L_Write (TXT$)
!      ("Prints" to the current text display.)
!    L_Clear()
!      (Clears the current text display to it's background color.)
!    L_ClearABox(TCX,TCY,Width,Hight,ColorToUse)
!      (Clears a portion of the current text display to a specific color.)
!    L_Setcolors(foreground,background)
!      (Sets the current foreground and background colors.)
!    L_locate(tcx,tcy)
!      (Sets the location of the current text display's text cursor.)
!    L_textmode(textmode)
!      (Sets the text mode. Accepts 1, 4, 6, 8.  1 is normal text.)
!    L_LocPA(pa)
!      (Converts the "Print @" from old computers to x/y locate coordinates.)
!
!  Keyboard:
!    L_KeyboardSetup(KeyboardAlpha,KeyboardColor)
!      (Loads the keyboard data, and draws the keyboards.)
!    L_WhatKey(TouchXcoord,TouchYcoord)
!      (Determines if a key has been touched, and stores it in bundle.)
!    L_Drawbuttons()
!      (Draws the keyboards.)
!    L_hidekeyboard(kbrd)
!      (Hides the current keyboard.)
!    L_showkeyboard(kbrd)
!      (Shows the current keyboard.)
!    L_CurrentKeyboard(keyboard)
!      (Sets the current keyboard.)
!    L_LoadButtonData()
!      (Loads the keyboard data.)
!
!  Graphics:
!    L_gcol(Alpha,color,fill)
! 
!    (Internal.  Sets the graphics color.)
!    L_OpenGR(Alpha,color,Status,Orientation)
!      (Internal.  Opens the graphics screen.)
!
!  Miscellanious Functions:
!    A$=L_NumberClip$(Number,Number$)
!      (Returns the number with the decimal removed. Example 1.0 becomes 1.)
! 
!  Keyboard gosubs:
!    Gettouch:
!      (Gets the touch coordinates.)
!    GetLastKey:
!      (Retreives the last key touched from the bundle.)
!
!  Test program:
!    Used to find problems in the library code.
!    1) Rem out the line: goto Skipthis.  At the top of the test program section.
!    2) Run the library as a program.
!
!--------------------------------------------------------------
!FindDisplay
!----------------------------
! IncDisplay11.bas
!----------------------------
!Last Change:10-16-2017
!Purpose: The new flexible multi-screen text display!  Now with
!  Bundles and Functionized.

!DisplayORI=0
!DISPlayBoarder=10
!DisplayRender=1

!DisplaySc[] format:
!Screen Type 2
!NumType=1
! DisplayMX=Display number of columns wide (char)
! DisplayMY=Display number of rows high (char)
! DisplayBackground=Background color 1 - 20
! DisplayStatus=Show status bar 0 = no, 1 = Yes.
! Rowhigh=Hight of character in pixels
! ColumnWide=Width of character in pixels
! DisplayTSZ=Text size number
! DisplayOffY=Offset Y coord of display
! DisplayOffX=Offset X coord of display
! ScreenPTR=BMP image pointer
! GON=Graphical Object Number of BMP image
! DisplayTW   - Text Width (Pixels)
!----------------------------
FN.DEF L_LibrarySetup(DisplayBoarder,DisplayORI,DisplayStatus,ScaleX,ScaleY)
 !setup graphics
 !New setup subroutine auto figures settings.
 !Set MX, MY, and ORI.  Gosub DisplaySetup
 !DisplayMY   - Number of Displayed Rows.
 !DisplayMX   - Number of Displayed Columns.
 !DisplayORI  - Screen orientation. Portrait = 1, Landscape = 0
 !DisplayBackground - Set ColorBackground to color number from GCOL. 
 !DisplayBoarder - Set to color number from GCOL.
 !DisplayStatus - Show/Hide status bar. 0 = Hide, 1 = Show.
 !-----
 !Setup figures TSZ, TW, OFFX and OFFY.
 !DisplayTSZ  - Text Size (Pixels)
 !DisplayTW   - Text Width (Pixels)
 !DisplayOFFX - Offset X (Pixels)
 !DisplayOFFY - Offset Y (Pixels)
 !-----
 !setup bundles
 BUNDLE.CREATE B2
 If B2=1
 !just created first bundle, make another for the library data.
 Bundle.Create B2
 endif
 ! b2>1 bundle just created use for library data.
 BUNDLE.PUT 1, "DonsBasicLibrary",B2
 
 a$="DonsBasicLibrary.bas  All data in this one bundle!"
 BUNDLE.PUT B2, "purpose",a$
 BUNDLE.PUT B2, "NumBundles", 1
 BUNDLE.PUT B2, "screens", -1
 BUNDLE.PUT B2, "keyboards",0
 BUNDLE.PUT B2, "curscreen", 0
 BUNDLE.PUT B2, "foreground",9
 BUNDLE.PUT B2, "background",1

 !Colors for L_Gcol, and L_OpenGR
 C1$="000000 ff0000 00ff00 0000ff ffff00 00ffff ff00ff 999999 ffffff 000099 "
 C2$="009900 009999 990000 990099 999900 993333 CCCCCC FFCC99 FF9900 FFCC00 "
 ColorString$=c1$+c2$
 
 BUNDLE.PUT B2, "colorstring",Colorstring$

 CALL L_OpenGR(255,DisplayBoarder,DisplayStatus,DisplayORI)
 GR.SCREEN DisplayMGX,DisplayMGY

 IF ScaleX>0
  Scale_Width=DisplayMGX/ScaleX
  Scale_Hight=DisplayMGY/ScaleY
  GR.Scale Scale_Width,Scale_Hight
  DisplayMGX=ScaleX
  DisplayMGY=ScaleY
 else
  Scale_Hight=0
  Scale_Width=0
 endif

 IF DisplayStatus=1
  GR.STATUSBAR DisplayStatusHight
 ELSE
  DisplayStatusHight=0
 ENDIF
 BUNDLE.PUT B2, "DisplayMGX", DisplayMGX
 BUNDLE.PUT B2, "DisplayMGY", DisplayMGY
 BUNDLE.PUT B2, "DisplayStatus", DisplayStatusHight
 BUNDLE.PUT B2, "ScaleX", Scale_Width
 BUNDLE.PUT B2, "ScaleY", Scale_Hight


 TextMode=1
 BUNDLE.PUT B2, "TextMode",TextMode

 !add screen 0 -- internal info screen
 L_addscreen(32,16,3)
 L_setcolors(1,3)
 L_ChangeScreen(0)

 !load screen 0 with startup info
 L_locate(1,1):P$="  --------------------------"+CHR$(13):L_write(P$)
 L_locate(7,2):L_write("Don's Basic Library")
 L_locate(6,3):L_write("Version: 2017/12/13")
 L_locate(10,5):L_write("by Sirdonzer")
 L_locate(3,6):L_write("Email: Donzerme@Yahoo.com")
 L_locate(4,7):P$="--------------------------" +CHR$(13) :L_write(P$)
 L_Locate(4,15):P$="--------------------------" +CHR$(13) :L_write(P$)
 L_locate(1,8): P$="Screen  0 ":L_write(P$)
 L_locate(1,9)
 A=0
 FN.RTN A
FN.END
!----------------------------
FN.DEF L_hidescreen(Screen)

 BUNDLE.GET 1, "DonsBasicLibrary",B2

 kn$="scrn"
 ScreenNum$=kn$+STR$(Screen)+"GON"
 BUNDLE.GET B2, screenNum$,GON
 GR.HIDE GON

FN.END
!----------------------------
FN.DEF L_addscreen(DisplayMX,DisplayMY,Displaybackground)
 !Adds a text display screen.
 !get bundle 1 info
 BUNDLE.GET 1, "DonsBasicLibrary",B2

 BUNDLE.GET B2, "NumBundles",NumBundles
 BUNDLE.GET B2, "screens",NumScreens
 BUNDLE.GET B2, "keyboards",NumKeyboards
 BUNDLE.GET B2, "DisplayMGX", DisplayMGX
 BUNDLE.GET B2, "DisplayMGY", DisplayMGY
 BUNDLE.GET B2, "DisplayStatus", DisplayStatusHight
 BUNDLE.GET B2, "curscreen", curscreen

 !Start textsize calculation
 ! curscreen=a51
 !subtract hight of the status bar if present.
 DisplayMGY=DisplayMGY-DisplayStatusHight
 Rowhigh=FLOOR(DisplayMGY/DisplayMY)
 DisplayMGY=DisplayMGY+DisplayStatusHight
 Columnwide=FLOOR(DisplayMGX/DisplayMX)
 !figure DisplayTSZ
 DisplayTSZ=Rowhigh
 GR.TEXT.TYPEFACE 2
 DO
  A14=0
  GR.TEXT.SIZE DisplayTSZ
  GR.TEXT.WIDTH DisplayTW, "A"
  GR.TEXT.HEIGHT A08,A09,A10
  A09=FLOOR(A09)
  A11=CEIL(A10)
  A12=FLOOR(A09)
  TextTR=A11-A12
  IF TextTR>Rowhigh
   A14=A14+1
  ENDIF
  IF DisplayTW>Columnwide
   A14=A14+1
  ENDIF
  IF A14>0
   DisplayTSZ=DisplayTSZ-1
  ENDIF
 UNTIL A14=0
 !fix the size of RowHigh and ColumnWide to the size of the text.
 IF Rowhigh>TextTR THEN Rowhigh=TextTR
 IF Columnwide>DisplayTW THEN Columnwide=DisplayTW
 !calculate offsets.
 A04=DisplayMGY-Displaystatushight
 A05=Rowhigh*DisplayMY
 A06=A04-A05
 A07=FLOOR(A06/2)
 DisplayOffY=A07+Displaystatushight
 DisplayOffX=FLOOR((DisplayMGX-(Columnwide * DisplayMX))/2)
 !The RowHigh and ColumnWide are the size of the background graphic boxes. 
 !TR is the total hight of Text in pixels.
 !----
 !set background color, create a screen sized bitmap, and show it.
 L_gcol(255,Displayboarder,1)
 !calculate bmp size here.
 A48=Rowhigh * DisplayMY
 A49=Columnwide * DisplayMX
 GR.BITMAP.CREATE ScreenPTR, A49,A48
 !GR.BITMAP.CREATE ScreenPTR,DisplayMGX,DisplayMGY
 !use offsets to center bmp.
 !must set color for bitmap.
 !Gr.bitmap.drawinto.start points the graphic tools at the bitmap "screenptr" 
 !must start and end before/after each "Printing/drawing".
 GR.BITMAP.DRAWINTO.START ScreenPTR
 !use ordinary graphic commands to draw stuff on bitmap.

 !clear screen
 Tcx=1
 TCY=1
 Width=DisplayMX
 Hight=DisplayMY
 A40=TCY
 A41=TCY+Hight-1
 A42=TCX
 A43=TCX+Width-1
 A44=(((A42-1))*Columnwide)
 A45=((A40-1)*Rowhigh)
 A46=((A43)*Columnwide)
 A47=((A41)*Rowhigh)
 CALL L_gcol(255,Displaybackground,1)
 GR.RECT A48,A44,A45,A46,A47
 GR.BITMAP.DRAWINTO.END
 !this next command adds the bitmap to the display list.
 !only need to do this once.
 GR.BITMAP.DRAW GON,ScreenPTR,1,1
 !Centers the bmpimage.
 GR.MODIFY ScreenPTR,"x",DisplayOffX
 GR.MODIFY ScreenPTR,"y",DisplayOffY
 !then gr.render to make it appear.
 GR.RENDER
 GR.HIDE GON

 !draw cursor
 !L_gcol(255,Displayboarder,1)
 !calculate bmp size here.
 !A48=Rowhigh
 !A49=Columnwide
 !GR.BITMAP.CREATE ScreenPTR2, A49,A48
 !GR.BITMAP.DRAWINTO.START ScreenPTR2
 !Draw Box
 !A28=1
 !A29=1
 !A30=Columnwide
 !A31=Rowhigh
 !CALL L_gcol(255,9,1)
 !GR.RECT A32,A28,A29,A30,A31
 !GR.BITMAP.DRAWINTO.END
 !GR.BITMAP.DRAW CursorGON,ScreenPTR2,1,1
 !GR.MODIFY ScreenPTR2,"x",DisplayOffX
 !GR.MODIFY ScreenPTR2,"y",DisplayOffY
 !GR.RENDER
 !GR.HIDE cursorGON

 !Store variables here.
 NumScreens=NumScreens+1
 !Put screen data into bundle #1.
 kn$="scrn"+STR$(NumScreens)
 Kn2$=kn$+"DisplayMX"
 BUNDLE.PUT B2,kn2$,DisplayMX
 Kn2$=kn$+"DisplayMY"
 BUNDLE.PUT B2,kn2$,DisplayMY
 Kn2$=kn$+"Displaybackground"
 BUNDLE.PUT B2,kn2$,Displaybackground
 Kn2$=kn$+"RowHigh"
 BUNDLE.PUT B2,kn2$,Rowhigh
 Kn2$=kn$+"ColumnWide"
 BUNDLE.PUT B2,kn2$,Columnwide
 Kn2$=kn$+"DisplayTSZ"
 BUNDLE.PUT B2,kn2$,DisplayTSZ
 Kn2$=kn$+"DisplayOFFY"
 BUNDLE.PUT B2,kn2$,DisplayOffY
 Kn2$=kn$+"DisplayOFFX"
 BUNDLE.PUT B2,kn2$,DisplayOffX
 Kn2$=kn$+"ScreenPtr"
 BUNDLE.PUT B2,kn2$,ScreenPTR
 Kn2$=kn$+"GON"
 BUNDLE.PUT B2,kn2$,GON
 !set the Text Cursor to the upper left corner
 Kn2$=kn$+"TCX"
 BUNDLE.PUT B2,kn2$,1
 Kn2$=kn$+"TCY"
 BUNDLE.PUT B2,kn2$,1
 kn2$=kn$+"cursorgon"
 BUNDLE.PUT b2,kn2$,cursorGON
 kn2$=kn$+"screenptr2"
 BUNDLE.PUT b2,kn2$,screenptr2
 curscreen=numscreens
 BUNDLE.PUT B2, "curscreen", curscreen
 BUNDLE.PUT B2, "screens",NumScreens
 L_ChangeScreen(0)

 a$="Screen "+STR$(curscreen)+CHR$(13)
 L_write(a$)
 A=0
 FN.RTN A
FN.END

!----------------------------
FN.DEF L_ChangeScreen(NewScreen)
 !Set NewScreen to the desired screen number, call ChangeScreen.

BUNDLE.GET 1, "DonsBasicLibrary",B2

 kn$="scrn"
 BUNDLE.GET B2, "curscreen",curscreen

 ScreenNum$=kn$+STR$(curScreen)+"GON"
 BUNDLE.GET B2, screenNum$,GON
 GR.HIDE GON
 ScreenNum$=kn$+STR$(NewScreen)+"GON"
 BUNDLE.GET B2, screenNum$,GON

 Screennum$=kn$+STR$(NewScreen)+"DisplayTSZ"
 BUNDLE.GET B2,Screennum$,DisplayTSZ
 GR.TEXT.SIZE DisplayTSZ
 !put any other change screen stuff here.
 GR.SHOW GON
 GR.RENDER
 BUNDLE.PUT B2, "curscreen",NewScreen

FN.END

!----------------------------
FN.DEF L_Write (TXT$)
 !set TCX,TCY,TXT$
 ! Textmode=1
 BUNDLE.GET 1, "DonsBasicLibrary",B2

 !get screen info
 BUNDLE.GET B2, "curscreen",curscreen
 kn$="scrn"+STR$(curScreen)
 BUNDLE.GET B2,"foreground",CF
 BUNDLE.GET B2,"background",CB

 !Get screen data from bundle.
 Kn2$=kn$+"DisplayMX"
 BUNDLE.GET B2,kn2$,DisplayMX
 Kn2$=kn$+"DisplayMY"
 BUNDLE.GET B2,kn2$,DisplayMY
 Kn2$=kn$+"Displaybackground"
 BUNDLE.GET B2,kn2$,Displaybackground
 Kn2$=kn$+"RowHigh"
 BUNDLE.GET B2,kn2$,Rowhigh
 Kn2$=kn$+"ColumnWide"
 BUNDLE.GET B2,kn2$,Columnwide
 Kn2$=kn$+"DisplayTSZ"
 BUNDLE.GET B2,kn2$,DisplayTSZ
 Kn2$=kn$+"DisplayOFFY"
 BUNDLE.GET B2,kn2$,DisplayOffY
 Kn2$=kn$+"DisplayOFFX"
 BUNDLE.GET B2,kn2$,DisplayOffX
 Kn2$=kn$+"ScreenPtr"
 BUNDLE.GET B2,kn2$,ScreenPTR
 Kn2$=kn$+"GON"
 BUNDLE.GET B2,kn2$,GON
 Kn2$=kn$+"TCX"
 BUNDLE.GET B2,kn2$,TCX
 Kn2$=kn$+"TCY"
 BUNDLE.GET B2,kn2$,TCY

 !get TextMode
 BUNDLE.GET B2, "TextMode",TextMode

 GR.TEXT.SIZE DisplayTSZ

 !prepair for writing
 A20=TCX
 A21=TCY
 !Lenth of TXT$
 A22=LEN(TXT$)
 !size of the grab in characters
 A23=1
 !TXT$ position pointer
 A24=1

 !Start write operation
 GR.BITMAP.DRAWINTO.START ScreenPTR

 !calculate TCX,TCY in pixels
 !text char position in pixels
 !both corners of the box, in pixels.

 !Do write operation
 FOR A24=1 TO A22

  !Grab a part of TXT$
  A26$=MID$(TXT$,A24,A23)

  !check for special characters.
  c=UCODE(a26$)
  !do not send L_write a zero!  It has problems...
  IF c=0 THEN c=32

  !note: These are not ascii/ansi/html codes.
  ! After searching, I desided to keep it simple,
  !and setup my own codes.

  !calculate position in pixels,
  !then draw erase box.
  A28=((A20-1)*Columnwide)
  A29=((A21-1)*Rowhigh)
  A30=A28+(Columnwide * A23)
  A31=A29+Rowhigh
  CALL L_gcol(255,CB,1)
  GR.RECT A32,A28,A29,A30,A31

  !check for text mode
  IF Textmode=1
   IF c>31
    !Draw Character
    A33=((A20-1)*Columnwide)
    A34=((A21-1)*Rowhigh)+DisplayTSZ
    CALL L_gcol(255,CF,1)
    GR.TEXT.DRAW A32,A33,A34,A26$

   ELSE
    ! C<31
    IF c=1
     !home the cursor (move to upper left corner. Thats 1,1.)
     A20=1
     A21=1
    ENDIF
    IF c=2 
     !cursor up
     A21=A21-1
     IF A21<1 THEN A21=DisplayMY
    ENDIF
    IF c=3
     !cursor down
     A21=A21+1
     IF A21>DisplayMY THEN A21=1
    ENDIF
    IF c=4
     !cursor left
     A20=A20-1
     IF A20<1 THEN A20=DisplayMX
    ENDIF
    IF c=5
     !cursor right
     A20=A20+1
     IF A20>DisplayMX THEN A20=1
    ENDIF
    IF c=8
     !backspace -- distructive backspace
     A20=A20-1
     IF A20<1 THEN A20=DisplayMX
     !Draw Box
     A28=((A20-1)*Columnwide)
     A29=((A21-1)*Rowhigh)
     A30=A28+(Columnwide * A23)
     A31=A29+Rowhigh
     CALL L_gcol(255,CB,1)
     GR.RECT A32,A28,A29,A30,A31
    ENDIF
    IF c=13
     !enter
     A20=1
     A21=A21+1
     IF A21>DisplayMY THEN A21=1
    ENDIF
   ENDIF
  ENDIF

  !check for semigraphics mode
  IF textmode>1

   !get bit string, and calculate variables
   B$=BIN$(c)
   b1$="00000000"
   B$=b1$+B$
   B$=RIGHT$(B$,8)
   ph=CEIL(Columnwide/2)
   pt1=CEIL(Rowhigh/3)
   pt2=CEIL((Rowhigh/3)*2)
   PQ1=CEIL(Rowhigh/4)
   pQ2=CEIL((Rowhigh/4)*2)
   pQ3=CEIL((Rowhigh/4)*3)

   !check each bit for a 1.
   IF textmode=4
    IF MID$(b$,5,1)="1"
     x1=A28:y1=A29:x2=A28+ph:y2=A29+pq2
     CALL L_gcol(255,CF,1)
     GR.RECT A32,X1,Y1,X2,Y2
    ENDIF
    IF MID$(b$,6,1)="1"
     x1=A28+PH:y1=A29:x2=A28+Columnwide:y2=A29+pq2
     CALL L_gcol(255,CF,1)
     GR.RECT A32,X1,Y1,X2,Y2
    ENDIF
    IF MID$(b$,7,1)="1"
     x1=A28:y1=A29+pq2:x2=A28+ph:y2=A29+Rowhigh
     CALL L_gcol(255,CF,1)
     GR.RECT A32,X1,Y1,X2,Y2
    ENDIF
    IF MID$(b$,8,1)="1"
     x1=A28+PH:y1=A29+PQ2:x2=A28+Columnwide:y2=A29+Rowhigh
     CALL L_gcol(255,CF,1)
     GR.RECT A32,X1,Y1,X2,Y2
    ENDIF
   ENDIF

   IF textmode=6
    IF MID$(b$,3,1)="1"
     x1=A28+PH:y1=A29+PT2:x2=A28+Columnwide:y2=A29+Rowhigh
     CALL L_gcol(255,CF,1)
     GR.RECT A32,X1,Y1,X2,Y2
    ENDIF
    IF MID$(b$,4,1)="1"
     x1=A28:y1=A29+PT2:x2=A28+PH:y2=A29+Rowhigh
     CALL L_gcol(255,CF,1)
     GR.RECT A32,X1,Y1,X2,Y2
    ENDIF
    IF MID$(b$,5,1)="1"
     x1=A28+PH:y1=A29+pt1:x2=A28+Columnwide:y2=A29+pt2
     CALL L_gcol(255,CF,1)
     GR.RECT A32,X1,Y1,X2,Y2
    ENDIF
    IF MID$(b$,6,1)="1"
     x1=A28:y1=A29+pt1:x2=A28+ph:y2=A29+pt2
     CALL L_gcol(255,CF,1)
     GR.RECT A32,X1,Y1,X2,Y2
    ENDIF
    IF MID$(b$,7,1)="1"
     x1=A28+PH:y1=A29:x2=A28+Columnwide:y2=A29+pt1
     CALL L_gcol(255,CF,1)
     GR.RECT A32,X1,Y1,X2,Y2
    ENDIF
    IF MID$(b$,8,1)="1"
     x1=A28:y1=A29:x2=A28+ph:y2=A29+pt1
     CALL L_gcol(255,CF,1)
     GR.RECT A32,X1,Y1,X2,Y2
    ENDIF
   ENDIF

   IF textmode=8
    IF MID$(b$,1,1)="1"
     x1=A28:y1=A29:x2=A28+ph:y2=A29+pq1
     CALL L_gcol(255,CF,1)
     GR.RECT A32,X1,Y1,X2,Y2
    ENDIF
    IF MID$(b$,2,1)="1"
     x1=A28+PH:y1=A29:x2=A28+Columnwide:y2=A29+pq1
     CALL L_gcol(255,CF,1)
     GR.RECT A32,X1,Y1,X2,Y2
    ENDIF
    IF MID$(b$,3,1)="1"
     x1=A28:y1=A29+pq1:x2=A28+ph:y2=A29+pq2
     CALL L_gcol(255,CF,1)
     GR.RECT A32,X1,Y1,X2,Y2
    ENDIF
    IF MID$(b$,4,1)="1"
     x1=A28+PH:y1=A29+pq1:x2=A28+Columnwide:y2=A29+pq2
     CALL L_gcol(255,CF,1)
     GR.RECT A32,X1,Y1,X2,Y2
    ENDIF
    IF MID$(b$,5,1)="1"
     x1=A28:y1=A29+pq2:x2=A28+ph:y2=A29+pq3
     CALL L_gcol(255,CF,1)
     GR.RECT A32,X1,Y1,X2,Y2
    ENDIF
    IF MID$(b$,6,1)="1"
     x1=A28+PH:y1=A29+pq2:x2=A28+Columnwide:y2=A29+pq3
     CALL L_gcol(255,CF,1)
     GR.RECT A32,X1,Y1,X2,Y2
    ENDIF
    IF MID$(b$,7,1)="1"
     x1=A28:y1=A29+pq3:x2=A28+ph:y2=A29+Rowhigh
     CALL L_gcol(255,CF,1)
     GR.RECT A32,X1,Y1,X2,Y2
    ENDIF
    IF MID$(b$,8,1)="1"
     x1=A28+PH:y1=A29+pq3:x2=A28+Columnwide:y2=A29+Rowhigh
     CALL L_gcol(255,CF,1)
     GR.RECT A32,X1,Y1,X2,Y2
    ENDIF
   ENDIF

  ENDIF

  !update cursor position
  A20=A20+1
  IF A20>DisplayMX
   A20=1
   A21=A21+1
   IF A21>DisplayMY
    A21=1
   ENDIF
  ENDIF

 NEXT

 !stop write operation
 GR.BITMAP.DRAWINTO.END
 GR.RENDER

 !Store cursor position
 TCX=A20
 TCY=A21
 kn$="scrn"+STR$(curScreen)
 kn2$=kn$+"TCX"
 BUNDLE.PUT B2,kn2$,TCX
 kn2$=kn$+"TCY"
 BUNDLE.PUT B2,kn2$,TCY
FN.END

!----------------------------
FN.DEF L_Clear()
 !Clears the screen.(Paints entire screen the background color.)
 !Uses ClearABox to do the work.

 !get screen data
 BUNDLE.GET 1, "DonsBasicLibrary",B2


 !Get screen data from bundle Numbun.
 BUNDLE.GET B2, "curscreen",curscreen
 kn$="scrn"+STR$(curScreen)
 Kn2$=kn$+"DisplayMX"
 BUNDLE.GET B2,kn2$,DisplayMX
 Kn2$=kn$+"DisplayMY"
 BUNDLE.GET B2,kn2$,DisplayMY
 Kn2$=kn$+"Displaybackground"
 BUNDLE.GET B2,kn2$,Displaybackground
 Kn2$=kn$+"RowHigh"
 BUNDLE.GET B2,kn2$,Rowhigh
 Kn2$=kn$+"ColumnWide"
 BUNDLE.GET B2,kn2$,Columnwide
 Kn2$=kn$+"DisplayTSZ"
 BUNDLE.GET B2,kn2$,DisplayTSZ
 Kn2$=kn$+"DisplayOFFY"
 BUNDLE.GET B2,kn2$,DisplayOffY
 Kn2$=kn$+"DisplayOFFX"
 BUNDLE.GET B2,kn2$,DisplayOffX
 Kn2$=kn$+"ScreenPtr"
 BUNDLE.GET B2,kn2$,ScreenPTR
 Kn2$=kn$+"GON"
 BUNDLE.GET B2,kn2$,GON
 Kn2$=kn$+"TCX"
 BUNDLE.GET B2,kn2$,TCX
 Kn2$=kn$+"TCY"
 BUNDLE.GET B2,kn2$,TCY

 !set coordinates to whole screen
 TCX=1
 TCY=1
 Width=DisplayMX
 Hight=DisplayMY
 L_ClearABox(TCX,TCY,Width,Hight,Displaybackground)

 !Move cursor back to upper left corner
 Kn2$=kn$+"TCX"
 B2=2
 BUNDLE.PUT B2,kn2$,TCX
 Kn2$=kn$+"TCY"
 BUNDLE.PUT B2,kn2$,TCY

FN.END

!----------------------------
FN.DEF L_ClearABox(TCX,TCY,Width,Hight,colortouse)
 !Clears a box on the screen (in characters).
 !(Paints a box in the background color.)
 ! Specs: (In characters)
 !  TCX,TCY - coords of the upper left corner of the box
 !  Width - width of box.
 !  Hight - Hight of box.

 ! IF tcx < 1 THEN tcx=DisplayMX
 ! IF tcx > DisplayMX THEN tcx=1
 ! IF tcY < 1 THEN tcy=DisplayMY
 ! IF tcY > DisplayMY THEN tcY=1

 BUNDLE.GET 1, "DonsBasicLibrary",B2

 !Get screen data from bundle Numbun.
 BUNDLE.GET B2, "curscreen",curscreen
 kn$="scrn"+STR$(curScreen)
 Kn2$=kn$+"DisplayMX"
 BUNDLE.GET B2,kn2$,DisplayMX
 Kn2$=kn$+"DisplayMY"
 BUNDLE.GET B2,kn2$,DisplayMY
 Kn2$=kn$+"Displaybackground"
 BUNDLE.GET B2,kn2$,Displaybackground
 Kn2$=kn$+"RowHigh"
 BUNDLE.GET B2,kn2$,Rowhigh
 Kn2$=kn$+"ColumnWide"
 BUNDLE.GET B2,kn2$,Columnwide
 Kn2$=kn$+"DisplayTSZ"
 BUNDLE.GET B2,kn2$,DisplayTSZ
 Kn2$=kn$+"DisplayOFFY"
 BUNDLE.GET B2,kn2$,DisplayOffY
 Kn2$=kn$+"DisplayOFFX"
 BUNDLE.GET B2,kn2$,DisplayOffX
 Kn2$=kn$+"ScreenPtr"
 BUNDLE.GET B2,kn2$,ScreenPTR
 Kn2$=kn$+"GON"
 BUNDLE.GET B2,kn2$,GON
 ! Kn2$=kn$+"TCX"
 ! BUNDLE.GET B2,kn2$,TCX
 ! Kn2$=kn$+"TCY"
 ! BUNDLE.GET B2,kn2$,TCY

 A40=TCY
 A41=TCY+Hight-1
 A42=TCX
 A43=TCX+Width-1
 !Draw Box
 GR.BITMAP.DRAWINTO.START ScreenPTR
 A44=(((A42-1))*Columnwide)
 A45=((A40-1)*Rowhigh)
 A46=((A43)*Columnwide)
 A47=((A41)*Rowhigh)

 L_gcol(255,colortouse,1)
 GR.RECT A48,A44,A45,A46,A47
 GR.BITMAP.DRAWINTO.END
FN.END
!----------------------------
FN.DEF L_Setcolors(foreground,background)

 BUNDLE.GET 1, "DonsBasicLibrary",B2

 BUNDLE.PUT B2,"foreground",foreground
 BUNDLE.PUT B2,"background",background
FN.END
!----------------------------
FN.DEF L_locate(tcx,tcy)

 BUNDLE.GET 1, "DonsBasicLibrary",B2

 !get screen info
 BUNDLE.GET B2, "curscreen",curscreen
 kn$="scrn"+STR$(curScreen)

 Kn2$=kn$+"DisplayMX"
 BUNDLE.GET B2,kn2$,DisplayMX
 Kn2$=kn$+"DisplayMY"
 BUNDLE.GET B2,kn2$,DisplayMY

 IF tcx < 1 THEN tcx=1
 IF tcx > DisplayMX THEN tcx=DisplayMX
 IF TCY < 1 THEN tcy=1
 IF TCY > DisplayMY THEN TCY=DisplayMY

 Kn2$=kn$+"TCX"
 Numbun=1
 BUNDLE.PUT B2,kn2$,TCX
 Kn2$=kn$+"TCY"
 BUNDLE.PUT B2,kn2$,TCY
FN.END
!----------------------------
FN.DEF L_textmode(TM)
 !set textmode
 !allowed modes: 1, 4, 6, 8

 BUNDLE.GET 1, "DonsBasicLibrary",B2

 F=0
 IF tm=1 THEN f=1
 IF tm=4 THEN f=1
 IF tm=6 THEN f=1
 IF tm=8 THEN f=1
 IF f=0 THEN tm=1
 BUNDLE.PUT B2, "TextMode",TM
FN.END
!----------------------------
FN.DEF L_LocPA(pa)
 !Convert the old "Print @" to x/y coordinates.
 !Get screen data from bundle.

 BUNDLE.GET 1, "DonsBasicLibrary",B2

 BUNDLE.GET B2, "curscreen",curscreen
 kn$="scrn"+STR$(curScreen)
 Kn2$=kn$+"DisplayMX"
 BUNDLE.GET B2,kn2$,DisplayMX
 Kn2$=kn$+"DisplayMY"
 BUNDLE.GET B2,kn2$,DisplayMY
 Kn2$=kn$+"Displaybackground"
 BUNDLE.GET B2,kn2$,Displaybackground
 Kn2$=kn$+"RowHigh"
 BUNDLE.GET B2,kn2$,Rowhigh
 Kn2$=kn$+"ColumnWide"
 BUNDLE.GET B2,kn2$,Columnwide
 Kn2$=kn$+"DisplayTSZ"
 BUNDLE.GET B2,kn2$,DisplayTSZ
 Kn2$=kn$+"DisplayOFFY"
 BUNDLE.GET B2,kn2$,DisplayOffY
 Kn2$=kn$+"DisplayOFFX"
 BUNDLE.GET B2,kn2$,DisplayOffX
 Kn2$=kn$+"ScreenPtr"
 BUNDLE.GET B2,kn2$,ScreenPTR
 Kn2$=kn$+"GON"
 BUNDLE.GET B2,kn2$,GON
 Kn2$=kn$+"TCX"
 BUNDLE.GET B2,kn2$,TCX
 Kn2$=kn$+"TCY"
 BUNDLE.GET B2,kn2$,TCY

 pa=pa+1
 y=CEIL(pa/DisplayMX)
 x=PA-((y-1)*DisplayMX)

 !save x/y coordinates
 L_locate(x,y)

FN.END
!----------------------------
FN.DEF L_Winfill(Xc,Yc,WinWidth,WinHight,Text$)
 !takes Text$ and writes it to a "window".  The window is
 !defined by winwidth, and winhight, and positioned at
 !xcoord, and Ycoord.

 L_locate(xc,yc)

 TL=LEN(text$)
 NY=CEIL(TL/WinWidth)
 IF NY>winhight
  ny=winhight
 ENDIF
 FOR y=1 TO ny
  y1=((y-1)*winwidth)+1
  a$=MID$(text$,y1,winwidth)
  y2=(y-1)+Yc
  L_locate(Xc,y2)
  L_write(a$)
 NEXT y
FN.END

!--------------------------------------------------------------
!FindKeyboard
!----------------------------
!IncKeyboard4.bas
!----------------------------
!Last Change:11-11-2016
!Purpose: An onscreen keyboard.  This has just the
!  keyboard load/draw subroutines.  Need to include
!  whatever keyboard data you need.
!
!Requires:
!  IncDisplay11.bas
!
!Use:
!  Put "IncKeyboard4.bas" after the Include IncDisplay11.bas line.
!  Put "setupkeyboard(keyboard alpha value, keyboard color number)
!   after Displaysetup() line.
!  Then include the keyboard data you want, after the
!   IncKeyboard4.bas line.
!    Example: INCLUDE IncDataKeyboardtyping.bas
!----------------------------
!Keyboard Start Block
!KeyboardAlpha=64
!KeyboardColor=9
!----------------------------
!----------------------------
FN.DEF L_KeyboardSetup(KeyboardAlpha,KeyboardColor)

 BUNDLE.GET 1, "DonsBasicLibrary",B2

 !L_ChangeScreen(0)
 P$="Keyboard data Loading"+CHR$(13)
 L_write(P$)
 L_CurrentKeyboard(1)
 !setup onscreen keyboard
 P$=">Colors"+CHR$(13)
 L_write(P$)
 BUNDLE.PUT B2, "KeyboardAlpha",KeyboardAlpha
 BUNDLE.PUT B2, "KeyboardColor",KeyboardColor
 P$=">Reading Data"
 L_write(P$)
 L_LoadButtonData()
 P$=">Drawing Keyboard: "
 L_write(P$)
 L_drawbuttons()
 L_CurrentKeyboard(1)
FN.END
!----------------------------
FN.DEF L_WhatKey(TX1,TY1)
 !takes the coordinates and figures out which key was touched.
 !returns: KeyTouch, and Type$
 !get bundle 1 info

BUNDLE.GET 1, "DonsBasicLibrary",B2

 BUNDLE.GET B2, "NumBundles",NumBundles
 BUNDLE.GET B2, "screens",NumScreens
 BUNDLE.GET B2, "keyboards",NumKeyboards
 BUNDLE.GET B2, "DisplayMGX", DisplayMGX
 BUNDLE.GET B2, "DisplayMGY", DisplayMGY
 BUNDLE.GET B2, "DisplayStatus", DisplayStatusHight
 BUNDLE.GET B2, "CurKeyboard", Keyboard

 !get all keyboard data from bundle #3
 
 !base keyboard name
 kN$="kbrd"+STR$(keyboard)

 !get the keyboard info
 BUNDLE.GET B2, "KeyType",KeyType$
 keynum$=kn$+"BXP"
 BUNDLE.GET B2, keyNum$,BXP
 keynum$=kn$+"BYP"
 BUNDLE.GET B2, keyNum$,BYP
 keynum$=kn$+"BOFFX"
 BUNDLE.GET B2, keyNum$,BOFFX
 keynum$=kn$+"BOFFY"
 BUNDLE.GET B2, keyNum$,BOFFY
 keynum$=kn$+"NumCol"
 BUNDLE.GET B2, keyNum$,NumCol
 keynum$=kn$+"NumRow"
 BUNDLE.GET B2, keyNum$,NumRow

 TX1=TX1-BOFFX
 TY1=TY1-BOFFY
 xpos=CEIL(tx1/bxp)
 Ypos=CEIL(ty1/byp)
 IF xpos<1 THEN xpos=1
 IF xpos>NumCol THEN xpos=NumCol
 IF ypos<1 THEN ypos=1
 IF ypos>NumRow THEN ypos=NumRow

 keynum$=kn$+"bttn"+STR$(Xpos)+STR$(Ypos)
 BUNDLE.GET B2, keyNum$,keytouch

 IF keytouch=0
  !no key there
 ELSE
  !get normal key
  L=keytouch
  KeyBNum$="bttn"+STR$(L)
  keyBNum$=KeyBNum$+"key"
  BUNDLE.GET B2, keyBNum$, K
 ENDIF

 type$=MID$(keytype$,keytouch,1)
 IF type$="1"
  !typeable character  
  keytouch=k
 ELSE
  !control character
 ENDIF

 !store keytouch,Type$
 BUNDLE.PUT B2, "keytouch",keytouch
 BUNDLE.PUT B2, "Type$",Type$
FN.END
!----------------------------
FN.DEF L_Drawbuttons()
 !draw keyboard here.
 !draws the button lines/names on screen.
 !get bundle 1 info

 BUNDLE.GET 1, "DonsBasicLibrary",B2

 BUNDLE.GET B2, "NumBundles",NumBundles
 BUNDLE.GET B2, "screens",NumScreens
 BUNDLE.GET B2, "keyboards",NumKeyboards
 BUNDLE.GET B2, "DisplayMGX", DisplayMGX
 BUNDLE.GET B2, "DisplayMGY", DisplayMGY
 BUNDLE.GET B2, "DisplayStatus", DisplayStatusHight
 BUNDLE.GET B2, "KeyboardAlpha",KeyboardAlpha
 BUNDLE.GET B2, "KeyboardColor",KeyboardColor

 !get keyboard bundle number
 kn$="kbrd"

 keynum$="NumOfButtons"
 BUNDLE.GET B2, keyNum$,NumBut
 DIM ButtonFlag[NumBut]

 FOR z=1 TO numkeyboards
  P$=" "+STR$(z)
  L_write(P$)
  kn2$=kn$+STR$(z)
  !Set initial text size
  keynum$=kn2$+"BYP"
  BUNDLE.GET B2, keyNum$,BYP
  bts=CEIL(byp/1.7)
  GR.TEXT.SIZE bts
  GR.SET.STROKE 4
  GR.TEXT.BOLD 1

  !create BMP image, and paint it transparent.
  GR.SCREEN w, h
  GR.BITMAP.CREATE BPtr, w, h
  GR.BITMAP.DRAWINTO.START BPtr
  GR.COLOR 0,0,0,0
  GR.RECT nobj, 1, 1, w, h

  !retreive keyboard data
  keynum$=kn2$+"NumCol"
  BUNDLE.GET B2, keyNum$,NumCol
  keynum$=kn2$+"NumRow"
  BUNDLE.GET B2, keyNum$,NumRow
  keynum$=kn2$+"BXP"
  BUNDLE.GET B2, keyNum$,BXP
  keynum$=kn2$+"BYP"
  BUNDLE.GET B2, keyNum$,BYP
  keynum$=kn2$+"BOFFX"
  BUNDLE.GET B2, keyNum$,BOFFX
  keynum$=kn2$+"BOFFY"
  BUNDLE.GET B2, keyNum$,BOFFY

  ! numcol=buttongridsize[1,z]
  ! numrow=buttongridsize[2,z]
  ! bxp=buttongridsize[3,z]
  ! byp=buttongridsize[4,z]
  ! BOFFX=Buttongridsize[5,z]
  ! BOFFY=ButtonGridSize[6,z]
  nobj=0

  !set keyboard color -- transparent but visible
  !about 1/3 opacity / alpha
  CALL L_gcol(KeyboardAlpha,KeyboardColor,1)

  ARRAY.FILL buttonflag[], 0
  !search for shortest/longest button names.
  S1C=0
  nmc=0
  pmc=0
  smc=0

  BUNDLE.GET B2, "KeyType",KeyType$

  FOR y=1 TO numrow
   FOR x=1 TO numcol
    !get button lengths
    keynum$=kn2$+"bttn"+STR$(X)+STR$(Y)
    BUNDLE.GET B2, keyNum$,B

    IF b>0
     !retrieve all key info, set b$ to key name.
     L=B
     KeyBNum$="bttn"+STR$(L)
     BUNDLE.GET B2, keyBNum$, N$
     keyBNum$=KeyBNum$+"key"
     BUNDLE.GET B2, keyBNum$, K
     T$=MID$(KeyType$,L,1)
     IF t$="0"
      B$=N$
     ELSE
      B$=CHR$(K)
     ENDIF

     L1=LEN(B$)
     IF L1>nmc
      pmc=L
      nmc=L1
     ENDIF
    ENDIF
   NEXT
  NEXT

  !calculate text sizes

  !make sure name fits square.
  !figure single-character name size
  a$="@"
  keynum$=kn2$+"1CX"
  BUNDLE.GET B2, keyNum$,B7
  keynum$=kn2$+"1CY"
  BUNDLE.GET B2, keyNum$,B8
  keynum$=kn2$+"MCX"
  BUNDLE.GET B2, keyNum$,B9
  keynum$=kn2$+"MCY"
  BUNDLE.GET B2, keyNum$,B10
  bw=bxp * B7
  bh=byp * B8*0.7
  loop1=0
  loop2=bh
  DO
   GR.TEXT.SIZE loop2
   GR.TEXT.WIDTH a,a$
   IF a<=bw
    loop1=1
   ELSE
    loop2=loop2-1
   ENDIF
  UNTIL loop1=1
  s1c=loop2

  !figure multi-character name size

  !  keyBNum$=kn2$
  !  BUNDLE.GET Numbun, keyBNum$,B$
  bw=bxp * B9
  bh=byp * B10*0.7
  loop1=0
  loop2=bh
  DO
   keyBNum$="bttn"+STR$(pmc)
   BUNDLE.GET B2, keyBNum$,B$
   GR.TEXT.SIZE loop2
   GR.TEXT.WIDTH a,b$
   IF a<=bw
    loop1=1
   ELSE
    loop2=loop2-1
   ENDIF
  UNTIL loop1=1
  smc=loop2

  !draw button lines
  ARRAY.FILL buttonflag[],0
  FOR y = 1 TO numrow
   FOR x = 1 TO numcol
    !get current button
    keynum$=kn2$+"bttn"+STR$(X)+STR$(Y)
    BUNDLE.GET B2, keyNum$,CB
    !calculate coordinates for lines.
    curl=x-1
    curl=curl*bxp
    curl=curl+1+BOFFX
    curr=x*bxp+BOFFX
    curt=y-1
    curt=curt*byp
    curt=curt+1+BOFFY
    curb=y*byp+BOFFY
    !get button values of adjacent squares
    IF x+1>numcol
     Rb=0
    ELSE
     keynum$=kn2$+"bttn"+STR$(X+1)+STR$(Y)
     BUNDLE.GET B2, keyNum$,rB
     !rb=button[x+1,y,z]
    ENDIF
    IF y+1>numrow
     bb=0
    ELSE
     keynum$=kn2$+"bttn"+STR$(X)+STR$(Y+1)
     BUNDLE.GET B2, keyNum$,bB
     !bb=button[x,y+1,z]
    ENDIF
    !compare button values, and draw lines.
    !Draw Right Line
    IF cb<>rb
     nobj=nobj+1
     GR.LINE a,curr,curt,curr,curb
     !keyboardobj[nobj,z]=a
    ENDIF
    !Draw bottom Line
    IF cb<>bb
     nobj=nobj+1
     GR.LINE a,curl,curb,curr,curb
     !keyboardobj[nobj,z]=a
    ENDIF
    !top row draw top line.
    IF CB>0 & Y=1
     nobj=nobj+1
     GR.LINE a,curl,curt,curr,curt
     !keyboardobj[nobj,z]=a
    ENDIF
    !left most column draw left line.
    IF cb>0 & x=1
     nobj=nobj+1
     GR.LINE a,curl,curt,curl,curb
     !keyboardobj[nobj,z]=a
    ENDIF

    !Check size of the button in squares.
    !Count from the upper left square of the button.
    IF cb>0
     IF ButtonFlag[cb]=0
      ButtonFlag[cb]=1

      !Counting to right.
      U=x
      V=0
      W=x
      Flagdo=0
      DO
       u=u+1
       IF u>numcol
        Flagdo=1
       ELSE
        keynum$=kn2$+"bttn"+STR$(u)+STR$(Y)
        BUNDLE.GET B2, keyNum$,V
        !V=button[u,y,z]
        IF v=cb
         w=u
        ELSE
         Flagdo=1
        ENDIF
       ENDIF
      UNTIL flagdo=1
      BCL1=x-1
      BCL=w-BCL1

      !Counting downwards.
      U=y6
      V=0
      W=y
      flagdo=0
      DO
       u=u+1
       IF u>numrow
        Flagdo=1
       ELSE
        keynum$=kn2$+"bttn"+STR$(X)+STR$(u)
        BUNDLE.GET B2, keyNum$,V
        !V=button[x,u,z]
        IF v=cb
         w=u
        ELSE
         Flagdo=1
        ENDIF
       ENDIF
      UNTIL flagdo=1
      bcd1=y-1
      BCD=w-BCD1

      !calculate button size in pixels
      BNPX=BCL * Bxp
      BNPY=BCD * Byp

      !Calculate position of button name

      L=CB
      KeyBNum$="bttn"+STR$(L)
      BUNDLE.GET B2, keyBNum$, N$
      keyBNum$=KeyBNum$+"key"
      BUNDLE.GET B2, keyBNum$, K
      T$=MID$(KeyType$,L,1)
      IF t$="0"
       IF n$=" "
        B$=CHR$(k)
       ELSE
        B$=N$
       ENDIF
      ELSE
       B$=CHR$(K)
      ENDIF

      L=LEN(b$)
      IF L=1
       loop2=s1c
      ELSE
       loop2=smc
      ENDIF
      GR.TEXT.SIZE loop2
      GR.TEXT.WIDTH a,b$
      a1=BNPX-a
      IF a1<1
       a2=0
      ELSE
       a2=a1 / 2
      ENDIF
      Axoff=curl+a2
      !axoff=FLOOR((bxp-a)/2)+curl
      a1=BNPY-loop2
      IF a1<1
       a2=0
      ELSE
       a2=a1 / 2
      ENDIF
      ayoff=curt+(BNPY * 0.5)+(loop2 * 0.5)

      !Draw the button name.
      nobj=nobj+1
      GR.TEXT.DRAW a,axoff,ayoff,B$
      !keyboardobj[nobj,z]=a
      GR.TEXT.SIZE bts
     ENDIF
    ENDIF
   NEXT x
  NEXT y
  GR.RENDER
  !buttongridsize[11,z]=nobj
  keyboard=z

  GR.TEXT.BOLD 0
  GR.SET.STROKE 0
  GR.BITMAP.DRAWINTO.END
  GR.BITMAP.DRAW GON, BPtr, 1 , 1
  GR.RENDER

  !Store keyboard data here
  !store screen GON here
  keyBNum$=kn2$+"GON"
  B3=1
  BUNDLE.PUT B2, keyBNum$,GON
  GR.HIDE GON
  GR.RENDER
 NEXT z
 P$=CHR$(13)
 L_write(P$)

 !all done
FN.END

!----------------------------
FN.DEF L_hidekeyboard(kbrd)
 !get bundle 1 info

 BUNDLE.GET 1, "DonsBasicLibrary",B2


 BUNDLE.GET B2, "NumBundles",NumBundles
 BUNDLE.GET B2, "screens",NumScreens
 BUNDLE.GET B2, "keyboards",NumKeyboards
 BUNDLE.GET B2, "DisplayMGX", DisplayMGX
 BUNDLE.GET B2, "DisplayMGY", DisplayMGY
 BUNDLE.GET B2, "DisplayStatus", DisplayStatusHight
 BUNDLE.GET B2, "CurKeyboard", Keyboard

 !Get keyboard GON number
 keyBNum$="kbrd"+STR$(kbrd)+"GON"
 BUNDLE.GET B2, keyBNum$,GON

 GR.HIDE GON

 GR.RENDER
FN.END
!----------------------------
FN.DEF L_showkeyboard(kbrd)
 !get bundle 1 info

 BUNDLE.GET 1, "DonsBasicLibrary",B2


 BUNDLE.GET B2, "NumBundles",NumBundles
 BUNDLE.GET B2, "screens",NumScreens
 BUNDLE.GET B2, "keyboards",NumKeyboards
 BUNDLE.GET B2, "DisplayMGX", DisplayMGX
 BUNDLE.GET B2, "DisplayMGY", DisplayMGY
 BUNDLE.GET B2, "DisplayStatus", DisplayStatusHight
 BUNDLE.GET B2, "CurKeyboard", Keyboard

 !get keyboard bundle number
 !Get keyboard GON number
 keyBNum$="kbrd"+STR$(kbrd)+"GON"
 BUNDLE.GET B2, keyBNum$,GON

 GR.SHOW GON

 GR.RENDER
FN.END
!----------------------------
FN.DEF L_CurrentKeyboard(keyboard)

 BUNDLE.GET 1, "DonsBasicLibrary",B2

 BUNDLE.GET B2, "keyboards",NumKeyboards

 IF keyboard<1 THEN keyboard=1
 IF keyboard>NumKeyboards THEN keyboard=NumKeyboards

 BUNDLE.PUT B2, "CurKeyboard", Keyboard
FN.END
!----------------------------
FN.DEF L_LoadButtonData()
 !--------------
 !get bundle 1 info

 BUNDLE.GET 1, "DonsBasicLibrary",B2

 BUNDLE.GET B2, "NumBundles",NumBundles
 BUNDLE.GET B2, "screens",NumScreens
 BUNDLE.GET B2, "keyboards",NumKeyboards
 BUNDLE.GET B2, "DisplayMGX", DisplayMGX
 BUNDLE.GET B2, "DisplayMGY", DisplayMGY
 BUNDLE.GET B2, "DisplayStatus", DisplayStatusHight

 !put all keyboard data into this bundle

 !Read the button data
 !read number of keyboards, dim array.
 READ.NEXT NumKeyboard
 BUNDLE.PUT B2,"keyboards",NumKeyboard

 READ.NEXT LargestGridX,LargestGridY
 BUNDLE.PUT B2,"LargestGridX",LargestGridX
 BUNDLE.PUT B2,"LargestGridY",LargestGridY

 !not needed, keep for info.
 !DIM buttongridsize[11,NumKeyboard],Button[LargestGridX,LargestGridY,NumKeyboard]

 n$="("+STR$(numKeyboard)+" keyboards)"+CHR$(13)
 L_write(n$)
 !read button grids
 FOR z=1 TO numKeyboard

  !base keyboard name for each keyboard
  kn$="kbrd"+STR$(z)

  READ.NEXT NumCol,NumRow
  keynum$=kn$+"NumCol"
  BUNDLE.PUT B2, keyNum$,NumCol
  keynum$=kn$+"NumRow"
  BUNDLE.PUT B2, keyNum$,NumRow

  keyBNum$=kn$+"bttn"
  FOR y = 1 TO NumRow
   !base Button name
   FOR X = 1 TO NumCol
    READ.NEXT B
    keynum$=keyBnum$+STR$(X)+STR$(Y)
    BUNDLE.PUT B2, keyNum$,B
   NEXT
  NEXT
  !calculate grid size per square.
  BXP=DisplayMGX / NumCol
  BXP=FLOOR(BXP)
  BYP=DisplayMGY / NumRow
  BYP=FLOOR(BYP)
  !This next section makes the buttons square.
  IF BXP>BYP
   BXP=BYP
  ELSE
   BYP=BXP
  ENDIF
  !calculate Keyboard Offsets
  BOFFX=DisplayMGX-(NumCol*BXP)
  IF BOFFX=0
   BOFFX=0
  ELSE
   BOFFX=FLOOR(BOFFX/2)
  ENDIF
  BOFFY=DisplayMGY-(NumRow*BYP)
  IF BOFFY=0
   BOFFY=0
  ELSE
   BOFFY=FLOOR(BOFFY/2)
  ENDIF
  !Store the keyboard info
  keynum$=kn$+"BXP"
  BUNDLE.PUT B2, keyNum$,BXP
  keynum$=kn$+"BYP"
  BUNDLE.PUT B2, keyNum$,BYP
  keynum$=kn$+"BOFFX"
  BUNDLE.PUT B2, keyNum$,BOFFX
  keynum$=kn$+"BOFFY"
  BUNDLE.PUT B2, keyNum$,BOFFY

  !read and store the last stuff.
  READ.NEXT B
  keynum$=kn$+"1CX"
  BUNDLE.PUT B2, keyNum$,B
  READ.NEXT B
  keynum$=kn$+"1CY"
  BUNDLE.PUT B2, keyNum$,B
  READ.NEXT B
  keynum$=kn$+"MCX"
  BUNDLE.PUT B2, keyNum$,B
  READ.NEXT B
  keynum$=kn$+"MCY"
  BUNDLE.PUT B2, keyNum$,B
 NEXT

 !Build keytype$, and KeyPrintable$
 KeyType$=""
 KeysPrintable$=""
 READ.NEXT NumBut
 keynum$="NumOfButtons"
 BUNDLE.PUT B2, keyNum$,NumBut

 !needed, keep for info
 DIM button$[NumBut], ButtonFlag[NumBut]

 !base Button name
 kN$="bttn"

 FOR x = 1 TO NumBut
  keyBNum$=kn$+STR$(x)
  READ.NEXT a$

  !read key data in new format
  t$=LEFT$(a$,1)
  a=IS_IN("/",a$,1)
  B=A-2
  N$=MID$(A$,2,B)
  C=IS_IN("/",A$,A+1)
  B=A+1
  D=C-1
  E=D-A
  F$=MID$(A$,B,E)
  K=VAL(F$)
  BUNDLE.PUT B2, keyBNum$,N$

  KeyBNum$=KeyBNum$+"key"
  BUNDLE.PUT B2, keyBNum$,K
  KeyType$=keytype$+T$

 NEXT

 !Store KeyType$
 BUNDLE.PUT B2, "KeyType",KeyType$

FN.END
!----------------------------
FN.DEF L_Input(A$)
 !grab a single line of text.
 !like the regular input...

 BUNDLE.GET 1, "DonsBasicLibrary",B2

 GOSUB getcursor
 L_showkeyboard(1)

 IF LEN(a$)=0
  a$=""
  L_locate(tcx,tcy)
  L_write("? []")
 ELSE
  L_locate(tcx,tcy)
  L_write("? "+a$+"[]")
 ENDIF

 cplk=0
 ext=0
 shft=0
 keyboard=1
 DO
  GOSUB gettouch
  L_whatkey(t1x,t1y)
  GOSUB getlastkey

  IF Type$="0"
   !control keys

   !Menu (1)
   !no menu code yet...

   !caplock (2)
   IF keytouch=2  
    IF cplk=0
     IF shft=1
      !do nothing keyboard already shifted
      cplk=1
     ENDIF
     IF shft=0
      !switch to shifted keyboard
      L_hidekeyboard(1)
      L_showkeyboard(2)
      L_currentkeyboard(2)
      cplk=1
     ENDIF
    ELSE
     !cplk=1
     cplk=0:shft=0
     L_hidekeyboard(2)
     L_showkeyboard(1)
     L_currentkeyboard(1)
    ENDIF
   ENDIF

   !enter (3)
   IF keytouch=3
    ext=1
   ENDIF

   !Tab (4) adds 8 spaces
   IF keytouch=4
    KEYPR$="        "
    A$=A$+keypr$
    L_locate(tcx,tcy)
    L_write("? "+A$+"[]")
   ENDIF

   !shift (5)
   IF keytouch=5
    IF cplk=0
     IF shft=0
      shft=1
      L_hidekeyboard(1)
      L_showkeyboard(2)
      L_currentkeyboard(2)
     ELSE
      shft=0
      L_hidekeyboard(2)
      L_showkeyboard(1)
      L_currentkeyboard(1)
     ENDIF
    ENDIF
   ENDIF

   !backspace (6)
   IF keytouch=6
    a=LEN(a$)
    IF a>0
     !backspace a character
     a$=LEFT$(a$,a-1)
     !backup 1 character position, print a space.
     !gosub getcursor
     !getcursor sets tcx/tcy from bundle
     !tcx=tcx-1
     L_locate(tcx,tcy)
     L_write("? "+a$+"[] ")
     L_locate(tcx,tcy)
    ENDIF
   ENDIF

   !show key (11)
   IF keytouch=11
    L_hidekeyboard(3)
    L_showkeyboard(1)
    L_currentkeyboard(1)
    shft=0
    cplk=0
   ENDIF

   !Hide key (12)
   IF keytouch=12
    IF shft=1
     L_hidekeyboard(2)
     L_currentkeyboard(3)
    ELSE
     L_hidekeyboard(1)
     L_currentkeyboard(3)
    ENDIF
    IF cplk=1
     L_hidekeyboard(2)
     L_currentkeyboard(3)
    ELSE
     L_hidekeyboard(1)
     L_currentkeyboard(3)
    ENDIF
    L_showkeyboard(3)
   ENDIF

  ELSE
   !Normal keys
   keypr$=CHR$(keytouch)
   A$=A$+keypr$
   L_locate(tcx,tcy):L_write("? "+A$+"[]")
   IF cplk=0
    IF shft=1
     shft=0
     L_hidekeyboard(2)
     L_showkeyboard(1)
     L_currentkeyboard(1)
    ENDIF
   ENDIF
  ENDIF

 UNTIL ext=1
 L_hidekeyboard(2)
 L_hidekeyboard(1)
 BUNDLE.PUT B2, "Grabaresult", A$

FN.END

!----------------------------
!keyboard data blank -- LEAVE REMARKED!
!This is here to show the keyboard data file format.
!Typing Keyboard data
!This is the second version of the "typing" keyboard.
!----------------------------
!KEYBOARD button data
!number of keyboards
!READ.DATA 3
!LargestGrid X,Y -- number of columns, number of rows
!READ.DATA 13,7

!#1 -- Unshifted
!READ.DATA 13,7
!READ.DATA   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
!READ.DATA   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
!READ.DATA  77, 30, 31, 32, 33, 34, 35, 36, 37, 38, 29, 26,  6
!READ.DATA   4, 94,100, 72, 95, 97,102, 98, 96, 92, 93, 42, 73
!READ.DATA   2,  2, 78, 96, 81, 83, 84, 85, 87, 88, 89, 40,  3
!READ.DATA   5,  5,103,101, 80, 99, 79, 91, 90, 25, 27,  7, 28
!READ.DATA  12,  1,  1, 72, 74, 13, 13, 13, 13, 20,  8,  9, 10
!Button size: Single Character
!READ.DATA 1,1
!Button Size: Multiple characters
!READ.DATA 1,1

!#2 -- Shifted
!READ.DATA 13,7
!READ.DATA   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
!READ.DATA   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
!READ.DATA 107, 14, 45, 16, 17, 18, 85, 19, 23, 21, 22, 76,  6
!READ.DATA   4, 62, 68, 50, 63, 65, 70, 66, 54, 60, 61, 24,105
!READ.DATA   2,  2, 46, 64, 49, 51, 52, 53, 55, 56, 57, 39,  3
!READ.DATA   5,  5, 31, 29, 48, 67, 47, 59, 58, 41, 43,  7, 44
!READ.DATA  12,  1,  1,104,106, 13, 13, 13, 13, 15,  8,  9, 10
!Button size: Single Character
!READ.DATA 1,1
!Button Size: Multiple characters
!READ.DATA 1,1

!#3 -- show
!READ.DATA 13,7
!READ.DATA   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
!READ.DATA   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
!READ.DATA   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
!READ.DATA   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
!READ.DATA   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
!READ.DATA   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
!READ.DATA  11,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
!Button size: Single Character
!READ.DATA 1,1
!Button Size: Multiple characters
!READ.DATA 1,1

!number of unique button names
!READ.DATA 107
!format: TypeName/asciicode/keyname
! (keyname is because some characters cannot appear in data statements.)
!READ.DATA "0Menu/0/","0CapLock/0/","0Enter/13/","0Tab/0/","0Shift/0/"
!READ.DATA "0Back/8","0 /9651/Up","0 /9665/Left","0 /9661/Down","0 /9655/Right"
!READ.DATA "0Show/0","0Hide/0/","1 /32/space","1 /33/!","1 /34/quote"
!READ.DATA "1 /35/#","1 /36/$","1 /37/percent","1 /38/ampersand","1 /39/Apost"
!READ.DATA "1 /40/(","1 /41/)","1 /42/*","1 /43/plus","1 /44/comma"
!READ.DATA "1 /45/-","1 /46/period","1 /47/Fslash","1 /48/0","1 /49/1"
!READ.DATA "1 /50/2","1 /51/3","1 /52/4","1 /53/5","1 /54/6"
!READ.DATA "1 /55/7","1 /56/8","1 /57/9","1 /58/:","1 /59/;"
!READ.DATA "1 /60/<","1 /61/=","1 /62/>","1 /63/?","1 /64/@"
!READ.DATA "1 /65/A","1 /66/B","1 /67/C","1 /68/D","1 /69/E"
!READ.DATA "1 /70/F","1 /71/G","1 /72/H","1 /73/I","1 /74/J"
!READ.DATA "1 /75/K","1 /76/L","1 /77/M","1 /78/N","1 /79/O"
!READ.DATA "1 /80/P","1 /81/Q","1 /82/R","1 /83/S","1 /84/T"
!READ.DATA "1 /85/U","1 /86/V","1 /87/W","1 /88/X","1 /89/Y"
!READ.DATA "1 /90/Z","1 /91/[","1 /92/Bslash","1 /93/]","1 /94/^"
!READ.DATA "1 /95/underscore","1 /96/`","1 /97/a","1 /98/b","1 /99/c"
!READ.DATA "1 /100/d","1 /101/e","1 /102/f","1 /103/g","1 /104/h"
!READ.DATA "1 /105/i","1 /106/j","1 /107/k","1 /108/l","1 /109/m"
!READ.DATA "1 /110/n","1 /111/o","1 /112/p","1 /113/q","1 /114/r"
!READ.DATA "1 /115/s","1 /116/t","1 /117/u","1 /118/v","1 /119/w"
!READ.DATA "1 /120/x","1 /121/y","1 /122/z","1 /123/{","1 /124/|"
!READ.DATA "1 /125/}","1 /126/~"
!end.

!--------------------------------------------------------------
!FindGraphics
!----------------------------
!Various Graphics setup and color functions.
!----------------------------
!The Color Names and their Codes:
!  Black, Red, Lime, Blue, Yellow, Cyan, Magenta, Grey, White
!  Navy, Green, Teal, Maroon, Purple, Olive, Brown, Silver
!  Tan, Orange, Gold
!
!Twenty different common colors.
!web safe color level numbers:
! (hex) 00  33  66  99  CC  FF
! (dec) 00  33  66  99 204 255
!
!000000 - Black
!000099 - Navy
!0000ff - Blue
!009900 - Green
!009999 - Teal
!00ff00 - Lime
!00ffff - Cyan
!990000 - Maroon
!990090 - Purple
!999900 - Olive
!999999 - Grey
!993333 - Brown
!CCCCCC - Silver
!FFCC99 - Tan
!ff0000 - Red
!ff00ff - Magenta
!ff9900 - Orange
!ffCC00 - Gold
!ffff00 - Yellow
!ffffff - White
!----------------------------
FN.DEF L_gcol(Alpha,color,fill)
 !color number can be 1-20,
 !Or it can be 9 or 10 digits long.
 !The leading 1 only holds the number at 10 digits.
 !(example: 1255204099 = Tan see above)

 BUNDLE.GET 1, "DonsBasicLibrary",B2

 C$=STR$(color)
 c=LEN(c$)
 IF c>8
  !get color codes from color number itself
  cc$=RIGHT$(c$,9)
  c1$=MID$(cc$,1,3)
  c2$=MID$(cc$,4,3)
  c3$=MID$(cc$,7,3)
  c1=VAL(c1$)
  c2=VAL(c2$)
  c3=VAL(c3$)
 ELSE
  !get color codes from colorstring$
  BUNDLE.GET B2, "colorstring",Colorstring$
  cp=color*7-6
  c$=MID$(colorstring$,cp,7)
  c1$=MID$(c$,1,2)
  c2$=MID$(C$,3,2)
  c3$=MID$(C$,5,2)
  c1=HEX(c1$)
  c2=HEX(c2$)
  c3=HEX(c3$)
 ENDIF
 GR.COLOR Alpha, c1, c2, c3, Fill
FN.END
!Written by:
!  Donald Hosford (Donzerme@Yahoo.com)
!
!The credits:
!  Roy -- His Excellent Idea to simplify the colors! Why didn't I think of it!
!  Mougino -- Nice idea to reduce the color codes to a short function.
!  Me -- I added 11 more "web safe" colors.  Added all the colors in a string.
!
!Input:
!  Alpha -- how solid the colors.  0 - transparent, 255 - solid.
!  Color -- the desired color (0 to 19).
!  Fill -- 0 - outline, 1 - filled it.
!
!Source:
!  This is from a couple of ideas by Roy and Mougino on the rfo.basic.forum.com.
!  Hex codes for twenty common colors, spaces are just separators.
!----------------------------
FN.DEF L_OpenGR(Alpha,color,Status,Orientation)
 !OpenGR function replaces GR.open,Pause1000, and Gr.orientation.

 BUNDLE.GET 1, "DonsBasicLibrary",B2
 
 C$=STR$(color)
 c=LEN(c$)
 IF c>8
  !get color codes from color number itself
  cc$=RIGHT$(c$,9)
  c1$=MID$(cc$,1,3)
  c2$=MID$(cc$,4,3)
  c3$=MID$(cc$,7,3)
  c1=VAL(c1$)
  c2=VAL(c2$)
  c3=VAL(c3$)
 ELSE
  !get color codes from colorstring$
  BUNDLE.GET B2, "colorstring",Colorstring$
  cp=color*7-6
  c$=MID$(colorstring$,cp,7)
  c1$=MID$(c$,1,2)
  c2$=MID$(C$,3,2)
  c3$=MID$(C$,5,2)
  c1=HEX(c1$)
  c2=HEX(c2$)
  c3=HEX(c3$)
 ENDIF
 GR.OPEN Alpha, c1, c2, c3, Status, Orientation
 PAUSE 1000
FN.END
!Written by:
!  Donald Hosford (SirDonzer@Yahoo.com)
!
!The credits:
!  This is based on My version of Roy's GCOL function.
!Input:
!  Alpha -- how solid the colors.  0 - transparent, 255 - solid.
!  Color -- the desired color (0 to 19).
!  Status -- Show/hide the status bar.  0 - outline, 1 - filled it.
!  Orientation -- What screen orientation.  0 - Lanscape, 1 - Portrait.
!
!Source:
!  This is based on my version of Roy's GCOL function.
!  See the GCOL notes.
!
!The Colors: (his first)
!  Black, Red, Lime, Blue, Yellow, Cyan, Magenta, Grey, White
!  Navy, Green, Teal, Maroon, Purple, Olive, Brown, Silver
!  Tan, Orange, Gold
!--------------------------------------------------------------
!FindMiscellanious
!----------------------------
!Various miscellanious functions.
!
!----------------------------
FN.DEF L_NumberClip$(Number,Number$)
 !take the number, clip off the decimals.
 Number$=STR$(number)
 L=LEN(number$)
 P=IS_IN(".",number$)
 Number$=LEFT$(number$,P-1)
 IF Number<10 THEN number$=" "+number$
 FN.RTN Number$
FN.END

FN.DEF L_Tab$(Tab)
 !returns a string "tab" characters long.
 a$=""
 for x = 1 to tab
  a$=a$+" "
 next
 FN.RTN A$
FN.END
!---------------------------------------------
GOTO LibrarySkip

gettouch:
!Start of the touch loop.
!Detects single touches only.
!Returns T1X,T1Y,T2X,T2Y - coordinates of touch and release.
!loop until the screen is touched

 BUNDLE.GET 1, "DonsBasicLibrary",B2

touch = 0
DO
 GR.TOUCH touch,t1x,t1y
UNTIL touch = 1
!loop until screen is not touched
DO
 GR.TOUCH touch,t2x,t2y
UNTIL touch = 0
BUNDLE.GET B2, "ScaleX", Scale_Width
BUNDLE.GET B2, "ScaleY", Scale_Hight

IF Scale_Width>0
 T1X= T1X / Scale_Width
 T1Y= T1Y / Scale_Hight
 T2X= T2X / Scale_Width
 T2Y= T2Y / Scale_Hight
endif

RETURN
!----------------------------
GetLastKey:
!get the last key touched.
!keytouch,Key$,Type$,KeyPr$

BUNDLE.GET 1, "DonsBasicLibrary",B2

BUNDLE.GET B2, "keytouch",keytouch
BUNDLE.GET B2, "Type$",Type$
! if key$="none" then no key pressed.
!Returns Type$, and Keytouch.
RETURN
!----------------------------
getcursor:
!get the position of the cursor on the current screen.
!get current screen

BUNDLE.GET 1, "DonsBasicLibrary",B2

BUNDLE.GET B2, "curscreen",curscreen
kn$="scrn"+STR$(curScreen)

!get cursor position
Kn2$=kn$+"TCX"
BUNDLE.GET B2,kn2$,TCX
Kn2$=kn$+"TCY"
BUNDLE.GET B2,kn2$,TCY
!Returns TCX, and TCY.
RETURN
!----------------------------
grabakey:
!grab a single keypress.
!like inkey...
GOSUB gettouch
L_whatkey(t1x,t1y)
GOSUB getlastkey
!returns Type$ and Keytouch
RETURN
!----------------------------
Grabaresult:
Result$=""

BUNDLE.GET 1, "DonsBasicLibrary",B2

BUNDLE.GET B2, "Grabaresult", Result$
!Returns Result$
RETURN
!----------------------------

!----------------------------
LibrarySkip:
!---------------------------------------------
