/***************************************************************************
 *   Copyright (C) 2005 by xavier helluy   *
 *   xavier.helluy@web.de   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA.             *
 ***************************************************************************/

#include "cluceneguisearch.h"
#include <klineedit.h>
#include <kpushbutton.h> 
#include <qpushbutton.h> 
#include <kapplication.h>
#include <kdebug.h>
#include <qpoint.h>
#include <qstringlist.h>
#include <qlabel.h>



///-/////////////// dialog scrollview manager /////////////////////////////-///

// modified from kpovmodeler pmdialogview.cpp
CLuceneGuiSearchHelper::CLuceneGuiSearchHelper( QWidget* parent, const char* name)
	: QScrollView( parent, name ), m_minimumWidth(0), m_minimumHeight(0), m_convenienceWidth(0),m_initGUI(TRUE), m_booleanSearchOn(FALSE)

{
	setVScrollBarMode( QScrollView::AlwaysOff );
	setHScrollBarMode( QScrollView::AlwaysOff );
	setFrameStyle( QFrame::Panel | QFrame::Sunken );
	setLineWidth( 0 );
	setMargins( 0, 0, 0, 0 );
	
	//more than one widget in the scrollview make qt have undefine behavior ???
	//the contents stays the size set by resizeContents().
	setResizePolicy(QScrollView::Manual);
	
	QSizePolicy qSizePolicy(QSizePolicy::MinimumExpanding,QSizePolicy::MinimumExpanding,FALSE);
	this->setSizePolicy(qSizePolicy);
	this->viewport()->setSizePolicy(qSizePolicy);
	
	this->viewport()->setBackgroundMode(QWidget::PaletteBackground);
	
	
	
	//create content layout
	a = new QWidget(viewport());
	layoutA = new QVBoxLayout(a);
	layoutA->setResizeMode(QLayout::Minimum);
	//create a layout holding all the query-field.
	layoutB = new QVBoxLayout(layoutA);
	layoutB->setResizeMode(QLayout::FreeResize);

	layoutB->setSpacing(20);
	layoutA->setSpacing(0);

// 	layoutA->addLayout(layoutB);
	layoutA->addStretch ( 0 );
	

	connect(this , SIGNAL(sizeChanged(int)) , this, SLOT(calculateSize()));
}


void CLuceneGuiSearchHelper::slotAddQueryFieldBelow()
{
	slotAddQueryField( tr2i18n( "Any string" ));
}


void CLuceneGuiSearchHelper::slotAddQueryField(QString pluginName)
{
	kdDebug() << "CLuceneGuiSearchHelper::addQueryField CALLED"  << pluginName << endl;
	
	int num;
	if ( m_queryFieldList.isEmpty() )
	{
		num = -1;
	}
	else
	{
		num = m_queryFieldList.count()-1 ;
	}
	num++;
	QString name = "Name" +QString::number(num+1);
	m_queryFieldList.append( 
			new QueryField(a, num+1 , m_convenienceWidth, name )
			       );
	
	QueryField * f = m_queryFieldList.at(num);
	
	f->setItemNum(num+1);
	if (m_booleanSearchOn)
	{
		f->m_queryFieldBase->number->setText(QString::number(num+1));
	}

	
	if ((num != 0) )
	{
		if (! m_queryFieldList.at(0)->m_queryFieldManager->removeQueryField->isShown() )
		{
			m_queryFieldList.at(0)->m_queryFieldManager->removeQueryField->setShown(TRUE);
		}
		
		m_queryFieldList.at(num-1)->m_queryFieldManager->addQueryFieldBelow->setShown(FALSE);
	}
	
	//adds the required plugin
	f->slotCreatePlugin( pluginName );
	layoutB->addWidget( f );
	
	if ( !(f->isShown()) )
		f->setShown( TRUE );

	//the testsmall big HACK to help find a suitable geometry when the dialog starts
	if (m_initGUI==FALSE)
	{
		this->calculateSize();
	}
	else
	{
		//do init
		kdDebug() << "CLuceneGuiSearchHelper::addQueryField FIRST INIT"  << pluginName << endl;

		m_initGUI = FALSE;
		//scrollbar calulation is useless I guess
		getMinWidthAndMinHeight();
		kdDebug() << "CLuceneGuiSearchHelper::addQueryField FIRST INITm_minimumWidth"  << m_minimumWidth<< endl;
// 		a->setMinimumSizeHint(QSize(m_minimumWidth,m_minimumHeight));
		a->updateGeometry();
		this->resize(m_minimumWidth,m_minimumHeight);
		f->m_queryFieldManager->removeQueryField->setShown(FALSE);
	}
	
	connect( f->m_queryFieldManager->addQueryFieldBelow, SIGNAL (clicked()), 
		 this, SLOT( slotAddQueryFieldBelow() ));
	connect( f, SIGNAL(removeQueryFieldClicked(int )) ,  
		 this, SLOT( slotRemoveQueryField(int) ));
	//used when the user changes the query-mainfield of a query-field widget
	connect(f , SIGNAL(minimumSizeChanged()) ,this, SLOT(calculateSize()));
}

