// C++ code Copyright (C) David R. Evans G4AMJ/NQ0I

#ifndef WINDOWH
#define WINDOWH

#include <suntool/scrollbar.h>
#include <suntool/sunview.h>
#include <suntool/text.h>
#include <suntool/panel.h>
#include <suntool/tty.h>
#include <suntool/icon.h>

#include <suntool/canvas.h>

#ifdef __GNUC__
#include <std.h>
#endif

#include <defines.h>
#include <list.h>
#include <icon.h>

class panel_item;
class text_item;

// window class
class window
{ friend class frame;
  friend class panel;
  friend class menu;

// protected:
public:
  Window w;

public:
  ~window(void) { window_destroy(w); }

// go through list and call single consume for each non-zero parameter
//  window& consume_kbd_events(short n, ... ) { window_set(w, WIN_CONSUME_KBD_EVENT, n, 0); return *this; }

  window& consume_pick_event(short n) { window_set(w, WIN_CONSUME_PICK_EVENT, n, 0); return *this; }
  window& fit_height(int margin) { window_set(w, WIN_FIT_HEIGHT, margin, 0); return *this; }
  window& fit_width(int margin) { window_set(w, WIN_FIT_WIDTH, margin, 0); return *this; }
  window& grab_all_input(boolean b = TRUE) { window_set(w, WIN_GRAB_ALL_INPUT, b, 0); return *this; }
  window& horizontal_scrollbar(Scrollbar s) { window_set(w, WIN_HORIZONTAL_SCROLLBAR, s, 0); return *this; }
  window& event_proc(void* vp) { window_set(w, WIN_EVENT_PROC, vp, 0); return *this; }
  window& vertical_scrollbar(Scrollbar s) { window_set(w, WIN_VERTICAL_SCROLLBAR, s, 0); return *this; }

  window& ignore_kbd_event(short n) { window_set(w, WIN_IGNORE_KBD_EVENT, n, 0); return *this; }
  window& ignore_pick_event(short n) { window_set(w, WIN_IGNORE_PICK_EVENT, n, 0); return *this; }

  window& release_event_lock(void) { window_release_event_lock(w); return *this; }

  window& kbd_focus(boolean b = TRUE) { window_set(w, WIN_KBD_FOCUS, b, 0); return *this; }
  window& show(boolean b = TRUE) { window_set(w, WIN_SHOW, b, 0); return *this; }

