/**
 * @file
 * Handling of email attachments
 *
 * @authors
 * Copyright (C) 2017-2024 Richard Russon <rich@flatcap.org>
 *
 * @copyright
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 2 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef MUTT_ATTACH_ATTACH_H
#define MUTT_ATTACH_ATTACH_H

#include <stdbool.h>
#include <stdio.h>
#include "expando/lib.h"

struct Body;
struct Buffer;

/**
 * struct AttachPtr - An email to which things will be attached
 */
struct AttachPtr
{
  struct Body *body;    ///< Attachment
  FILE *fp;             ///< Used in the recvattach menu
  int parent_type;      ///< Type of parent attachment, e.g. #TYPE_MULTIPART
  char *tree;           ///< Tree characters to display
  int level;            ///< Nesting depth of attachment
  int num;              ///< Attachment index number
  bool unowned : 1;     ///< Don't unlink on detach
  bool decrypted : 1;   ///< Not part of message as stored in the email->body
  bool collapsed : 1;   ///< Group is collapsed
};

/**
 * ExpandoDataAttach - Expando UIDs for Attachments
 *
 * @sa ED_ATTACH, ExpandoDomain
 */
enum ExpandoDataAttach
{
  ED_ATT_CHARSET = 1,          ///< AttachPtr.body
  ED_ATT_NUMBER,               ///< AttachPtr.num
  ED_ATT_TREE,                 ///< AttachPtr.tree
};

/**
 * struct AttachCtx - A set of attachments
 */
struct AttachCtx
{
  struct Email *email;    ///< Used by recvattach for updating
  FILE *fp_root;          ///< Used by recvattach for updating

  struct AttachPtr **idx; ///< Array of attachments
  short idxlen;           ///< Number of attachmentes
  short idxmax;           ///< Size of attachment array

  short *v2r;             ///< Mapping from virtual to real attachment
  short vcount;           ///< The number of virtual attachments

  FILE **fp_idx;          ///< Extra FILE* used for decryption
  short fp_len;           ///< Number of FILE handles
  short fp_max;           ///< Size of FILE array

  struct Body **body_idx; ///< Extra struct Body* used for decryption
  short body_len;         ///< Number of Body parts
  short body_max;         ///< Size of Body array
};

void              mutt_actx_add_attach  (struct AttachCtx *actx, struct AttachPtr *attach);
void              mutt_actx_ins_attach  (struct AttachCtx *actx, struct AttachPtr *attach, int aidx);
void              mutt_actx_add_body    (struct AttachCtx *actx, struct Body *b);
void              mutt_actx_add_fp      (struct AttachCtx *actx, FILE *fp_new);
void              mutt_actx_free        (struct AttachCtx **ptr);
void              mutt_actx_entries_free(struct AttachCtx *actx);
struct AttachCtx *mutt_actx_new         (void);

void              mutt_aptr_free(struct AttachPtr **ptr);
struct AttachPtr *mutt_aptr_new (void);

void attach_arrow(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf);
void attach_C    (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf);
void attach_c    (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf);
void attach_D    (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf);
void attach_d    (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf);
void attach_e    (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf);
void attach_F    (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf);
void attach_f    (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf);
void attach_I    (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf);
void attach_M    (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf);
void attach_m    (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf);
void attach_Q    (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf);
void attach_s    (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf);
void attach_T    (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf);
void attach_t    (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf);
void attach_u    (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf);

long attach_n_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags);
long attach_X_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags);

#endif /* MUTT_ATTACH_ATTACH_H */
