#ifndef WIDENTITY_PROXY_MODEL_H_
#define WIDENTITY_PROXY_MODEL_H_

#include <vector>

#include <Wt/WAbstractProxyModel>
#include <Wt/WSignalMapper>

namespace Wt {

class WT_API WIdentityProxyModel : public WAbstractProxyModel
{
public:
  WIdentityProxyModel(WObject *parent = 0);
  virtual ~WIdentityProxyModel();

  int columnCount(const WModelIndex &parent = WModelIndex()) const;
  WModelIndex index(int row, int column, const WModelIndex &parent = WModelIndex()) const;
  WModelIndex mapFromSource(const WModelIndex &sourceIndex) const;
  WModelIndex mapToSource(const WModelIndex &proxyIndex) const;
  WModelIndex parent(const WModelIndex &child) const;
  int rowCount(const WModelIndex &parent = WModelIndex()) const;

  void setSourceModel(WAbstractItemModel *sourceModel);

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

  /* I think these two should go into the base class, in Qt at least they do.
     Same holds for others not implemented here: setHeaderData() ... */
  void sort(int column, SortOrder order);
  boost::any headerData(int section,
			Orientation orientation = Horizontal,
			int role = DisplayRole) const;
private:
  class DefaultModel;

  std::vector<Wt::Signals::connection> modelConnections_;

  void sourceColumnsAboutToBeInserted(const WModelIndex &parent, int start, int end);
  void sourceColumnsAboutToBeRemoved(const WModelIndex &parent, int start, int end);
  void sourceColumnsInserted(const WModelIndex &parent, int start, int end);
  void sourceColumnsRemoved(const WModelIndex &parent, int start, int end);
  void sourceRowsAboutToBeInserted(const WModelIndex &parent, int start, int end);
  void sourceRowsAboutToBeRemoved(const WModelIndex &parent, int start, int end);
  void sourceRowsInserted(const WModelIndex &parent, int start, int end);
  void sourceRowsRemoved(const WModelIndex &parent, int start, int end);
  void sourceDataChanged(const WModelIndex &topLeft, const WModelIndex &bottomRight);
  void sourceHeaderDataChanged(Orientation orientation, int start, int end);
  void sourceLayoutAboutToBeChanged();
  void sourceLayoutChanged();
  void sourceModelReset();
};

} // namespace Wt

#endif // #ifndef WIDENTITY_PROXY_MODEL_H_

