//  This may look like C code, but it is really -*- C++ -*-

//  ------------------------------------------------------------------
//  The Goldware Library
//  Copyright (C) 1990-1999 Odinn Sorensen
//  Copyright (C) 1999-2000 Alexander S. Aganichev
//  ------------------------------------------------------------------
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Library General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library 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
//  Library General Public License for more details.
//
//  You should have received a copy of the GNU Library General Public
//  License along with this program; if not, write to the Free
//  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
//  MA 02111-1307, USA
//  ------------------------------------------------------------------
//  $Id$
//  ------------------------------------------------------------------
//  AdeptXBBS structures.
//  ------------------------------------------------------------------


//  ------------------------------------------------------------------
//  Only include once!

#ifndef __GMXBBS_H
#define __GMXBBS_H


//  ------------------------------------------------------------------
//  Required

#include <gmoarea.h>
#include <gusrxbbs.h>


//  ------------------------------------------------------------------

#if defined(GOLD_CANPACK)
#pragma pack(1)
#endif


//  ------------------------------------------------------------------
//  Bitmaps for the header.fflags

#define FFLAGS_MSGPRIVATE  0x0001  // private message,
#define FFLAGS_MSGCRASH    0x0002  // accept for forwarding
#define FFLAGS_MSGREAD     0x0004  // read by addressee
#define FFLAGS_MSGSENT     0x0008  // sent OK (remote)
#define FFLAGS_MSGFILE     0x0010  // file attached to msg
#define FFLAGS_MSGFWD      0x0020  // being forwarded
#define FFLAGS_MSGORPHAN   0x0040  // unknown dest node
#define FFLAGS_MSGKILL     0x0080  // kill after mailing
#define FFLAGS_MSGLOCAL    0x0100  // FidoNet vs. local
#define FFLAGS_MSGXX1      0x0200  //
#define FFLAGS_MSGXX2      0x0400  // STRIPPED by FidoNet<tm>
#define FFLAGS_MSGFRQ      0x0800  // file request
#define FFLAGS_MSGRRQ      0x1000  // receipt requested
#define FFLAGS_MSGCPT      0x2000  // is a return receipt
#define FFLAGS_MSGARQ      0x4000  // audit trail requested
#define FFLAGS_MSGURQ      0x8000  // update request


//  ------------------------------------------------------------------
//  Bitmaps for the header.xflags

#define XFLAGS_MSGDELETED  0x0001  // deleted message,
#define XFLAGS_MSGANON     0x0002  // anonymous message
#define XFLAGS_MSGECHO     0x0004  // unmoved echo message
#define XFLAGS_MSGNET      0x0008  // unmoved net message

#define XFLAGS_MSGHOLD     0x0010  // file attached to msg
#define XFLAGS_MSGHOST     0x0020  // being forwarded
#define XFLAGS_MSGSCANNED  0x0040  // Fidonet scanned
#define XFLAGS_MSGKEEP     0x0080  // don't delete

#define XFLAGS_MSGTREATED  0x0100  // soft cr's & lf's removed
#define XFLAGS_MSGPACKED   0x0200  // message LZSS compressed
#define XFLAGS_MSGGSCAN    0x0400  // GroupMail scanned
#define XFLAGS_MSGRSCAN    0x0800  // rfc0822 scanned

#define XFLAGS_MSGARCHIVED 0x4000  // Message stored
#define XFLAGS_MSGTAGGED   0x8000  // used by offline readers


//  ------------------------------------------------------------------
//  AdeptXBBS Message Header (*.Data)