  window& fit_height(void) { window_fit_height(w); return *this; }
  window& fit_width(void) { window_fit_width(w); return *this; }

// access functions -- set
  window& below(window& win) { window_set(w, WIN_BELOW, win, 0); return *this; }
  window& bottom_margin(int n) { window_set(w, WIN_BOTTOM_MARGIN, n, 0); return *this; }
  window& columns(int n) { window_set(w, WIN_COLUMNS, n, 0); return *this; }
  window& column_gap(int n) { window_set(w, WIN_COLUMN_GAP, n, 0); return *this; }
  window& column_width(int n) { window_set(w, WIN_COLUMN_WIDTH, n, 0); return *this; }
  window& error_msg(char* msg) { window_set(w, WIN_ERROR_MSG, msg, 0); return *this; }
  window& set_font(Pixfont* font) { window_set(w, WIN_FONT, font, 0); return *this; }
  window& height(int n) { window_set(w, WIN_HEIGHT, n, 0); return *this; }
  window& set_input_designee(int id) { window_set(w, WIN_INPUT_DESIGNEE, id, 0); return *this; }
  window& set_input_designee(window& w) { window_set(w, WIN_INPUT_DESIGNEE, w.device_number(), 0); return *this; }
  window& left_margin(int n) { window_set(w, WIN_LEFT_MARGIN, n, 0); return *this; }
  window& menu(Menu m) { window_set(w, WIN_MENU, m, 0); return *this; }
  window& set_mouse_xy(int x = 0, int y = 0) { window_set(w, WIN_MOUSE_XY, x, y, 0); return *this; }
  window& name(char* name) { window_set(w, WIN_NAME, name, 0); return *this; }
  window& set_percent_height(int n) { window_set(w, WIN_PERCENT_HEIGHT, n, 0); return *this; }
  window& set_percent_width(int n) { window_set(w, WIN_PERCENT_WIDTH, n, 0); return *this; }
  window& right_margin(int n) { window_set(w, WIN_RIGHT_MARGIN, n, 0); return *this; }
  window& right_of(window& win) { window_set(w, WIN_RIGHT_OF, win, 0); return *this; }
  window& row_gap(int n) { window_set(w, WIN_ROW_GAP, n, 0); return *this; }
  window& row_height(int n) { window_set(w, WIN_ROW_HEIGHT, n, 0); return *this; }
  window& top_margin(int n) { window_set(w, WIN_TOP_MARGIN, n, 0); return *this; }
  window& width(int n) { window_set(w, WIN_WIDTH, n, 0); return *this; }
  window& x(int x) { window_set(w, WIN_X, x, 0); return *this; }
  window& y(int y) { window_set(w, WIN_Y, y, 0); return *this; }

// access functions -- get
  int bottom_margin(void) { return (int)window_get(w, WIN_BOTTOM_MARGIN); }
  int columns(void) { return (int)window_get(w, WIN_COLUMNS); }
  int column_gap(void) { return (int)window_get(w, WIN_COLUMN_GAP); }
  int column_width(void) { return (int)window_get(w, WIN_COLUMN_WIDTH); }
  char* device_name(void) { return (char*)window_get(w, WIN_DEVICE_NAME); }
  int device_number(void) { return (int)window_get(w, WIN_DEVICE_NUMBER); }
  int event_state(short n) { return (int)window_get(w, WIN_EVENT_STATE, n); }
  int fd(void) { return (int)window_get(w, WIN_FD); }
  Pixfont* get_font(void) { return (Pixfont*)window_get(w, WIN_FONT); }
  int height(void) { return (int)window_get(w, WIN_HEIGHT); }
  int get_input_designee(void) { return (int)window_get(w, WIN_INPUT_DESIGNEE); }
  int left_margin(void) { return (int)window_get(w, WIN_LEFT_MARGIN); }
  Menu menu(void) { return (Menu)window_get(w, WIN_MENU); }
  char* name(void) { return (char*)window_get(w, WIN_NAME); }
  Window owner(void) { return (Window)window_get(w, WIN_OWNER); }
  Pixwin* get_pixwin(void) { return (Pixwin*)window_get(w, WIN_PIXWIN); }
  int right_margin(void) { return (int)window_get(w, WIN_RIGHT_MARGIN); }
  int row_gap(void) { return (int)window_get(w, WIN_ROW_GAP); }
  int row_height(void) { return (int)window_get(w, WIN_ROW_HEIGHT); }
  int top_margin(void) { return (int)window_get(w, WIN_TOP_MARGIN); }
  int width(void) { return (int)window_get(w, WIN_WIDTH); }
  int x(void) { return (int)window_get(w, WIN_X); }
  int y(void) { return (int)window_get(w, WIN_Y); }
  Window_type type(void) { return (Window_type)window_get(w, WIN_TYPE); }
};

