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

 Copyright 2012 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 <QAction>
#include <QDebug>
#include <QHeaderView>
#include <QInputDialog>
#include <QMenu>
#include <QMessageBox>

#include "MvQKeyDialog.h"
#include "MvQKeyProfileTree.h"
 
#include "MvKeyProfile.h"

#include "MvQKeyProfileModel.h"

MvQKeyProfileTree::MvQKeyProfileTree(MvQKeyProfileModel *messageModel,
				     MvQKeyProfileSortFilterModel *filterModel)
{
	messageModel_=messageModel;
	messageSortModel_=filterModel;
	
	//Message model
	/*messageModel_= new MvQKeyProfileModel;
	messageSortModel_= new MvQKeyProfileSortFilterModel;
        messageSortModel_->setSourceModel(messageModel_);
	messageSortModel_->setDynamicSortFilter(true);
	messageSortModel_->setFilterRole(Qt::UserRole);
	//messageSortModel_->setFilterRegExp(QRegExp("[1]"));
	messageSortModel_->setFilterFixedString("1");
	messageSortModel_->setFilterKeyColumn(0);*/

	predefinedKeysOnly_=false;
	
	//Tree
	editable_=true;
	setObjectName("messageTree");
	setProperty("mvStyle",0);
	setSortingEnabled(true); 
	sortByColumn (0,Qt::AscendingOrder); 
	setAlternatingRowColors(true);
        setAllColumnsShowFocus(true);
	setModel(messageSortModel_);	
	//messageTree_->header()->setContextMenuPolicy(Qt::CustomContextMenu);
	setActvatedByKeyNavigation(true);
	setAcceptDrops(true);
	setDragDropMode(QAbstractItemView::DropOnly);
	setRootIsDecorated(false);

	//Set header ContextMenuPolicy
	header()->setContextMenuPolicy(Qt::CustomContextMenu);

	connect(header(),SIGNAL(customContextMenuRequested(const QPoint &)),
                this, SLOT(slotMessageTreeContextMenu(const QPoint &)));

	connect(header(),SIGNAL(sectionMoved(int,int,int)),
                this, SLOT(slotMessageTreeColumnMoved(int,int,int)));
}

void MvQKeyProfileTree::setEditable(bool b)
{
	editable_=b;

	if(editable_)
	{	
		setAcceptDrops(true);
		setDragDropMode(QAbstractItemView::DropOnly);
#ifdef METVIEW_QT5		
		header()->setSectionsMovable(true);
#else
		header()->setMovable(true);
#endif
	}	
	else
	{
		setAcceptDrops(false);
		setDragDropMode(QAbstractItemView::NoDragDrop);
#ifdef METVIEW_QT5		
		header()->setSectionsMovable(false);
#else
		header()->setMovable(false);
#endif
	}
}

void MvQKeyProfileTree::slotMessageTreeContextMenu(const QPoint &position)
{
	if(!editable_)
		return;

	int section=header()->logicalIndexAt(position); 
	
	if(section< 0 || section >= header()->count())
		return;

       	MvKeyProfile* prof = messageModel_->keyProfile();
	if(prof==0 || section >= static_cast<int>(prof->size()))
		return;

		
	QList<QAction*> actions;

	//Inser new key
	QAction *actionInsert = new QAction(this);
        actionInsert->setObjectName(QString::fromUtf8("actionInsert"));
	actionInsert->setText(tr("Insert key"));
        //actionDelete->setShortcut(tr("Ctrl+D"));
	actions.append(actionInsert);
	
	//Check if users can define keys
	if(predefinedKeysOnly_)
	{	
		actionInsert->setEnabled(false);
	}
	
	//Edit
	
#ifdef METVIEW_EXPERIMENTAL
	bool keyEditable=prof->at(section)->editable();
	QAction *actionEdit;
	if(keyEditable)
	{
	  	actionEdit = new QAction(this);
       		actionEdit->setObjectName(QString::fromUtf8("actionEdit"));
		actionEdit->setText(tr("Edit key"));
        	//actionRename->setShortcut(tr("Ctrl+L"));	
		actions.append(actionEdit);
	}	
#endif

	QAction *actionDelete = new QAction(this);
        actionDelete->setObjectName(QString::fromUtf8("actionDelete"));
	actionDelete->setText(tr("Delete key"));
        //actionDelete->setShortcut(tr("Ctrl+D"));
	actions.append(actionDelete);

	//Rename
	QAction *actionRename = new QAction(this);
        actionRename->setObjectName(QString::fromUtf8("actionRename"));
	actionRename->setText(tr("Rename header"));
        //actionRename->setShortcut(tr("Ctrl+L"));
	actions.append(actionRename);
	
    	if(actions.count() > 0)
	{
        	QAction *action=QMenu::exec(actions, header()->mapToGlobal(position));

		if(action == actionInsert)
		{			
         		insertMessageTreeColumn(section);				
		}
		else if(action == actionRename)
		{			
         		renameMessageTreeHeader(section);				
		}
		else if(action == actionDelete)
		{
			deleteMessageTreeColumn(section);
		}
#ifdef METVIEW_EXPERIMENTAL
		else if(keyEditable && 
		        action == actionEdit)
		{			
         		editMessageTreeHeader(section);				
		}
#endif
	}
	
	foreach(QAction *action,actions)
	{
		delete action;
	}
}


