// -*- c++ -*-
//  Generated by gtkmmproc from ./../ctree.gen_h -- DO NOT MODIFY!
#ifndef _GTKMM_CTREE_H
#define _GTKMM_CTREE_H

/* $Id: ctree.h,v 1.2 2003/06/17 16:37:40 pbd Exp $ */

/* ctree.h
 *
 * Copyright (C) 2000 The Gtk-- Development Team
 *
 * 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 library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/**********************************************************************
WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
***********************************************************************
  This wrapper is new to the kit.  The old one was so out of date
  as to not be useful.  This wrapper has not been time tested
  like the others, please be sure to report unexpected crashes, strange
  behavior and unusable methods.  A number of the available methods
  may not have been defined correctly yet.
***********************************************************************
WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
**********************************************************************/

#include <gtk--/clist.h>
#include <gtk/gtkctree.h>

namespace Gtk {
class CTree;
class CTree_Class;
}
namespace Gtk { Gtk::CTree *wrap (GtkCTree *o); }
namespace Gtk
{
class CTree;
class CTree_Class;

namespace CTree_Helpers {

class RowList;
class TreeList;
class Element
  {
      friend class RowList;
      friend class TreeList;

      Gtk::SArray  text_;
      guint8        spacing_;
      Gdk_Pixmap    pixmap_closed_;
      Gdk_Bitmap    mask_closed_;
      Gdk_Pixmap    pixmap_opened_;
      Gdk_Bitmap    mask_opened_;
      bool          is_leaf_;
      bool          expanded_;
    public:
      Element(const Gtk::SArray& text,
              bool is_leaf=false,
              bool expanded=false);
      Element(const Gtk::SArray& text,
              Gdk_Pixmap pixmap_closed,
              Gdk_Bitmap mask_closed,
              Gdk_Pixmap pixmap_opened,
              Gdk_Bitmap mask_opened,
              bool is_leaf=false,
              bool expanded=false);
  };

typedef Element LeafElem;

class BranchElem : public Element
  {
    public:
      BranchElem(const Gtk::SArray& text,
              bool expanded=false);
      BranchElem(const Gtk::SArray& text,
              Gdk_Pixmap pixmap_closed,
              Gdk_Bitmap mask_closed,
              Gdk_Pixmap pixmap_opened,
              Gdk_Bitmap mask_opened,
              bool expanded=false);
  };

/****************************************************************/
class Row;
class Cell
  {
    protected:
      friend class Row;
      GtkCTree     *tree_;
      GtkCTreeNode *node_;
      gint          column_;

      Cell(GtkCTree* parent, GtkCTreeNode* row, gint column);
      Cell();

    public:
      GtkCellType get_type() const;

      Gtk::Style* get_style() const;
      nstring get_text() const;
      Gdk_Pixmap get_pixmap() const;
      Gdk_Bitmap get_mask() const;

      void set_style(Gtk::Style* style=0);
      void set_style(Gtk::Style& style);
      void set_text(const nstring&);
      void set_pixmap(const Gdk_Pixmap& pixmap,const Gdk_Bitmap& mask=0);
      void set_shift(gint vertical,gint horizontal);

      void clear();

      void moveto(gfloat row_align=0.5,gfloat col_align=0.5);
  };


class CellIterator: private Cell
  {
    private:
      friend class Row;
      CellIterator(GtkCTree* parent, GtkCTreeNode* row, gint column)
        : Cell(parent,row,column)
        {}

    public:
      CellIterator()
        : Cell()
        {}

      typedef bidirectional_iterator_tag iterator_category;
      typedef size_t size_type;
      typedef ptrdiff_t difference_type;

      typedef Cell  value_type;
      typedef Cell* pointer;
      typedef Cell& reference;
      typedef CellIterator Self;

      Self&  operator++();
      Self&  operator--();
      Self   operator++(int) {Self t=*this; Self::operator++(); return t;}
      Self   operator--(int) {Self t=*this; Self::operator--(); return t;}

      reference operator*()  const;
      pointer operator -> () const;

      bool operator ==(const Self& cell) const {return column_==cell.column_;}
      bool operator !=(const Self& cell) const {return column_!=cell.column_;}
  };

/****************************************************************/
class RowList;
class SelectionList;
class Row
  {
      friend class RowList;
    public:
      typedef Row                                Self;
      typedef Cell                               value_type;
      typedef value_type &                       reference;
      typedef const value_type &                 const_reference;

      typedef CellIterator                       iterator;
      typedef G_List_ConstIterator<iterator>     const_iterator;
      typedef G_List_ReverseIterator<iterator>   reverse_iterator;
      typedef G_List_ConstIterator<reverse_iterator>   const_reverse_iterator;