// the canvas type
class canvas : public window
{
public:
  canvas(window& owner, Attr_avlist& atlist) { w = window_create(owner, CANVAS, ATTR_LIST, atlist, 0); }
  canvas(char* owner, Attr_avlist& atlist) { w = window_create(owner, CANVAS, ATTR_LIST, atlist, 0); }
  canvas(window& owner) { w = window_create(owner.w, CANVAS, 0); }
  canvas(char* owner) { w = window_create(owner, CANVAS, 0); }
  canvas(void) { w = window_create(NULL, CANVAS, 0); }

// access functions -- set
  canvas& auto_clear(boolean b) { window_set(w, CANVAS_AUTO_CLEAR, b, 0); return *this; }
  canvas& auto_expand(boolean b) { window_set(w, CANVAS_AUTO_EXPAND, b, 0); return *this; }
  canvas& auto_shrink(boolean b) { window_set(w, CANVAS_AUTO_SHRINK, b, 0); return *this; }
  canvas& fast_mono(boolean b) { window_set(w, CANVAS_FAST_MONO, b, 0); return *this; }
  canvas& fixed_image(boolean b) { window_set(w, CANVAS_FIXED_IMAGE, b, 0); return *this; }
  canvas& canvas_height(int n) { window_set(w, CANVAS_HEIGHT, n, 0); return *this; }
  canvas& margin(int n) { window_set(w, CANVAS_MARGIN, n, 0); return *this; }
  canvas& retained(boolean b) { window_set(w, CANVAS_RETAINED, b, 0); return *this; }
  canvas& canvas_width(int n) { window_set(w, CANVAS_WIDTH, n, 0); return *this; }

//  canvas& repaint_proc(int (*pf)(Canvas, Pixwin*, Rectlist)) { window_set(w, CANVAS_REPAINT_PROC, pf, 0); return *this; }

// access functions -- get
  boolean auto_clear(void) { return (boolean)window_get(w, CANVAS_AUTO_CLEAR); }
  boolean auto_expand(void) { return (boolean)window_get(w, CANVAS_AUTO_EXPAND); }
  boolean auto_shrink(void) { return (boolean)window_get(w, CANVAS_AUTO_SHRINK); }
  boolean fast_mono(void) { return (boolean)window_get(w, CANVAS_FAST_MONO); }
  boolean fixed_image(void) { return (boolean)window_get(w, CANVAS_FIXED_IMAGE); }
  int canvas_height(void) { return (int)window_get(w, CANVAS_HEIGHT); }
  int margin(void) { return (int)window_get(w, CANVAS_MARGIN); }
  Pixwin* pixwin(void) { return (Pixwin*)window_get(w, CANVAS_PIXWIN); }
  boolean retained(void) { return (boolean)window_get(w, CANVAS_RETAINED); }
  int canvas_width(void) { return (int)window_get(w, CANVAS_WIDTH); }
};

// the frame type
class frame : public window
{
public:
  frame(window& owner, Attr_avlist& atlist) { w = window_create(owner.w, FRAME, ATTR_LIST, atlist, 0); }
  frame(char* owner, Attr_avlist& atlist) { w = window_create(owner, FRAME, ATTR_LIST, atlist, 0); }
  frame(window& owner) { w = window_create(owner.w, FRAME, 0); }
  frame(char* owner) { w = window_create(owner, FRAME, 0); }
  frame(void) { w = window_create(NULL, FRAME, 0); }

// access functions -- set
  frame& closed(boolean b) { window_set(w, FRAME_CLOSED, b, 0); return *this; }
  frame& embolden_label(boolean b) { window_set(w, FRAME_EMBOLDEN_LABEL, b, 0); return *this; }
  frame& icon(myicon& i) { window_set(w, FRAME_ICON, i.i, 0); return *this; }
  frame& inherit_colours(boolean b) { window_set(w, FRAME_INHERIT_COLORS, b, 0); return *this; }
  frame& label(char* l) { window_set(w, FRAME_LABEL, l, 0); return *this; }
  frame& no_confirm(boolean b) { window_set(w, FRAME_NO_CONFIRM, b, 0); return *this; }
  frame& confirm(boolean b) { window_set(w, FRAME_NO_CONFIRM, !b, 0); return *this; }
  frame& show_label(boolean b) { window_set(w, FRAME_SHOW_LABEL, b, 0); return *this; }
  frame& show_shadow(boolean b) { window_set(w, FRAME_SHOW_SHADOW, b, 0); return *this; }
  frame& subwindows_adjustable(boolean b) { window_set(w, FRAME_SUBWINDOWS_ADJUSTABLE, b, 0); return *this; }


// access functions -- get
  boolean closed(void) { return (boolean)window_get(w, FRAME_CLOSED); }
  boolean embolden_label(void) { return (boolean)window_get(w, FRAME_EMBOLDEN_LABEL); }
//  Icon icon(void) { return (Icon)window_get(w, FRAME_ICON); }
  boolean inherit_colours(void) { return (boolean)window_get(w, FRAME_INHERIT_COLORS); }
  char* label(void) { return (char*)window_get(w, FRAME_LABEL); }
  Frame subframe(int n) { return (Frame)window_get(w, FRAME_NTH_SUBFRAME, n, 0); }
  boolean show_label(void) { return (boolean)window_get(w, FRAME_SHOW_LABEL); }
  boolean show_shadow(void) { return (boolean)window_get(w, FRAME_SHOW_SHADOW); }
  boolean subwindows_adjustable(void) { return (boolean)window_get(w, FRAME_SUBWINDOWS_ADJUSTABLE); }

