//  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$
//  ------------------------------------------------------------------
//  Read areas from D'Bridge
//  ------------------------------------------------------------------

#include <cstdlib>
#include <gmemdbg.h>
#include <gstrall.h>
#if defined(__GOLD_GUI__)
#include <gvidall.h>
#include <gvidgui.h>
#endif
#undef GCFG_NODB
#include <gedacfg.h>
#include <gs_db.h>


//  ------------------------------------------------------------------
//  Read D'Bridge 1.30

void gareafile::ReadDB130(char* /*tag*/, char* dbpath)
{
  AreaCfg aa;
  DB130_AA1 AA1;
  DB130_AA2 AA2;
  Path file1, file2;

  MakePathname(file1, dbpath, "dbridge.aa1");
  MakePathname(file2, dbpath, "dbridge.aa2");

  gfile fp1(file1, "rb", sharemode);
  if (fp1.isopen())
  {
    fp1.SetvBuf(NULL, _IOFBF, 8192);

    if (not quiet)
      STD_PRINTNL("* Reading " << file1);

    gfile fp2(file2, "rb", sharemode);
    if (fp2.isopen())
    {
      fp2.SetvBuf(NULL, _IOFBF, 8192);

      if (not quiet)
        STD_PRINTNL("* Reading " << file2);

      while (fp1.Fread(&AA1, sizeof(DB130_AA1)))
      {
        fp2.Fread(&AA2, sizeof(DB130_AA2));

        if (AA1.allocated and strchr("QFqf", AA2.msgbase))
        {
          aa.reset();
          switch(g_toupper(AA2.msgbase)) {
            case 'Q':
              aa.basetype = "HUDSON";
              aa.board = AA2.board;
              break;
            case 'F':
              aa.basetype = fidomsgtype;
              aa.setpath(STRNP2C(AA2.path));
              break;
          }
          switch(g_toupper(AA2.kind)) {
            case 'N':
              aa.type = GMB_NET;
              aa.attr = attribsnet;
              break;
            case 'E':
              aa.type = GMB_ECHO;
              aa.attr = attribsecho;
              break;
            default:
              aa.type = GMB_LOCAL;
              aa.attr = attribslocal;
          }
          STRNP2C(AA2.origin);
          aa.setorigin(AA2.origin);
          aa.attr.pvt(AA2.ispvt);
          aa.groupid = (char)AA2.group;
          aa.setechoid(STRNP2C(AA1.echoid));
          aa.setdesc(STRNP2C(AA2.desc));
          aa.aka = AA2.addr;
          AddNewArea(aa);
        }
      }
    }
  }
}


//  ------------------------------------------------------------------
//  Read D'Bridge B1046

void gareafile::ReadDB1046(char* file, char* /*tag*/)
{
  AreaCfg aa;
  DB1046_ADF* ADF = (DB1046_ADF*)throw_calloc(1, sizeof(DB1046_ADF));

  gfile fp(file, "rb", sharemode);
  if (fp.isopen())
  {
    fp.SetvBuf(NULL, _IOFBF, 8192);

    if (not quiet)
      STD_PRINTNL("* Reading " << file);

    while (fp.Fread(ADF, sizeof(DB1046_ADF)))
    {
      if(ADF->allocated and strchr("QFqf", ADF->msgbase)) {
        aa.reset();
        switch(g_toupper(ADF->msgbase)) {
          case 'Q':
            aa.basetype = "HUDSON";
            aa.board = ADF->board;
            break;
          case 'F':
            aa.basetype = fidomsgtype;
            aa.setpath(STRNP2C(ADF->path));
            break;
        }
        switch(g_toupper(ADF->kind)) {
          case 'N':
            aa.type = GMB_NET;
            aa.attr = attribsnet;
            break;
          case 'E':
            aa.type = GMB_ECHO;
            aa.attr = attribsecho;
            break;
          default:
            aa.type = GMB_LOCAL;
            aa.attr = attribslocal;
        }
        STRNP2C(ADF->origin);
        aa.setorigin(ADF->origin);
        aa.attr.pvt(ADF->ispvt);
        aa.groupid = (char)ADF->group;
        aa.setechoid(STRNP2C(ADF->echoid));
        aa.setdesc(STRNP2C(ADF->desc));
        aa.aka = ADF->addr;
        AddNewArea(aa);
      }
    }
  }

  throw_free(ADF);
}


