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


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

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

#include <gmopcbd.h>


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

int PcbArea::load_message(int __mode, gmsg* __msg, PcbHdr& __hdr)
{

    // Read index record for msg
    PcbIdx _idx;
    lseekset(data->fhidx, (__msg->msgno-data->base.lowmsgno)*sizeof(PcbIdx));
    read(data->fhidx, &_idx, sizeof(PcbIdx));
    __msg->txtstart = _idx.offset;

    // Read message header
    lseekset(data->fhmsg, AbsV(_idx.offset));
    read(data->fhmsg, &__hdr, sizeof(PcbHdr));
    __msg->txtlength = (__hdr.blocks-1)*128;
    __msg->txtblocks = __hdr.blocks;

    __msg->timesread = 1;

    // Convert attributes
    __msg->pcboard.status = __hdr.status;
    if(not islocal())
        __msg->attr.uns(__hdr.date[5] != '\xC4');
    __msg->attr.pvt((__hdr.status == '*') or (__hdr.status == '+'));
    __msg->attr.rcv((__hdr.status == '+') or (__hdr.status == '-') or (__hdr.status == '`') or (__hdr.status == '^') or (__hdr.status == '#'));
    __msg->attr.del(__hdr.activestatus == 226);
    __msg->pcboard.exthdrflags = __hdr.exthdrflags;

    // Convert msgno and replylinks
    __hdr.msgno = B2L(__hdr.msgno);
    __hdr.refno = B2L(__hdr.refno);
    __msg->link.to_set(__hdr.refno);

    // Convert date and time
    int _year, _month, _day, _hour, _minute;
    sscanf(__hdr.date, "%d%*c%d%*c%2d", &_month, &_day, &_year);
    sscanf(__hdr.time, "%d%*c%2d", &_hour, &_minute);
    struct tm _tm;
    _tm.tm_year  = (_year < 80) ? (_year+100) : _year;
    _tm.tm_mon   = _month - 1;
    _tm.tm_mday  = _day;
    _tm.tm_hour  = _hour;
    _tm.tm_min   = _minute;
    _tm.tm_sec   = 0;
    _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;
    __msg->arrived = 0;

    // Convert names and subject and password
    strtrim(strncpy(__msg->by, __hdr.origname, 25));
    strtrim(strncpy(__msg->to, __hdr.destname, 25));
    strtrim(strncpy(__msg->re, __hdr.subject,  25));
    strtrim(strncpy(__msg->pcboard.password, __hdr.password, 12));

    uint _msgsize = (uint)__msg->txtlength;

    // Allocate memory for the message text
    __msg->txt = (char*)throw_realloc(__msg->txt, _msgsize+256);
    char* _tmptxt = (char*)throw_calloc(1, _msgsize+1);

    // Read the message text, trim spaces and translate PCB linefeeds
    read(data->fhmsg, _tmptxt, _msgsize);
    strtrim(_tmptxt);
    if(not wide->foreign)
        strchg(_tmptxt, 0xE3, 0x0D);

    //int _line = 0;
    char _eby[122] = {""};
    char _eto[122] = {""};
    char* _dst = __msg->txt;
    char* _src = _tmptxt;
    while(*_src)
    {
        //char* _begline = _src;

        // Check for extended header
        PcbExtHdr* _ehdr = (PcbExtHdr*)_src;
        if(_ehdr->id == 0x40FF)
        {
            if(     strnieql(_ehdr->function, "TO     ", 7))
                strncpy(_eto, _ehdr->desc, 60);
            else if(strnieql(_ehdr->function, "TO2    ", 7))
                strncpy(_eto+60, _ehdr->desc, 60);
            else if(strnieql(_ehdr->function, "FROM   ", 7))
                strncpy(_eby, _ehdr->desc, 60);
            else if(strnieql(_ehdr->function, "FROM2  ", 7))
                strncpy(_eby+60, _ehdr->desc, 60);
            else if(strnieql(_ehdr->function, "SUBJECT", 7))
                strtrim(strncpy(__msg->re, _ehdr->desc, 60));
            _src += sizeof(PcbExtHdr);
        }
        else
        {
            while(*_src)
            {
                *_dst++ = *_src;
                if(*_src++ == CR)
                {
#if 0
                    // Get address and attribute from FidoPCB
                    if(isnet())
                    {
                        _line++;
                        if((_line == 1) and (*_begline == '(' /*)*/))
                        {
                            Addr _addr;
                            _addr.ResetFast();
                            char* _ptr = _begline + 1;
                            int _incoming = false;
                            if(strnieql(_ptr, "FROM:", 5))
                            {
                                _incoming = true;
                                _ptr += 5;
                            }
                            _addr.set(strskip_wht(_ptr));
                            if(not _incoming and strieql(__msg->by, WideUsername[0]))
                            {
                                __msg->dest = _addr;
                                __msg->odest = _addr;
                            }
                            else
                            {
                                __msg->orig = _addr;
                                __msg->oorig = _addr;
                            }
                        }
                        else if((_line == 2) and (*_begline == '(' /*)*/))
                        {
                            _src[-1] = NUL;
                            if(striinc("HOLD", _begline))
                                __msg->attr.hld1();
                            if(striinc("IMM", _begline))
                                __msg->attr.imm1();
                            if(striinc("CRASH", _begline))
                                __msg->attr.cra1();
                            if(striinc("INTL", _begline))
                                __msg->attr.zon1();
                            _src[-1] = CR;
                        }
                    }
#endif
                    break;
                }
            }
        }
    }
    *_dst = NUL;
    strtrim(_eby);
    if(*_eby)
        strxcpy(__msg->by, _eby, sizeof(__msg->by));
    strtrim(_eto);
    if(*_eto)
        strxcpy(__msg->to, _eto, sizeof(__msg->to));

    if(isnet() and not isemail())
    {
        char* ptr = strchr(__msg->by, '@');
        if(ptr)
        {
            *ptr++ = NUL;
            __msg->orig.reset(ptr);
            __msg->oorig = __msg->orig;
        }
        ptr = strchr(__msg->to, '@');
        if(ptr)
        {
            *ptr++ = NUL;
            char* ptr2 = strskip_txt(ptr);
            if(*ptr2)
            {
                *ptr2++ = NUL;
                while(*ptr2)
                {
                    if(*ptr2 == '+')
                    {
                        // get flags
                        switch(g_toupper(*(++ptr2)))
                        {
                        case 'C':
                            __msg->attr.cra1();
                            break;
                        case 'D':
                            __msg->attr.dir1();
                            break;
                        }
                    }
                    else if(*ptr2 == '[')
                    {
                        // get from-aka address
                        ptr2++;
                        char* ptr3 = ptr2;
                        ptr2 = strskip_to(ptr2, ']');
                        if(*ptr2)
                        {
                            *ptr2++ = NUL;
                            __msg->orig.reset(ptr3);
                            __msg->oorig = __msg->orig;
                        }
                    }
                    ptr2++;
                }
            }
            __msg->dest.reset(ptr);
            __msg->odest = __msg->dest;
        }
    }

    throw_free(_tmptxt);

    if(not (__mode & GMSG_TXT))
        throw_release(__msg->txt);

    GFTRK(0);

    return true;
}


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

int PcbArea::load_hdr(gmsg* __msg)
{

    GFTRK("PcbLoadHdr");

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


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

int PcbArea::load_msg(gmsg* __msg)
{

    GFTRK("PcbLoadMsg");

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


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

