/***************************************************************************
 *   Copyright (C) 2003 by S�astien Laot                                 *
 *   slaout@linux62.org                                                    *
 *                                                                         *
 *   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 Street, Fifth Floor, Boston, MA  02110-1301, USA.             *
 ***************************************************************************/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <tqlayout.h>
//#include <tdetoolbarbutton.h>
#include <tqtoolbutton.h>
#include <tqlabel.h>
//#include <tqcombobox.h>
//#include <klineedit.h>
#include <kiconloader.h>
#include <tdelocale.h>
#include <tdeglobalsettings.h>
#include <tdeapplication.h>
#include <kiconloader.h>
#include <tqpixmap.h>
#include <tqimage.h>
#include <tqpainter.h>
#include <tqbitmap.h>
#include <kdialogbase.h>

#include "filter.h"
//#include "settings.h"
#include "global.h"
#include "bnpview.h"
#include "tools.h"
#include "tag.h"
#include "focusedwidgets.h"

/** FilterBar */

FilterBar::FilterBar(TQWidget *parent, const char *name)
 : TQWidget(parent, name)/*, m_blinkTimer(this), m_blinkedTimes(0)*/
{
	TQHBoxLayout *hBox  = new TQHBoxLayout(this, /*margin*/0, /*spacing*/0);

	// Create every widgets:
	TQIconSet resetIconSet = kapp->iconLoader()->loadIconSet("locationbar_erase", TDEIcon::Toolbar);
	TQIconSet inAllIconSet = kapp->iconLoader()->loadIconSet("edit-find",         TDEIcon::Toolbar);


	m_resetButton        = new TQToolButton(this);
	m_resetButton->setIconSet(resetIconSet);
	m_resetButton->setTextLabel(i18n("Reset Filter"));//, /*groupText=*/"", this, TQT_SLOT(reset()), 0);
	m_resetButton->setAutoRaise(true);
			//new TDEToolBarButton("locationbar_erase", /*id=*/1230, this, /*name=*/0, i18n("Reset Filter"));
	m_lineEdit           = new FocusedLineEdit(this);
	TQLabel *label        = new TQLabel(m_lineEdit, i18n("&Filter: "), this);
	m_tagsBox            = new FocusedComboBox(this);
	TQLabel *label2       = new TQLabel(m_tagsBox, i18n("T&ag: "), this);
	m_inAllBasketsButton = new TQToolButton(this);
	m_inAllBasketsButton->setIconSet(inAllIconSet);
	m_inAllBasketsButton->setTextLabel(i18n("Filter all Baskets"));//, /*groupText=*/"", this, TQT_SLOT(inAllBaskets()), 0);
	m_inAllBasketsButton->setAutoRaise(true);

	// Configure the Reset button:
	m_resetButton->setEnabled(false);

	// Configure the Tags combobox:
	repopulateTagsComnbo();

	// Configure the Serach in all Baskets button:
	m_inAllBasketsButton->setToggleButton(true);
//	m_inAllBasketsButton->setOn(true);
//	Global::bnpView->toggleFilterAllBaskets(true);

//	m_lineEdit->setMaximumWidth(150);

	// Layout all those widgets:
//	hBox->addStretch();
	hBox->addWidget(m_resetButton);
	hBox->addSpacing(KDialogBase::spacingHint());
	hBox->addWidget(label);
	hBox->addWidget(m_lineEdit);
	hBox->addSpacing(KDialogBase::spacingHint());
	hBox->addWidget(label2);
	hBox->addWidget(m_tagsBox);
	hBox->addSpacing(KDialogBase::spacingHint());
	hBox->addWidget(m_inAllBasketsButton);

	m_data = new FilterData(); // TODO: Not a pointer! and return a const &  !!

//	connect( &m_blinkTimer,         TQT_SIGNAL(timeout()),                   this, TQT_SLOT(blinkBar())                  );
	connect(  m_resetButton,        TQT_SIGNAL(clicked()),                   this, TQT_SLOT(reset())                     );
	connect(  m_lineEdit,           TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(textChanged(const TQString&)) );
	connect(  m_tagsBox,            TQT_SIGNAL(activated(int)),              this, TQT_SLOT(tagChanged(int))             );

//	connect(  m_inAllBasketsButton, TQT_SIGNAL(clicked()),                   this, TQT_SLOT(inAllBaskets())              );
	connect(  m_inAllBasketsButton, TQT_SIGNAL(toggled(bool)), Global::bnpView, TQT_SLOT(toggleFilterAllBaskets(bool)) );

	connect( m_lineEdit, TQT_SIGNAL(escapePressed()),  this, TQT_SIGNAL(escapePressed()) );
	connect( m_lineEdit, TQT_SIGNAL(returnPressed()),  this, TQT_SIGNAL(returnPressed()) );
	connect( m_tagsBox,  TQT_SIGNAL(escapePressed()),  this, TQT_SIGNAL(escapePressed()) );
	connect( m_tagsBox,  TQT_SIGNAL(returnPressed2()), this, TQT_SIGNAL(returnPressed()) );
}

FilterBar::~FilterBar()
{
}

void FilterBar::setFilterAll(bool filterAll)
{
	m_inAllBasketsButton->setOn(filterAll);
}

void FilterBar::setFilterData(const FilterData &data)
{
	m_lineEdit->setText(data.string);

	int index = 0;
	switch (data.tagFilterType) {
		default:
		case FilterData::DontCareTagsFilter: index = 0; break;
		case FilterData::NotTaggedFilter:    index = 1; break;
		case FilterData::TaggedFilter:       index = 2; break;
		case FilterData::TagFilter:          filterTag(data.tag);     return;
		case FilterData::StateFilter:        filterState(data.state); return;
	}

	if (m_tagsBox->currentItem() != index) {
		m_tagsBox->setCurrentItem(index);
		tagChanged(index);
	}
}

