#ifndef KIOAPT_APTPROTOCOL_H
#define KIOAPT_APTPROTOCOL_H

#include <tqstring.h>
#include <tqcstring.h>

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

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

#include <memory>

class TQCString;

namespace Parsers
{
	class Parser;
}

class AptProtocol : public TQObject, public TDEIO::SlaveBase {
  TQ_OBJECT
  

  friend class AptCache;

  AptCache m_process;
  PackageManager* m_adept_batch;

  typedef TQMap<TQString, TQString> 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;

  TQString m_stylesheet;
  TQString m_header_background;
  TQString m_logo;
  TQString m_logo_alt;


public:
  AptProtocol( const TQCString &pool_socket, const TQCString &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 TQCString& string);

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

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

	void data(const TQByteArray& array);

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

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

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

private:
  std::unique_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 TQString& 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 TQString& 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 TQString& url, const QueryOptions& options );

  /**
   * Sends an application/x-adept_batch file with commands
   * understandable by adept_batch */
  void adept_batch( const TQString& 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 TQString& 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 TQString& query, const QueryOptions& options);

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

	bool check_validpackage(const TQString& query);
  TQString make_html_form() const;
	TQString make_html_tail(const TQString& note = TQString(), bool with_form = true);

  KShellProcess * p;

};

#endif
