/* -*- mode: c++; indent-tabs-mode: nil; -*-
 *
 * 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: Recipe.h,v 1.12 2003/06/19 17:54:18 rjesse Exp $
 */
 
#ifndef RECIPE_H
#define RECIPE_H

#include "Ingredient.h"
#include "RecipeImageData.h"

#include <qdatetime.h>
#include <qmap.h>
#include <qpixmap.h>
#include <qstring.h>
#include <qstringlist.h>

class RecipeData;

/*!
  \internal data structure to store arbitrary custom data for a recipe.
  Only to be used for import of CookML documents.
*/
class RecipeCustomData {
   public:
      RecipeCustomData();
      RecipeCustomData( const QString&, const QString&, const QString&);
      QString key() const;
      QString datatype() const;
      QString value() const;

      void setKey( const QString&);
      void setDatatype( const QString&);
      void setValue( const QString&);

   private:
      QString m_key;
      QString m_datatype;
      QString m_value;
};

/*!
  That's all what describes a recipe.
*/
class Recipe {
   public:
      /*! Categories are stored as a list of strings. */
      typedef QStringList Categories;

      /*!
        Keywords are stored as a list of strings.
        Each string in this list contains keywords that belong together.
      */
      typedef QStringList Keywords;
      
      /*!
        List of ingredients.
      */
      typedef QValueList<Ingredient> IngredientList;
      /*!
        This map is used to separate the ingredients into individual
        parts.
      */
      typedef QMap<QString,IngredientList> Ingredients;

      /*! Holds the directions in order to cook the recipe.
        The text can be richtext or plain text. The format
        is to be detected automatically by the program.
      */
	  typedef QString Directions;
      enum Complexity { UnsetComplexity = 0, 
                        Easy = 1, Average = 2, Tough = 3 };
      
      Recipe();                 //!< Constructor.
      Recipe( const Recipe&);   //!< Copy constructor.
      ~Recipe();                //!< Destructor.
      Recipe& operator=( const Recipe&);
      bool operator==( const Recipe&) const;
      
      void clear();
      bool contains( const QString&, bool cs = false) const;
      bool isValid() const;
      void invalidate();
      
      QString title() const;
      void setTitle( const QString&);

      QString fingerprint() const;
      void setFingerprint( const QString&);
      void calculateFingerprint();

      QString lang() const;
      void setLang( const QString&);

      QString typist() const;
      void setTypist( const QString&);
      QString typistEmail() const;
      void setTypistEmail( const QString&);

      QString source() const;
      void setSource( const QString&);

      QDateTime created() const;
      void setCreationDate( const QDateTime&);

      QDateTime modified() const;
      void setModificationDate( const QDateTime&);
      QString modificationUser() const;
      void setModificationUser( const QString&);
      QString modificationEmail() const;
      void setModificationEmail( const QString&);

      QTime preparationTime( const QString&) const;
      QTime overallPreparationTime() const;
      QMap<QString,QTime> preparationTimes() const;
      void setPreparationTime( const QString&, const QTime&);
      void setPreparationTimes( const QMap<QString,QTime>&);

      int yieldQty() const;
      void setYieldQty( const int);
      int yieldRange() const;
      void setYieldRange( const int);
      QString yieldUnit() const;
      void setYieldUnit( const QString&);

      float wwPoints() const;
      void setWwPoints( const float);

      QString costs() const;
      void setCosts( const QString&);
      
      Complexity complexity() const;
      void setComplexity( const Complexity&);

      Categories categories() const;
      void setCategories( const Categories&);
      void addCategories( const Categories&);
      void addCategory( const QString&);
      bool removeCategory( const QString&);

      Keywords keywords() const;
      void setKeywords( const Keywords&);
      void addKeywords( const QString&);

      Ingredients ingredients() const;
      void addIngredient( const Ingredient&, const QString& group = QString::null);
      void setIngredients( const Ingredients&);

      Directions directions() const;
      Directions directionsAsRichtext() const;
      void add2Directions( const QString&, const bool constructRichtext = true);
      void setDirections( const Directions&);

      //! \internal Remember which cookbooks this recipe belongs to.
      QStringList cookbooks() const;
      void setCookbooks( const QStringList&);
      void addCookbook( const QString&);
      bool removeCookbook( const QString&);

      //! @name Pictures
      //@{
      QPixmap picture() const;
      QPixmap picture( const QString&) const;
      QString pictureUri( const QString&) const;
      QString pictureAsBase64( const QString&) const;
      QValueList<RecipeImageData>& pictures() const;
      QStringList allPictureLabels() const;
      void setDefaultPicture();
      void setPicture( const QString&, const QPixmap&);
      bool removePicture( const QString&);
      void setPictureUri( const QString&, const QString&);
      void setPictures( const QValueList<RecipeImageData>&);
      bool hasValidPicture() const;
      void setPictureAsValid( bool valid = true);
      void updateMimeSourceFactory() const;
      static QPixmap decodeBase64( const QString&);
      static QString encodeBase64( const QPixmap&);
      //@}

      QMap<QString,QString>& blsContents() const;
      void addBlsContent( const QString&, const QString&);
      void setBlsContents( const QMap<QString,QString>&);
      
      QMap<QString,QStringList>& remarks() const;
      void setRemarks( const QMap<QString,QStringList>&);
      void setRemarksForUser( const QString&, const QStringList&);

      QValueList<RecipeCustomData>& customData() const;
      void setCustomData( const QValueList<RecipeCustomData>&);
      void addCustomData( const QString&, const QString&, const QString&);
      
   private:
      RecipeData* r;
      void detach();
      QPixmap& createPicture( int, int) const;
};

/*****************************************************************************
  Recipe stream functions
 *****************************************************************************/
QDataStream& operator<<( QDataStream&, const RecipeCustomData&);
QDataStream& operator>>( QDataStream&, RecipeCustomData&);
QDataStream& operator<<( QDataStream&, const Recipe&);
QDataStream& operator>>( QDataStream&, Recipe&);
#endif // RECIPE_H