void MvQKeyProfileTree::insertMessageTreeColumn(int column)
{
	MvKey *key = new MvKey;	
	MvQKeyEditDialog keyDialog(key);

	if(keyDialog.exec()  == QDialog::Accepted)
	{  
		//Get the current profile from the model.
		messageModel_->keyProfileIsAboutToChange();
		MvKeyProfile* prof = messageModel_->keyProfile();
		
		if(column >=0 && column < static_cast<int>(prof->size()))
		{		
			prof->addKey(key);
			prof->reposition(prof->size()-1,column+1);		
			messageModel_->setKeyProfile(prof);
			emit profileChanged(true);

		}
	}	
}

void MvQKeyProfileTree::editMessageTreeHeader(int column)
{
	if(!editable_)
		return;

	MvKeyProfile* prof = messageModel_->keyProfile();
	if(prof==0 || column < 0 || column >= static_cast<int>(prof->size()))
		return;
	
	string name=prof->at(column)->name();

	MvQKeyEditDialog edit(prof->at(column));
	if(edit.exec()  == QDialog::Accepted)
	{
		//If the key name was not changed
		if(name == prof->at(column)->name())
		{
			messageModel_->keyProfileIsAboutToChange();
			//prof->at(column)->setShortName(text.toStdString());
			messageModel_->setKeyProfile(prof);

			emit profileChanged();
		}
		else
		{
			emit profileChanged(true);
		}
	}

}	

void MvQKeyProfileTree::renameMessageTreeHeader(int column)
{
	if(!editable_)
		return;

	MvKeyProfile* prof = messageModel_->keyProfile();
		if(column < 0 || column >= static_cast<int>(prof->size()))
			return;
		
	bool ok;
     	QString text = QInputDialog::getText(0, 
				tr("Rename header"),
                        	tr("New name:"), QLineEdit::Normal,
                                prof->at(column)->shortName().c_str(), &ok);
				
	if (ok && !text.isEmpty())
        { 			
		messageModel_->keyProfileIsAboutToChange();
		prof->at(column)->setShortName(text.toStdString());
		messageModel_->setKeyProfile(prof);
		emit profileChanged();
	}
}	

void MvQKeyProfileTree::deleteMessageTreeColumn(int column)
{	
	if(!editable_)
		return;

	MvKeyProfile* prof = messageModel_->keyProfile();
	if(column < 0 || column >= static_cast<int>(prof->size()))
		return;

	QMessageBox msgBox;

	QString str=tr("Are you sure that you want to delete key <b>");
	str+=QString::fromStdString(prof->at(column)->name()) ;
	str+="</b>?";

 	msgBox.setText(str);
 	msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
	msgBox.setDefaultButton(QMessageBox::Cancel);
	msgBox.setWindowTitle(tr("Delete key"));
	
	int ret=msgBox.exec();

	switch (ret) 
	{
   	case QMessageBox::Yes:
       	{	
		messageModel_->keyProfileIsAboutToChange();
		prof->deleteKey(column);
		messageModel_->setKeyProfile(prof);
		emit profileChanged();
	}
      	break;
   	case QMessageBox::Cancel:
       	// Cancel was clicked
       	break;
   	default:
       	// should never be reached
      	 break;
	}
}	

void  MvQKeyProfileTree::slotMessageTreeColumnMoved(int logicalIndex, int oldVisualIndex, int newVisualIndex)
{
	if(logicalIndex != oldVisualIndex)
	{
		qDebug() << "MvQGribExaminerBase::slotMessageTreeColumnMoved> problem with column indices!"; 
	}

	MvKeyProfile* prof = messageModel_->keyProfile();
	if(oldVisualIndex >=0 && oldVisualIndex < static_cast<int>(prof->size()) &&
	   newVisualIndex >=0 && newVisualIndex < static_cast<int>(prof->size()) &&
	   oldVisualIndex != newVisualIndex)
	{
		//for(int i=0; i < messageTree_->header()->count(); i++)
		//	qDebug() << "header: (" << i << ") " << messageTree_->header()->logicalIndex(i);

		prof->reposition(oldVisualIndex,newVisualIndex);

		//We need it because 
		//	- QHeaderView::reset() does not initialize the 
		//         the logicalindeces
		//      - But if the column count is changes the 
		//         logicalIndeces are reinitialized
		messageModel_->keyProfileIsAboutToChange();
		messageModel_->setKeyProfile(0); 

		messageModel_->keyProfileIsAboutToChange();
		messageModel_->setKeyProfile(prof);

		for(int i=0;i < messageModel_->columnCount()-1; i++)
		{ 
			resizeColumnToContents(i);
		}

		emit profileChanged();
	}
}
