#ifndef KIOAPT_APTPROTOCOL_H
#define KIOAPT_APTPROTOCOL_H

#include <qstring.h>
#include <qcstring.h>

#include <kurl.h>
#include <kio/global.h>
#include <kio/slavebase.h>

#include "debug.h"
#include "aptcache.h"
#include "packagemanager.h"

#include <memory>

class QCString;

namespace Parsers
{
	class Parser;
}

class AptProtocol : public QObject, public KIO::SlaveBase {
  Q_OBJECT

  friend class AptCache;

  AptCache m_process;
  PackageManager* m_pkgmanager;

  typedef QMap<QString, QString> QueryOptions;

  /** This this the URL that should be used if we want
   * to get the same output again. It is especially
   * used in the make_html_form for the command link.
   *
   * The get() method sets it to apt:/command?query
   * the various methods should add the relevant options,
   * that is options which modify the query itself.
   * The GUI-related options (like show_filelist in the
   * show command) should NOT be added
   */
  KURL m_query;

  /** if m_act is false, the ioslave is in browse-only
   * mode (for forbidding install, for instance) */
  bool m_act, m_search, m_internal;

  QString m_stylesheet;
  QString m_header_background;
  QString m_logo;
  QString m_logo_alt;


public:
  AptProtocol( const QCString &pool_socket, const QCString &app_socket );
  virtual ~AptProtocol();
  virtual void mimetype( const KURL& url );
  virtual void get ( const KURL& url );

  /** Sends the string to the ioslave's master
   * SlaveBase::data() sends a byte array as is. Since we
   * definitely don't want to send \0 to the master,
   * we redefine data() for strings */
  void data(const QCString& string);

  /** @overload */
  void data(const QString& string);

  /** @overload */
  void data(const char* string);

	void data(const QByteArray& array);

  KURL buildURL(const QString& command, const QString& query) const;
  KURL buildURL(const KURL& query) const;

  QString stylesheet() const;
  QString header_background() const;
  QString logo() const;
  QString logo_alt() const;

private slots:
  void token_dispatch(const QString& tag, const QString& value);

private:
  std::auto_ptr<Parsers::Parser> m_parser;

  /** apt-cache search
   * Performs apt-cache search, with the query encoded in url.query()
   * and sends the result as an HTML file */
  void search( const QString& url, const QueryOptions& options );

  /** apt-cache show
   * Performs apt-cache search, with the package name encoded in url.query()
   * and sends the result as an HTML file.
   * It checks that the query contains a valid package name */
  void show( const QString& url, const QueryOptions& options );

  /** apt-cache policy
   * Performs apt-cache policy, with the package name encoded in url.query()
   * and sends the result as an HTML file.
   * It checks that the query contains a valid package name */
  void policy( const QString& url, const QueryOptions& options );

  /**
   * Sends an application/x-pkgmanager file with commands
   * understandable by kpkgmanager */
  void pkgmanager( const QString& url, const QueryOptions& options );

  /**
   * Shows a form where one can enter parameters for some queries
   **/
  void help();

  /** Offline listing of the file of a package */
  bool can_listfiles(bool is_installed) const;
  void listfiles( const QString& query, const QueryOptions& options);

  /** Offline file search.
   * Searches the package which contains the specified file */
  bool can_searchfile(bool is_installed) const;
  void searchfile( const QString& query, const QueryOptions& options);

	bool can_online(int mode) const;
  void online( const QString& query, const QueryOptions& options);

	bool check_validpackage(const QString& query);
  QString make_html_form() const;
	QString make_html_tail(const QString& note = QString::null, bool with_form = true);

};

#endif
