/***************************** LICENSE START ***********************************

 Copyright 2013 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#include "MvQLayerSuperPage.h"

//#include <QDebug>

#include <QAction>
#include <QDropEvent>
#include <QMenu>

#include "Assertions.hpp"
#include "Root.h"

//==================================================================
//
//	MvQLayerSuperPageModel
//
//==================================================================

MvQLayerSuperPageModel::MvQLayerSuperPageModel (QObject* parent) :
     QAbstractItemModel(parent)
{}  

MvQLayerSuperPageModel::~MvQLayerSuperPageModel()
{
   icons_.clear();
}

int MvQLayerSuperPageModel::columnCount( const QModelIndex& parent) const
{
//if ( parent.isValid() )
//   qDebug() << "MvQLayerSuperPageModel::columnCount 0";
//else
//      qDebug() << "MvQLayerSuperPageModel::columnCount 1";

   return parent.isValid() ? 0 : 1;
}

int MvQLayerSuperPageModel::rowCount( const QModelIndex& index) const
{
   if (!index.isValid() )
      return  icons_.count();
   else
      return  0;
}

QVariant MvQLayerSuperPageModel::data( const QModelIndex& index, int role ) const
{
   if( role != Qt::DisplayRole && role != Qt::DecorationRole  &&
       role != Qt::ForegroundRole &&  role != Qt::UserRole  &&
       role != Qt::FontRole )
      return QVariant();

   if( !index.isValid() )
      return QVariant();

   if( index.row() < 0 || index.row() >= icons_.count() )
      return QVariant();

   MvQLayerContentsIcon icon = icons_[index.row()];

//qDebug() << "MvQLayerSuperPageModel::data " << icon.name() << icon.type() << icon.id();

   switch(role)
   {
      case Qt::DecorationRole:
      { //qDebug() << "DecorationRole";
         return icon.pixmap();
      }

      case Qt::DisplayRole:
      { //qDebug() << "DisplayRole";
         return icon.name();
      }

//      case Qt::UserRole:
//         return icon->path();
      default:
      { //qDebug() << "default";
         break;
      }
   }

   return QVariant();	  
}


QModelIndex MvQLayerSuperPageModel::index( int row, int column, const QModelIndex& /*parent */) const
{
   return createIndex(row,column,(void*)0);
}

QModelIndex MvQLayerSuperPageModel::parent( const QModelIndex & /*index*/ ) const
{
   return QModelIndex();
}

void MvQLayerSuperPageModel::setIcons(MvIconList& iconList)
{
   // Clear current list of icons
   beginResetModel();
   icons_.clear();

   // Add new icons
   MvListCursor lCursor = iconList.begin();
   while (lCursor != iconList.end())
   {
      MvIcon mvicon = *lCursor;
      MvQLayerContentsIcon icon( QString(mvicon.IconName()), QString(mvicon.IconClass()), QString::number(mvicon.Id()) );

      icons_ << icon;   
      ++lCursor;
   }
         
   endResetModel();
}

MvQLayerContentsIcon* MvQLayerSuperPageModel::indexToIcon(const QModelIndex& index)
{
   MvQLayerContentsIcon* icon = 0;
   if( !index.isValid() || index.column() < 0 || index.column() > icons_.count() )
      return icon;

   icon = &icons_[index.row()];

   return icon;
}

#if 0
bool MvQLayerSuperPageModel::add( const MvQLayerContentsIcon& icon )
{
   if( icons_.contains(icon) )
      return false;

   beginResetModel();
   icons_ << icon;
   endResetModel();

   return true;
}

void MvQLayerSuperPageModel::remove( const MvQLayerContentsIcon& icon )
{
   beginResetModel();
   icons_.removeAll(icon);
   endResetModel();
}
#endif

void MvQLayerSuperPageModel::reset()
{
   // Get Presentable SuperPage and the DataBase
   Presentable* pres = Root::Instance().FindSuperPage();
   assert(pres != 0);  // Root::Instance().FindSuperPage() can return a NULL pointer
   MvIconDataBase& dataBase = pres->IconDataBase();

   // Retrieve icons from the DataBase
   MvIconList iconList;
   dataBase.RetrieveIcon(presentableId(),iconList);

   // Update list of icons
   setIcons(iconList);
}

//=================================================================
//
//	MvQLayerSuperPageView
//
//=================================================================

