/* 
 * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; version 2 of the
 * License.
 * 
 * This program 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301  USA
 */
#ifndef _MFORMS_GRTTREEVIEW_H_
#define _MFORMS_GRTTREEVIEW_H_

#include "mforms/view.h"
#include "mforms/menu.h"
#include "mforms/treenodeview.h"

#include <vector>

#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace bec {
  class TreeModel;
  struct NodeId;
};

namespace mforms {
  class GRTTreeView;
  
  enum GRTTreeColumnType
  {
    StringGRTColumnType,
    IconStringGRTColumnType,
    IntegerGRTColumnType,
    CheckGRTColumnType,
    IconGRTColumnType
  };

#ifndef SWIG
  struct GRTTreeViewImplPtrs
  {
    bool (__stdcall *create)(GRTTreeView *self, mforms::TreeOptions options);
    
    void (__stdcall *set_model)(GRTTreeView *self, bec::TreeModel *model);

    int (__stdcall *add_column)(GRTTreeView *self, GRTTreeColumnType type, int model_column, 
                                const std::string &name);

    int (__stdcall *add_column_editable)(GRTTreeView *self, GRTTreeColumnType type, int model_column, 
                                const std::string &name);
    
    void (__stdcall *set_column_width)(GRTTreeView *self, int model_column, int width);

    void (__stdcall *refresh)(GRTTreeView *self, const bec::NodeId &node);
    
    void (__stdcall *set_allow_multi_selection)(GRTTreeView *self, bool);
    bool (__stdcall *get_selected_node)(GRTTreeView *self, bec::NodeId &node);
    int (__stdcall *get_selection)(GRTTreeView *self, std::vector<bec::NodeId> &nodes);
    void (__stdcall *set_expanded)(GRTTreeView *self, const bec::NodeId& node, bool expanded);
    
    void (__stdcall *row_count_changed)(GRTTreeView *self, const bec::NodeId& parent, int old_count);

    // This one is only needed for windows
    void (__stdcall *enable_asynch_loading)(GRTTreeView *self, bool enabled);
  };
#endif

  class MFORMS_EXPORT GRTTreeView : public View
  {
  public:
    GRTTreeView(mforms::TreeOptions options);
    
    void set_model(bec::TreeModel *model);
    void set_allow_multi_selection(bool flag);

    int add_column(GRTTreeColumnType type, int model_column, const std::string &name);
    int add_column_editable(GRTTreeColumnType type, int model_column, const std::string &name);
    
    void set_column_width(int model_column, int width);

    void refresh(const bec::NodeId &node); // call with bec::NodeId() for a full refresh
    void row_count_changed(const bec::NodeId &parent, int old_count);

    // can't return bec::NodeId because we cant include grt/tree_model.h from here
    bool get_selected_node(bec::NodeId &node);
    int get_selection(std::vector<bec::NodeId> &nodes);
    void set_expanded(const bec::NodeId& node, bool expanded);
    void enable_asynch_loading(bool enabled);
    
    /** Sets a context menu to be attached to the treeview, to be shown on right click
     
     Note: Ownership of the context menu remains with the caller and it will not be freed
     when this object is deleted. */
    void set_context_menu(Menu *menu);
    
    /** Returns the context menu object attached to the treeview */
    Menu *get_context_menu() { return _context_menu; }
    
#ifndef SWIG
    boost::signals2::signal<void (const bec::NodeId&, int)>* signal_row_activate() { return &_activate_signal; }
    boost::signals2::signal<void ()>* signal_changed() {return &_changed_signal;}

  public:
    void row_activate_callback(const bec::NodeId &node, int column);
    void changed();

#endif
  protected:
    GRTTreeViewImplPtrs *_grttreeview_impl;
    boost::signals2::signal<void (const bec::NodeId&, int)> _activate_signal;
    boost::signals2::signal<void ()> _changed_signal;
    Menu *_context_menu;
  };
}

#endif // !DOXYGEN_SHOULD_SKIP_THIS
#endif /* _GRTTREEVIEW_H_ */