      typedef size_t                             difference_type;
      typedef size_t                             size_type;

    protected:
      friend class ::Gtk::CTree;
      friend class CTree_Class;
      friend class SelectionIterator;
      GtkCTree* tree_;
      GtkCTreeNode* node_;


      iterator begin_() const
        { return iterator(tree_,node_,0); }
      iterator end_() const
        { return iterator(tree_,node_,size()); }

    public:
      Row(GtkCTree* tree,GtkCTreeNode* node)
        : tree_(tree), node_(node) {}
      Row() : tree_(0), node_(0) {}

      void set_style(Gtk::Style* style=0);
      void set_style(Gtk::Style& style);
      Gtk::Style* get_style();

      void set_selectable(bool);
      bool get_selectable();

      void set_background(const Gdk_Color&);
      void set_foreground(const Gdk_Color&);

      gpointer get_data();
      void set_data(gpointer);
      void set_data(gpointer,GtkDestroyNotify);

      guint8 get_spacing();         //gtk_ctree_get_node_info
      GtkVisibility is_visible();
      bool          is_viewable();
      bool          is_leaf();      //gtk_ctree_get_node_info
      bool          is_expanded();  //gtk_ctree_get_node_info

      void expand();
      void expand_recursive();
      void expand_to_depth(int depth);
      void collapse();
      void collapse_recursive();
      void collapse_to_depth(int depth);
      void toggle_expansion();
      void toggle_expansion_recursive();

      void set_spacing(guint8);//gtk_ctree_get_node_info
      void set_leaf(bool);     //gtk_ctree_get_node_info
      void set_opened (const Gdk_Pixmap&,const Gdk_Bitmap&);
      void set_closed (const Gdk_Pixmap&,const Gdk_Bitmap&);

      void select();
      void select_recursive();
      void unselect();
      void unselect_recursive();
      void sort();
      void sort_recursive();

      RowList subtree();
      Row     get_parent();

      /*** Cell Vector operations ***/

      iterator begin()
        {return begin_();}
      iterator end()
        {return end_();}

      const_iterator begin() const
        { return const_iterator(begin_()); }
      const_iterator end() const
        { return const_iterator(end_()); }

      reverse_iterator rbegin()
        { return reverse_iterator(end_()); }
      reverse_iterator rend()
        { return reverse_iterator(begin_()); }

      const_reverse_iterator rbegin() const
        { return const_reverse_iterator(reverse_iterator(end_())); }
      const_reverse_iterator rend() const
        { return const_reverse_iterator(reverse_iterator(begin_())); }

      size_type size() const
        { return size_type(((GtkCList*)tree_)->columns); }
      size_type max_size()
        { return size_type(((GtkCList*)tree_)->columns); }
      bool empty()
        { return false; }

      value_type operator[](size_type l) const
        { return Cell(tree_, node_, l); }

// - check if get_parent was successful.
// - check in tree_select_row(Row) function if Row is the same than
//   previously selected/clicked Row
// - gpointer Version to check e.g. for NULL
      bool operator == (const Self     tRow)  const
        { return (tRow.node_ == node_); }
      bool operator == (const gpointer tNull) const
        { return (node_ == tNull); }
      bool operator != (const Self     tRow)  const
        { return (tRow.node_ != node_); }
      bool operator != (const gpointer tNull) const
        { return (node_ != tNull); }
  };

/****************************************************************/
class RowIterator : protected Row
  {
    protected:
      friend class RowList;
      friend class Gtk::CTree;
      GtkCTreeNode* pnode_;
      RowIterator(GtkCTree* parent,GtkCTreeNode* pnode, GtkCTreeNode* node)
        : Row(parent,node), pnode_(pnode) {}

    public:
      typedef bidirectional_iterator_tag iterator_category;
      typedef size_t size_type;
      typedef ptrdiff_t difference_type;

      typedef Row  value_type;
      typedef Row* pointer;
      typedef Row& reference;
      typedef RowIterator Self;

      RowIterator(): Row() {}

      bool operator == (const Self& i) const {return node_==i.node_;}
      bool operator != (const Self& i) const {return node_!=i.node_;}

      Self&  operator++();
      Self&  operator--();
      Self   operator++(int) {Self t=*this; Self::operator++(); return t;}
      Self   operator--(int) {Self t=*this; Self::operator--(); return t;}

      reference operator*() const;
      pointer operator -> () const;

  };

// this one goes through every element in depth first pattern.
class TreeIterator : protected Row
  {
    private:
      friend class TreeList;

