#ifndef PANELITEMH
#define PANELITEMH

#include <defines.h>
#include <window.h>

#include <suntool/panel.h>
#include <suntool/sunview.h>

// generic panel item class
class panel_item 
{ friend class panel;
  
protected:
  Panel_item pi;
  Panel* _owner;
  panel* _owner_panel;

public:
  ~panel_item(void)
  { _owner_panel->item -= (void*)&pi;
    panel_destroy_item(pi);
  }

  Panel_item next(void)
  { return (Panel_item)panel_get(pi, PANEL_NEXT_ITEM); }

  Panel parent(void) 
  { return (Panel)panel_get(pi, PANEL_PARENT_PANEL); }

  panel_item& paint(Panel_setting ps = PANEL_CLEAR)
  { panel_paint(pi, ps); return *this; }

  operator Panel_item() { return pi; }

// access functions -- set
  panel_item& accept_keystroke(boolean b)
  { panel_set(pi, PANEL_ACCEPT_KEYSTROKE, b, 0); return *this; }

  panel_item& column(int n)
  { panel_set(pi, PANEL_ITEM_X, ATTR_COL(n), 0); return *this; }

  panel_item& x(int n)
  { panel_set(pi, PANEL_ITEM_X, n, 0); return *this; }

  panel_item& y(int n)
  { panel_set(pi, PANEL_ITEM_Y, n, 0); return *this; }

  panel_item& label_x(int n)
  { panel_set(pi, PANEL_LABEL_X, n, 0); return *this; }

  panel_item& label_y(int n)
  { panel_set(pi, PANEL_LABEL_Y, n, 0); return *this; }

  panel_item& label(char* lab)
  { label_string(lab); return *this; }

  panel_item& label_bold(boolean b)
  { panel_set(pi, PANEL_LABEL_BOLD, b, 0); return *this; }

  panel_item& label_font(Pixfont* pf)
  { panel_set(pi, PANEL_LABEL_FONT, pf, 0); return *this; }

  panel_item& label_image(Pixrect* pr)
  { panel_set(pi, PANEL_LABEL_IMAGE, pr, 0); return *this; }

  panel_item& label_string(char* label)
  { panel_set(pi, PANEL_LABEL_STRING, label, 0); return *this; }

  panel_item& layout(Panel_setting ps)
  { panel_set(pi, PANEL_LAYOUT, ps, 0); return *this; }

  panel_item& menu_title_font(Pixfont* pf)
  { panel_set(pi, PANEL_MENU_TITLE_FONT, pf, 0); return *this; }

  panel_item& menu_title_image(Pixrect* pr)
  { panel_set(pi, PANEL_MENU_TITLE_IMAGE, pr, 0); return *this; }

  panel_item& menu_title_string(char* label)
  { panel_set(pi, PANEL_MENU_TITLE_STRING, label, 0); return *this; }

  panel_item& paint_on_set(Panel_setting ps)
  { panel_set(pi, PANEL_PAINT, ps, 0); return *this; }

  panel_item& row(int n)
  { panel_set(pi, PANEL_ITEM_Y, ATTR_ROW(n), 0); return *this; }

  panel_item& show(boolean b)
  { panel_set(pi, PANEL_SHOW_ITEM, b, 0); return *this; }

  panel_item& show_menu(boolean b)
  { panel_set(pi, PANEL_SHOW_MENU, b, 0); return *this; }

  panel_item& value_x(int n)
  { panel_set(pi, PANEL_VALUE_X, n, 0); return *this; }

  panel_item& value_y(int n)
  { panel_set(pi, PANEL_VALUE_Y, n, 0); return *this; }

