/*! @file

    @id $Id$
*/
//       1         2         3         4         5         6         7         8
// 45678901234567890123456789012345678901234567890123456789012345678901234567890

#ifndef CARDGUI_MODEL_HXX
#define CARDGUI_MODEL_HXX

#include <cardos.hxx>

#include <QtCore/QAbstractItemModel>
#include <QtGui/QFont>

class CardGuiModel: public QAbstractItemModel {
    
    Q_OBJECT;

  public:
    
    CardGuiModel(cardos::Commands& cmd, const std::string& path):
        _rootItem(cmd, path) {
    }

    QVariant data(const QModelIndex &index, int role) const {
      if (!index.isValid()) return QVariant();
      cardos::Object* o(static_cast<cardos::Object*>(index.internalPointer()));
      switch (role) {
        case Qt::TextAlignmentRole:
          return Qt::AlignTop;
         case Qt::FontRole:
           if (index.column() == 2) {
             QFont f("Monospaced");
             f.setStyleHint(QFont::TypeWriter);
             return f;
           } else return QVariant();
        case Qt::DisplayRole:
          switch (index.column()) {
            case 0: return QString::fromStdString(o->logicalName());
            case 1: return QString::fromStdString(o->name());
            case 3: return QString::fromStdString(o->contentInfo());
            case 2: if (o->content().size())
              return QString::fromStdString(crypto::readable(o->content()));
            default: return QVariant();
          }
        default: return QVariant();
      }
    }
    
    Qt::ItemFlags flags(const QModelIndex &index) const {
      if (!index.isValid()) return 0;
      return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    }
   
    QVariant headerData(int section, Qt::Orientation orientation,
                        int role = Qt::DisplayRole) const {
      if (orientation!=Qt::Horizontal || role!=Qt::DisplayRole)
        return QVariant();
      switch (section) {
        case 0: return "Object";
        case 1: return "ID";
        case 3: return "Logical Content";
        case 2: return "Binary Content";
        default: return QVariant();
      }
    }
    
    QModelIndex index(int row, int column,
                      const QModelIndex &parent = QModelIndex()) const {
      if (!hasIndex(row, column, parent)) return QModelIndex();
      const cardos::Object* parentItem(0);
      if (!parent.isValid())
        parentItem = &_rootItem;
      else
        parentItem = static_cast<cardos::Object*>(parent.internalPointer());
      if (row<parentItem->size())
        return
          createIndex(row, column, &(*parentItem->children().at(row)));
      return QModelIndex();
    }

    std::pair<const cardos::Object*, int> scan(const cardos::Object& o,
                                               const cardos::Object* c) const {
      int i(0);
      for (cardos::Object::Children::const_iterator it(o.children().begin());
           it!=o.children().end(); ++it, ++i) {
        if (it->get()==c) return std::make_pair(&o, i);
        std::pair<const cardos::Object*, int> res(scan(**it, c));
        if (res.first) return res;
      }
      return std::make_pair((const cardos::Object*)0, 0);
    }
   
    QModelIndex parent(const QModelIndex &index) const {
      if (!index.isValid()) return QModelIndex();
      cardos::Object* childItem
        (static_cast<cardos::Object*>(index.internalPointer()));
      if (childItem==&_rootItem) return QModelIndex();
      std::pair<const cardos::Object*, int>
        parentItem(scan(_rootItem, childItem));
      if (!parentItem.first) return QModelIndex();
      return createIndex(parentItem.second, 0,
                         const_cast<cardos::Object*>(parentItem.first));
    }
    
    int rowCount(const QModelIndex &parent = QModelIndex()) const  {
      if (parent.isValid() && parent.internalPointer())
        return static_cast<cardos::Object*>(parent.internalPointer())->size();
      else
        return _rootItem.size();
    }

    int columnCount(const QModelIndex &parent = QModelIndex()) const {
      return 4;
    }
        
  protected:
    cardos::Dir _rootItem;
};

#endif
