/* -*- mode: c++; tab-width: 4; -*-
 *
 * Copyright (c) 2000-2003, Roland Jesse
 * All rights reserved.
 *
 * This file is part of the Mango recipe management distribution.
 * For license and copyright information see the file COPYRIGHT or 
 * <http://www.opensource.org/licenses/bsd-license.html>.
 *
 * $Id: RecipeModel.h,v 1.15 2003/04/07 04:50:56 rjesse Exp $
 */
 
#ifndef RECIPE_MODEL_H
#define RECIPE_MODEL_H

#include "Error.h"
#include <qdom.h>
#include <qobject.h>
#include <qstring.h>
#include <qvaluelist.h>

// Disable some warnings of MSVC++.
#ifdef Q_OS_WIN32
# pragma warning( disable : 4290)   // C++ exception declaration ignored.
#endif

class Recipe;
class Importer;
class Menu;
class QProgressDialog;

/*!
 * Model class for recipes. One of these models represents a cookbook which
 * can be seen as a collection of recipes that even might have something
 * in common.
 */
class RecipeModel : public QObject {
      Q_OBJECT

   public:
      /*! List of all recipes in this model (cookbook). */
	  typedef QValueList<Recipe> RecipeList;

     /*! List of all menus in this model (cookbook). */
     typedef QValueList<Menu> MenuList;

	  /*! List of supported recipe formats */
	  enum RecipeFormat {
         Mango = 1,
         MealMaster = 2,
         RecipeML = 3,
         Rezkonv = 4,
         CookML = 5
      };

      RecipeModel( bool isTemp = false);
	  RecipeModel( const RecipeModel&, bool isTemp = false);
	  RecipeModel( const QString&, bool isTemp = false);
      RecipeModel( const QString&, const RecipeFormat, bool isTemp = false);
      ~RecipeModel();

	  RecipeModel& operator=( const RecipeModel&); //!< Assignment operator.
	  RecipeModel& operator+=( RecipeModel&); //!< Append another Cookbook.
	  RecipeModel& operator+=( Recipe&); //!< Append a Recipe.
	  void add( Recipe&);
      void remove( const Recipe&);
      void update( const Recipe&);

      bool contains( const Recipe&) const;
	  bool isEmpty() const;
	  bool isModified() const;
	  void markAsModified( bool modified = true);
      
	  RecipeList getRecipeList() const;	//!< Return all recipes.
	  QString getName() const;	//!< Return the name of this cookbook.
	  void setName( const QString&); //!< Set cookbook's name.
	  QString getFileName() const;
	  void setFileName( const QString&);
	  
	  RecipeList findByCategory( const QString&) const;
	  Recipe findByTitle( const QString&) throw (Error);
	  void saveToFile() throw (Error);

     MenuList getMenuList() const;
     void addMenu( const Menu&);

   signals:
      void notify();

   private slots:
      void slotCancelImport();
      void slotImporterStarted( const QString&, const int);
      void slotImporterProgress( const int, const int);
      
   private:
	  void loadMangoFile( const QString&) throw (Error);
	  void loadMMFile( const QString&) throw (Error);
	  void loadRecipeMLFile( const QString&) throw (Error);
      void loadRKFile( const QString&) throw (Error);
      void loadCookMLFile( const QString&) throw (Error);

	  QString m_name;		//!< name of the cookbook
	  QString m_filename;		//!< file name associated with this cookbook
     RecipeList m_recipes;
     MenuList m_menus;
	  bool m_modified;
	  /*! Marks whether or not this cookbook is of temporary nature.
		Temporary cookbooks are not to be saved to disk. They are ususally
		used to handle search results and such.
	  */
	  bool m_isTemp;

      Importer* m_importer;      //!< Importer to load from file et cetera.
      void deleteImporter();
      void setupImporterProgress();
      QProgressDialog* m_progressImport; //!< For showing importer progress to the user.
};
#endif // RECIPE_MODEL_H