MvQLayerSuperPageView::MvQLayerSuperPageView (MvQLayerSuperPageModel* model, QWidget *parent) : 
      QListView(parent),
      model_(model)
{
   // Set behaviour
   setViewMode(QListView::IconMode);
   setFlow(QListView::LeftToRight);
   setMovement(QListView::Snap);
   setWrapping(false);
   setResizeMode(QListView::Adjust);
//   setIconSize(QSize(48, 48));
//   setMaximumHeight(75);
   setSpacing(5);

   QFont font;
   QFontMetrics fm(font);
   setMaximumHeight(fm.size(Qt::TextExpandTabs,"A").height()+32+10+5+10);

   // Double click
   connect(this,SIGNAL(doubleClicked(QModelIndex)),
           this,SLOT(slotDoubleClickItem(QModelIndex)));

   // Context menu
   createContextMenu();
   setContextMenuPolicy(Qt::ActionsContextMenu);
//   connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
//           this, SLOT(slotContextMenu(const QPoint&)));

   // Drag and Drop settings
   setMouseTracking(true);
   setAcceptDrops(true);
   setDragEnabled(true);
   setDropIndicatorShown(true);
   setDragDropMode(QAbstractItemView::DragDrop);

   setModel(model);
}

MvQLayerSuperPageView::~MvQLayerSuperPageView()
{
   foreach(QAction *ac,actions_)
   {
      delete ac;
      ac = 0;
   }
}

void  MvQLayerSuperPageView::slotDoubleClickItem (const QModelIndex& index)
{
   if( !index.isValid() )
      return;

   // Get icon from the model
   MvQLayerContentsIcon *icon = model_->indexToIcon(index);
   if(!icon)
      return;

   // Start editor
   icon->startEditor();
}

#if 0
void MvQLayerSuperPageView::slotContextMenu(const QPoint& pos)
{
   // Get index from position
   QModelIndex index = this->indexAt(pos); 
   if( !index.isValid() )
      return;

   // Get icon from the model
   MvQLayerContentsIcon *icon = model_->indexToIcon(index);
   if(!icon)
      return;

   //Insert new key
   QList<QAction*> actions;
   QAction *actionEdit = new QAction(this);
   actionEdit->setObjectName(QString::fromUtf8("actionEdit"));
   actionEdit->setText(tr("Edit in Plot"));
   QFont font = actionEdit->font();
   font.setWeight(QFont::Bold);
   actionEdit->setFont(font);
   actionEdit->setShortcut(QKeySequence(tr("Ctrl+E")));
   actions.append(actionEdit);
   if(!icon->canBeEdited())
      actionEdit->setEnabled(false); 

   //Inser new key
   QAction *actionSave = new QAction(this);
   actionSave->setObjectName(QString::fromUtf8("actionSave"));
   actionSave->setText(tr("Save to Disk"));
//   actionSave->setShortcut(QKeySequence(QKeySequence::Save));
   actionSave->setShortcut(QKeySequence::Save);
   actions.append(actionSave);
   if(!icon->canBeSaved())
      actionSave->setEnabled(false); 

   QAction *actionDelete = new QAction(this);
   actionDelete->setObjectName(QString::fromUtf8("actionDelete"));
   actionDelete->setText(tr("Remove from Plot"));
   actionDelete->setShortcuts(QKeySequence::Delete);
   actions.append(actionDelete);
   if(!icon->canBeDeleted())
      actionDelete->setEnabled(false); 

   QAction *res = QMenu::exec(actions,this->mapToGlobal(pos));   
   if(res == actionEdit)
      icon->startEditor();
   else if(res == actionSave)
      icon->saveIcon();
   else if(res == actionDelete)
      icon->deleteIcon();

   foreach(QAction *ac,actions)
      delete ac;
}
#else
void MvQLayerSuperPageView::createContextMenu()
{
   // Insert Edit key
   actionEdit_ = new QAction(this);
   actionEdit_->setObjectName(QString::fromUtf8("actionEdit"));
   actionEdit_->setText(tr("Edit in Plot"));
   QFont font = actionEdit_->font();
   font.setWeight(QFont::Bold);
   actionEdit_->setFont(font);
   actionEdit_->setShortcut(tr("Ctrl+E"));
   actionEdit_->setShortcutContext(Qt::WidgetWithChildrenShortcut);
   actions_.append(actionEdit_);
   
   addAction(actionEdit_);
   connect(actionEdit_, SIGNAL(triggered()), this, SLOT(slotEdit()));

   // Insert Save key
   actionSave_ = new QAction(this);
   actionSave_->setObjectName(QString::fromUtf8("actionSave"));
   actionSave_->setText(tr("Save to Disk"));
   actionSave_->setShortcut(QKeySequence::Save);
   actionSave_->setShortcutContext(Qt::WidgetWithChildrenShortcut);
   actions_.append(actionSave_);

   addAction(actionSave_);
   connect(actionSave_, SIGNAL(triggered()), this, SLOT(slotSave()));

   // Insert Delete key
   actionDelete_ = new QAction(this);
   actionDelete_->setObjectName(QString::fromUtf8("actionDelete"));
   actionDelete_->setText(tr("Remove from Plot"));
   actionDelete_->setShortcuts(QKeySequence::Delete);
   actionDelete_->setShortcutContext(Qt::WidgetWithChildrenShortcut);
   actions_.append(actionDelete_);

   addAction(actionDelete_);
   connect(actionDelete_, SIGNAL(triggered()), this, SLOT(slotDelete()));
}

