' *************************************************************
' PROGRAM:      gdf.bac
' PURPOSE:      graphical (g) disk fill (df)
' AUTHOR:               original bask/ksh by Peter van Eerten
'                       Bacon HUG version by vovchik (Puppy Linux forum)
' COMMENTS:     based on PvE's ksh/bash versions for gtk-server        
' DEPENDS:      bacon (build 25), hug (0.71)
' PLATFORM:     Puppy Linux (actually, any *nix)
' DATE:         03-03-2013
' VERSION:      0.1a
' LICENSE:      GLP3
' URL:          http://www.basic-converter.org
' **************************************************************


' ************************
' INCLUDES
' ************************

INCLUDE "hug.bac", INIT, HUGOPTIONS, WINDOW, \
        PROPERTY, LINE, ATTACH, FRAME, CANVAS, SQUARE, OUT, QUIT, DISPLAY, CALLBACK, \
        MOUSE, FONT

INIT

' ************************
' END INCLUDES
' ************************


' ************************
' DECLARATIONS
' ************************

CONST version$ = "0.1a"
SETENVIRON "OUTPUT_CHARSET", "UTF-8"
OPTION INTERNATIONAL TRUE
DECLARE SIZES$[32], USED$[32], AVAIL$[32], NAMES$[32] TYPE STRING
DECLARE drive_count TYPE NUMBER
HUGOPTIONS("NOSCALING")

' ************************
' END DECLARATIONS
' ************************


' ************************
' SUBS & FUNCTIONS
' ************************

' ------------------
FUNCTION GETWORD$(STRING mystring$, NUMBER word_number, STRING delimiter$)
' ------------------
        ' GETWORD$() returns the nth delimited word/substring, where
        ' mystring = string to search
        ' word_number = The nth word/substring to return
        ' delimiter = a delimiter between words/substrings (usually a space
        ' but it could be anything, e.g. NL$ when reading a text file)
        LOCAL  i, mypos, n TYPE NUMBER
        LOCAL string_temp$ TYPE STRING
        i = 0
        mypos  = 0
        n = 1
        string_temp$ = ""
        mystring$ = CONCAT$(mystring$, delimiter$)
        REPEAT
                mypos  = INSTR(mystring$, delimiter$, n)
                INCR i
                IF i = word_number THEN
                        string_temp$ = MID$(mystring$, n, (mypos - n))
                END IF
                n = mypos + 1
        UNTIL mypos IS FALSE
        RETURN string_temp$
END FUNCTION

' ------------------
SUB DISKINFO(STRING a1$[], STRING a2$[], STRING a3$[])
' ------------------
        ' Get sizes/utilization and names of all mounted partitions
        LOCAL INFO$ TYPE STRING
        LOCAL i TYPE NUMBER
        INFO$ = CHOP$(EXEC$("df | grep dev"))
        WHILE INSTR(INFO$, "  ") DO
                INFO$ = REPLACE$(INFO$, "  ", " ")
        WEND
        SPLIT INFO$ BY NL$ TO INFO_ARRAY$ SIZE drive_count
        SORT INFO_ARRAY$
        FOR i = 0 TO drive_count - 1
                SIZES$[i] = GETWORD$(INFO_ARRAY$[i], 2, " ")
                USED$[i] = GETWORD$(INFO_ARRAY$[i], 3, " ")
                AVAIL$[i] = GETWORD$(INFO_ARRAY$[i], 4, " ")
                NAMES$[i] = GETWORD$(INFO_ARRAY$[i], 6, " ")
                IF NAMES$[i] = "/" THEN
                        NAMES$[i] = CONCAT$(NAMES$[i], " [root fs]")
                END IF
        NEXT i
END SUB

' ------------------
SUB MOUSE_KILL()
' ------------------
     LOCAL x
     x = MOUSE(0)
     IF x > -1 THEN
          QUIT
     END IF
END SUB

