MODULE editor;

(* based on the kilo editor building course*)

(* Step 6 *)

IMPORT FIO, SYSTEM, termios, libc, STextIO;

VAR 
    c           : CHAR;
    p           : POINTER TO CHAR;
    thetermios  : termios.TERMIOS;
    result      : INTEGER;

    PROCEDURE disableRawMode(): INTEGER;
        (* PROCEDURE tcsetattr (fd: INTEGER; option: INTEGER; t: TERMIOS) : INTEGER ; *)
        (* PROCEDURE tcsflush () : INTEGER ; like drain, except discard any pending input *)
        VAR
            TCSAFLUSH : INTEGER;
            result    : INTEGER; 
        
    BEGIN
        (* we have to call this procedure because in C, it's a macro *)
        TCSAFLUSH := termios.tcsflush ();
        result := termios.tcsetattr(FIO.StdOut, TCSAFLUSH, SYSTEM.ADR(thetermios));
        RETURN result;
    END disableRawMode;

    PROCEDURE enableRawMode;
        (* PROCEDURE tcgetattr (fd: INTEGER; t: TERMIOS) : INTEGER ; *)
        (* exitP = PROCEDURE () : INTEGER ; *)
        (* PROCEDURE atexit (proc: exitP) : [ INTEGER ] ; *)
        (* PROCEDURE SetFlag (t: TERMIOS; f: Flag; b: BOOLEAN) : BOOLEAN ; *)

        VAR
            TCSAFLUSH   : INTEGER;
            result      : INTEGER;
            bresult     : BOOLEAN;
            raw         : termios.TERMIOS;
    BEGIN
        TCSAFLUSH := termios.tcsflush (); 
        result := termios.tcgetattr(2, SYSTEM.ADR(thetermios));
        libc.atexit(disableRawMode);
        raw := thetermios;
        bresult := termios.SetFlag(SYSTEM.ADR(raw),termios.lecho, TRUE);
        result := termios.tcsetattr(2, TCSAFLUSH, SYSTEM.ADR(raw));
    END enableRawMode;

BEGIN
    enableRawMode;
    p := SYSTEM.ADR(c);
    (* PROCEDURE ReadNBytes (f: File; nBytes: CARDINAL; dest: ADDRESS) : CARDINAL ; *)
    WHILE (FIO.ReadNBytes(FIO.StdIn,1,p) = 1) AND (c <> "q") DO
        ;
    END;
END editor.