// -*- C++ -*- //

/* datamodeliter.h
 *
 * Copyright 2003 libgdamm 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 <glibmm/object.h>
#include <libgdamm/set.h>
#include <libgdamm/value.h>

_DEFS(libgdamm,libgda)
_PINCLUDE(libgdamm/private/set_p.h)

namespace Gnome
{

namespace Gda
{

_WRAP_GERROR(DataModelIterError, GdaDataModelIterError, GDA_DATA_MODEL_ITER_ERROR)

/** Data model iterator.
 *
 * A Gda::DataModelIter object is used to iterate through the rows of a Gda::DataModel. 
 * If the data model is accessible in a random access way then any number of Gda::DataModelIter 
 * objects can be created on the same data model, and if the data model only supports a cursor 
 * based access then only one Gda::DataModelIter can be created. In any case creating a 
 * Gda::DataModelIter should be done using the create_iter() method. 
 *
 * When a Gda::DataModelIter is valid (that is when it points to an existing row in the data model it iterates through), 
 * the individual values (corresponding to each column of the data model, at the pointer row) 
 * can be accessed using the get_value_at() or 
 * get_value_for_field() methods (or in the same way Gda::Set's values are 
 * accessed as Gda::DataModelIter inherits the Gda::Set).
 *
 * Right after being created, a Gda::DataModelIter is invalid (does not point to any row of its data model).
 * To read the first row of the data model, use the move_next() method. 
 * Calling this method several times will move the iterator forward, up to when the data model has 
 * no more rows and the Gda::DataModelIter will be declared invalid (and move_next() 
 * has returned FALSE). Note that at this point, the number of rows in the data model will be known.
 *
 * If the data model supports it, a Gda::DataModelIter can be moved backwards using the 
 * move_prev() method. However if the iterator is invalid, moving backwards will 
 * not be possible (on the contrary to move_next() which moves to the first row).
 *
 * The move_to_row() method, if the iterator can be moved both forward and backwards,
 * can move the iterator to a specific row (sometimes faster than moving it forward or backwards a number of times).
 *
 * @ingroup DataModels
 */
class DataModelIter
 : public Set
{
  _CLASS_GOBJECT(DataModelIter, GdaDataModelIter, GDA_DATA_MODEL_ITER, Set, GdaSet)
protected:
  _WRAP_CTOR(DataModelIter(const Glib::RefPtr<DataModel>& data_model), gda_data_model_create_iter)

public:
  _WRAP_CREATE(const Glib::RefPtr<DataModel>& data_model)

  _WRAP_METHOD(bool is_valid() const, gda_data_model_iter_is_valid)
  _WRAP_METHOD(bool move_next(), gda_data_model_iter_move_next)
  _WRAP_METHOD(bool move_prev(), gda_data_model_iter_move_prev)
  _WRAP_METHOD(bool move_to_row(int row), gda_data_model_iter_move_to_row)
  _WRAP_METHOD(int get_row() const, gda_data_model_iter_get_row)
  _WRAP_METHOD(void invalidate_contents(), gda_data_model_iter_invalidate_contents)
    
  _WRAP_METHOD(Glib::RefPtr<Holder> get_holder_for_field(int col), gda_data_model_iter_get_holder_for_field, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Holder> get_holder_for_field(int col) const, gda_data_model_iter_get_holder_for_field, refreturn)

  _WRAP_METHOD(Value get_value_at(int col) const, gda_data_model_iter_get_value_at)
  _WRAP_METHOD(Value get_value_for_field(const Glib::ustring& field_name) const, gda_data_model_iter_get_value_for_field)
  _WRAP_METHOD(bool set_value_at(int col, const Value& value), gda_data_model_iter_set_value_at, errthrow)
    
  _WRAP_PROPERTY("current-row", int)
  _WRAP_PROPERTY("data-model", Glib::RefPtr<DataModel>)
  _WRAP_PROPERTY("forced-model", Glib::RefPtr<DataModel>)
  _WRAP_PROPERTY("update-model", bool)

  _WRAP_SIGNAL(void end_of_data(), "end-of-data")
  _WRAP_SIGNAL(void row_changed(int row), "row-changed")
};

} // namespace Gda
} // namespace Gnome

