/* ====================================================================
 * Copyright (c) 2007,      Martin Hauner
 *                          http://subcommander.tigris.org
 *
 * Subcommander is licensed as described in the file doc/COPYING, which
 * you should have received as part of this distribution.
 * ====================================================================
 */

#ifndef _SC_REPOMODEL_H
#define _SC_REPOMODEL_H

// sc
#include "sublib/TargetId.h"
#include "util/String.h"
#include "svn/DirEntryTypes.h"
class DetailsParam;
class ListParam;
class ScModel;
namespace sc {
  class Error;
}

// qt
#include <QtCore/QObject>

// sys
#include <map>


/** Data object of RepoModelEntries. */
class RepoModelEntry
{
public:
  svn::DirEntries entries;
};

/** Map type for caching svn list results. */
typedef std::map< sc::String, RepoModelEntry > RepoModelEntries;


/** Model class for RepositoryDialog. */
class RepoModel : public QObject, public TargetId
{
  typedef QObject super;
   Q_OBJECT;

public:
  /** Construct a RepoModel with the given @a url and @a model. */
  RepoModel( const sc::String& url, ScModel* model );
  ~RepoModel();

  /** Handle asynchronous result. QObject override. */
  bool event( QEvent* e );

  /** Set the current model url to @a url. */
  void setUrl( const sc::String& url );

  /**
   * Return the current model url.
   */
  const sc::String& getUrl() const;
  /**
   * Return the repository root url of the current model url. Only valid
   * after the root() command has been triggered.
   */
  const sc::String& getRoot() const;

  /** 
   * Test if the given @a url was already listed. Returns true if @a url is
   * listed, otherwise false.
   */
  bool isListed( const sc::String& url );

  /**
   * Fills @a entries with the list result of the given @a url.
   */
  void getEntries( const sc::String& url, svn::DirEntries& entries );

  /**
   * Returns the parent url of the model url. Returns a NullString if the model
   * url is the root url of the repository.
   */
  sc::String parent();

  /// @name Commands
  // @{
  /** Trigger a list on @a url */
  void list( const sc::String& url );
  /** Trigger extraction of the repository root url for the current model url */
  void root();
  // @}

public slots:
  /// @name Results
  // @{
  /** Handle list command result. */
  void result( ListParam*, const sc::Error* );
  /** Handle root command result. */
  void result( DetailsParam*, const sc::Error* );
  // @}

signals:
  /// @name Finished signals
  // @{
  /** Signals a finished list command on @a url. */
  void doneList( const sc::String& url );
  /** Signals a finished root command */
  void doneRoot();
  // @}

private:
  ScModel*         _model;   ///< root model
  sc::String       _url;     ///< current url
  sc::String       _root;    ///< root url of the repository

  RepoModelEntries _entries; ///< list cache
};

#endif // _SC_REPOMODEL_H