void CLuceneGuiSearchHelper::slotRemoveQueryField(int itemNum)
{
	kdDebug() << "CLuceneGuiSearchHelper::removeField iteNum:"  << endl;
	
	//the "real" query-field id to remove
	int ref = itemNum -1;
	layoutB->remove(m_queryFieldList.at(ref));
	m_queryFieldList.setAutoDelete(TRUE);
	m_queryFieldList.remove( ref );//FIXME;autodelete
	
	int MaxRef = m_queryFieldList.count() - 1;
	
	int newItemNum = itemNum ;
	QueryField * mf;
	//update the id-number of the fields
	for (mf = m_queryFieldList.at(ref ) ; mf ; mf = m_queryFieldList.next() )
	{
		mf->setItemNum(newItemNum);
		if (m_booleanSearchOn)
		{
			mf->m_queryFieldBase->number->setText(QString::number(newItemNum));
		}
		newItemNum++;
	}
	
	//update the remove-addBelow buttons
	m_queryFieldList.at(MaxRef)->m_queryFieldManager->addQueryFieldBelow->setShown(TRUE);
	if (MaxRef == 0)
	{
		m_queryFieldList.at(MaxRef)->m_queryFieldManager->removeQueryField->setShown(FALSE);
	}
	
	//why not
	this->calculateSize();
	
}