      TreeIterator(GtkCTree* parent,GtkCTreeNode* node)
        : Row(parent,node) {}

    public:
      typedef bidirectional_iterator_tag iterator_category;
      typedef size_t size_type;
      typedef ptrdiff_t difference_type;

      typedef Row  value_type;
      typedef Row* pointer;
      typedef Row& reference;
      typedef TreeIterator Self;

      TreeIterator() {}

      bool operator == (const Self& i) const {return node_==i.node_;}
      bool operator != (const Self& i) const {return node_!=i.node_;}

      Self&  operator++();
      Self&  operator--();
      Self   operator++(int) {Self t=*this; Self::operator++(); return t;}
      Self   operator--(int) {Self t=*this; Self::operator--(); return t;}

      reference operator*() const;
      pointer operator -> () const;
  };

/****************************************************************/
class RowList
  {
    public:
      typedef Row                                value_type;
      typedef value_type &                       reference;
      typedef const value_type &                 const_reference;

      typedef RowIterator                        iterator;
      typedef G_List_ConstIterator<iterator>     const_iterator;
      typedef G_List_ReverseIterator<iterator>   reverse_iterator;
      typedef G_List_ConstIterator<reverse_iterator>   const_reverse_iterator;

      typedef size_t                             difference_type;
      typedef size_t                             size_type;

    private:
      friend class Row;
      friend class ::Gtk::CTree;

      GtkCTree* parent_;
      GtkCTreeNode* node_;

      RowList(GtkCTree* parent, GtkCTreeNode* node)
        : parent_(parent), node_(node) {};

      iterator begin_() const;
      iterator end_() const;

    public:

      iterator begin()
        {return begin_();}
      iterator end()
        {return end_();}

      const_iterator begin() const
        { return const_iterator(begin_()); }
      const_iterator end() const
        { return const_iterator(end_()); }

      reverse_iterator rbegin()
        { return reverse_iterator(end_()); }
      reverse_iterator rend()
        { return reverse_iterator(begin_()); }

      const_reverse_iterator rbegin() const
        { return const_reverse_iterator(reverse_iterator(end_())); }
      const_reverse_iterator rend() const
        { return const_reverse_iterator(reverse_iterator(begin_())); }

      value_type front() const     { return *begin(); }
      value_type back() const      { return *(--end()); }

      // This is order n. (use at own risk)
      value_type operator[](size_type l) const;

      size_type size() const;
      size_type max_size() const { return size_type(-1); }
      bool empty() const;

      iterator insert(iterator position, const Element& e);

      void push_front(const Element& e) { insert(begin(),e); }
      void push_back(const Element& e)  { insert(end(),e); }
      void pop_front()                  { erase(begin()); }
      void pop_back()                   { erase(--end()); }

      void clear();

      iterator erase(iterator);
      void erase(iterator start, iterator stop);
      void remove(const_reference);

      void swap(iterator, iterator);
      void move(iterator, iterator);
      iterator find_data(gpointer) const;
  };

class TreeList
  {
    public:
      typedef Row                                value_type;
      typedef value_type &                       reference;
      typedef const value_type &                 const_reference;

      typedef TreeIterator                       iterator;
      typedef G_List_ConstIterator<iterator>     const_iterator;
//      typedef G_List_ReverseIterator<iterator>   reverse_iterator;
//      typedef G_List_ConstIterator<reverse_iterator>   const_reverse_iterator;

      typedef size_t                             difference_type;
      typedef size_t                             size_type;

    private:
      friend class Gtk::CTree;
      GtkCTree* tree_;
      TreeList(GtkCTree* tree) :tree_(tree) {}

      iterator begin_() const;
      iterator end_() const;

    public:
      TreeList() {}
      ~TreeList() {}

      iterator begin()
        {return begin_();}
      iterator end()
        {return end_();}

      const_iterator begin() const
        { return const_iterator(begin_()); }
      const_iterator end() const
        { return const_iterator(end_()); }

 //     reverse_iterator rbegin()
 //       { return reverse_iterator(end_()); }
 //     reverse_iterator rend()
 //       { return reverse_iterator(begin_()); }

 //     const_reverse_iterator rbegin() const
 //       { return const_reverse_iterator(reverse_iterator(end_())); }
 //     const_reverse_iterator rend() const
 //       { return const_reverse_iterator(reverse_iterator(begin_())); }

      //value_type front() const     { return *begin(); }
      //value_type back() const      { return *(--end()); }

      // This is order n. (use at own risk)
      value_type operator[](size_type l) const;

      // size_type size() const;  (not computable)
      size_type max_size() const { return size_type(-1); }
      bool empty() const;
  };

