/***************************** 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 "MvQFolderViewDelegate.h"

#include <QApplication>
#include <QDebug>
#include <QLinearGradient>
#include <QLineEdit>
#include <QPainter>
#include <QStyleOptionViewItem>
#include <QTimer>

#include "MvQFolderModel.h"
#include "MvQTheme.h"

//===========================================
//
//  MvQFolderViewDelegate
//
//===========================================

MvQFolderViewDelegate::MvQFolderViewDelegate(QWidget *parent) : 
      QStyledItemDelegate(parent),
      timer_(0),
      blinkCnt_(-1),
      blinkNum_(5),
      enablePaint_(true)
{ 	
  	setColours("itemview_main");
}

void MvQFolderViewDelegate::setColours(QString group)
{
  	editPen_=QPen(MvQTheme::colour(group,"edit_pen"));
	editBrush_=MvQTheme::brush(group,"edit_brush");
	hoverPen_=QPen(MvQTheme::colour(group,"hover_pen"));
	hoverBrush_=MvQTheme::brush(group,"hover_brush");
	selectPen_=QPen(MvQTheme::colour(group,"select_pen"));
	selectBrush_=MvQTheme::brush(group,"select_brush");
  
}

void MvQFolderViewDelegate::blink(const QModelIndex &index)
{
  	blinkIndex_=index;
	if(!timer_)
	{
	  	timer_ = new QTimer(this);
     		connect(timer_, SIGNAL(timeout()), 
			this, SLOT(slotBlink()));
	}
	
    	blinkCnt_=0;
	timer_->start(150);
}

void  MvQFolderViewDelegate::slotBlink()
{
  	emit repaintIt(blinkIndex_);
	if(blinkCnt_== 2*blinkNum_+1)
	{
	  	timer_->stop();
		blinkIndex_=QModelIndex();
		blinkCnt_=-1;
	}
	else
	  	blinkCnt_++;
}  

QWidget* MvQFolderViewDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
             const QModelIndex &index) const
{
    	if (index.column() == 0) 
    	{
        	QLineEdit *le = new QLineEdit(parent);
        	//timeEdit->setDisplayFormat("mm:ss");
        
		//connect(le,SIGNAL(editingFinished()),
                //	this,SLOT(commitAndCloseEditor()));
		QFont font;
		QFontMetrics fm(font);
		le->setMinimumHeight(fm.height()+10);
		return le;
    	} 
	else
	{
        	return QStyledItemDelegate::createEditor(parent, option, index);
    	}
}

void MvQFolderViewDelegate::setEditorData(QWidget *editor,const QModelIndex &index) const
{
	if(index.column() == 0) 
    	{
        	QLineEdit *le = qobject_cast<QLineEdit *>(editor);
		le->setObjectName("iconLabel");
		QString txt=index.model()->data(index, Qt::EditRole).toString();		
        	le->setText(txt);
		
		QFont font;
		QFontMetrics fm(font);
		le->setMinimumWidth(fm.width(txt)+16);
		
		le->setCursorPosition(0);
		le->deselect();
		
		connect(le,SIGNAL(cursorPositionChanged(int,int)),
			this,SLOT(slotInitEditor(int,int)));
	}
    	else 
	{
        	QStyledItemDelegate::setEditorData(editor, index);
    	}
}

void MvQFolderViewDelegate::setModelData(QWidget *editor,
                                 QAbstractItemModel *model,
                                 const QModelIndex &index) const
{
	if (index.column() == 0) 
	{
        	QLineEdit *le = qobject_cast<QLineEdit *>(editor);              
        	model->setData(index,le->text());
    	} 
    	else 
	{
        	QStyledItemDelegate::setModelData(editor, model, index);
	}
}

void MvQFolderViewDelegate::slotInitEditor(int /*oldPos*/, int /*newPos*/)
{
 	QLineEdit *le = qobject_cast<QLineEdit *>(sender()); 

	le->setCursorPosition(0);
	le->deselect();
	
	le->disconnect(SIGNAL(cursorPositionChanged(int,int)));
} 

void MvQFolderViewDelegate::changeSize(const QModelIndex& index)
{
 	emit sizeHintChanged(index);
	
}  

		
//===========================================
//
//  MvQIconDelegate
//
//===========================================

MvQIconDelegate::MvQIconDelegate(QWidget *parent) : MvQFolderViewDelegate(parent), stripeMode_(false)
{
}

void MvQIconDelegate::setStripeMode(bool b) 
{
  	stripeMode_=b;
	if(stripeMode_)
	  	setColours("itemview_helper");
}

