/***************************** 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 <QDebug>
#include <QIcon>

#include "MvQKeyProfileModel.h"

#include "MvQKeyMimeData.h"
#include "MvKeyProfile.h"

bool MvQKeyProfileSortFilterModel::lessThan ( const QModelIndex &left, const QModelIndex &right) const
{
 	QString leftData = sourceModel()->data(left).toString();
     	QString rightData = sourceModel()->data(right).toString();

	//Sort as int
	if(QString::number(leftData.toInt()) == leftData)
	{
		return leftData.toInt() < rightData.toInt();
	}
	else if(QString::number(leftData.toFloat()) == leftData)
	{
		return leftData.toFloat() < rightData.toFloat();
	}
	else
	{
		return QString::localeAwareCompare(leftData, rightData) < 0;	
	}
}

MvQKeyProfileModel::MvQKeyProfileModel()
{
	profile_=0;
}

bool MvQKeyProfileModel::isDataSet() const
{
	return (profile_ == 0) ? false : true;		
}

void MvQKeyProfileModel::keyProfileIsAboutToChange()
{
	beginResetModel();
}

void MvQKeyProfileModel::setKeyProfile(MvKeyProfile *prof)
{
#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
	//beginResetModel();
#endif
	profile_=prof;

	messageFilterStatus_.clear();
	if(profile_)
	{
		for(unsigned int i=0; i < profile_->valueNum(0); i++)
		{
			messageFilterStatus_.push_back(true);
		}
	}
	
	//loadKeyFilter();
	//Reset the model (views will be notified)
#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
	endResetModel(); 
#endif
}

void MvQKeyProfileModel::setKeyFilter(MvQKeyFilter filter)
{
#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
	beginResetModel();
#endif
	filter_=filter;

	loadKeyFilter();

	//Reset the model (views will be notified)
#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
	endResetModel(); 
#endif
}



int MvQKeyProfileModel::columnCount( const QModelIndex& /* parent */ ) const
{
   	if(!isDataSet())
		return 0;
	
	return profile_->size();
}

int MvQKeyProfileModel::rowCount( const QModelIndex& index) const
{
    	if(!isDataSet())
		return 0;

	if (!index.isValid() )
	{
		return  profile_->valueNum(0);
	}
	else
	{
		return 0;
	}
}

QVariant MvQKeyProfileModel::data( const QModelIndex& index, int role ) const
{
    	if ( !index.isValid())
	{
		return QVariant();
	}
	else if(role == Qt::UserRole )
	{
		if(messageFilterStatus_[index.row()] == true)
			return QString("1");
		else
			return QString("0");	
	
	}
	else if(role == Qt::TextAlignmentRole)
	{
		if(profile_->at(index.column())->name() == "MV_Value")
			return Qt::AlignRight;

		else
			return QVariant();
	}
	else if(role != Qt::DisplayRole )
        {	
		return QVariant();
	}
   


	return label(index.row(),index.column());
}


QVariant MvQKeyProfileModel::headerData( const int section, const Qt::Orientation orient , const int role ) const
{
    	if ( !isDataSet() || orient != Qt::Horizontal || 
	    (role != Qt::DisplayRole && role != Qt::ToolTipRole && role != Qt::DecorationRole) ||
	     section < 0 || section >= profile_->size())
	{
        	return QAbstractItemModel::headerData( section, orient, role );
	}

 	if(section < 0 || section >= profile_->size())
	{
		return QVariant();
	}

	if(role == Qt::DisplayRole )
	{
		if(profile_->at(section)->name() == "MV_Value")
		{
			
		}
		
		return QString(profile_->at(section)->shortName().c_str());
	}
	else if(role == Qt::ToolTipRole)
	{
		QString desc(profile_->at(section)->description().c_str());
			
		if(profile_->at(section)->name() == "MV_Value")
		{
			string xv=profile_->at(section)->metaData("x_coord");
			string yv=profile_->at(section)->metaData("y_coord");
			
			QString s("key: ");
			s+=QString(profile_->at(section)->name().c_str()) + "\n";
			s+=desc + "\n";
			s+="x: " + QString::fromStdString(xv) + "\n" +
			   "y: "  + QString::fromStdString(yv);
			
			return s;
		}

		if(profile_->at(section)->name().find("MV_") != string::npos)
		{	
			//QString str="MV key: "  + QString(profile_->at(section)->name().c_str()) +  "\n";
			//str += desc;
			return desc;
		}

		//GRIB
		if(desc.isEmpty())
		{
			QString str("GRIB API key: \n");
			str.append(profile_->at(section)->name().c_str());
			return str;
		}
		
		//BUFR
		QString sec(profile_->at(section)->metaData("section").c_str());
		if(!sec.isEmpty())
		{
			QString centre(profile_->at(section)->metaData("centre").c_str());
			QString s=desc +  "\n(Section: " + sec;
			if(!centre.isEmpty())
			{
				s+=" Centre: " + centre;  
			}
			s+=")";
			return s;
		}
		else
		{
			return desc;
		}
	}
	else if(role == Qt::DecorationRole)
	{
		QString str(profile_->at(section)->name().c_str());
		if(filter_.contains(str))
		{
			return QIcon(QString::fromUtf8(":/examiner/keyFilter"));
		}
		else 
			return QVariant();
	}

	return QVariant();
}