  class SelectionList;

  class SelectionIterator: protected Row
  {
    private:
      friend class SelectionList;
      GList* glist_node_;

      SelectionIterator(GtkCTree* parent, GList* node)
        : Row(parent,0), glist_node_(node)
        {}

    public:
      typedef bidirectional_iterator_tag iterator_category;
      typedef size_t size_type;
      typedef ptrdiff_t difference_type;

      typedef Row  value_type;
      typedef Row* pointer;
      typedef Row& reference;

      typedef SelectionIterator Self;

      SelectionIterator()
        {}

      SelectionIterator(const Self& s)
        : Row(s), glist_node_(s.glist_node_) {}

      Self& operator= (const Self& s)
        { Row::operator=(s); glist_node_=s.glist_node_; return *this; }

      reference operator*()  const;
      pointer operator -> () const;

      Self&  operator++();
      Self&  operator--();
      Self   operator++(int) {Self t=*this; Self::operator++(); return t;}
      Self   operator--(int) {Self t=*this; Self::operator--(); return t;}

      bool operator ==(const Self& row) const {return glist_node_==row.glist_node_;}
      bool operator !=(const Self& row) const {return glist_node_!=row.glist_node_;}
  };

  class SelectionList
  {
    public:
      typedef Row                                value_type;
      typedef value_type &                       reference;
      typedef const value_type &                 const_reference;

      typedef SelectionIterator                  iterator;
      typedef G_List_ConstIterator<iterator>     const_iterator;
      typedef G_List_ReverseIterator<iterator>   reverse_iterator;
      typedef G_List_ConstIterator<reverse_iterator>   const_reverse_iterator;

      typedef size_t                             difference_type;
      typedef size_t                             size_type;

    private:
      friend class Gtk::CTree;
      Gtk::CTree *parent_; // this will be shared with the other lists.

      iterator begin_() const;
      iterator end_() const;

      GList*& glist() const;

    public:
      iterator begin()
        {return begin_();}
      iterator end()
        {return end_();}

      const_iterator begin() const
        { return const_iterator(begin_()); }
      const_iterator end() const
        { return const_iterator(end_()); }

      reverse_iterator rbegin()
        { return reverse_iterator(end_()); }
      reverse_iterator rend()
        { return reverse_iterator(begin_()); }

      const_reverse_iterator rbegin() const
        { return const_reverse_iterator(reverse_iterator(end_())); }
      const_reverse_iterator rend() const
        { return const_reverse_iterator(reverse_iterator(begin_())); }

      value_type front() const     { return *begin(); }
      value_type back() const      { return *(--end()); }

      // This is order n. (use at own risk)
      value_type operator[](size_type l) const;

      size_type size(void) const;
      size_type max_size(void) const { return size_type(-1); }
      bool empty(void) { return glist() == 0; }

      void all();
      void clear();
      void undo();

      // this has no insert method, items can only be removed
  };




} /* namespace CTree_Helpers */



//: A widget displaying a hierarchical tree.
//- The {\class Gtk::CTree} widget is used for showing a hierarchical tree to the user, for example a directory tree.
//-
//- The tree is internally represented as a set of {GtkCTreeNode} structures.
//-
//- The interface has much in common with the {\class Gtk::CList} widget: rows (nodes) can be selected by
//- the user etc.
//-
//- Positions in the tree are often indicated by two arguments, a parent and a sibling, both
//- {GtkCTreeNode} pointers. If the parent is NULL, the position is at the root of the tree and if
//- the sibling is NULL, it will be the last child of parent, otherwise it will be inserted just before the
//- sibling.
class CTree : public CList
{

public:
  typedef CTree          CppObjectType;
  typedef CTree_Class    CppClassType;
  typedef GtkCTree           BaseObjectType;
  typedef GtkCTreeClass      BaseClassType;

private:
  friend class CTree_Class;
  static CppClassType ctree_class;

  CTree(const CTree&);
  CTree& operator=(const CTree&); // not implemented

protected:
  void   initialize_class();
  explicit CTree(GtkCTree *castitem);

public:
  static GtkType get_type();
  GtkCTree* gtkobj()             { return (GtkCTree*)(gtkobject); }
  const GtkCTree* gtkobj() const { return (GtkCTree*)(gtkobject); }
  static bool isA(Object *checkcast);

  // Hook for proxies
  static const char* const signal_names[];

  virtual ~CTree();

private:

public:

  typedef Gtk::CTree_Helpers::Element       Element;
  typedef Gtk::CTree_Helpers::Cell          Cell;

