//  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$
//  ------------------------------------------------------------------
//  PCBoard Structures.
//  ------------------------------------------------------------------


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

#ifndef __GMPCBD_H
#define __GMPCBD_H


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

#include <gmoarea.h>
#include <gs_pcb.h>
#include <gusrpcb.h>


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

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


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

typedef char PcbName[25+1];


//  ------------------------------------------------------------------
//  PCBoard Message Base Header (<msgbase>. file)

struct PcbBase {

  int32_t  highmsgno;                // High Message Number       (0 to 16,700,000)
  int32_t  lowmsgno;                 // Low Message Number        (0 to 16,700,000)
  int32_t  active;                   // Number of Active Messages (0 to 32,767)
  int32_t  callers;                  // Number of System Callers (Main Message Base Only)
  char  locked[6];                // The "LOCKED" field for pre-14.2 systems (see note 1)
  byte  reserved[106];            // Reserved for future use
};


//  ------------------------------------------------------------------
//  PCBoard Individual Message Header (in <msgbase>. file)

struct PcbHdr {

  char  status;                   // Message Status Flag (see note 2)
  int32_t  msgno;                    // Message Number   (0 to 16,700,000)
  int32_t  refno;                    // Reference Number (0 to 16,700,000)
  byte  blocks;                   // Number of 128 Byte Blocks in Message (see note 3)
  char  date[8];                  // Date of Message Entry (in "mm-dd-yy" format)
  char  time[5];                  // Time of Message Entry (in "hh:mm" format)
  char  destname[25];             // Name of the User to whom the Message is Addressed
  int32_t  replydate;                // Date of the Reply Message (in yymmdd format)
  char  replytime[5];             // Time of the Reply Message (in "hh:mm" format)
  char  hasreply;                 // The Letter "R" if the Message has a Reply
  char  origname[25];             // Name of the User who wrote the Message
  char  subject[25];              // Subject of the Message
  char  password[12];             // Password Need to Read the Message (if any)
  byte  activestatus;             // Active Status (225 = active, 226 = inactive)
  char  echoed;                   // The Letter "E" if the Message is to be Echoed
  byte  reserved[4];              // Reserved for future use
  byte  exthdrflags;              // Extended Header Flags (version 15.0)
  byte  reserved2;                // Reserved for future use
};


//  ------------------------------------------------------------------
//  PCBoard Extended Header (version 15.0) (in <msgbase>. file)

struct PcbExtHdr {

  short  id;                       // Extended Header ID = must be equal to 40FFh
  char  function[7];              // Extended Header Function
  char  colon;                    // A colon (:) character
  char  desc[60];                 // Extended Header Description (subj, to, from, etc)
  char  status;                   // Status (N or R)
  char  separator;                // Line Separator (E3h, or 0Dh for foreign systems)
};


//  ------------------------------------------------------------------
//  PCBoard Version 15.0 Style Index (<msgbase>.IDX file)

struct PcbIdx {

  int32_t     offset;                // Offset (0 if none, >0 if active, <0 if killed)
  int32_t     num;                   // Message Number
  char     to[25];                // TO Name
  char     from[25];              // FROM Name
  char     status;                // Status Character (from Message Header)
  word     date;                  // Date of Message (in julian date format)
  char     reserved[3];           // Reserved for future use
};


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

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


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

struct PcbData {
  int      fhmsg;
  int      fhidx;
  int      islocked;
  PcbBase  base;
};


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

struct PcbWide {
  int            isopen;
  int            fhusr;
  int            fhinf;
  int            userno;
  PcbUser*       user;
  Path           usersidxpath;
  Path           usersinf;
  Path           users;
  int            numareas;
  PcbUsers       usersrec;
  PcbUsersInfHdr usershdr;
  int32_t           usershdrsize;
  int32_t*          lastread;
  int32_t           confbytelen;
  int32_t           extconflen;
  int            foreign;
  const char*    path;
};


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

class PcbArea : public gmo_area {

protected:

  PcbWide* wide;
  PcbData* data;

  int just_scanning;

  void data_open();
  void data_close();

  int test_open(const char* __file);

  void raw_open();
  void raw_close();

  void save_lastread();
  void raw_scan(int __keep_index, int __scanpm=false);
  int load_message(int __mode, gmsg* __msg, PcbHdr& __hdr);
  void save_message(int __mode, gmsg* __msg, PcbHdr& __hdr);

public:

  PcbArea() { wide = NULL; data = NULL; just_scanning = false; }
  virtual ~PcbArea() {}

  virtual bool havearrivedstamp() const { return false; }
  virtual bool havereceivedstamp() const { return false; }
  virtual bool requirehardterm() const { return true; }

  //  ----------------------------------------------------------------
  //  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 PcbData* pcbdata;
extern PcbWide* pcbwide;
extern int      pcbdatano;


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

#endif

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

