-----------------------------------------------------------
--                   Eiffel/S examples                   --
-----------------------------------------------------------
--               Copyright (C) 1991 - 1993               --
--                           by                          --
--                   SiG Computer GmbH                   --
--                  All rights reserved                  --
-----------------------------------------------------------
-- Release : 1.3 - October 1993                          --
-----------------------------------------------------------
-- Authors : Lambert Strether & Michael Schweitzer       --
-----------------------------------------------------------

  
  
class INTERACT -- some things needed in nearly every interactive program

inherit
    EXCEPTION 
    end

feature

    USER_ABORT : INTEGER is 9999    -- User pressed Break key (^C, ^D)

-----------------------------------------------------------

    io : BASIC_IO is

        once
            !!result
        end

-----------------------------------------------------------

    fmt : FORMAT is

        once
            !!result
        end

-----------------------------------------------------------

    fs : FILE_SYSTEM is

        once
            !!result.make
        end


-----------------------------------------------------------

    the_string    : STRING
    the_integer   : INTEGER
    the_character : CHARACTER
    the_real      : REAL
    the_answer    : BOOLEAN

-----------------------------------------------------------

    get_a_string (msg : STRING) is

        local
            done : BOOLEAN

        do
            from
            until
                done
            loop
                io.put_string (msg)
                io.get_string

                if io.last_string.count > 0 then
                    the_string := io.last_string
                    done       := true
                elseif io.end_of_input then
                    raise ("interact.get_a_string", "user abort",
                                                        USER_ABORT, void)
                else
                    io.put_string ("Sorry; that wasn't a %
                                                    %valid input string%N")
                end
            end
        end

-----------------------------------------------------------

    get_a_character (msg : STRING) is

        local
            done : BOOLEAN

        do
            from
            until
                done
            loop
                io.put_string (msg)
                io.get_string

                if io.last_string.count > 0 then
                    the_character := io.last_string.item (1)
                    done          := true
                elseif io.end_of_input then
                    raise ("interact.get_a_character", "user abort",
                                                        USER_ABORT, void)
                else
                    io.put_string ("Sorry; that wasn't a valid input%N")
                end
            end
        end

-----------------------------------------------------------

    get_an_integer (msg : STRING) is

        do
            io.put_string (msg)
            io.get_string

            if io.end_of_input then 
                raise ("interact.get_an_integer", "user abort", 
                                                    USER_ABORT, void) 
            else 
                the_integer := fmt.s2i (io.last_string)
            end

        rescue
            if not io.end_of_input then
                io.put_string ("Sorry; that wasn't an integer%N")
                retry
            end
        end

-----------------------------------------------------------

    get_a_real (msg : STRING) is

        do
            io.put_string (msg)
            io.get_string

            if io.end_of_input then 
                raise ("interact.get_a_real", "user abort", 
                                                    USER_ABORT, void) 
            else 
                the_real := fmt.s2r (io.last_string)
            end

        rescue
            if not io.end_of_input then
                io.put_string ("Sorry; that wasn't a real number%N")
                retry
            end
        end

-----------------------------------------------------------

    get_a_boolean (msg, yes, no : STRING) is

    -- typical usage :
    -- get_a_boolen ("Do you really want to delete all files? ", "Yy", "Nn")

        local
            c    : CHARACTER
            i    : INTEGER
            done : BOOLEAN

        do
            from
            until
                done
            loop
                io.put_string (msg)
                io.get_string

                if io.end_of_input then
                    raise ("interact.get_a_boolean", "user abort",
                                                    USER_ABORT, void)
                end

                if io.last_string.count > 0 then
                    c := io.last_string.item (1)
                else
                    c := '%U'
                end

                from
                    i := 1
                until
                    done or else i > yes.count
                loop
                    if c = yes.item (i) then
                        the_answer := true
                        done       := true
                    end

                    i := i + 1
                end

                if not done then
                    from
                        i := 1
                    until
                        done or else i > no.count
                    loop
                        if c = no.item (i) then
                            the_answer := false
                            done       := true
                        end

                        i := i + 1
                    end
                end

                if not done then
                    io.put_string ("Sorry; that wasn't a valid answer%N")
                end
            end
        end
-----------------------------------------------------------

    give_help (path : STRING) is

        local
            tf : TEXTFILE
            i  : INTEGER

        do
            if fs.file_exists (path) and then
               fs.has_readperm (path)    then

                !!tf.connect_to (fs.access_file (path, "rw", false))
                from
                    i := 1
                until
                    i > tf.count
                loop
                    io.put_string (tf.item (i))
                    io.put_newline
                    i := i + 1

                    if i > tf.count or else i \\ 20 = 0 then
                        io.put_string ("Press ENTER (RETURN) to continue >")
                        io.get_string

                        if io.end_of_input then
                            raise ("interact.give_help", "user abort",
                                                        USER_ABORT, void)
                        end
                    end
                end

                tf.disconnect
            end

        rescue
            tf.disconnect
        end

end -- class INTERACT