QString MvQKeyProfileModel::label(const int row, const int column ) const
{
	if(!isDataSet() || row < 0 || row >= profile_->valueNum(0) || column < 0 || column >= profile_->size())
	{
		return QString();
	}
	
	//qDebug() << "label" << row << column ;

	//qDebug() << "   " << QString::fromStdString(profile_->at(column)->value().at(row));

	//string id=profile_->at(column)->name();
	//return QString(grib_->message().at(row)->getKeyData(id).c_str());


	return QString(profile_->at(column)->value().at(row).c_str());
}

QModelIndex MvQKeyProfileModel::index( int row, int column, const QModelIndex & parent ) const
{
   	if(!isDataSet()) 
	{
		return QModelIndex();
	}

	return createIndex(row,column,(void*)0);
}


QModelIndex MvQKeyProfileModel::parent( const QModelIndex & index ) const
{
    return QModelIndex();
}

void MvQKeyProfileModel::loadKeyFilter()
{
	int num=profile_->valueNum(0);

	messageFilterStatus_.clear();

	for(unsigned int i=0; i <num; i++)
	{
		messageFilterStatus_.push_back(true);

		QMapIterator<QString, QStringList> it(filter_);
 		while (it.hasNext()) 
		{
     			it.next();
			MvKey *key=profile_->key(it.key().toStdString());
			if(key)
			{
				if(it.value().contains(QString(key->value().at(i).c_str())) == false)
				{
					messageFilterStatus_[i]=false;
					break;
				}
			}
		}
	}
 }

Qt::ItemFlags MvQKeyProfileModel::flags ( const QModelIndex & index) const
{
	Qt::ItemFlags defaultFlags;

	defaultFlags=Qt::ItemIsEnabled |
		   Qt::ItemIsSelectable;

	return Qt::ItemIsDropEnabled | defaultFlags;
}

Qt::DropActions MvQKeyProfileModel::supportedDropActions() const
{
	return Qt::CopyAction;
}

QStringList MvQKeyProfileModel::mimeTypes() const
 {
	QStringList types;
    	types << "metview/mvkey";
    	return types;
 }

QMimeData* MvQKeyProfileModel::mimeData(const QModelIndexList &indexes) const
{
	return QAbstractItemModel::mimeData(indexes);
}

bool MvQKeyProfileModel::dropMimeData(const QMimeData *data,
     Qt::DropAction action, int row, int column, const QModelIndex &parent)
{
	if(!profile_)
		return false;

	if (action == Qt::IgnoreAction)
        	return true;

     	if (!data->hasFormat("metview/mvkey"))
        	return false;

	const MvQKeyMimeData *keyData=qobject_cast<const MvQKeyMimeData*>(data);

	if(!keyData || keyData->keys().isEmpty())
		return false;

	//Dnd from a key model --> insert new column
	if(keyData->model() != this)
	{
		//qDebug() << "other";	
		beginResetModel();
		QMapIterator<int,MvKey*> it(keyData->keys());
		while(it.hasNext()) 
		{
     			it.next();
			MvKey *key=it.value()->clone();	
			profile_->addKey(key);
			if(parent.isValid() && parent.column() >= 0 && parent.column() < profile_->size()-1)
			{
			  	profile_->reposition(profile_->size()-1,parent.column()+1);				
			}	
		}

		emit keyInserted();

		endResetModel();		
	}

     	return true;
}