  panel_item& notify_proc(void* ptr)
  { panel_set(pi, PANEL_NOTIFY_PROC, ptr, 0); return *this; }

// access functions -- get
  boolean accept_keystroke(void) { return (boolean)panel_get(pi, PANEL_ACCEPT_KEYSTROKE); }
//  int colour_index(void) { return (int)panel_get(pi, PANEL_ITEM_COLOR); }
  int x(void) { return (int)panel_get(pi, PANEL_ITEM_X); }
  int y(void) { return (int)panel_get(pi, PANEL_ITEM_Y); }
  int label_x(void) { return (int)panel_get(pi, PANEL_LABEL_X); }
  int label_y(void) { return (int)panel_get(pi, PANEL_LABEL_Y); }
  char* label(void) { return label_string(); }
  boolean label_bold(void) { return (boolean)panel_get(pi, PANEL_LABEL_BOLD); }
  Pixfont* label_font(void) { return (Pixfont*)panel_get(pi, PANEL_LABEL_FONT); }
  Pixrect* label_image(void) { return (Pixrect*)panel_get(pi, PANEL_LABEL_IMAGE); }
  char* label_string(void) { return (char*)panel_get(pi, PANEL_LABEL_STRING); }
  Panel_setting layout(void) { return (Panel_setting)panel_get(pi, PANEL_LAYOUT); }
  Pixfont* menu_title_font(void) { return (Pixfont*)panel_get(pi, PANEL_MENU_TITLE_FONT); }
  Pixrect* menu_title_image(void) { return (Pixrect*)panel_get(pi, PANEL_MENU_TITLE_IMAGE); }
  char* menu_title_string(void) { return (char*)panel_get(pi, PANEL_MENU_TITLE_STRING); }
  Panel_setting paint_on_set(void) { return (Panel_setting)panel_get(pi, PANEL_PAINT); }
  boolean show(void) { return (boolean)panel_get(pi, PANEL_SHOW_ITEM); }
  boolean show_menu(void) { return (boolean)panel_get(pi, PANEL_SHOW_MENU); }
  int value_x(void) { return (int)panel_get(pi, PANEL_VALUE_X); }
  int value_y(void) { return (int)panel_get(pi, PANEL_VALUE_Y); }

};

// the button type
class button : public panel_item
{

public:
  button(panel& owner_panel)
    { pi = panel_create_item(owner_panel.w, PANEL_BUTTON, 0);
      _owner = &owner_panel.w; 
      _owner_panel = &owner_panel;
      _owner_panel->item += (void*)&pi;
    }
  button(panel& owner_panel, DREstring& lbl) 
    { pi = panel_create_item(owner_panel.w, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(owner_panel.w, (char*)lbl, lbl.length() + 1, 0), 0);
      _owner = &owner_panel.w; 
      _owner_panel = &owner_panel;
      _owner_panel->item += (void*)&pi; 
  }
  button(panel& owner_panel, DREstring& lbl, void* not_proc) 
    { pi = panel_create_item(owner_panel.w, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(owner_panel.w, (char*)lbl, lbl.length() + 1, 0), 0);
      _owner = &owner_panel.w; 
      _owner_panel = &owner_panel;
      _owner_panel->item += (void*)&pi; 
      notify_proc(not_proc);
    }
};

// the message type
class message : public panel_item
{  
public:
  message(panel& owner_panel, DREstring& lbl)
  { pi = panel_create_item(owner_panel.w, PANEL_MESSAGE, 
                           PANEL_LABEL_STRING, (char*)lbl, 0);
    _owner = &owner_panel.w;
    _owner_panel = &owner_panel;
    _owner_panel->item += (void*)&pi;
  }
};