struct XbbsHdr {
  char    majorversion; // Minor revision number of this message style
  char    minorversion; // Minor revision number of this message style
  uint16_t  structlen;  // The length of this data structure
  char    from[60];     // Who the message is from
  char    to[60];       // Who the message is to
  char    subj[70];     // The subject of the message
  char    date[35];     // Date the message was written
  char    indate[4];    // Import date
  uint32_t  msgnum;     // Current message number
  uint32_t  timesread;  // Number of times the message has been read
  time32_t  timerecv;   // Time user received this message
  uint32_t  length;     // Length of message stored in .Text Data file
  int32_t   start;      // Pointer to starting byte in .Text Data file
  uint32_t  extra1;     // Extra space  // Was going to be for reply
  uint32_t  extra2;     // Extra space  // linking instead came up with
  uint32_t  extra3;     // Extra space  // a better method
  Addr      origaddr;   // Messages origin
  Addr      destaddr;   // Messages destination
  uint16_t  cost;       // Cost to send this message
  uint16_t  fflags;     // Fidonet related flags
  uint16_t  xflags;     // XBBS related flags
  uint32_t  iflags;     // Internet related flags
  uint32_t  oflags;     // Other network related flags
};


//  ------------------------------------------------------------------
//  AdeptXBBS Message Index (*.Index)

struct XbbsIdx {
  uint16_t  to;             // Checksum of the to field
  uint16_t  from;           // Checksum of the from field
  uint16_t  subj;           // Checksum of the subject field
  uint32_t  msgidcrc;       // MSGID 32-bit CRC of address field (starting value 0xFFFFFFFF)
  uint32_t  msgidserialno;  // MSGID Serial number field
  uint32_t  replycrc;       // REPLY 32-bit CRC of address field (starting value 0xFFFFFFFF)
  uint32_t  replyserialno;  // REPLY Serial number field
};


//  ------------------------------------------------------------------
//  AdeptXBBS Personal Mail Index

struct XbbsPmi {
  int32_t  areanumber;
  int32_t  msgnumber;
  char  from[60];
  char  subject[70];
  char  date[20];
};


//  ------------------------------------------------------------------

#if defined(GOLD_CANPACK)
#pragma pack()
#endif


//  ------------------------------------------------------------------

struct XbbsData {
  int      fhdata;
  int      fhindex;
  int      fhlmr;
  int      fhtext;
  int      islocked;
  XbbsIdx* idx;
  uint     idx_size;
};


//  ------------------------------------------------------------------

struct XbbsWide {
  int       fhpmi;
  int       userno;
  XbbsUser* user;
  XbbsPmi*  pmi;
  int       isopen;
  const char* path;
};


//  ------------------------------------------------------------------

class XbbsArea : public gmo_area {

protected:

  XbbsWide* wide;
  XbbsData* data;

  void data_open();
  void data_close();

  void raw_open();
  void raw_close();
  void refresh();
  int load_message(int __mode, gmsg* __msg, XbbsHdr& __hdr);

  void lock_file(int handle, int32_t position, int32_t length);
  void unlock_file(int handle, int32_t position, int32_t length);

  int test_open(const char* __file, int sharemode=-1);
  void save_lastread();
  void raw_scan(int __keep_index, int __scanpm=false);
  void save_message(int __mode, gmsg* __msg, XbbsHdr& __hdr);

  void update_personal_mail(gmsg* __msg, XbbsHdr& __hdr, int __status);

public:

  XbbsArea() { wide = NULL; data = NULL; }
  virtual ~XbbsArea() {}

  //  ----------------------------------------------------------------
  //  Messagebase member functions
  
  void open();
  void close();

  void suspend();
  void resume();

  void lock();
  void unlock();

  void scan();
  void scan_area();
  void scan_area_pm();

  int load_hdr(gmsg* msg);
  int load_msg(gmsg* msg);

  void save_hdr(int mode, gmsg* msg);
  void save_msg(int mode, gmsg* msg);

  void del_msg(gmsg* msg);

  void new_msgno(gmsg* msg);
  char* user_lookup(char* lookfor);
  int renumber();

  void update_timesread(gmsg* msg);

  Line* make_dump_msg(Line*& lin, gmsg* msg, char* lng_head);
};


//  ------------------------------------------------------------------

extern XbbsWide* xbbswide;
extern XbbsData* xbbsdata;
extern int       xbbsdatano;


//  ------------------------------------------------------------------

#endif

//  ------------------------------------------------------------------