' ------------------
SUB MK_GUI()
' ------------------
        LOCAL IDX, MAXSIZE, MARGE, XPOS, WIDTH1, WIDTH2, SCREENW, FRAMEW, CANVASW, LINEW
        LOCAL q$, drive_size$, drive_used$, drive_avail$ TYPE STRING
        IDX = 0
        MAXSIZE = 0
        q$ = CHR$(34)
        ' Find maximum size
        WHILE IDX < drive_count DO
                IF VAL(SIZES$[IDX]) >= MAXSIZE THEN
                        MAXSIZE = VAL(SIZES$[IDX])
                END IF
                INCR IDX
        WEND
        ' Space between columns
        MARGE = 10
        ' Start of first column
        XPOS = 20
        ' Width of the columns
        WIDTH1 = 90
        WIDTH2 = 80
        SCREENW = WIDTH1 * drive_count + MARGE * drive_count + 50
        IF SCREENW < 300 THEN
                SCREENW = 300
        END IF
        FRAMEW = SCREENW - 10
        CANVASW = SCREENW - 30
        LINEW = SCREENW - 50
        ' Define GUI - main window
        win = WINDOW(CONCAT$("BaCon Graphical Disk Fill - v.", version$), SCREENW, 430)
        PROPERTY(win, "icon-name", "gtk-harddisk")
        ' Attach frame
        frame = FRAME(FRAMEW, 420)
        PROPERTY(frame, "label", "Disk usage for mounted devices ")
        ATTACH(win, frame, 5, 5)
        ' Setup the drawing canvas, draw stuff
        canvas = CANVAS(CANVASW + 8, 390)
        PROPERTY(canvas, "tooltip-text", " Click left mouse button to exit. ")
        ATTACH(win, canvas, 14, 29)
        CALLBACK(canvas, MOUSE_KILL)
        ' Draw axis
        LINE("#000000", 20, 365, (drive_count * MARGE) + (drive_count * WIDTH1), 365)
        ' Draw legend
        SQUARE("#00FF11", 20, 3, 10, 10, 1)
        SQUARE("#000000", 20, 3, 10, 10, 0)
        OUT("Total space", "#000000", "#FFFFFF", 40, 0)
        SQUARE("#FF1100", 160, 3, 10, 10, 1)
        SQUARE("#000000", 160, 3, 10, 10, 0)
        OUT("Used space","#000000", "#FFFFFF", 180, 0)
        IDX = 0
        WHILE IDX < drive_count DO
        ' Draw columns
                HEIGHT = INT(VAL(SIZES$[IDX])/MAXSIZE * 310)
                YPOS = 340 - HEIGHT
                SQUARE("#00FF11", XPOS, YPOS + 25, WIDTH1, HEIGHT, 1 )
                SQUARE("#000000", XPOS, YPOS + 25, WIDTH1, HEIGHT, 0)
                ' Draw capacity info
                YPOS = YPOS - 15
                fmt$ = "#,##0.000"
                PRINT (VAL(SIZES$[IDX])/1024)/1000 FORMAT "%.3f\n" TO drive_size$
                PRINT (VAL(USED$[IDX])/1024)/1000 FORMAT "%.3f\n" TO drive_used$
                PRINT (VAL(AVAIL$[IDX])/1024)/1000 FORMAT "%.3f\n" TO drive_avail$
                OUT(CONCAT$(CHOP$(drive_size$), " (GB)"), "#007700", "#FFFFFF", XPOS, YPOS + 6)
                OUT(CONCAT$(CHOP$(drive_avail$)," free"), "#0000FF", "#FFFFFF", XPOS, YPOS + 22)
                ' Draw usage info
                XPOS = XPOS + 5
                HEIGHT = INT(VAL(USED$[IDX])/MAXSIZE * 310)
                YPOS = 340 - HEIGHT
                SQUARE("#FF1100", XPOS, YPOS + 25, WIDTH2, HEIGHT, 1)
                SQUARE("#000000", XPOS, YPOS + 25, WIDTH2, HEIGHT, 0)
                ' Draw drive name text
                YPOS = 345
                OUT(NAMES$[IDX], "#000000", "#FFFFFF", XPOS, YPOS + 25)
                XPOS = XPOS + WIDTH1 + MARGE - 5
                ' Next column
                INCR IDX
        WEND
END SUB

' ************************
' END SUBS & FUNCTIONS
' ************************


' ************************
' MAIN
' ************************

' Use *nix df to get disk info 
DISKINFO(SIZES$, USED$, NAMES$)
' Calc screen vars and create GUI
MK_GUI
' Show GUI
DISPLAY
END

' ************************
' END MAIN
' ************************