  typedef Gtk::CTree_Helpers::Row           Row;
  typedef Gtk::CTree_Helpers::RowList       RowList;

  typedef Gtk::CTree_Helpers::TreeList      TreeList;




  //: Create tree with titles.
  CTree(const Gtk::SArray& titles, gint tree_column=0);

  //: Create tree without titles.
  CTree(gint columns, gint tree_column=0);

  //: Used to determine if a particular coordinat lies on an expander button.
  //- x, y: The coordinates to check.
  //- Returns: True if the given coordinates lie on an expander button.


  bool is_hot_spot(gint x,gint y);

  //: Set the amount of indentation between levels in the tree.
  //- indent: The number of pixels to  the levels of the tree.


  void set_indent(gint indent);

  //: Set the spacing between the tree graphic and the actual node content.
  //- spacing: The number of pixels between the tree and the node's content.


  void set_spacing(gint spacing);



  void set_show_stub(bool show_stub);

  typedef GtkCTreeLineStyle LineStyle;
  typedef GtkCTreeExpanderStyle ExpanderStyle;
  typedef GtkCTreeCompareDragFunc CompareDragFunc;



  void set_line_style(LineStyle style);



  void set_expander_style(ExpanderStyle style);



  void set_drag_compare_func(CompareDragFunc p0);

  // signals  (these are totally unwrappable!)

  TreeList tree()
    { return TreeList(gtkobj());}
  const TreeList tree() const
    { return TreeList(const_cast<GtkCTree*>(gtkobj()));}

  RowList rows()
    { return RowList(gtkobj(),0);}
  const RowList rows() const
    { return RowList(const_cast<GtkCTree*>(gtkobj()),0);}

  // convenience functions (order N)
  Row row(int i)             {return rows()[i]; }
  const Row row(int i) const {return rows()[i]; }

  CTree_Helpers::SelectionList& selection()
    {
      return reinterpret_cast<CTree_Helpers::SelectionList&>(ctree_self);
      //pointer to ref cast works because
      //Gtk::CTree* parent_ is only member data of SelectionList.
      //TODO: Add a SelectionList constructor instead.
    }
  const CTree_Helpers::SelectionList& selection() const
    {
      return reinterpret_cast<const CTree_Helpers::SelectionList&>(ctree_self);
      //pointer to ref cast works because
      //Gtk::Tree* parent_ is only member data of SelectionList.
      //TODO: Add a SelectionList constructor instead.
    }

public:

    class Proxy_tree_select_row
      : public ProxySignal2<void,GtkCTreeNode*,gint,CppObjectType,BaseObjectType,0>
      {
          typedef ProxySignal2<void,GtkCTreeNode*,gint,CppObjectType,BaseObjectType,0> BaseType;
        public:
          Connection connect(const SigC::Slot2<void,Gtk::CTree::Row,gint> &s);
      };
    class Proxy_tree_unselect_row
      : public ProxySignal2<void,GtkCTreeNode*,gint,CppObjectType,BaseObjectType,1>
      {
          typedef ProxySignal2<void,GtkCTreeNode*,gint,CppObjectType,BaseObjectType,1> BaseType;
        public:
          Connection connect(const SigC::Slot2<void,Gtk::CTree::Row,gint> &s);
      };
    class Proxy_tree_expand
      : public ProxySignal1<void,GtkCTreeNode*,CppObjectType,BaseObjectType,2>
      {
          typedef ProxySignal1<void,GtkCTreeNode*,CppObjectType,BaseObjectType,2> BaseType;
        public:
          Connection connect(const SigC::Slot1<void,Gtk::CTree::Row> &s);
      };
    class Proxy_tree_collapse
      : public ProxySignal1<void,GtkCTreeNode*,CppObjectType,BaseObjectType,3>
      {
          typedef ProxySignal1<void,GtkCTreeNode*,CppObjectType,BaseObjectType,3> BaseType;
        public:
          Connection connect(const SigC::Slot1<void,Gtk::CTree::Row> &s);
      };
  union
    {
      CppObjectType * ctree_self;
      Proxy_tree_select_row tree_select_row;
      Proxy_tree_unselect_row tree_unselect_row;
      Proxy_tree_expand tree_expand;
      Proxy_tree_collapse tree_collapse;
    };

protected:
  // impl functions
    virtual void tree_select_row_impl(Gtk::CTree::Row row,gint column);
    virtual void tree_unselect_row_impl(Gtk::CTree::Row row,gint column);
    virtual void tree_expand_impl(Gtk::CTree::Row row);
    virtual void tree_collapse_impl(Gtk::CTree::Row row);

};

}

#endif
