/*
    ktnefwriter.cpp

    SPDX-FileCopyrightText: 2002 Bo Thorsen <bo@sonofthor.dk>

    This file is part of KTNEF, the KDE TNEF support library/program.

    SPDX-License-Identifier: LGPL-2.0-or-later
 */
/*!
 * @file
 * This file is part of the API for handling TNEF data and
 * defines the KTNEFWriter class.
 *
 * @author Bo Thorsen
 */

#pragma once
#include <QStringList>

#include "ktnef_export.h"
#include <memory>
#include <qglobal.h>

class QString;
class QVariant;
class QIODevice;
class QDataStream;
class QDateTime;

namespace KTnef
{
class KTNEFWriterPrivateData;
/*!
 * \brief
 * Manages the writing of @acronym TNEF attachments.
 */
class KTNEF_EXPORT KTNEFWriter
{
public:
    /*!
     * The different types of messages.
     */
    enum MessageType {
        Appointment, /*!< Appointment */
        MeetingCancelled, /*!< The meeting is cancelled */
        MeetingRequest, /*!< Meeting request */
        MeetingNo, /*!< Negative response to a meeting request */
        MeetingYes, /*!< Affirmative response to a meeting request */
        MeetingTent /*!< Tentative affirmative to a meeting request */
    };

    /*!
     * The different types of message statuses.
     */
    enum Method {
        PublishNew, /*!< Publish new */
        Obsolete, /*!< Replace the message */
        RequestNew, /*!< Request a new message */
        RequestUpdate, /*!< Request an update */
        Unknown /*!< Unknown */
    };

    /*!
     * The different types of meeting roles.
     */
    enum Role {
        ReqParticipant, /*!< Required participant */
        OptParticipant, /*!< Optional participant */
        NonParticipant, /*!< Non-participant */
        Chair /*!< Meeting chairperson */
    };

    /*!
     * The different types of participant statuses.
     */
    enum PartStat {
        NeedsAction, /*!< No information about the task/invitation received */
        Accepted, /*!< Accepted the task/invitation */
        Declined, /*!< Declined the task/invitation */
        Tentative, /*!< Tentatively accepted the task/invitation */
        Delegated, /*!< Delegated the task to another */
        Completed, /*!< Completed the task */
        InProcess /*!< Work on the task is in-progress */
    };

    /*!
     * The different priorities.
     */
    enum Priority {
        High = 2, /*!< High priority task */
        Normal = 3, /*!< Normal priority task */
        Low = 1 /*!< Low priority task */
    };

    /*!
     * The different alarm actions.
     */
    enum AlarmAction {
        Display /*!< Display the alarm */
    };

    /*!
     * Constructs a @acronym TNEF writer object.
     */
    KTNEFWriter();

    /*!
     * Destroys the @acronym TNEF writer object.
     */
    ~KTNEFWriter();

    /*!
     * Adds a @acronym TNEF property.
     *
     * \a tag is the @acronym TNEF tag
     * \a type is the property type
     * \a value is the property value
     */
    void addProperty(int tag, int type, const QVariant &value);

    /*!
     * Writes a @acronym TNEF property to the #QDataStream specified by \a stream.
     *
     * A @acronym TNEF property has a 1 byte type (LVL_MESSAGE or LVL_ATTACHMENT),
     * a 4 byte type/tag, a 4 byte length, the data and finally the checksum.
     *
     * The checksum is a 16 byte int with all bytes in the data added.
     *
     * \a stream is the #QDataStream to write
     * \a bytes is a pointer to an int type that will contain
     * the number of bytes written to the \a stream
     * \a tag is the @acronym TNEF tag
     *
     * Returns false if an invalid @acronym TNEF tag was specified by \a tag or
     * if there are no properties to write; else true.
     */
    [[nodiscard]] bool writeProperty(QDataStream &stream, int &bytes, int tag) const;

    /*!
     * Writes the attachment to the #QIODevice specified by \a file.
     *
     * \a file is the #QIODevice to write.
     * Returns true if the write was successful; otherwise false.
     */
    [[nodiscard]] bool writeFile(QIODevice &file) const;

    /*!
     * Writes the attachment to the #QDataStream specified by \a stream.
     *
     * \a stream is the #QDataStream to write.
     * Returns true if the write was successful; otherwise false.
     */
    [[nodiscard]] bool writeFile(QDataStream &stream) const;

    /*!
     * Sets the sender's \a name and \a email address.
     *
     * \a name is the sender's name.
     * \a email is the sender's email address.
     */
    void setSender(const QString &name, const QString &email);

    /*!
     * Sets the #MessageType to \a methodType.
     *
     * \a methodType is the #MessageType.
     */
    void setMessageType(MessageType methodType);

    /*!
     * Sets the #Method to \a method.
     *
     * \a method is the #Method.
     */
    void setMethod(Method method);

    /*!
     * Clears the attendees list.
     */
    void clearAttendees();

    /*!
     * Adds a meeting participant (attendee).
     *
     * \a name is the name of the attendee
     * \a role is the #Role of the attendee
     * \a partstat is the status #PartStat of the attendee
     * \a rsvp is true if the attendee will attend the meeting; else false
     * \a email is the email address of the attendee
     */
    void addAttendee(const QString &name, Role role, PartStat partstat, bool rsvp, const QString &email);

    /*!
     * Sets the name of the organizer to \a organizer.
     * The organizer is any string identifier; it could be the name
     * of a person, or the application that sent the invitation, for example.
     *
     * \a organizer is the organizer identifier.
     */
    void setOrganizer(const QString &organizer);

    /*!
     * Sets the Starting Date and Time to \a dtStart.
     *
     * \a dtStart is the starting date/time.
     */
    void setDtStart(const QDateTime &dtStart);

    /*!
     * Sets the Ending Date and Time to \a dtEnd.
     *
     * \a dtEnd is the ending date/time.
     */
    void setDtEnd(const QDateTime &dtEnd);

    /*!
     * Sets the Location to \a location.
     *
     * \a location is the location.
     */
    void setLocation(const QString &location);

    /*!
     * Sets the @acronym UID to \a uid.
     *
     * \a uid is the @acronym UID.
     */
    void setUID(const QString &uid);

    /*!
     * Sets the timestamp to \a dtStamp.
     *
     * \a dtStamp is the timestamp.
     */
    void setDtStamp(const QDateTime &dtStamp);

    /*!
     * Sets the category list to \a categories.
     *
     * \a categories is the list categories.
     */
    void setCategories(const QStringList &categories);

    /*!
     * Sets the description to \a description.
     *
     * \a description is the description.
     */
    void setDescription(const QString &description);

    /*!
     * Sets the summary to \a summary.
     *
     * \a summary is the summary.
     */
    void setSummary(const QString &summary);

    /*!
     * Sets the priority to \a priority.
     *
     * \a priority is the #Priority.
     */
    void setPriority(Priority priority);

    /*!
     * Sets the alarm.
     *
     * \a description is the alarm description
     * \a action is the alaram #AlarmAction
     * \a wakeBefore is the alarm Date/Time
     */
    void setAlarm(const QString &description, AlarmAction action, const QDateTime &wakeBefore);

private:
    std::unique_ptr<KTNEFWriterPrivateData> const d;

    Q_DISABLE_COPY(KTNEFWriter)
};

}
