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

/* set.h
 *
 * Copyright 2006 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 <libgdamm/datahandler.h>
#include <libgdamm/value.h>

_DEFS(libgdamm,libgda)
_PINCLUDE(glibmm/private/object_p.h)

namespace Gnome
{

namespace Gda
{

class DataModel;

_WRAP_GERROR(HolderError, GdaHolderError, GDA_HOLDER_ERROR) 

/** Container for a single Gda::Value.
 *
 * The GdaHolder is a container for a single Gda::Value value. It also specifies 
 * various attributes of the contained value (default value, ...)
 *
 * @ingroup DataHandlers
 */
class Holder : public Glib::Object
{
  _CLASS_GOBJECT(Holder, GdaHolder, GDA_HOLDER, Glib::Object, GObject)
protected:
  Holder(GType g_type, const Glib::ustring& id);    
public:
  _WRAP_CREATE(GType g_type, const Glib::ustring& id)
  _WRAP_METHOD(Glib::RefPtr<Holder> copy() const, gda_holder_copy)
  
  _WRAP_METHOD(GType get_g_type() const, gda_holder_get_g_type)
  _WRAP_METHOD(Glib::ustring get_id() const, gda_holder_get_id)

  _WRAP_METHOD(Value get_value() const, gda_holder_get_value)


  _WRAP_METHOD(Glib::ustring get_value_str(const Glib::RefPtr<DataHandler>& dh) const, gda_holder_get_value_str)

  _WRAP_METHOD(bool set_value_as_value(const Value& value), gda_holder_set_value, errthrow)

  //TODO: Documentation:
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  template <class ValueType>
  bool set_value(const ValueType& value);
#else
  template <class ValueType>
  bool set_value(const ValueType& value, std::auto_ptr<Glib::Error>& error);
#endif

  _WRAP_METHOD(bool set_value_str(const Glib::RefPtr<DataHandler>& dh, const Glib::ustring& value), gda_holder_set_value_str, errthrow)
  _WRAP_METHOD(bool take_value(const Value& value), gda_holder_take_value, errthrow)
  _WRAP_METHOD(Value take_static_value (const Value& value, bool& value_changed), gda_holder_take_static_value, errthrow)

  void set_attribute(const Glib::ustring& attribute, const Value& value);
  _IGNORE(gda_holder_set_attribute)
  //TODO: gda_holder_set_attribute() has stupid memory management: _WRAP_METHOD(void set_attribute(const Glib::ustring& attribute, const Value& value), gda_holder_set_attribute)

  _WRAP_METHOD(Value get_attribute(const Glib::ustring& attribute) const, gda_holder_get_attribute) 
  
  _WRAP_METHOD(Value get_default_value() const, gda_holder_get_default_value)
  _WRAP_METHOD(void set_default_value(const Value& value), gda_holder_set_default_value)
  _WRAP_METHOD(bool set_value_to_default(), gda_holder_set_value_to_default)
  _WRAP_METHOD(bool value_is_default() const, gda_holder_value_is_default)

  _WRAP_METHOD(void force_invalid(), gda_holder_force_invalid)
  _WRAP_METHOD(bool is_valid() const, gda_holder_is_valid)
  _WRAP_METHOD(void set_not_null(bool not_null = true), gda_holder_set_not_null)
  _WRAP_METHOD(bool get_not_null() const, gda_holder_get_not_null)

  _WRAP_METHOD(Glib::RefPtr<DataModel> get_source_model(int& col), gda_holder_get_source_model)
  _WRAP_METHOD(Glib::RefPtr<const DataModel> get_source_model(int& col) const, gda_holder_get_source_model)

  _WRAP_METHOD(bool set_source_model(const Glib::RefPtr<DataModel>& model, int col), gda_holder_set_source_model, errthrow)

  _WRAP_METHOD(void set_bind(const Glib::RefPtr<Holder>& bind_to), gda_holder_set_bind, errthrow)
  _WRAP_METHOD(Glib::RefPtr<Holder> get_bind(), gda_holder_get_bind, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Holder> get_bind() const, gda_holder_get_bind, refreturn, constversion)

  _WRAP_PROPERTY("description", Glib::ustring)
  _WRAP_PROPERTY("full-bind", Glib::RefPtr<Holder>)
  _WRAP_PROPERTY("g-type", gulong)
  _WRAP_PROPERTY("id", Glib::ustring)
  _WRAP_PROPERTY("name", Glib::ustring)
  _WRAP_PROPERTY("not-null", bool)
  _WRAP_PROPERTY("simple-bind", Glib::RefPtr<Holder>)
  _WRAP_PROPERTY("source-column", int)
  _WRAP_PROPERTY("source-model", Glib::RefPtr<DataModel>)

  _WRAP_SIGNAL(void changed(), "changed")
  _WRAP_SIGNAL(void source_changed(), "source-changed")
  
#m4 _CONVERSION(`GValue*',`const Value&',`Value($3)')
#m4 _CONVERSION(`GError*', `Glib::Error*', `Glib::wrap($3)')
#m4 _CONVERSION(`Glib::Error', `GError*', `($3).gobj()')
  _WRAP_SIGNAL(Glib::Error validate_change(const Value& value), "validate-change", no_default_handler)
  
#m4 _CONVERSION(`const char*',`const Glib::ustring&',__GCHARP_TO_USTRING)
  _WRAP_SIGNAL(void attribute_changed(const Glib::ustring& attr_name, const Value& value), "attribute-changed", no_default_handler)

};

#ifndef DOXYGEN_SHOULD_SKIP_THIS
#ifdef GLIBMM_EXCEPTIONS_ENABLED
template <class ValueType> inline
bool Holder::set_value(const ValueType& value)
{
  Gnome::Gda::Value gdavalue(value);
  return this->set_value_as_value(gdavalue);
}
#else
template <class ValueType> inline
bool Holder::set_value(const ValueType& value, std::auto_ptr<Glib::Error>& error)
{
  Gnome::Gda::Value gdavalue(value);
  return this->set_value_as_value(gdavalue, error);
}
#endif
#endif //DOXYGEN_SHOULD_SKIP_THIS

} // namespace Gda
} // namespace Gnome
