// -*- c++ -*-
/* $Id: treepath.ccg,v 1.5 2005/11/29 16:38:10 murrayc Exp $ */

/* Copyright 1998-2002 The gtkmm Development Team
 *
 * 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.1 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <gtkmm/treemodel.h>
#include <glibmm/utility.h>
#include <gtk/gtk.h>


namespace Gtk
{

TreePath::TreePath(TreePath::size_type n, TreePath::value_type value)
:
  gobject_(gtk_tree_path_new())
{
  for(; n > 0; --n)
    gtk_tree_path_append_index(gobject_, value);
}

TreePath::TreePath(const Glib::ustring& path)
:
  gobject_ (gtk_tree_path_new_from_string(path.c_str()))
{}

TreePath::TreePath(const TreeModel::iterator& iter)
:
  // The GtkTreePath* is always newly created.
  gobject_ (gtk_tree_model_get_path(iter.get_model_gobject(), const_cast<GtkTreeIter*>(iter.gobj())))
{}

TreePath& TreePath::operator=(const TreeModel::iterator& iter)
{
  TreePath temp(iter);
  swap(temp);
  return *this;
}

void TreePath::clear()
{
  TreePath empty_path;
  swap(empty_path);
}

TreePath::size_type TreePath::size() const
{
  return gtk_tree_path_get_depth(gobject_);
}

TreePath::operator bool() const
{
  return !empty();
}

bool TreePath::empty() const
{
  if(!gobject_)
    return true;

  return (gtk_tree_path_get_depth(gobject_) == 0);
}

TreePath::reference TreePath::operator[](TreePath::size_type i)
{
  int *const indices = gtk_tree_path_get_indices(gobject_);
  return indices[i];
}

TreePath::const_reference TreePath::operator[](TreePath::size_type i) const
{
  const int *const indices = gtk_tree_path_get_indices(gobject_);
  return indices[i];
}

TreePath::iterator TreePath::begin()
{
  return gtk_tree_path_get_indices(gobject_);
}

TreePath::iterator TreePath::end()
{
  return gtk_tree_path_get_indices(gobject_) + gtk_tree_path_get_depth(gobject_);
}

TreePath::const_iterator TreePath::begin() const
{
  return gtk_tree_path_get_indices(gobject_);
}

TreePath::const_iterator TreePath::end() const
{
  return gtk_tree_path_get_indices(gobject_) + gtk_tree_path_get_depth(gobject_);
}

bool TreePath::get_from_selection_data(const SelectionData& selection_data, Glib::RefPtr<TreeModel>& model, TreePath& path) //static 
{
  GtkTreeModel* src_model = 0;
  GtkTreePath* src_path = 0;
  gboolean result = gtk_tree_get_row_drag_data(const_cast<GtkSelectionData*>(selection_data.gobj()), &src_model, &src_path);

  model = Glib::wrap(src_model, true /* take_copy=true */);
  
  //gtk_tree_get_row_drag_data gives us ownership of src_path.
  path = Glib::wrap(src_path, false /* take_copy=false */);

  return result;
}

bool TreePath::get_from_selection_data(const SelectionData& selection_data, TreePath& path) //static
{
  GtkTreePath* src_path = 0;
  gboolean result = gtk_tree_get_row_drag_data(const_cast<GtkSelectionData*>(selection_data.gobj()), 0, &src_path);

  //gtk_tree_get_row_drag_data gives us ownership of src_path.
  path = Glib::wrap(src_path, false /* take_copy=false */);

  return result;
}


bool TreePath::set_in_selection_data(SelectionData& selection_data, const Glib::RefPtr<const TreeModel>& model) const
{
  return gtk_tree_set_row_drag_data(selection_data.gobj(), const_cast<GtkTreeModel*>(model->gobj()), const_cast<GtkTreePath*>(gobj()));  
}

_DEPRECATE_IFDEF_START
Glib::ArrayHandle<int> TreePath::get_indices() const
{
  // gtk_tree_path_get_indices() returns a pointer to an internal array,
  // similar to std::string::data().  Thus the OWNERSHIP_NONE flag.

  return Glib::ArrayHandle<int>(gtk_tree_path_get_indices(gobject_),
                                gtk_tree_path_get_depth(gobject_),
                                Glib::OWNERSHIP_NONE);
}
_DEPRECATE_IFDEF_END
  
} // namespace Gtk