//adapted from kpovmodeler, but this doesn't work for me
void CLuceneGuiSearchHelper::calculateSize( )
{
	kdDebug() << "CLuceneGuiSearchHelper::calculateSize() CALLED"  << endl;
	
	//minimum size of the scroll-content:
	//    query-field widgets size calculated from main.cpp and
	//    getMinWidthAndMinHeight at the begining
	kdDebug() << "CLuceneGuiSearchHelper::calculateSize() miniW"  << m_minimumWidth <<endl;
	kdDebug() << "CLuceneGuiSearchHelper::calculateSize() miniH"  << m_minimumHeight <<endl;
	
	//height of the contents
	m_contentWidth 		= m_minimumWidth;
	m_contentHeight 	= layoutB->sizeHint().height();
	if (m_contentHeight< m_minimumHeight)
	{
		kdDebug() << "CLuceneGuiSearchHelper::calculateSize() MINIH : "  << endl;

		//we have few fields but want some free space
		m_contentHeight = m_minimumHeight;
	}

	QSize newSize( m_contentWidth,m_contentHeight); 
	
	kdDebug() << "CLuceneGuiSearchHelper::calculateSize() QSIZE : "  << newSize << endl;

	//size "allowed" by the current window size
	//FIXME: the resize events don't always resize the Qscollview
	m_convenienceWidth  = geometry().width()-2*lineWidth();
	m_convenienceHeight = geometry().height()-2*lineWidth();
	//HACK
// 	m_convenienceHeight = layoutB->sizeHint().height();
	

	
	kdDebug() << "CLuceneGuiSearchHelper::calculateSize() thisGeo"  	<< geometry()<<endl;
	kdDebug() << "CLuceneGuiSearchHelper::calculateSize() viewGeo"  	<< viewport()->geometry()<<endl;
	kdDebug() << "CLuceneGuiSearchHelper::calculateSize() thisGeoHint"  	<< sizeHint()<<endl;
	kdDebug() << "CLuceneGuiSearchHelper::calculateSize() thisGeoMinHint"  	<< minimumSizeHint()<<endl;

	kdDebug() << "CLuceneGuiSearchHelper::calculateSize() viewGeoHint"  	<< viewport()->sizeHint()<<endl;

	kdDebug() << "CLuceneGuiSearchHelper::calculateSize() pGeo"      << parentWidget()->geometry()<<endl;
	kdDebug() << "CLuceneGuiSearchHelper::calculateSize() pGeoHint"  << parentWidget()->sizeHint()<<endl;

	kdDebug() << "CLuceneGuiSearchHelper::calculateSize() layAHint"  << layoutA->sizeHint()<<endl;
	kdDebug() << "CLuceneGuiSearchHelper::calculateSize() layBHint"  << layoutB->sizeHint()<<endl;
	kdDebug() << "CLuceneGuiSearchHelper::calculateSize() layAHgeo"  << layoutA->geometry()<<endl;
	kdDebug() << "CLuceneGuiSearchHelper::calculateSize() layBHgeo"  << layoutB->geometry()<<endl;
	kdDebug() << "CLuceneGuiSearchHelper::calculateSize() layAHgeo"  << layoutA->minimumSize()<<endl;
	kdDebug() << "CLuceneGuiSearchHelper::calculateSize() a        "  << a->sizeHint()<<endl;
	
	setVScrollBarMode( AlwaysOff );
	setHScrollBarMode( AlwaysOff );
	setVScrollBarMode( AlwaysOff );
	setHScrollBarMode( AlwaysOff );
	setMargins( 0, 0, 0, 0 );
	
	m_convenienceWidth  = geometry().width()-2*lineWidth();
	m_convenienceHeight = geometry().height()-2*lineWidth();

	if(  m_convenienceWidth  < m_contentWidth )
	{
		kdDebug() << "CLuceneGuiSearchHelper::calculateSize() A"  <<endl;

		setHScrollBarMode( AlwaysOn );
		m_convenienceHeight = m_convenienceHeight - horizontalScrollBar( )->height( );
		if( m_convenienceHeight   < m_contentHeight )
		{
			kdDebug() << "CLuceneGuiSearchHelper::calculateSize() B"  <<endl;
			setVScrollBarMode( AlwaysOn );
		}
		else
		{
			kdDebug() << "CLuceneGuiSearchHelper::calculateSize() C"  <<endl;
			newSize.setHeight( m_convenienceHeight );
		}
	}
	else if( m_convenienceHeight < m_contentHeight )
	{
		kdDebug() << "CLuceneGuiSearchHelper::calculateSize() D"  <<endl;
		setVScrollBarMode( AlwaysOn );
		m_convenienceWidth = m_convenienceWidth - horizontalScrollBar( )->height( );
		if( m_convenienceWidth <  m_contentWidth)
		{
			kdDebug() << "CLuceneGuiSearchHelper::calculateSize() E"  <<endl;
			setHScrollBarMode( AlwaysOn );
		}
		else
		{
			kdDebug() << "CLuceneGuiSearchHelper::calculateSize() F"  <<endl;

			newSize.setWidth(m_convenienceWidth );
		}
	}
	else
	{
		kdDebug() << "CLuceneGuiSearchHelper::calculateSize() G"  <<endl;

		newSize.setWidth( m_convenienceWidth );
		newSize.setHeight( m_convenienceHeight );
	}
	
	resizeContents( newSize.width( ), newSize.height( ) );
	a->resize( newSize.width( ), newSize.height( ));
	kdDebug() << "CLuceneGuiSearchHelper::calculateSize() QSIZE resized: "  << newSize << endl;
}

