// zeal - A portable Glk-based Z-code interpreter
// Copyright (C) 2000 Jeremy Condit <jcondit@eecs.harvard.edu>
// 
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

// =======================================================================
//  iface.h:
//
//  this file contains a class representing the i/o interface, plus a
//  class representing glk streams.  both inherit from zscii_output,
//  which means they can process results for the bfish class.
// =======================================================================

#ifndef _iface_h_
#define _iface_h_

#include "zeal.h"
#include "output.h"

const uint NUM_STREAMS = 4;
const uint MAX_STACK = 15;

struct timer_info {
    uword interval; // in tenths of seconds
    address addr;
};

class input_continue {
    public:
        virtual void execute(uword result) = 0;
        virtual void cancel() = 0;
};

class iface : public zscii_output {
    public:
        iface(winid_t mainwin, int strictz_in);
        virtual ~iface();

        typedef enum { UPPER, LOWER } win;
        typedef enum { ROMAN, REVERSE, BOLD, ITALIC, FIXED } style;

        void split_window(uint lines);
        void set_window(win w);
        void erase_window(win w);
        void erase_line();
        void set_cursor(uint x, uint y);
        void get_cursor(uint* x, uint* y);
        void set_text_style(style s);

        void select(uint stream, address addr = 0);
        void deselect(uint stream);

        void put_char(ubyte z);
        void put_error(char* format, ...);
        bool put_warning(char* warning, bool* warned);

        void read_zscii(timer_info* timer, input_continue* cont);
        void read_zscii_line(address addr, uword n,
                             timer_info* timer, input_continue* cont);

        bool blocked();
        void process_event(event_t* ev);
        void finish_read(bool success, uword value);

        void show_status();

        void check_transcript();

    private:
        ubyte zscii_to_latin(ubyte z);
        ubyte latin_to_zscii(glsi32 c);

        void reset_cursor();
        void adjust_cursor(ubyte c);

        void sync_arrangement();

        winid_t lower_win;
        winid_t upper_win;
        winid_t status_win;

        frefid_t script_file;
        frefid_t cmd_file;

        win select_win;

        uint cur_x;
        uint cur_y;

        uint real_height;

        char* line_buf;
        uword line_buf_size;
        address line_addr;
        address ipt_addr;

        input_continue* cont;

        bool now_blocked;

        bool script_flag;

        uint strictz;

        strid_t out_stream[NUM_STREAMS + 1];
        bool out_select[NUM_STREAMS + 1];

        strid_t out_mem_stack[MAX_STACK];
        uint out_mem_top;
};

class stream_output : public zscii_output {
    public:
        stream_output(strid_t s_in);
        virtual ~stream_output();

        virtual void put_char(ubyte z);

    private:
        strid_t s;
};

#endif // _iface_h_
