/***************************** 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 <QAbstractItemModel>
#include <QComboBox>
#include <QDebug>
#include <QHBoxLayout>
#include <QHeaderView>
#include <QLabel>
#include <QLineEdit>
#include <QTreeView>

#include "MvQTreeViewSearchLine.h"

MvQTreeViewSearchLine::MvQTreeViewSearchLine(QTreeView *view,int searchColumn,QString searchLabelText) :
	MvQAbstractSearchLine(searchLabelText), view_(view), searchColumn_(searchColumn)
{
	connect(view_->model(),SIGNAL(modelReset()),
		this,SLOT(slotUpdateColumns()));
	
	connect(view_->header(),SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
		this,SLOT(slotSortingHappened(int,Qt::SortOrder)));	
		
	connect(this,SIGNAL(indexSelected(const QModelIndex&)),
		view_,SIGNAL(clicked(const QModelIndex&)));
		
	label_->setText(tr("&Find in column:"));
	
	currentResultItem_=0;	
	
	for(int i=0; i < view_->model()->columnCount(); i++)
	{
	  	columns_[view_->model()->headerData(i,Qt::Horizontal).toString()]=i;
	}	

	columnCb_=new QComboBox;
	columnCb_->setSizeAdjustPolicy(QComboBox::AdjustToContents);
	
	qDebug() << "layout count" << layout_->count();
	
	for(int index=0; index < layout_->count(); index++)
	{
	  	qDebug() << "layout count" << layout_->count();
		
		if(layout_->itemAt(index)->widget() == searchLine_)
		{  
			layout_->insertWidget(index,columnCb_);  //!!!!!!!!
			break;
		}
	}	
	
	columnCb_->addItems(columns_.keys());

	int i=0;
	foreach(QString s,columns_.keys())
	{
		if(columns_[s]==searchColumn_)
		{
			columnCb_->setCurrentIndex(i);
		}
		
		i++;	
	}
	
	connect(columnCb_, SIGNAL(currentIndexChanged(const QString&)), 
		this, SLOT(slotSearchColumnChanged(const QString&)));		
}


MvQTreeViewSearchLine::~MvQTreeViewSearchLine()
{

}

void MvQTreeViewSearchLine::clear()
{
	currentResultItem_=0;
	resultItems_.clear();
	
	MvQAbstractSearchLine::clear();
}	
  
void MvQTreeViewSearchLine::slotFind(QString txt)
{
	if(txt.simplified().isEmpty())
	{
	 	currentResultItem_=0;
		resultItems_.clear();
		updateButtons(false);
		return;
	}	
  
  	QModelIndex current=view_->currentIndex();
	if(!current.isValid())
		current=view_->model()->index(0,0);
		
	current=view_->model()->index(current.row(),searchColumn_,current.parent());
	
  	resultItems_=view_->model()->match(current,
			    Qt::DisplayRole,txt,-1,
		            Qt::MatchStartsWith | Qt::MatchRecursive | Qt::MatchWrap);
  
	if(resultItems_.count() > 0)
	{
		selectIndex(resultItems_[0]);
		currentResultItem_=0;
		updateButtons(true);
	}  
	else
	{  
	  	currentResultItem_=0;
		updateButtons(false);
	}	
	
}

void MvQTreeViewSearchLine::slotFindNext()
{
	if(status_==true && resultItems_.count() > 0)
	{
		currentResultItem_++;
		if(currentResultItem_ >= resultItems_.count())	
		{
		  	currentResultItem_=0;
		}
		selectIndex(resultItems_[currentResultItem_]);
	}
}

void MvQTreeViewSearchLine::slotFindPrev()
{
	if(status_==true && resultItems_.count() > 0)
	{
		currentResultItem_--;
		if(currentResultItem_ <0)	
		{
		  	currentResultItem_=resultItems_.count()-1;
		}
		selectIndex(resultItems_[currentResultItem_]);
	}
}

void MvQTreeViewSearchLine::slotSearchColumnChanged(const QString& text)
{
	if(columns_.find(text) != columns_.end())
	{
	  	if(columns_[text] != searchColumn_)
		{
		  	searchColumn_=columns_[text];
			clear();
		}	
			
	}
}

void MvQTreeViewSearchLine::slotUpdateColumns()	
{		
	//Check if columns have changed
	if(columns_.size() == view_->model()->columnCount())
	{  
		bool equal=true;
		for(int i=0; i < view_->model()->columnCount(); i++)
		{
  			QString s=view_->model()->headerData(i,Qt::Horizontal).toString();
			if(columns_.find(s) == columns_.end() || 
			   columns_[s] != i)
			{
			  	equal=false;
				break;
			}
		}
		if(equal)
		{
		  	slotFindNext();
			return;
		}			
	}	
			  
  	//If the columns have changed reset everything

	QString searchColumnName;
	foreach(QString s,columns_.keys())
	{
		if(columns_[s] == searchColumn_)
		{
			searchColumnName=s;
			break;
		}
	}
	
	columns_.clear();	
	for(int i=0; i < view_->model()->columnCount(); i++)
	{
	  	QString s=view_->model()->headerData(i,Qt::Horizontal).toString();
		
		columns_[s]=i;
		if(searchColumnName==s)
		{
			searchColumn_=i;
		}	
	}

	if(searchColumn_ <0 || searchColumn_ >= view_->model()->columnCount())
	{
		searchColumn_=0;
	}	
		
	columnCb_->disconnect(SIGNAL(currentIndexChanged(const QString&)));
	columnCb_->clear();
	
	columnCb_->addItems(columns_.keys());

	int i=0;
	foreach(QString s,columns_.keys())
	{
		if(columns_[s]==searchColumn_)
		{
			columnCb_->setCurrentIndex(i);
		}
		
		i++;	
	}
	
	connect(columnCb_, SIGNAL(currentIndexChanged(const QString&)), 
		this, SLOT(slotSearchColumnChanged(const QString&)));		


	clear();
}


void MvQTreeViewSearchLine::slotSortingHappened(int,Qt::SortOrder)
{
	if(isVisible())
		slotFind(searchLine_->text());	  
}  

void MvQTreeViewSearchLine::selectIndex(const QModelIndex& index)
{
	view_->setCurrentIndex(index);
	emit indexSelected(index);
}