void MvQIconDelegate::paint(QPainter *painter,const QStyleOptionViewItem &option,
		           const QModelIndex& index) const
{
	if(!enablePaint_)
	{
		return;  
	}  
	  
	if(index.column() == 0)
	{
		bool blink=(blinkCnt_ != -1 && (index == blinkIndex_ && blinkCnt_ % 2 ==0));
		
		QStyleOptionViewItemV4 vopt(option);
   		initStyleOption(&vopt, index);
   
    		const QStyle *style = vopt.widget ? vopt.widget->style() : QApplication::style();
    		const QWidget* widget = vopt.widget;

		QString txt=index.data(Qt::DisplayRole).toString();
		QPixmap pixmap=index.data(Qt::DecorationRole).value<QPixmap>();
		
		//Save painter state
		painter->save();
	         
						  
	        QString text=index.data(Qt::DisplayRole).toString();		
		QRect textRect = style->subElementRect(QStyle::SE_ItemViewItemText, &vopt, widget);
		
		//Background
		
		if(blink)
		{  
		  	QRect fillRect=option.rect.adjusted(0,1,-1,-1);
			painter->fillRect(fillRect,Qt::black);
		}
		else if(index.data(MvQFolderModel::EditorRole).toBool())
		{  			
			QRect fillRect=option.rect.adjusted(0,1,-1,-1);
			painter->fillRect(fillRect,editBrush_);
			painter->setPen(editPen_);
			painter->drawRect(fillRect);
		}
		else if(option.state & QStyle::State_Selected)
		{	
			//QRect fillRect=option.rect.adjusted(0,1,-1,-textRect.height()-1);
			QRect fillRect=option.rect.adjusted(0,1,-1,-1);
			painter->fillRect(fillRect,selectBrush_);
			painter->setPen(selectPen_);
			painter->drawRect(fillRect);
		}	
		else if(option.state & QStyle::State_MouseOver)
		{	
			QRect fillRect=option.rect.adjusted(0,1,-1,-1);
			painter->fillRect(fillRect,hoverBrush_);
			painter->setPen(hoverPen_);
			painter->drawRect(fillRect);
		}
		
		//Pixmap
                QRect iconRect = style->subElementRect(QStyle::SE_ItemViewItemDecoration, &vopt, widget);              
		painter->drawPixmap(iconRect,pixmap);
				
		//Text rect
		QFont font = index.data(Qt::FontRole).value<QFont>();   
		painter->setFont(font);
		
		if(blink)
		  	painter->setPen(Qt::white);
		else
			painter->setPen(index.data(Qt::ForegroundRole).value<QColor>());
					
		painter->drawText(textRect,Qt::AlignLeft,text);
		
		painter->restore();			
	}		
	else
	{		
		QStyledItemDelegate::paint(painter,option,index);
	}
}

QSize MvQIconDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
  	QSize s=QStyledItemDelegate::sizeHint(option,index);
	
	//qDebug() << "decoration" <<index.data(Qt::DisplayRole).toString() <<  option.decorationSize;
	
	return s;
}

//===========================================
//
//  MvDetailedViewDelegate
//
//===========================================

MvQDetailedViewDelegate::MvQDetailedViewDelegate(QWidget *parent) : MvQFolderViewDelegate(parent)
{
}

void MvQDetailedViewDelegate::paint(QPainter *painter,const QStyleOptionViewItem &option,
		           const QModelIndex& index) const
{
	if(index.column() <= 5)
	{
		bool blink=(blinkCnt_ != -1 && (index == blinkIndex_ && blinkCnt_ % 2 ==0));
		
		QStyleOptionViewItemV4 vopt(option);
   		initStyleOption(&vopt, index);
   
    		const QStyle *style = vopt.widget ? vopt.widget->style() : QApplication::style();
    		const QWidget* widget = vopt.widget;

		//Save painter state
		painter->save();
				
		//Get current values from model
		QString text=index.data(Qt::DisplayRole).toString();
		QRect textRect = style->subElementRect(QStyle::SE_ItemViewItemText, &vopt, widget);
		
		//Background
		if(index.column()==0)
		{
			QRect fillRect=QRect(option.rect.x(),option.rect.y(),painter->device()->width(),option.rect.height());
			
			if(blink)
			{  
				painter->fillRect(option.rect,Qt::black);
			}
			else if(index.data(MvQFolderModel::EditorRole).toBool())
			{  			
				painter->fillRect(fillRect,editBrush_);
				painter->setPen(editPen_);
				painter->drawLine(fillRect.topLeft(),fillRect.topRight());
				painter->drawLine(fillRect.bottomLeft(),fillRect.bottomRight());			
			}
			else if(option.state & QStyle::State_Selected)
			{	
				//QRect fillRect=option.rect.adjusted(0,1,-1,-textRect.height()-1);			
				painter->fillRect(fillRect,selectBrush_);
				painter->setPen(selectPen_);
				painter->drawLine(fillRect.topLeft(),fillRect.topRight());
				painter->drawLine(fillRect.bottomLeft(),fillRect.bottomRight());
			}	
			else if(option.state & QStyle::State_MouseOver)
			{	
				//QRect fillRect=option.rect.adjusted(0,1,-1,-1);
				painter->fillRect(fillRect,hoverBrush_);
				painter->setPen(hoverPen_);
				painter->drawLine(fillRect.topLeft(),fillRect.topRight());
				painter->drawLine(fillRect.bottomLeft(),fillRect.bottomRight());
			}
		
		}
		
		//Pixmap		
		if(index.column() == 0)
		{
			QPixmap pixmap=index.data(Qt::DecorationRole).value<QPixmap>();
			QRect iconRect = style->subElementRect(QStyle::SE_ItemViewItemDecoration, &vopt, widget);     
			//iconRect.adjust(2,2,-2,-2);							
			painter->drawPixmap(iconRect,pixmap);
		}
	
		
		//Text rect
		QFont font = index.data(Qt::FontRole).value<QFont>();   
		painter->setFont(font);
		if(blink)
			painter->setPen(Qt::white);
		else
		  	painter->setPen(index.data(Qt::ForegroundRole).value<QColor>());
		
		painter->drawText(textRect,Qt::AlignLeft | Qt::AlignVCenter,text);
			
		//restore painter state
		painter->restore();			
	}		
	else
	{		
		QStyledItemDelegate::paint(painter,option,index);
	}
}

QSize MvQDetailedViewDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
	QSize size=QStyledItemDelegate::sizeHint(option,index);
	return size+QSize(0,4);
}