#ifndef GAMEUI_ENGINE_H
#define GAMEUI_ENGINE_H

/*
 * Backend engine for game installer UI
 *
 * Copyright (C) 2003--2007  Enrico Zini <enrico@debian.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <ept/apt/apt.h>
#include <ept/debtags/debtags.h>
#include <ept/debtags/vocabulary.h>
#include <xapian.h>
#include <string>
#include <set>
#include <vector>

namespace ept {
namespace apt {
class Apt;
}
}

struct Result
{
	std::string name;
	float popcon;
	int relevance;
	bool operator<(const Result& r) const
	{
		return name < r.name;
	}
};

class Engine
{
public:
	enum State { ANY, INSTALLED, NOTINSTALLED };

protected:
	/// Apt data provider
	ept::apt::Apt m_apt;

	/// Debtags data provider
	ept::debtags::Debtags m_debtags;

	/// Vocabulary data provider
	ept::debtags::Vocabulary m_vocabulary;

	/// Xapian data provider
	Xapian::Database m_db;

	/// Xapian stemmer
	Xapian::Stem m_stem;

	/// Xapian query parser
	Xapian::QueryParser m_qp;

	std::string m_filter_keywords;
	std::string m_filter_type;
	std::string m_filter_iface;
	Engine::State m_filter_state;

	bool m_dirty;

	std::vector<Result> m_results;
	std::set<std::string> m_types;
	std::set<std::string> m_interfaces;

	float m_max;
	float m_res_max;

	int m_popcon_validx;

	Xapian::Query makeQuery();
	void recompute();

	float read_popcon(const Xapian::Document& doc) const;

public:
	/// Facet to use as the main package type
	std::string mainFacet;

	/// Facet to use as the secondary package type
	std::string secondaryFacet;

	/// Global filter that is ANDed to all queries
	Xapian::Query globalFilter;

	Engine();

	/// Access the apt data provider
	ept::apt::Apt& apt() { return m_apt; }

	/// Access the debtags data provider
	ept::debtags::Debtags& debtags() { return m_debtags; }

	/// Access the tag vocabulary
	ept::debtags::Vocabulary& voc() { return m_vocabulary; }

	/// Check if popcon data is available
	bool hasPopcon() const { return m_popcon_validx != -1; }

	/// Get the list of available game types
	const std::set<std::string>& types()
	{
		if (m_dirty) recompute();
		return m_types;
	}

	/// Get the list of available interfaces
	const std::set<std::string>& interfaces()
	{
		if (m_dirty) recompute();
		return m_interfaces;
	}

	/// Get the resulting list of packages
	const std::vector<Result>& results()
	{
		if (m_dirty) recompute();
		return m_results;
	}

	/// Get a list of packages similar to the given one
	std::vector<Result> related(const std::string& name, int count = 10) const;

	/// Get the maximum popcon score in the result set
	float popconLocalMax() const { return m_res_max; }

	/// Get the maximum popcon score seen so far
	float popconMax() const { return m_max; }

	/**
	 * Set the keyword filter from the given string (which will be tokenized
	 * and stemmed properly)
	 */
	void setKeywordFilter(const std::string& keywords = std::string());

	/**
	 * Set the game type filter
	 */
	void setTypeFilter(const std::string& tag = std::string());

	/**
	 * Set the interface type filter
	 */
	void setInterfaceFilter(const std::string& tag = std::string());

	/**
	 * Set the installed state filter
	 */
	void setInstalledFilter(Engine::State state = ANY);

	/**
	 * Get the current value of the installed filter
	 */
	Engine::State getInstalledFilter() const { return m_filter_state; }
};

// vim:set ts=4 sw=4:
#endif
