#include <boost/foreach.hpp>

#include <Wt/WModelIndex>
#include <Wt/WBreak>	// TODO

#include "AudioDatabaseWidget.hpp"

#include "TableFilterWidget.hpp"
#include "SearchFilterWidget.hpp"
#include "TrackWidget.hpp"

AudioDatabaseWidget::AudioDatabaseWidget( Wt::WContainerWidget *parent)
: Wt::WContainerWidget(parent),
 _db("test.db"),	// TODO
_refreshingFilters(false)
{
	std::size_t idFilter (0);
	{
		SearchFilterWidget* search = new SearchFilterWidget(this);
		_filters.push_back( search );
		search->update().connect( boost::bind(&AudioDatabaseWidget::handleFilterUpdated, this, idFilter++) );
	}

	{
		TableFilterWidget* filterTable = new TableFilterWidget(_db, "genre", "name", this);
		_filters.push_back( filterTable );
		filterTable->update().connect( boost::bind(&AudioDatabaseWidget::handleFilterUpdated, this, idFilter++) );
	}
	{
		TableFilterWidget* filterTable = new TableFilterWidget(_db, "artist", "name", this);
		_filters.push_back( filterTable );
		filterTable->update().connect( boost::bind(&AudioDatabaseWidget::handleFilterUpdated, this, idFilter++) );
	}
	{
		TableFilterWidget* filterTable = new TableFilterWidget(_db, "release", "name", this);
		_filters.push_back( filterTable );
		filterTable->update().connect( boost::bind(&AudioDatabaseWidget::handleFilterUpdated, this, idFilter++) );
	}

	{
		TrackWidget* track = new TrackWidget(_db, this);
		_filters.push_back( track );
		track->trackSelected().connect(this, &AudioDatabaseWidget::handleTrackSelected);
	}

}

void
AudioDatabaseWidget::search(const std::string& text)
{
	SearchFilterWidget* searchWidget ( dynamic_cast<SearchFilterWidget*>(_filters.front() ) );

	searchWidget->setText(text);
}


void
AudioDatabaseWidget::handleTrackSelected(boost::filesystem::path p)
{
	_trackSelected.emit(p);
}

void
AudioDatabaseWidget::handleFilterUpdated(std::size_t idFilterUpdated)
{
	// TODO disconnect from event!
	if (_refreshingFilters)
		return;

	_refreshingFilters = true;

	std::cout << "FILTER " << idFilterUpdated << " has been UPDATED!" << std::endl;

	FilterWidget::Constraint currentConstraint;

	currentConstraint.where.And( WhereClause( "track.artist_id = artist.id and track.release_id = release.id and track_genre.track_id = track.id and genre.id = track_genre.genre_id"));

	for (std::size_t idFilter = 0; idFilter < _filters.size(); ++idFilter)
	{
		std::cout << "Processing Filter INDEX " << idFilter << std::endl;
		FilterWidget* filter = _filters.at(idFilter);

		// Apply contraints created by previous filters
		if (idFilter > idFilterUpdated) {
			filter->refresh(currentConstraint);
		}

		// Get constraints generated by this filter
		// (Note: adding accross successive calls)
		filter->getConstraint(currentConstraint);
	}

	_refreshingFilters = false;

}

void
AudioDatabaseWidget::selectNextTrack(void)
{
	std::cout << "Wants to select next track!" << std::endl;

	TrackWidget* trackWidget ( dynamic_cast<TrackWidget*>(_filters.back() ) );

	trackWidget->selectNextTrack();
}



