

#include "history_tree.h"
#include "workbench/wb_history_tree.h"

HistoryTree::HistoryTree(wb::WBContextUI *wbui)
  : _wbui(wbui)
{
  set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
  add(_tree);
  set_shadow_type(Gtk::SHADOW_IN);
  _tree.set_headers_visible(false);
  _tree.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);

  show_all();
 
  _model= Gtk::ListStore::create(record);
  _tree.set_model(_model);

  _tree.append_column("", record.text);

  _tree.signal_row_activated().connect(sigc::mem_fun(this, &HistoryTree::activate_row));

  _history = _wbui->get_history_tree();

  scoped_connect(_history->tree_changed_signal(),boost::bind(&HistoryTree::refresh_tree, this, _1, _2));
}

HistoryTree::~HistoryTree()
{
  _refresh_conn.disconnect();
}

void HistoryTree::refresh_tree(const bec::NodeId &parent, int ocount)
{
  _refresh_conn.disconnect();
  _refresh_conn = _wbui->get_wb()->get_grt_manager()->run_once_when_idle(boost::bind(&HistoryTree::refresh, this));
}


void HistoryTree::refresh()
{
  int old_count = _model->children().size();
  int new_count = _history->count();
  
  if (old_count == new_count)
  {
    for (int i = std::max(new_count-3, 0); i < new_count; i++)
    {
      Gtk::TreePath path;
      path.push_back(i);
      Gtk::TreeRow row = *_model->get_iter(path);
      std::string text;
      _history->get_field(i, 0, text);
      row[record.text] = text;
    }
  }
  else
  {
    if (old_count > new_count)
    {
      for (int i = old_count-1; i >= new_count; --i)
      {
        Gtk::TreePath path;
        path.push_back(i);
        _model->erase(_model->get_iter(path));
      }
    }
    else
    {
      for (int i = new_count-1; i >= old_count; --i)
      {
        Gtk::TreeRow row;
        std::string text;
        _history->get_field(i, 0, text);
        row = *_model->append();
        row[record.text] = text;
      }
    }
  }
}


void HistoryTree::activate_row(const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *column)
{
  _history->activate_node(path.back());
}

void HistoryTree::handle_menu(const std::string&, const std::vector<bec::NodeId>& nodes)
{
  std::string text;
  std::string line;

  if (nodes.size() == 1)
  {
    const int size = _history->count_children(bec::NodeId());

  for (int i = 0; i < size; ++i)
  {
    _history->get_field(bec::NodeId(i), wb::HistoryTreeBE::Description, line);
    text += line;
    text += '\n';
  }
  }
  else
  {
    for (int i = 0; i < (int)nodes.size(); ++i)
    {
      _history->get_field(nodes[i], wb::HistoryTreeBE::Description, line);
      text += line;
      text += '\n';
    }
  }

  Glib::RefPtr<Gtk::Clipboard> cb = Gtk::Clipboard::get();

  cb->set_text(text);
  cb->store();
}
