//  This may look like C code, but it is really -*- C++ -*-

//  ------------------------------------------------------------------
//  The Goldware Library
//  Copyright (C) 1990-1999 Odinn Sorensen
//  Copyright (C) 1999-2000 Alexander S. Aganichev
//  ------------------------------------------------------------------
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Library General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library 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
//  Library General Public License for more details.
//
//  You should have received a copy of the GNU Library 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
//  ------------------------------------------------------------------
//  $Id$
//  ------------------------------------------------------------------
//  GCUI: Golded+ Character-oriented User Interface.
//  Class gwinput: Input form and field editing (declarations).
//  ------------------------------------------------------------------

#ifndef __gwinput_h
#define __gwinput_h


//  ------------------------------------------------------------------

#include <gwindow.h>


//  ------------------------------------------------------------------

class gwinput
{

public:

    class field
    {

    public:

        gwinput* form;

        int   pos;
        int   max_pos;
        vattr attr;
        bool  fill_acs;
        vchar fill;
        int   entry;

        char* buf;
        int buf_left_pos;
        int buf_end_pos;
        int buf_pos;
        int buf_len;

        std::string& destination;

        int id;
        int row;
        int column;
        int max_column;
        int conversion;
        int entry_mode;

        field* prev;
        field* next;

        field(gwinput* iform, int idnum, int wrow, int wcol, int field_width, std::string& dest, int dest_size, int cvt, int mode);
        ~field();

        bool visible();

        void move_left();
        void move_right();

        bool left();
        bool right();
        bool left_word();
        bool right_word();
        bool delete_left();
        bool delete_char();
        bool delete_word(bool left);
        bool insert_char(char ch);
        bool overwrite_char(char ch);
        bool home();
        bool end();

        void update();
        void activate();
        void deactivate();

        void restore();
        void commit();

        void convert();
        bool adjust_mode();
        void conditional();

        void move_cursor();
        void draw(int from_pos=0);

        void clear_field();

        void clipboard_paste();
        void clipboard_copy();
    };

    field* first_field;
    field* current;

    enum
    {
        entry_new,
        entry_update,
        entry_conditional,
        entry_noedit
    };

    enum
    {
        cvt_none,
        cvt_lowercase,
        cvt_uppercase,
        cvt_mixedcase
    };

    vattr idle_attr;
    vattr active_attr;
    vattr edit_attr;
    bool fill_acs;

    vchar idle_fill;
    vchar active_fill;
    vchar edit_fill;

    int insert_mode;

    int done;
    int dropped;

    int start_id;

    bool cursor_was_hidden;

    gwindow &window;

    gwinput(gwindow &w);
    virtual ~gwinput();

    void setup(vattr i_attr, vattr a_attr, vattr e_attr, vchar fill, bool fill_acs);

    void add_field(int idnum, int wrow, int wcol, int field_width, std::string& dest, int dest_size, int cvt=gwinput::cvt_none, int mode=gwinput::entry_conditional);

    bool first(int id=0);
    bool next();
    bool previous();
    bool last();

    bool first_visible();
    bool next_visible();
    bool previous_visible();
    bool last_visible();

    bool move_to(int wrow, int wcol);

    field* field_at(int wrow, int wcol);
    field* get_field(int id);

    void draw_all();
    void reload_all();
    void show_cursor();

    void drop_form();
    void form_complete();
    void field_complete();
    void go_next_field();
    void go_previous_field();
    void go_up();
    void go_down();
    void go_left();
    void go_right();
    void delete_left();
    void delete_char();
    void go_field_begin();
    void go_field_end();
    void go_form_begin();
    void go_form_end();
    void toggle_insert();
    void restore_field();
    void delete_left_word();
    void delete_right_word();
    void go_left_word();
    void go_right_word();
    void enter_char(char ch);

    void prepare_form();
    void finish_form();

    void clear_field();

    void clipboard_cut();
    void clipboard_paste();
    void clipboard_copy();

    bool handle_key(gkey key);

    // These are supposed to be overridden by the inheriting class
    virtual bool handle_other_keys(gkey& key);
    virtual bool validate();
    virtual void before();
    virtual void after();
};


//  ------------------------------------------------------------------

class gwinput2 : public gwinput
{

public:

    gwinput2(gwindow &w) : gwinput(w) { }

    bool run(int helpcat);
};


//  ------------------------------------------------------------------

#endif

//  ------------------------------------------------------------------
