/***************************************************************************
 *                                                                         *
 *   LIBRARY.CPP                                                           *
 *                                                                         *
 *   Copyright (c) 1993-1997 Galacticomm, Inc.    All Rights Reserved.     *
 *                                                                         *
 *   File Library Wrapper Class                                            *
 *                                                                         *
 *                                                 - N.C. Osterc  11/04/98 *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"
#include "majorbbs.h"
#include "galfilh.h"
#include <cstring>
#include "libapi.h"
#include "library.h"
#include "file.h"

enum {LOGBEGIN, LOGNEXT, LOGCOPY, LOGPROCESS};

#define FILREV "$Revision: 4 $"
#define LOCKNUM    2
#define DAYSINWEEK 7
#define XFRSIZ     4800

MARKSOURCE(library);

library::library()                 // dfault constr
{
     m_delState=0;
     ::memset(static_cast<struct libdisk*>(this),0,sizeof(struct libdisk));
     m_fileNameBuf[0]='\0';
     m_logCode=LOGBEGIN;
}

library::library(                  // constructor
const CHAR *name)
{
     m_delState=0;
     ::memset(static_cast<struct libdisk*>(this),0,sizeof(struct libdisk));
     ::stlcpy(lib.libname,name,FLNAMESZ);
     m_fileNameBuf[0]='\0';
     m_logCode=LOGBEGIN;
     load();
}

library::~library()                // destructor
{
}

bool
library::load()                    // load lib information into class
{
     ASSERT(::strlen(lib.libname) > 0);

     bool          bResult=false;
     struct fllib* libptr=libfind(lib.libname);

     if (0 != libptr) {
          bResult=true;
          ::memmove(&(this->lib),libptr,sizeof(struct fllib));
          loadldsc(this);
     }
     return(bResult);
}

bool
library::clearLibMem()             // clear current library from memory
{
     ASSERT(strlen(lib.libname) > 0);

     bool           bResult=false;
     struct fllib*  libptr=libfind(lib.libname);

     if (0 != libptr) {
          bResult=true;
          ::memset(libptr,0,sizeof(struct fllib));
     }
     return(bResult);
}

bool
library::exists()                  // does lib exist?
{
     ASSERT(strlen(lib.libname) > 0);

     return(0 != libfind(lib.libname));
}

bool
library::create()                  // create new lib
{
     ASSERT(strlen(lib.libname) > 0);
     bool rc=false;

     libraryAPI* lAPI=new libraryAPI();

     if (!lAPI->outOfLibs()) {
          lib.day=today();
          lib.time=now();
          if (savelib(this)) {
               rc=true;
          }
     }
     delete lAPI;
     return(rc);
}

bool
library::update()                  // update existing lib
{
     ASSERT(strlen(lib.libname) > 0);

     return(!savelib(this));       // stupid API function returns false
                                   // if update successfully
}

FLMANCODE                          // indicates still working (false) or done (true)
library::removeFromDisk()          // remove this lib from disk
{
     ASSERT(strlen(lib.libname) > 0);

     if (!cycdelib(&m_delState,lib.libname,m_fileNameBuf)) {
          m_delState=0;
          return(FLMAN_SUCCESS);
     }
     return(FLMAN_WORKING);
}

const CHAR *
library::getLongDesc()             // get library long description
{
     m_strDesc="";

     for (INT z=0; z < NLDLIN; z++) {
          m_strDesc+=ldesc[z];
          m_strDesc+="\r";
     }
     return(m_strDesc.c_str());
}

bool
library::setLongDesc(              // set library long description
const CHAR *desc)
{
     ASSERT(0 != desc);

     setmem(&ldesc,NLDLIN*FLLDESCS,0);

     SHORT numrts=::itemcntd(desc,"\r\n");

     INT z=0;

     for (INT i=0; i < numrts; i++) {
          CHAR* line=::itemidxd(desc,i,"\r\n");
          if (strlen(line) >= FLLDESCS) {
               return(false);
          }
          else if (*line == '\0') {
               continue;
          }
          else {
               ::stlcpy(ldesc[z],line,FLLDESCS);
               ++z;
               if (z > NLDLIN) {
                    return(false);
               }
          }
     }
     return(true);
}

SHORT
library::getFilesAdded(            // set files added for part. day
SHORT day)
{
     ASSERT(day < ULDAYS);

     return(lib.newfiles[day]);
}

SHORT
library::getFilesAddedWeekly()     // get files added in past week
{
     SHORT tot=0;

     for (INT i=0; i < DAYSINWEEK; i++) {
          tot+=lib.newfiles[i];
     }
     return(tot);
}

bool
library::getWriteLock(             // obtain permission to write to lib
INT *locku)
{
     ASSERT(lib.libname != NULL);

     return ((*locku=w2writ(lib.libname,"*",LOCKNUM)) == NOCONFLICT);
}

VOID
library::releaseWriteLock()        // release lock
{
     donewrit(LOCKNUM);
}

struct fllib *
library::getLibMemPtr()
{
     return(libfind(this->lib.libname));
}

FLMANCODE
library::log(                      // log all files
CHAR *userid,
CHAR **lfname,
bool approve,
CHAR *pathToLog)
{
     string path=pathToLog;

     switch (m_logCode) {
     case LOGBEGIN:
          if (0 == path.length()) {
               path=getCurPath();
          }
          if (::fnd1st(&m_fblk,path.c_str(),0)) {
               m_logCode=LOGPROCESS;
          }
          else {
               return(FLMAN_SUCCESS);
          }
          break;
     case LOGPROCESS:
          logProcess(userid,lfname,approve);
          if (strlen(pathToLog) > 0) {
               m_srcFile=fileparts(GCPART_PATH,pathToLog,m_storePath,GCMAXPTH);
               m_destFile=fileparts(GCPART_PATH,getCurPath(),m_storePath,GCMAXPTH);
               if (!sameas(m_srcFile.c_str(),m_destFile.c_str())) {
                    m_srcFile+=m_fblk.ff_name;
                    m_destFile+=m_fblk.ff_name;
                    if ((m_srcf=::fopen(m_srcFile.c_str(),FOPRB)) != NULL
                     && (m_destf=::fopen(m_destFile.c_str(),FOPWB)) != NULL) {
                         m_logCode=LOGCOPY;
                         break;
                    }
               }
          }
          m_logCode=LOGNEXT;
          break;
     case LOGCOPY:
          *lfname=NULL;
          if (0 == xfrfil(m_srcf,m_destf,XRFSIZ)) {
               m_logCode=LOGNEXT;
          }
          break;
     case LOGNEXT:
          *lfname=NULL;
          if (!fndnxt(&m_fblk)) {
               m_logCode=LOGBEGIN;
               return(FLMAN_SUCCESS);
          }
          m_logCode=LOGPROCESS;
          break;
     default:
          ASSERTM(false,"Unhandled case in File Logging Switch");
     }
     return(FLMAN_WORKING);
}

VOID
library::logProcess(               // do some processing
CHAR *userid,
CHAR **loggedFile,
bool approve)
{
     file f(lib.libname,m_fblk.ff_name);
     if (!f.load() && f.nameOk()) {
          if (approve) {
               ::stlcpy(f.udate,ddat2srt(today()),DATESZ);
               f.utime=now();
          }
          else {
               ::stlcpy(f.udate,NOTAPPED,DATESZ);
               f.utime=0;
          }
          f.siz=m_fblk.ff_fsize;
          ::stlcpy(f.numdls,"0",NUMSZ);
          ::stlcpy(f.fdate,ddat2srt(m_fblk.ff_fdate),DATESZ);
          f.tim=m_fblk.ff_ftime;
          ::stlcpy(f.ulby,userid,UIDSIZ);
          ::memset(f.desc,0,DESCSIZ);
          if (f.log(approve)) {
               ::stlcpy(m_loggedFile,f.filname,FLFILENM);
               *loggedFile=m_loggedFile;
          }
     }
}

const CHAR *
library::getCurPath()              // get current lib path
{
     m_spath=lib.path;
     if (0 == m_spath.length()) {
          m_spath=".\\";
          m_spath+=lib.libname;
          m_spath+="\\*.*";
     }
     else {
          if (m_spath[m_spath.length()-1] == '\\') {
               m_spath+="*.*";
          }
          else {
               m_spath+="\\*.*";
          }
     }
     return(m_spath.c_str());
}
