' Line-by-line diff comparison using LCS algorithm
#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL i  AS LONG
    LOCAL j  AS LONG
    LOCAL m  AS LONG
    LOCAL n  AS LONG
    LOCAL idx  AS LONG
    LOCAL up  AS LONG
    LOCAL left  AS LONG
    LOCAL textA(20) AS STRING
    LOCAL textB(20) AS STRING
    LOCAL lcsVal(400) AS LONG
    LOCAL lcsLen AS LONG
    LOCAL lineA  AS LONG
    LOCAL lineB  AS LONG
    LOCAL numLinesA  AS LONG
    LOCAL numLinesB  AS LONG
    LOCAL matchCount  AS LONG
    LOCAL addCount  AS LONG
    LOCAL delCount  AS LONG
    LOCAL sA  AS STRING
    LOCAL sB  AS STRING
    LOCAL da  AS LONG
    LOCAL db  AS LONG
    PRINT "=== Diff Tool (LCS-based) ==="
    PRINT

    numLinesA = 6
    numLinesB = 7

    textA(0) = "def hello(name):              "
    textA(1) = "    print('Hello, ' + name)   "
    textA(2) = "    return True               "
    textA(3) = "                              "
    textA(4) = "def add(a, b):                "
    textA(5) = "    return a + b              "

    textB(0) = "def hello(name):              "
    textB(1) = "    greeting = 'Hello, '      "
    textB(2) = "    print(greeting + name)    "
    textB(3) = "    return True               "
    textB(4) = "                              "
    textB(5) = "def add(a, b):                "
    textB(6) = "    result = a + b            "

    PRINT "--- File A (" & FORMAT$(numLinesA) & " lines) ---"
    FOR i = 0 TO numLinesA - 1
        PRINT "  " & FORMAT$(i + 1) & ": " & TRIM$(textA(i))
    NEXT i
    PRINT

    PRINT "--- File B (" & FORMAT$(numLinesB) & " lines) ---"
    FOR i = 0 TO numLinesB - 1
        PRINT "  " & FORMAT$(i + 1) & ": " & TRIM$(textB(i))
    NEXT i
    PRINT

    m = numLinesA
    n = numLinesB

    FOR i = 0 TO m
        idx = i * (n + 1) + 0
        lcsVal(idx) = 0
    NEXT i
    FOR j = 0 TO n
        idx = 0 * (n + 1) + j
        lcsVal(idx) = 0
    NEXT j

    FOR i = 1 TO m
        FOR j = 1 TO n
            sA = TRIM$(textA(i - 1))
            sB = TRIM$(textB(j - 1))
            idx = i * (n + 1) + j
            up = (i - 1) * (n + 1) + j
            left = i * (n + 1) + (j - 1)
            IF sA = sB THEN
                lcsVal(idx) = lcsVal((i - 1) * (n + 1) + (j - 1)) + 1
            ELSE
                IF lcsVal(up) >= lcsVal(left) THEN
                    lcsVal(idx) = lcsVal(up)
                ELSE
                    lcsVal(idx) = lcsVal(left)
                END IF
            END IF
        NEXT j
    NEXT i

    lcsLen = lcsVal(m * (n + 1) + n)
    PRINT "--- Diff Output ---"
    PRINT "  LCS length: " & FORMAT$(lcsLen) & " lines"
    PRINT

    matchCount = 0
    addCount = 0
    delCount = 0

    lineA = m
    lineB = n

    WHILE lineA > 0
        IF lineB = 0 THEN GOTO whileEnd
        sA = TRIM$(textA(lineA - 1))
        sB = TRIM$(textB(lineB - 1))
        IF sA = sB THEN
            PRINT "  " & FORMAT$(lineA) & " " & FORMAT$(lineB) & " " & sA
            matchCount = matchCount + 1
            lineA = lineA - 1
            lineB = lineB - 1
        ELSE
            da = lcsVal((lineA - 1) * (n + 1) + lineB)
            db = lcsVal(lineA * (n + 1) + (lineB - 1))
            IF da >= db THEN
                PRINT "- " & FORMAT$(lineA) & "  : " & sA
                delCount = delCount + 1
                lineA = lineA - 1
            ELSE
                PRINT "+   " & FORMAT$(lineB) & " " & sB
                addCount = addCount + 1
                lineB = lineB - 1
            END IF
        END IF
    WEND

whileEnd:
    WHILE lineB > 0
        sB = TRIM$(textB(lineB - 1))
        PRINT "+   " & FORMAT$(lineB) & " " & sB
        addCount = addCount + 1
        lineB = lineB - 1
    WEND

    PRINT
    PRINT "--- Statistics ---"
    PRINT "  Matches: " & FORMAT$(matchCount)
    PRINT "  Additions: " & FORMAT$(addCount)
    PRINT "  Deletions: " & FORMAT$(delCount)
    PRINT "  Total changes: " & FORMAT$(addCount + delCount)

    PRINT
    PRINT "Diff tool complete."

    FUNCTION = 0
END FUNCTION