//  ------------------------------------------------------------------
//  Read D'Bridge B1047.A22 and B1047.A27+

void gareafile::ReadDB1047A22(char* file, int reclen, char* /*tag*/)
{
  AreaCfg aa;
  DB1047A22_ADF* ADF = (DB1047A22_ADF *)throw_malloc(reclen);

  if (ADF)
  {
    gfile fp(file, "rb", sharemode);
    if (fp.isopen())
    {
      fp.SetvBuf(NULL, _IOFBF, 8192);

      if (not quiet)
        STD_PRINTNL("* Reading " << file);

      while (fp.Fread(ADF, reclen))
      {
        if (ADF->allocated and strchr("QFqf", ADF->msgbase))
        {
          aa.reset();
          switch(g_toupper(ADF->msgbase)) {
            case 'Q':
              aa.basetype = "HUDSON";
              aa.board = ADF->board;
              break;
            case 'F':
              aa.basetype = fidomsgtype;
              aa.setpath(STRNP2C(ADF->path));
              break;
          }
          switch(g_toupper(ADF->kind)) {
            case 'N':
              aa.type = GMB_NET;
              aa.attr = attribsnet;
              break;
            case 'E':
              aa.type = GMB_ECHO;
              aa.attr = attribsecho;
              break;
            default:
              aa.type = GMB_LOCAL;
              aa.attr = attribslocal;
          }
          STRNP2C(ADF->origin);
          aa.setorigin(ADF->origin);
          aa.attr.pvt(ADF->ispvt);
          aa.groupid = (char)ADF->group;
          aa.setechoid(STRNP2C(ADF->echoid));
          aa.setdesc(STRNP2C(ADF->desc));
          aa.aka = ADF->addr;
          AddNewArea(aa);
        }
      }
    }

    throw_free(ADF);
  }
}


//  ------------------------------------------------------------------
//  Read D'Bridge B2011

void gareafile::ReadDB2011(char* file, int reclen, char* /*tag*/)
{
  AreaCfg aa;
  DB2011_ADF* ADF = (DB2011_ADF *)throw_malloc(reclen);

  if (ADF)
  {
    gfile fp(file, "rb", sharemode);
    if (fp.isopen())
    {
      fp.SetvBuf(NULL, _IOFBF, 8192);

      if (not quiet)
        STD_PRINTNL("* Reading " << file);

      while (fp.Fread(ADF, reclen))
      {
        if (ADF->allocated and strchr("QFqf", ADF->msgbase))
        {
          aa.reset();
          switch(g_toupper(ADF->msgbase)) {
            case 'Q':
              if(ADF->board < 1 or ADF->board > 200)
                continue;   // Bad area number
              aa.basetype = "HUDSON";
              aa.board = ADF->board;
              break;
            case 'F':
              aa.basetype = fidomsgtype;
              aa.setpath(STRNP2C(ADF->path));
              break;
          }
          switch(g_toupper(ADF->kind)) {
            case 'N':
              aa.type = GMB_NET;
              aa.attr = attribsnet;
              break;
            case 'E':
              aa.type = GMB_ECHO;
              aa.attr = attribsecho;
              break;
            default:
              aa.type = GMB_LOCAL;
              aa.attr = attribslocal;
          }
          STRNP2C(ADF->origin);
          aa.setorigin(ADF->origin);
          aa.attr.pvt(ADF->ispvt);
          aa.groupid = (char)ADF->group;
          aa.setechoid(STRNP2C(ADF->echoid));
          aa.setdesc(STRNP2C(ADF->desc));
          aa.aka = ADF->addr;
          AddNewArea(aa);
        }
      }
    }

    throw_free(ADF);
  }
}


//  ------------------------------------------------------------------
//  Read D'Bridge areas, various versions...