void FilterBar::repopulateTagsComnbo()
{
	static const int ICON_SIZE = 16;

	m_tagsBox->clear();
	m_tagsMap.clear();
	m_statesMap.clear();

	m_tagsBox->insertItem("",                   0);
	m_tagsBox->insertItem(i18n("(Not tagged)"), 1);
	m_tagsBox->insertItem(i18n("(Tagged)"),     2);

	int index = 3;
	Tag     *tag;
	State   *state;
	TQString  icon;
	TQString  text;
	TQPixmap  emblem;
	for (Tag::List::iterator it = Tag::all.begin(); it != Tag::all.end(); ++it) {
		tag   = *it;
		state = tag->states().first();
		// Insert the tag in the combo-box:
		if (tag->countStates() > 1) {
			text = tag->name();
			icon = "";
		} else {
			text = state->name();
			icon = state->emblem();
		}
		emblem = kapp->iconLoader()->loadIcon(icon, TDEIcon::Desktop, ICON_SIZE, TDEIcon::DefaultState, 0L, /*canReturnNull=*/true);
		m_tagsBox->insertItem(emblem, text, index);
		// Update the mapping:
		m_tagsMap.insert(index, tag);
		++index;
		// Insert sub-states, if needed:
		if (tag->countStates() > 1) {
			for (State::List::iterator it2 = tag->states().begin(); it2 != tag->states().end(); ++it2) {
				state = *it2;
				// Insert the state:
				text = state->name();
				icon = state->emblem();
				emblem = kapp->iconLoader()->loadIcon(icon, TDEIcon::Desktop, ICON_SIZE, TDEIcon::DefaultState, 0L, /*canReturnNull=*/true);
				// Indent the emblem to show the hierarchy relation:
				if (!emblem.isNull())
					emblem = Tools::indentPixmap(emblem, /*depth=*/1, /*deltaX=*/2 * ICON_SIZE / 3);
				m_tagsBox->insertItem(emblem, text, index);
				// Update the mapping:
				m_statesMap.insert(index, state);
				++index;
			}
		}
	}
}

void FilterBar::reset()
{
	m_lineEdit->setText(""); // m_data->isFiltering will be set to false;
	if (m_tagsBox->currentItem() != 0) {
		m_tagsBox->setCurrentItem(0);
		tagChanged(0);
	}
}

void FilterBar::filterTag(Tag *tag)
{
	int index = 0;

	for (TQMap<int, Tag*>::Iterator it = m_tagsMap.begin(); it != m_tagsMap.end(); ++it)
		if (it.data() == tag) {
			index = it.key();
			break;
		}
	if (index <= 0)
		return;

	if (m_tagsBox->currentItem() != index) {
		m_tagsBox->setCurrentItem(index);
		tagChanged(index);
	}
}

void FilterBar::filterState(State *state)
{
	int index = 0;

	for (TQMap<int, State*>::Iterator it = m_statesMap.begin(); it != m_statesMap.end(); ++it)
		if (it.data() == state) {
			index = it.key();
			break;
		}
	if (index <= 0)
		return;

	if (m_tagsBox->currentItem() != index) {
		m_tagsBox->setCurrentItem(index);
		tagChanged(index);
	}
}

void FilterBar::inAllBaskets()
{
	// TODO!
}

void FilterBar::setEditFocus()
{
	m_lineEdit->setFocus();
}

bool FilterBar::hasEditFocus()
{
	return m_lineEdit->hasFocus();
}

const FilterData& FilterBar::filterData()
{
	return *m_data;
}

void FilterBar::textChanged(const TQString &text)
{
	m_data->string = text;
	m_data->isFiltering = (!m_data->string.isEmpty() || m_data->tagFilterType != FilterData::DontCareTagsFilter);
	m_resetButton->setEnabled(m_data->isFiltering);
	emit newFilter(*m_data);
}

void FilterBar::tagChanged(int index)
{
	m_data->tag   = 0;
	m_data->state = 0;
	switch (index) {
		case 0:
			m_data->tagFilterType = FilterData::DontCareTagsFilter;
			break;
		case 1:
			m_data->tagFilterType = FilterData::NotTaggedFilter;
			break;
		case 2:
			m_data->tagFilterType = FilterData::TaggedFilter;
			break;
		default:
			// Try to find if we are filtering a tag:
			TQMapIterator<int, Tag*> it = m_tagsMap.find(index);
			if (it != m_tagsMap.end()) {
				m_data->tagFilterType = FilterData::TagFilter;
				m_data->tag           = *it;
			} else {
				// If not, try to find if we are filtering a state:
				TQMapIterator<int, State*> it2 = m_statesMap.find(index);
				if (it2 != m_statesMap.end()) {
					m_data->tagFilterType = FilterData::StateFilter;
					m_data->state         = *it2;
				} else {
					// If not (should never happens), do as if the tags filter was reseted:
					m_data->tagFilterType = FilterData::DontCareTagsFilter;
				}
			}
			break;
	}
	m_data->isFiltering = (!m_data->string.isEmpty() || m_data->tagFilterType != FilterData::DontCareTagsFilter);
	m_resetButton->setEnabled(m_data->isFiltering);
	emit newFilter(*m_data);
}

#include "filter.moc"