// the slider type
class slider : public panel_item
{
public:
  slider(panel& owner_panel)
  { pi = panel_create_item(owner_panel.w, PANEL_SLIDER, 0); 
   _owner = &owner_panel.w; 
   _owner_panel = &owner_panel;
   _owner_panel->item += (void*)&pi;
}

// access functions -- set
  slider& min_value(int n)
  { panel_set(pi, PANEL_MIN_VALUE, n, 0); return *this; }
  slider& max_value(int n)
  { panel_set(pi, PANEL_MAX_VALUE, n, 0); return *this; }
  slider& notify_level(Panel_setting ps)
  { panel_set(pi, PANEL_NOTIFY_LEVEL, ps, 0); return *this; }
  slider& show_range(boolean b)
  { panel_set(pi, PANEL_SHOW_RANGE, b, 0); return *this; }
  slider& show_value(boolean b)
  { panel_set(pi, PANEL_SHOW_VALUE, b, 0); return *this; }
  slider& width(int n)
  { panel_set(pi, PANEL_SLIDER_WIDTH, n, 0); return *this; }
  slider& value(int n)
  { panel_set(pi, PANEL_VALUE, n, 0); return *this; }
  slider& value_font(Pixfont* pf)
  { panel_set(pi, PANEL_VALUE_FONT, pf, 0); return *this; }

// access functions -- get
  int min_value(void) { return (int)panel_get(pi, PANEL_MIN_VALUE); }
  int max_value(void) { return (int)panel_get(pi, PANEL_MAX_VALUE); }
  Panel_setting notify_level(void) { return (Panel_setting)panel_get(pi, PANEL_NOTIFY_LEVEL); }
  boolean show_range(void) { return (boolean)panel_get(pi, PANEL_SHOW_RANGE); }
  boolean show_value(void) { return (boolean)panel_get(pi, PANEL_SHOW_VALUE); }
  int width(void) { return (int)panel_get(pi, PANEL_SLIDER_WIDTH); }
  int value(void) { return (int)panel_get(pi, PANEL_VALUE); }
  Pixfont* value_font(void) { return (Pixfont*)panel_get(pi, PANEL_VALUE_FONT); }
};

// the text item type
class text_item : public panel_item
{
public:
  text_item(panel& owner_panel) { pi = panel_create_item(owner_panel.w, PANEL_TEXT, 0); _owner = &owner_panel.w;  
                                 _owner_panel = &owner_panel; _owner_panel->item += (void*)&pi;}

  operator Panel_item() { return pi; }
  text_item& clear(void) { value(""); label(""); notify_proc((void*)panel_text_notify); return *this; }

// access functions -- set
  text_item& mask_char(char c) { panel_set(pi, PANEL_MASK_CHAR, c, 0); return *this; }
  text_item& notify_level(Panel_setting ps) { panel_set(pi, PANEL_NOTIFY_LEVEL, ps, 0); return *this; }
  text_item& notify_string(char* s) { panel_set(pi, PANEL_NOTIFY_STRING, s, 0); return *this; }
  text_item& stored_length(int n) { panel_set(pi, PANEL_VALUE_STORED_LENGTH, n, 0); return *this; }
  text_item& displayed_length(int n) { panel_set(pi, PANEL_VALUE_DISPLAY_LENGTH, n, 0); return *this; }
  text_item& display_length(int n) { this->displayed_length(n); return *this; }
  text_item& value(char* s) { panel_set(pi, PANEL_VALUE, s, 0); return *this; }
  text_item& value_font(Pixfont* pf) { panel_set(pi, PANEL_VALUE_FONT, pf, 0); return *this; }

// access functions -- get
  char mask_char(void) { return (char)panel_get(pi, PANEL_MASK_CHAR); }
  Panel_setting notify_level(void) { return (Panel_setting)panel_get(pi, PANEL_NOTIFY_LEVEL); }
  char* notify_string(void) { return (char*)panel_get(pi, PANEL_NOTIFY_STRING); }
  int stored_length(void) { return (int)panel_get(pi, PANEL_VALUE_STORED_LENGTH); }
  int displayed_length(void) { return (int)panel_get(pi, PANEL_VALUE_DISPLAY_LENGTH); }
  int display_length(void) { return this->displayed_length(); }
  char* value(void) { return (char*)panel_get(pi, PANEL_VALUE); }
  Pixfont* value_font(void) { return (Pixfont*)panel_get(pi, PANEL_VALUE_FONT); }
};

#endif
