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

//  ------------------------------------------------------------------
//  The Goldware Library
//  Copyright (C) 1990-1999 Odinn Sorensen
//  ------------------------------------------------------------------
//  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$
//  ------------------------------------------------------------------
//  WildCat! 4.x messagebase engine.
//  ------------------------------------------------------------------


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

#include <gmemdbg.h>
#include <gdbgtrk.h>
#include <gstrall.h>

#include <gmowcat.h>


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

int WCatArea::load_message(int __mode, gmsg* __msg, WCatHdr& __hdr)
{

    // Setup some local variables for speed
    int _fhdat = data->fhdat;
    WCatIdx* _idx = data->idx;
    uint _reln = Msgn->ToReln(__msg->msgno);

    // Load the message header
    __hdr = WCatHdr();
    lseekset(_fhdat, _idx[_reln-1].offset);
    read(_fhdat, &__hdr, sizeof(WCatHdr));

    // Convert header

    __msg->timesread = 1;

    __msg->link.to_set(__hdr.reference);

    struplow(strnp2cc(__msg->by, __hdr.from, 70));
    struplow(strnp2cc(__msg->to, __hdr.to, 70));
    strnp2cc(__msg->re, __hdr.subject, 70);

    strnp2cc(__msg->wildcat.from_title,      __hdr.fromtitle, 10);
    strnp2cc(__msg->wildcat.to_title,        __hdr.totitle, 10);
    strnp2cc(__msg->wildcat.network,         __hdr.network, 8);
    strnp2cc(__msg->wildcat.internal_attach, __hdr.internalattach, 12);
    strnp2cc(__msg->wildcat.external_attach, __hdr.externalattach, 12);

    memcpy(__msg->wildcat.reserved, __hdr.reserved, 20);

    __msg->wildcat.from_userid = __hdr.fromuserid;
    __msg->wildcat.to_userid = __hdr.touserid;
    __msg->wildcat.next_unread = __hdr.nextunread;
    __msg->wildcat.prev_unread = __hdr.prevunread;

    __msg->cost = (uint)__hdr.cost;

    __msg->orig.zone  = __msg->oorig.zone  = __hdr.origaddr.zone;
    __msg->orig.net   = __msg->oorig.net   = __hdr.origaddr.net;
    __msg->orig.node  = __msg->oorig.node  = __hdr.origaddr.node;
    __msg->orig.point = __msg->oorig.point = __hdr.origaddr.point;

    __msg->dest.zone  = __msg->odest.zone  = __hdr.destaddr.zone;
    __msg->dest.net   = __msg->odest.net   = __hdr.destaddr.net;
    __msg->dest.node  = __msg->odest.node  = __hdr.destaddr.node;
    __msg->dest.point = __msg->odest.point = __hdr.destaddr.point;

    // Convert date and time
    struct tm _tm;
    int32_t _time;
    unsigned _year, _month, _day, _hour, _minute, _second;

    __msg->written = __msg->arrived = __msg->received = 0;

    if(__hdr.msgdate and __hdr.msgtime)
    {
        JDN2YMD(__hdr.msgdate+1, &_year, &_month, &_day);
        _time = __hdr.msgtime-1;
        _hour = (unsigned)(_time / 3600L);
        _minute = (unsigned)((_time % 3600L) / 60L);
        _second = (unsigned)(_time - ((_hour*3600L)+_minute*60L));
        _tm.tm_year  = _year - 1900;
        _tm.tm_mon   = _month - 1;
        _tm.tm_mday  = _day;
        _tm.tm_hour  = _hour;
        _tm.tm_min   = _minute;
        _tm.tm_sec   = _second;
        _tm.tm_isdst = -1;
        time32_t a   = gmktime(&_tm);
        struct tm tp;
        ggmtime(&tp, &a);
        tp.tm_isdst  = -1;
        time32_t b   = gmktime(&tp);
        __msg->written = a + a - b;
    }

    if(__hdr.readdate and __hdr.readtime)
    {
        JDN2YMD(__hdr.readdate+1, &_year, &_month, &_day);
        _time = __hdr.readtime-1;
        _hour = (unsigned)(_time / 3600L);
        _minute = (unsigned)((_time % 3600L) / 60L);
        _second = (unsigned)(_time - ((_hour*3600L)+_minute*60L));
        _tm.tm_year  = _year - 1900;
        _tm.tm_mon   = _month - 1;
        _tm.tm_mday  = _day;
        _tm.tm_hour  = _hour;
        _tm.tm_min   = _minute;
        _tm.tm_sec   = _second;
        _tm.tm_isdst = -1;
        time32_t a   = gmktime(&_tm);
        struct tm tp;
        ggmtime(&tp, &a);
        tp.tm_isdst  = -1;
        time32_t b   = gmktime(&tp);
        __msg->received = a + a - b;
    }


    // Convert fidoflag attributes
    __msg->attr.pvt(__hdr.fidoflags & FIDO_PVT);
    __msg->attr.cra(__hdr.fidoflags & FIDO_CRASH);
    __msg->attr.rcv(__hdr.fidoflags & FIDO_RECEIVED);
    __msg->attr.snt(__hdr.fidoflags & FIDO_SENT);
    __msg->attr.att(__hdr.fidoflags & FIDO_ATTACH);
    __msg->attr.trs(__hdr.fidoflags & FIDO_TRANSIT);
    __msg->attr.orp(__hdr.fidoflags & FIDO_ORPHAN);
    __msg->attr.k_s(__hdr.fidoflags & FIDO_KILLSENT);
    __msg->attr.loc(__hdr.fidoflags & FIDO_LOCAL);
    __msg->attr.hld(__hdr.fidoflags & FIDO_HOLD);
    __msg->attr.rsv(__hdr.fidoflags & FIDO_RESERVED);
    __msg->attr.frq(__hdr.fidoflags & FIDO_FREQ);
    __msg->attr.rrq(__hdr.fidoflags & FIDO_RETRECREQ);
    __msg->attr.rrc(__hdr.fidoflags & FIDO_RETREC);
    __msg->attr.arq(__hdr.fidoflags & FIDO_AUDITREQ);
    __msg->attr.urq(__hdr.fidoflags & FIDO_UPDREQ);

    // Convert mflag attributes
    __msg->attr.pvt(__hdr.mflags & mfPrivate);
    __msg->attr.rab(__hdr.mflags & mfReceiveable);
    __msg->attr.rcv(__hdr.mflags & mfReceived);
    __msg->attr.rrc(__hdr.mflags & mfReceipt);
    __msg->attr.car(__hdr.mflags & mfCarboned);
    __msg->attr.fwd(__hdr.mflags & mfForwarded);
    __msg->attr.efl(__hdr.mflags & mfEchoFlag);
    __msg->attr.hrp(__hdr.mflags & mfHasReplies);
    __msg->attr.del(__hdr.mflags & mfDeleted);
    __msg->attr.tag(__hdr.mflags & mfTagged);
    __msg->attr.snt(__hdr.mflags & mfSent);

    // Set the unsent attribute
    __msg->attr.uns(__msg->attr.loc() and not __msg->attr.snt());

    __msg->txtlength = __hdr.msgbytes;

    // If message text is requested
    if(__mode & GMSG_TXT)
    {

        // Get length of message text
        uint _txtlen = __hdr.msgbytes;

        // Allocate space for the message text
        __msg->txt = (char*)throw_calloc(1, _txtlen+256);

        // Read the message text
        read(_fhdat, __msg->txt, _txtlen);

        // Convert kludge char from NUL to CTRL-A
        char* p = __msg->txt;
        for(int n=0; n<_txtlen; n++,p++)
        {
            if(*p == '\0')
                *p = CTRL_A;
        }
    }

    GFTRK(0);

    // Success
    return true;
}


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

int WCatArea::load_hdr(gmsg* __msg)
{

    GFTRK("WCatLoadHdr");

    WCatHdr _hdr;
    return load_message(GMSG_HDR, __msg, _hdr);
}


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

int WCatArea::load_msg(gmsg* __msg)
{

    GFTRK("WCatLoadMsg");

    WCatHdr _hdr;
    return load_message(GMSG_HDRTXT, __msg, _hdr);
}


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

