/* 
 * Copyright (c) 2007, 2010, 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
 */

#include "stdafx.h"
#include "wb_history_tree.h"
#include "wb_context.h"
#include "base/string_utilities.h"

using namespace wb;
using namespace bec;
using namespace grt;

int HistoryTreeBE::count_children(const NodeId &parent)
{
  if (!parent.is_valid())
    return _undom->get_undo_stack().size() + _undom->get_redo_stack().size();

  return 0;
}


bool HistoryTreeBE::get_field(const NodeId &node, int column, std::string &value)
{
  std::deque<UndoAction*> &undostack(_undom->get_undo_stack());
  std::deque<UndoAction*> &redostack(_undom->get_redo_stack());

  if (node[0] < (int)undostack.size())
  {
    if (column == Type)
      value= "U";
    else
      value= undostack[node[0]]->description();
    return true;
  }
  else if (node[0] < (int)(undostack.size() + redostack.size()))
  {
    if (column == Type)
      value= "R";
    else
      value= "("+redostack[redostack.size() - (node[0] - undostack.size()) - 1]->description()+")";
    return true;
  }
  return false;
}


NodeId HistoryTreeBE::get_child(const NodeId &parent, int index)
{
  return NodeId(parent).append(index);
}


HistoryTreeBE::HistoryTreeBE(WBContext *wb, UndoManager *undom)
: _undom(undom), _wb(wb)
{
  _old_row_count = 0;
  scoped_connect(undom->signal_redo(),boost::bind(&HistoryTreeBE::handle_redo, this, _1));
  scoped_connect(undom->signal_undo(),boost::bind(&HistoryTreeBE::handle_undo, this, _1));
  scoped_connect(undom->signal_changed(),boost::bind(&HistoryTreeBE::handle_change, this));
}


void HistoryTreeBE::refresh()
{
}


bool HistoryTreeBE::activate_node(const bec::NodeId &node)
{
  _wb->execute_in_grt_thread("Undo", 
    boost::bind(&HistoryTreeBE::activate_node_grt, this, _1, node));
  return true;
}


grt::ValueRef HistoryTreeBE::activate_node_grt(grt::GRT *grt, const bec::NodeId &node)
{
  std::deque<UndoAction*> &undostack(_undom->get_undo_stack());
  std::deque<UndoAction*> &redostack(_undom->get_redo_stack());

  // undo
  if (node[0] < (int)undostack.size())
  {
    while ((int)undostack.size() > node[0])
      _undom->undo();
  }
  // redo
  else if (node[0] <= (int)(undostack.size() + redostack.size()))
  {
    while ((int)undostack.size() <= node[0])
      _undom->redo();
  }

  return grt::IntegerRef(0);
}

bec::MenuItemList HistoryTreeBE::get_popup_items_for_nodes(const std::vector<bec::NodeId> &nodes)
{
  bec::MenuItemList items;
  bec::MenuItem item;
  if (nodes.size() <= 1)
    item.caption = _("Copy history entries to clipboard");
  else
    item.caption = _("Copy selected history entries to clipboard");
  item.name    = "copyHistory";
  item.enabled = nodes.size() > 0;
  items.push_back(item);

  return items;
}

bool HistoryTreeBE::activate_popup_item_for_nodes(const std::string &name, const std::vector<bec::NodeId> &unsorted_nodes)
{
  return false;
}


void HistoryTreeBE::handle_redo(grt::UndoAction*)
{
  int new_count= count();
  g_message("redo %i -> %i", _old_row_count, count());
  tree_changed(_old_row_count);
  _old_row_count = new_count;
}


void HistoryTreeBE::handle_undo(grt::UndoAction*)
{
  int new_count= count();
  g_message("undo %i -> %i", _old_row_count, count());
  tree_changed(_old_row_count);
  _old_row_count = new_count;
}


void HistoryTreeBE::handle_change()
{
  int new_count= count();
  
  tree_changed(_old_row_count);
  
  _old_row_count = new_count;
}