//FIXME:do complete rewrite 
void CLuceneGuiSearchHelper::getMinWidthAndMinHeight()
{
	QSize sizeLayoutA = layoutA->sizeHint();
	QSize sizeLayoutB = layoutB->sizeHint();
	kdDebug() << "CLuceneGuiSearchHelper::updateQueryFieldDisplay():sizeLayoutA "<< sizeLayoutA<<endl;
	kdDebug() << "CLuceneGuiSearchHelper::updateQueryFieldDisplay():sizeLayoutB "<< sizeLayoutB<<endl;
	
	QueryField * mf;
// 	int maxAllmin(0);
// 	int maxAllconv(0);
	int maxAllnewWidth(0);
	int maxAllnewHeight(0);

	//FIXME: normaly there should be only one item, but the function had been written
	//in a different context for the mamy-items case.
	for (mf = m_queryFieldList.first() ; mf ; mf = m_queryFieldList.next() )
	{
		kdDebug() << "CLuceneGuiSearchHelper::updateQueryFieldDisplay() UPDATE FIELD GEOMETRY: "<< endl;
		if (maxAllnewWidth < mf->m_newWidth)
		{
			maxAllnewWidth =  mf->m_newWidth;
		}
		if ( maxAllnewHeight< mf->m_newHeight)
		{
			maxAllnewHeight =  mf->m_newHeight;
		}
	}
	
	if ( m_minimumWidth + horizontalScrollBar( )->height( ) < maxAllnewWidth + horizontalScrollBar( )->height( ))
	{
		//new m_minimumWidth found
		m_minimumWidth = maxAllnewWidth;// + horizontalScrollBar( )->height( );
	}
	
	// calculate minHeight: at least 5* one field and conven
	int count = m_queryFieldList.count();
// 	int dim(0);
	//FIXME:check it is not bigger than the screen
	if (count>0)
	{
		QRect rect = m_queryFieldList.last()->geometry();
		this->m_minimumHeight = rect.height()*(7);
	}
	else
	{
		//an arbitrary guess
		m_minimumHeight = 200;
	}
	
	kdDebug() << "CLuceneGuiSearchHelper::updateQueryFieldDisplay()  m_minimumHeight"<< m_minimumHeight<<endl;
	
// 	this->setMinimumSize(m_minimumWidth , m_minimumHeight);

}


void CLuceneGuiSearchHelper::resizeEvent( QResizeEvent*  /*ev*/  )
{
	kdDebug() << "CLuceneGuiSearchHelper::resizeEvent() CALLED Geo: "<< this->geometry()<<endl;
	
	calculateSize();
}
/*
//setup minimum size of the qscrollview
QSize CLuceneGuiSearchHelper::minimumSizeHint ()
{
	QSize lsize = QSize(m_minimumWidth, m_minimumHeight);
	kdDebug() << "CLuceneGuiSearchHelper::minimumSizeHint() CAAAAAAAAAAAAAAAAAAAALLLLLLLLLED: "<< lsize<<endl;
	

	//add the scollbar size here maybe
	return lsize;
}

//setup prefered size of the qscrollview
QSize CLuceneGuiSearchHelper::sizeHint ()
{
	kdDebug() << "CLuceneGuiSearchHelper::sizeHint() CAAAAAAAAAAAAAAAAAAAALLLLLLLLLED: "<< endl;

	return minimumSizeHint ();
}*/

#include "cluceneguisearchhelper.moc"

