// This may look like C code, but it's really -*- C++ -*-
/*
 * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium.
 *
 * See the LICENSE file for terms of use.
 */
#ifndef WABSTRACT_PROXY_MODEL_H_
#define WABSTRACT_PROXY_MODEL_H_

#include <Wt/WAbstractItemModel>

namespace Wt {

/*! \class WAbstractProxyModel Wt/WAbstractProxyModel Wt/WAbstractProxyModel
 *  \brief An abstract proxy model for %Wt's item models.
 *
 * A proxy model does not store data, but presents data from a source
 * model in another way. It may provide filtering, sorting, or other
 * computed changes to the source model. A proxy model may be a fully
 * functional model, that also allows modification of the underlying
 * model.
 *
 * This abstract proxy model may be used as a starting point for
 * implementing a custom proxy model, when WSortFilterProxyModel is
 * not adequate. It implements data access and manipulation using the
 * a virtual mapping method (mapToSource()) to access and manipulate
 * the underlying sourceModel().
 *
 * \ingroup modelview
 */
class WAbstractProxyModel : public WAbstractItemModel
{
public:
  /*! \brief Constructor.
   */
  WAbstractProxyModel(WObject *parent = 0);

  /*! \brief Map a source model index to the proxy model.
   *
   * This method returns a model index in the proxy model that
   * corresponds to the model index <i>sourceIndex</i> in the source
   * model. This method must only be implemented for source model
   * indexes that are mapped and thus are the result of mapToSource().
   *
   * \sa mapToSource()
   */
  virtual WModelIndex mapFromSource(const WModelIndex& sourceIndex) const = 0;

  /*! \brief Map a proxy model index to the source model.
   *
   * This method returns a model index in the source model that
   * corresponds to the proxy model index <i>proxyIndex</i>.
   *
   * \sa mapFromSource()
   */
  virtual WModelIndex mapToSource(const WModelIndex& proxyIndex) const = 0;

  /*! \brief Set a source model.
   *
   * The source model provides the actual data for the proxy
   * model.
   *
   * Ownership of the source model is <i>not</i> transferred.
   */
  virtual void setSourceModel(WAbstractItemModel *sourceModel);

  /*! \brief Returns the source model.
   *
   * \sa setSourceModel()
   */
  WAbstractItemModel *sourceModel() const { return sourceModel_; }

  virtual boost::any data(const WModelIndex& index, int role = DisplayRole)
    const;
  virtual bool setData(const WModelIndex& index, const boost::any& value,
		       int role = EditRole);

  virtual int flags(const WModelIndex& index) const;

  virtual bool setHeaderData(int section, Orientation orientation,
			     const boost::any& value,
			     int role = EditRole);
  virtual boost::any headerData(int section,
				Orientation orientation = Horizontal,
				int role = DisplayRole) const;

  virtual bool insertColumns(int column, int count,
			     const WModelIndex& parent = WModelIndex());
  virtual bool insertRows(int row, int count,
			  const WModelIndex& parent = WModelIndex());
  virtual bool removeColumns(int column, int count,
			     const WModelIndex& parent = WModelIndex());
  virtual bool removeRows(int row, int count,
			  const WModelIndex& parent = WModelIndex());

  virtual std::string mimeType() const;
  virtual std::vector<std::string> acceptDropMimeTypes() const;

  virtual void dropEvent(const WDropEvent& e, DropAction action,
			 int row, int column, const WModelIndex& parent);

  virtual void *toRawIndex(const WModelIndex& index) const;
  virtual WModelIndex fromRawIndex(void *rawIndex) const;

  using WAbstractItemModel::setData;
  using WAbstractItemModel::data;
  using WAbstractItemModel::setHeaderData;

private:
  WAbstractItemModel     *sourceModel_;
};

}

#endif // WSORT_FILTER_PROXY_MODEL_H_
