/* 
 * © 2008-2009 Sun Microsystems, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
#ifndef _MFORMS_TREEVIEW_H_
#define _MFORMS_TREEVIEW_H_

#include <mforms/base.h>
#include <mforms/control.h>

/**
 * Implementation of a control class for a treeview control.
 */
namespace mforms {
  class TreeView;
  
  /** Determines what type a column should have (mainly describing the column *editor*). */
  enum TreeColumnType
  {
    StringColumnType,
    IntegerColumnType,
    CheckColumnType
  };

  /** Options used to customize what to show in the tree. */
  enum TreeOptions
  {
    TreeShowLines        = 1 << 0, // doesn't exist in mac/gtk (remove this)
    TreeShowPlusMinus    = 1 << 1, // doesn't exist in mac/gtk (remove this)
    TreeShowHeader       = 1 << 2,
    TreeNoColumns        = 1 << 3, // On non-Windows platforms columns are always on, so switch them on
                                   // on Windows too by default and use this flag to switch them off, if really needed.
                                   // At least gtk has problems with arbitrary items for a tree. Treeview in gtk is
                                   // built on View-Source model, where source is a row/column based thing. That may
                                   // require some hacking to support NoColums in gtk, so really think if that worth it.
    TreeAllowReorderRows = 1 << 4,
  };

  struct TreeViewImplPtrs
  {
    bool (__stdcall *create)(TreeView *self, TreeOptions options);
    
    int (__stdcall *add_column)(TreeView *self, TreeColumnType type, const std::string &name, int initial_width, bool editable);
    void (__stdcall *end_columns)(TreeView *self);
    
    void (__stdcall *clear_rows)(TreeView *self);

    void (__stdcall *delete_row)(TreeView *self, int row);
    int (__stdcall *add_row)(TreeView *self);
    int (__stdcall *get_selected)(TreeView *self);
    void (__stdcall *set_selected)(TreeView *self, const int idx);

    int (__stdcall *count)(TreeView *self);

    void (__stdcall *set_row_tag)(TreeView *self, int row, const std::string &value);
    void (__stdcall *set_string)(TreeView *self, int row, int column, const std::string &value);
    void (__stdcall *set_int)(TreeView *self, int row, int column, int value);
    void (__stdcall *set_check)(TreeView *self, int row, int column, bool value);

    std::string (__stdcall *get_row_tag)(TreeView *self, int row);
    std::string (__stdcall *get_string)(TreeView *self, int row, int column);
    int (__stdcall *get_int)(TreeView *self, int row, int column);
    bool (__stdcall *get_check)(TreeView *self, int row, int column);
  };


  class MFORMS_EXPORT TreeView : public Control
  {
  public:
    TreeView(TreeOptions options);

    int add_column(TreeColumnType type, const std::string &name, int initial_width, bool editable);
    void end_columns();

    void clear_rows();
    void delete_row(int row);
    int add_row();
    //! Retuns index of the selected item, if no item is selected -1 is returned
    int get_selected();
    void set_selected(const int idx);

    int count();
    
    std::string get_row_tag(int row);
    void set_row_tag(int row, const std::string &tag);

    void set(int row, int column, const std::string &value);
    void set(int row, int column, const char *value) { set(row, column, std::string(value)); }
    void set(int row, int column, int value);
    void set(int row, int column, bool check);

    std::string get_string(int row, int column);
    int get_int(int row, int column);
    bool get_check(int row, int column);

    sigc::signal<void>  signal_changed() {return _signal_changed;}
    
    void emit_changed()
    {
      if (!_updating)
        _signal_changed.emit();
    }
  protected:
    TreeViewImplPtrs *_treeview_impl;
    sigc::signal<void>  _signal_changed;
    bool _updating;
  };
}

#endif /* _TREEVIEW_H_ */