  operator Frame() { return (Frame)w; }
};

// the panel type
class panel : public window
{ friend class panel_item;
  friend class button;
  friend class message;
  friend class slider;
  friend class text_item;

  glist item;

public:
  panel(window& owner, Attr_avlist& atlist) { w = window_create(owner, PANEL, ATTR_LIST, atlist, 0); }
  panel(char* owner, Attr_avlist& atlist) { w = window_create(owner, PANEL, ATTR_LIST, atlist, 0); }
  panel(window& owner) { w = window_create(owner.w, PANEL, 0); }
  panel(char* owner) { w = window_create(owner, PANEL, 0); }
  panel(void) { w = window_create(NULL, PANEL, 0); }

  panel& paint(Panel_setting ps = PANEL_CLEAR) { panel_paint(w, ps); return *this; }
  panel& advance_caret(void) { panel_advance_caret(w); return *this; }
  panel& backup_caret(void) { panel_backup_caret(w); return *this; }
  panel& destroy_items(void);

  panel& item_event_proc(void* vp) { window_set(w, PANEL_EVENT_PROC, vp, 0); return *this; }
  panel& background_proc(void* vp) { window_set(w, PANEL_BACKGROUND_PROC, vp, 0); return *this; }

  int caret_on_last(void);
  int caret_on_item(int n);                              // counts from 1

// access functions -- set
  panel& accept_keystroke(boolean b) { window_set(w, PANEL_ACCEPT_KEYSTROKE, b, 0); return *this; }
  panel& blink_caret(boolean b) { window_set(w, PANEL_BLINK_CARET, b, 0); return *this; }
  panel& caret_item(Panel_item i) { window_set(w, PANEL_CARET_ITEM, i, 0); return *this; }
  panel& caret_item(panel_item& i);
  panel& caret_item(text_item& i);
  panel& caret_item(int n);                               // wrt 1
  panel& item_x_gap(int n) { window_set(w, PANEL_ITEM_X_GAP, n, 0); return *this; }
  panel& item_y_gap(int n) { window_set(w, PANEL_ITEM_Y_GAP, n, 0); return *this; }
  panel& layout(Panel_setting ps) { window_set(w, PANEL_LAYOUT, ps, 0); return *this; }
  panel& show_menu(boolean b) { window_set(w, PANEL_SHOW_MENU, b, 0); return *this; }


// access functions -- get
  boolean accept_keystroke(void) { return (boolean)window_get(w, PANEL_ACCEPT_KEYSTROKE); }
  boolean blink_caret(void) { return (boolean)window_get(w, PANEL_BLINK_CARET); }
  panel_item caret_item(void); 
  panel_item first_item(void);
  panel_item last_item(void);
  int item_x_gap(void) { return (int)window_get(w, PANEL_ITEM_X_GAP); }
  int item_y_gap(void) { return (int)window_get(w, PANEL_ITEM_Y_GAP); }
  Panel_setting layout(void) { return (Panel_setting)window_get(w, PANEL_LAYOUT); }
  boolean show_menu(void) { return (boolean)window_get(w, PANEL_SHOW_MENU); }

};

// the textsw type
class textsw : public window
{
public:
  textsw(window& owner, Attr_avlist& atlist) { w = window_create(owner, TEXTSW, ATTR_LIST, atlist, 0); }
  textsw(char* owner, Attr_avlist& atlist) { w = window_create(owner, TEXTSW, ATTR_LIST, atlist, 0); }
  textsw(void) { w = window_create(NULL, TEXTSW, 0); }
};

// the tty type
class tty : public window
{
public:
  tty(window& owner, Attr_avlist& atlist) { w = window_create(owner, TTY, ATTR_LIST, atlist, 0); }
  tty(char* owner, Attr_avlist& atlist) { w = window_create(owner, TTY, ATTR_LIST, atlist, 0); }
  tty(void) { w = window_create(NULL, TTY, 0); }
};

#endif
