// 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 WT_API WAbstractProxyModel : public WAbstractItemModel
{
public:
  /*! \brief Constructor.
   */
  WAbstractProxyModel(WObject *parent = 0);

  /*! \brief Maps a source model index to the proxy model.
   *
   * This method returns a model index in the proxy model that
   * corresponds to the model index \p sourceIndex 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 Maps 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 \p proxyIndex.
   *
   * \sa mapFromSource()
   */
  virtual WModelIndex mapToSource(const WModelIndex& proxyIndex) const = 0;

  /*! \brief Sets the 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 WFlags<ItemFlag> flags(const WModelIndex& index) 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;

#ifndef WT_CNOR
  using WAbstractItemModel::setHeaderData;
#endif // WT_CNOR

protected:
  /*! \brief Create a source model index.
   *
   * This is a utility function that allows you to create indexes in
   * the source model. In this way, you can reuse the internal pointers of
   * the source model in proxy model indexes, and convert a proxy model index
   * back to the source model index using this method.
   */
  WModelIndex createSourceIndex(int row, int column, void *ptr) const;

private:
  WAbstractItemModel     *sourceModel_;
};

}

#endif // WSORT_FILTER_PROXY_MODEL_H_