void gareafile::ReadDBridge(char* tag)
{
  AreaCfg aa;
  char* ptr;
  int line;
  char buf[256], type, options[80];
  Path dbpath, file, badecho, netpath;

  *dbpath = NUL;
  strcpy(options, tag);

  ptr = strtok(tag, " \t");
  while(ptr) {
    if(*ptr != '-') {
      AddBackslash(strcpy(dbpath, ptr));
      break;
    }
    ptr = strtok(NULL, " \t");
  }
  if(*dbpath == NUL) {
    ptr = getenv("DBRIDGE");
    if(ptr == NULL)
      ptr = getenv("DB");
    if(ptr)
      AddBackslash(strcpy(dbpath, ptr));
  }
  if(*dbpath == NUL)
    strcpy(dbpath, areapath);

  MakePathname(file, dbpath, "dbridge.prm");

  gfile fp(file, "rt", sharemode);
  if (fp.isopen())
  {
    if (not quiet)
      STD_PRINTNL("* Reading " << file);

    // Read netmail storage method etc
    for (line = 1; line <= 2; line++)
      fp.Fgets(buf, 255);
    type = (char)g_toupper(*buf);

    // Fido-style netmail path
    line++;
    fp.Fgets(buf, 255);
    strtrim(buf);
    strcpy(netpath, buf);

    // BADECHO area
    for(; line <= 8; line++)
      fp.Fgets(buf, 255);
    strtrim(buf);
    strcpy(badecho, buf);

    // Hudson path
    for(; line <= 11; line++)
      fp.Fgets(buf, 255);
    strtrim(buf);
    CfgHudsonpath(buf);

    // Primary address
    for(; line <= 15; line++)
      fp.Fgets(buf, 255);
    strtrim(buf);
    CfgAddress(buf);

    // Username
    for(; line <= 17; line++)
      fp.Fgets(buf, 255);
    strtrim(buf);
    //CfgUsername(buf);

    // Hudson netmail board
    for(; line <= 20; line++)   // NOTE: was 17 in older versions
      fp.Fgets(buf, 255);

    // Address/misc field
    if(type == 'F' or type == 'Q') {
      aa.reset();
      aa.type = GMB_NET;
      aa.attr = attribsnet;
      if(type == 'F') {
        aa.basetype = fidomsgtype;
        aa.setpath(strbtrim(netpath));
      }
      else if(type == 'Q') {
        strtrim(buf);
        aa.basetype = "HUDSON";
        aa.board = atoi(buf+50);
      }
      aa.setdesc("D'Bridge Netmail");
      aa.setautoid("NETMAIL");
      AddNewArea(aa);
    }

    strbtrim(badecho);
    if(*badecho) {
      aa.reset();
      aa.basetype = fidomsgtype;
      aa.type = GMB_ECHO;
      aa.attr = attribsecho;
      aa.setpath(badecho);
      aa.setdesc("D'Bridge Bad Messages");
      aa.setautoid("ECHO_BAD");
      AddNewArea(aa);
    }

    fp.Fclose();
  }

  // Read the areafile from the correct version
  MakePathname(file, dbpath, "dbridge.adf");
  if(fexist(file)) {
    long size = GetFilesize(file);
    if(size != -1L) {
      if(striinc("-2011", options))
        ReadDB2011(file, sizeof(DB2011_ADF), options);
      else if(striinc("-1047A27", options))
        ReadDB1047A22(file, sizeof(DB1047A27_ADF), options);
      else if(striinc("-1047A22", options))
        ReadDB1047A22(file, sizeof(DB1047A22_ADF), options);
      else if(striinc("-1046", options))
        ReadDB1046(file, options);
      else if((size % sizeof(DB2011_ADF)) == 0)
        ReadDB2011(file, sizeof(DB2011_ADF), options);
      else if((size % sizeof(DB1047A27_ADF)) == 0)
        ReadDB1047A22(file, sizeof(DB1047A27_ADF), options);
      else if((size % sizeof(DB1047A22_ADF)) == 0)
        ReadDB1047A22(file, sizeof(DB1047A22_ADF), options);
      else if((size % sizeof(DB1046_ADF)) == 0)
        ReadDB1046(file, options);
    }
  }
  else if(fexist(AddPath(dbpath, "DBRIDGE.AA1"))) {
    ReadDB130(options, dbpath);
  }
}


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