/* -*- mode: c++; indent-tabs-mode: nil; -*-
 *
 * Copyright (c) 2000-2003, Roland Jesse
 * All rights reserved.
 *
 * This file is part of the Mango distribution.
 * For license and copyright information see the file COPYRIGHT or 
 * <http://www.opensource.org/licenses/bsd-license.html>.
 *
 * $Id: Repository.h,v 1.14 2003/05/11 16:14:06 rjesse Exp $
 */

#ifndef REPOSITORY_H
#define REPOSITORY_H

#include "RecipeModel.h"
#include "Recipe.h"
#include "Error.h"

//#include <string>				// FIXME: substitute std::string by QString

#include <qdict.h>
#include <qdir.h>
#include <qsettings.h>
#include <qstringlist.h>

/*!
  All known recipes are stored herein.
 
  To be more precise: The recipes are stored in cookbooks
  (RecipeModels) and the cookbooks are managed here. The maximum
  number of cookbooks to be stored is kind of fixed (but can be
  changed). It is initially hard coded to 9973, which is a prime. See
  the QDict class documentation for more information.
 
  This repository keeps track of a "current" recipe. That is the recipe
  that is currently visible to the user. This notion of a current recipe
  is for instance used for printing purposes.
 
  This class works as a model in the sense of the MVC pattern.
*/
class Repository : public QObject {
      Q_OBJECT
      
   public:
      /*!
        Each cookbook is associated with a name. Note: This stores pointers
        to the cookbooks.
      */
      typedef QDict<RecipeModel> Cookbooks;

   private:
      /*! Eases traversion of all stored cookbooks. */
      typedef QDictIterator<RecipeModel> CookbooksIterator;

   public:
      static Repository* getInstance();
      static void deleteInstance();

      RecipeModel* addCookbookFromFile( const QString&) throw (Error);
      RecipeModel* addCookbookFromFile( const QString&, RecipeModel::RecipeFormat format);
      void insertCookbook( const RecipeModel*);
      void createCookbook( const QString&);
      RecipeModel* getCookbook( const QString&) const throw (Error);
      Cookbooks getAllCookbooks() const;
      bool hasCookbook( const QString&) const;
      bool hasUnsavedCookbooks() const;
      void saveAllChanges();
      void removeCookbook( const QString&, bool deleteAlso = false);
      
      void addCategory( const QString&);
      Recipe::Categories getKnownCategories() const;
      
      void setCurrentRecipe( const Recipe&);
      Recipe currentRecipe() const;
      
      //! \bug obsolete?! \see setDefaultPath()
      bool setCurrentDir( QDir&); //!< Set the current working directory.
      QDir getCurrentDir() const; //!< Return the current working directory.
      
      // Iterate cookbooks.
      int getNumOfCookbooks() const;
      QStringList getCookbookNames() const;
      QStringList getCookbookFileNames() const;
      
      // Handling of default paths.
      QString defaultPath( const QString&);
      void setDefaultPath( const QString&, const QString&);
      
      // Access to the session management object.
      static QSettings sessionObject();

      //! Provide access to the currently active version number when reading in files in Mango's native format.
      Q_INT32 activeMangoFormatVersion() const;
      //! Store the version number of the recipe currently being read in.
      void setActiveMangoFormatVersion( const Q_INT32);
      
   signals:
      //! A cookbook with this name was just added to the repository.
      void cookbookAdded( const QString&);
      
   protected:
	  Repository();
	  ~Repository();
      
   private:
//	  typedef std::pair<std::string,QString*> Measure;
      QMap<QString,QString> m_defaultPaths;
      
	  static Repository* m_instance;
      
	  Recipe m_currentRecipe;
	  Cookbooks m_cookbooks;
	  /*!
	   * List of available categories.
	   *
	   * Initially, this is empty. Entries are added either when typed in
	   * while manually adding a new recipe or when reading in recipes from
	   * external cookbooks.
	   */
	  Recipe::Categories m_categories;

      Q_INT32 m_activeMangoFormatVersion;
};
#endif // REPOSITORY_H
