// This may look like C code, but it's really -*- C++ -*-
/*
 * Copyright (C) 2011 Emweb bvba, Kessel-Lo, Belgium.
 *
 * See the LICENSE file for terms of use.
 */
#ifndef WT_MAIL_MESSAGE_H_
#define WT_MAIL_MESSAGE_H_

#include <Wt/Mail/Mailbox>

namespace Wt {

  class WStringStream;

  namespace Mail {

/*! \brief Enumeration for a recipient type.
 *
 * \sa Message::addRecipient()
 */
enum RecipientType {
  To, //!< To: recipient
  Cc, //!< Cc: recipient
  Bcc //!< Bcc: recipient (is omitted from the recipients in the message itself)
};

/*! \class Message Wt/Mail/Message Wt/Mail/Message
 *  \brief A mail message.
 *
 * This class represents a MIME-compliant mail message.
 *
 * The message can have a plain text body and an optional HTML body,
 * which when present is encoded as an MIME multipart/alternative. It
 * is recommended to send the same contents both in a plain text and
 * an HTML variant.
 *
 * Recipient names, names, and body text may contain unicode text.
 *
 * \sa Client::send()
 *
 * \ingroup mail
 */
class WT_API Message
{
public:
  struct Recipient {
    RecipientType type;
    Mailbox mailbox;
  };

  /*! \brief Default constructor.
   *
   * Creates an empty message. You need to add at least a sender and a recipient
   * to create a valid email message.
   */
  Message();

  /*! \brief Sets the sender mailbox.
   */
  void setFrom(const Mailbox& from);

  /*! \brief Returns the sender mailbox.
   *
   * \sa setFrom()
   */
  const Mailbox& from() const { return from_; }

  /*! \brief Sets the reply-to mailbox.
   */
  void setReplyTo(const Mailbox& replyTo);

  /*! \brief Returns the reply-to mailbox.
   *
   * \sa setReplyTo()
   */
  const Mailbox& replyTo() const { return replyTo_; }

  /*! \brief Sets a subject.
   */
  void setSubject(const WString& subject);

  /*! \brief Returns the subject.
   *
   * \sa setSubject()
   */
  const WString& subject() const;

  /*! \brief Sets the plain text body.
   *
   * This is the plain text mail contents.
   *
   * \sa addHtmlBody()
   */
  void setBody(const WString& text);

  /*! \brief Adds a recipient.
   *
   * A mail can have multiple recipients.
   */
  void addRecipient(RecipientType type, const Mailbox& recipient);

  /*! \brief Returns the recipients.
   *
   * \sa addRecipient()
   */
  const std::vector<Recipient>& recipients() const { return recipients_; }

  /*! \brief Adds an HTML body.
   *
   * The \p text should be an HTML version of the plain text body.
   */
  void addHtmlBody(const WString& text);

  void addAttachment(const std::string& mimeType /* ... */);

  /*! \brief Writes the message to the stream.
   *
   * This writes the message as a MIME 1.0 message to the output stream.
   */
  void write(std::ostream& out) const;

private:
  Mailbox from_, replyTo_;
  std::vector<Recipient> recipients_;

  WString subject_, body_, htmlBody_;

  static void encodeChar(WStringStream& s, unsigned char c);
  static void encodeWord(const WString& text, std::ostream& out,
			 bool quoteIfNeeded);
  static void encodeQuotedPrintable(const WString& text, std::ostream& out);

  friend class Mailbox;
};

  }
}

#endif // WT_MAIL_MESSAGE_H_