void MvQLayerSuperPageView::currentChanged(const QModelIndex& current, const QModelIndex& previous) 
{
   // Get icon from the model
   MvQLayerContentsIcon *icon = model_->indexToIcon(current);
   if(!icon)
      return;

   // Check options visibility
   bool bvis = icon->canBeEdited() ? true : false;
   actionEdit_->setEnabled(bvis); 

   bvis = icon->canBeSaved() ? true : false;
   actionSave_->setEnabled(bvis); 

   bvis = icon->canBeDeleted() ? true : false;
   actionDelete_->setEnabled(bvis); 

   QListView::currentChanged(current,previous);
}

void MvQLayerSuperPageView::slotEdit()
{
   // Get selected index
   QModelIndex index = currentIndex();

   // Get icon from the model
   MvQLayerContentsIcon *icon = model_->indexToIcon(index);
   if(!icon)
      return;

   // Edit icon
   icon->startEditor();
}

void MvQLayerSuperPageView::slotSave()
{
   // Get selected index
   QModelIndex index = currentIndex();

   // Get icon from the model
   MvQLayerContentsIcon *icon = model_->indexToIcon(index);
   if(!icon)
      return;

   // Save icon
   icon->saveIcon();
}

void MvQLayerSuperPageView::slotDelete()
{
   // Get selected index
   QModelIndex index = currentIndex();

   // Get icon from the model
   MvQLayerContentsIcon *icon = model_->indexToIcon(index);
   if(!icon)
      return;

   // Delete icon
   icon->deleteIcon();
}
#endif

void MvQLayerSuperPageView::dragEnterEvent (QDragEnterEvent* event)
{
   if( (event->proposedAction() == Qt::CopyAction ||
        event->proposedAction() == Qt::MoveAction) )
      event->accept();
   else
      event->ignore();
}

void MvQLayerSuperPageView::dragLeaveEvent (QDragLeaveEvent* event)
{
//   layerId_ = -1;   // initialise with a non-valid value
//   model_->setHighlightedLayer(QModelIndex(),layerId_);
   event->accept();
}

void MvQLayerSuperPageView::dragMoveEvent (QDragMoveEvent* event)
{
   if( (event->proposedAction() == Qt::CopyAction ||
        event->proposedAction() == Qt::MoveAction) )
      event->accept();
   else
      event->ignore();
}

void MvQLayerSuperPageView::dropEvent (QDropEvent* event)
{
   if( event->proposedAction() != Qt::CopyAction &&
       event->proposedAction() != Qt::MoveAction )
   {
      event->ignore();
      return;
   }

   // Get dropped icon
   MvQDrop drop(event);
   if(drop.hasData())
   {
      // Get index from the dropped position (the target icon)
//      QModelIndex index = this->indexAt(event->pos()); 
//      if( !index.isValid() )
//      {
//         cout << "Drop not accepted: MvQLayerView::dropEvent" << endl;
//         return;
//      }

      // To handle the dropped icon
      emit iconDropped(drop);

      event->accept();
      return;
   }
   else
   {
      cout << "dropEvent relayed base class: MvQLayerView::dropEvent" << endl;
      QListView::dropEvent(event);
   }
}
