/***************************************************************************
 *                                                                         *
 *   SYNDFIL.CPP                                                           *
 *                                                                         *
 *   Copyright (c) 1998       Galacticomm, Inc.    All Rights Reserved.    *
 *                                                                         *
 *   Active HTML File Library File Detail Synthesis                        *
 *   Implementation                                                        *
 *                                                                         *
 *                                                - Phil Henning 11/17/98  *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"
#include "majorbbs.h"
#include "galacth.h"
#include "dnf.h"
#include "dnfmgr.h"
#include "ahutil.h"
#include "filtvb.h"
#include "syndfil.h"
#include "filagent.h"
#include "galfilah.h"

#define FILREV "$Revision: 10 $"

static
dnfStep dnfSuccessSteps[]={
     dnfStep(DNFMAPEND)
};
static
dnfMap filSuccessMap(PPFIX "/view/file/indexn.htm","Success Response",dnfSuccessSteps);

static
dnfStep dnfOSSuccessSteps[]={
     dnfStep(DNFMAPEND)
};
static
dnfMap filOSSuccessMap(PPFIX "/view/file/indexo.htm","Success Response",dnfOSSuccessSteps);

static
dnfStep dnfErrorSteps[]={
     dnfStep(DNFMAPEND)
};
static
dnfMap filErrorMap(PPFIX "/view/lib/error.htm","Error Response",dnfErrorSteps);

const CHAR*                             //  found file name
getFDFileName(                          // get found file name
const WIN32_FIND_DATA& fd);             //  find data struct

//
//  List Libs Synthesis Member Functions
//


synFileDetail::synFileDetail(
acthSession* _ses,
bool anonok,
INT lvlcnt)   : synBaseAuth(_ses,anonok,theFilAgent->m_hfilkey,lvlcnt)
              , m_fh(INVALID_HANDLE_VALUE)
{
     memset(&m_fllib,0,sizeof(struct fllib));
     memset(&m_flfile,0,sizeof(struct flfile));
     memset(&m_fb,0,sizeof(struct ffblk));
     memset(&m_key,0,sizeof(union combo));
}

synFileDetail::~synFileDetail()
{
     if (m_fh != INVALID_HANDLE_VALUE) {
          FindClose(m_fh);
     }
}


ACTHCODE
synFileDetail::proceedRequest()              // setup request context
{
     ACTHCODE rc=synBaseAuth::proceedRequest();

     if (rc != ACTHMORE) {
          return(rc);
     }
     if (ses->param("lib")) {
          INT sz=ses->paramRoom("lib");
          CHAR* val=new CHAR[sz+1];
          ses->param("lib",val,sz);
          struct fllib* libptr=libfind(val);
          if (libptr == NULL) {
               m_err=ERR_INVALIDLIB;
               m_errtext=val;
          }
          else if (m_usr == NULL && strlen(libptr->keyreq) > 0) {
               return(ACTHNOANON);
          }
          else if (!ahHasLibKey(m_usr,libptr,libptr->keyreq)) {
               return(ACTHFORBID);
          }
          delete [] val;
          if (libptr != NULL) {
               m_fllib=*libptr;
          }
     }
     else {
          m_err=ERR_PARAMMISSING;
          m_errtext="lib";
     }
     if (m_err == ERR_NOERROR) {
          if (ses->param("file")) {
               INT sz=ses->paramRoom("file");
               CHAR* val=new CHAR[sz+1];
               ses->param("file",val,sz);
               if (!CheckFileExists(val,m_fllib.flags&FLGDOS)) {
                    m_err=ERR_INVALIDFILE;
                    m_errtext=val;
               }
               delete [] val;
          }
          else {
               m_err=ERR_PARAMMISSING;
               m_errtext="file";
          }
     }
     m_SynState=SYNSTATE_SYNTH;
     return(rc);
}

bool
synFileDetail::CheckFileExists(              // check if file exists
const CHAR* filname,                         // filename
bool isOSOnly)                               // is file in os only lib?
{
     bool rc=false;

     if (isOSOnly) {
          ostrstream ost;
          ost << libpath(&m_fllib) << SLS << filname << ends;
          rc=fndfile(&m_fb,ost.str(),0);
          if ((m_fh=FindFirstFile(ost.str(),&m_findData)) != INVALID_HANDLE_VALUE) {
               strcpy(m_fb.ff_name,getFDFileName(m_findData));
          }
          ost.rdbuf()->freeze();
     }
     else {
          stlcpy(m_key.key1.libname,m_fllib.libname,FLNAMESZ);
          stlcpy(m_key.key1.filname,filname,FLFILENM);
          dfaSetBlk(flfdat);
          if (dfaQueryEQ(&m_key,COMPLF)) {
               rc=true;
               dfaAbsRec(&m_flfile,COMPLF);
          }
          dfaRstBlk();
     }
     return(rc);
}

ACTHCODE
synFileDetail::proceedSynth()                // proceed with synthesis
{
     m_SynState=SYNSTATE_RESPONSE;
     return(ACTHMORE);
}

ACTHCODE
synFileDetail::proceedDerivedResponse()      // proceed with response
{
     ACTHCODE rc=ACTHMORE;

     if (m_err != ERR_NOERROR) {
          if (m_dnf == NULL) {
               rc=errorResponse(filErrorMap,PPFIX "/view/file/");
          }
          else if (m_dnf->process() == DNFEND) {
               rc=ACTHDONE;
          }
          return(rc);
     }
     if (m_dnf == NULL) {
          CHAR ch=m_fllib.flags&FLGDOS ? 'O' : 'N';
          if (!(m_fllib.flags&FLGDOS)) {
               ::buildAllDetail(m_flfile.desc,&m_strDesc,&m_strDetail,&m_strDetailLine,&m_strDetailRaw,&m_strDetailJS);
          }
          CHAR* fnbuf;
          if (ses->urlargc() > m_lvlcnt) {
               const CHAR* fnptr=ses->urlargv(m_lvlcnt);
               fnbuf=new CHAR[strlen(fnptr)+1];
               strcpy(fnbuf,fnptr);
          }
          else {
               fnbuf=new CHAR[sizeof("INDEX*.HTM")+1];
               strcpy(fnbuf,"INDEX*.HTM");
          }
          m_strTemplate=fnbuf;
          strrpl(fnbuf,'*',ch);
          string strfname=PPFIX "/view/file/";
          strfname+=fnbuf;
          m_dnf=dnfCreateHandler(&bout,&filSuccessMap,strfname.c_str());
          delete [] fnbuf;

     }
     else {
          ::setLibVars(&m_fllib,m_usr);
          if (!(m_fllib.flags&FLGDOS)) {
               ::setFileVars(&m_flfile,m_usr);
               ::setFileDetailVars(m_strDesc,m_strDetail,m_strDetailLine,m_strDetailRaw,m_strDetailJS);
          }
          else {
               ::setOSFileVars(&m_fb,&m_fllib,m_usr);
          }
          if (m_dnf->process() == DNFEND) {
               rc=ACTHDONE;
          }
     }
     return(rc);
}

INT
synFileDetail::translateError()              // translate err to mcv file op
{
     switch (m_err) {
     case ERR_INVALIDLIB:
          return(ERRVF03);
     case ERR_PARAMMISSING:
          return(ERRVF01);
     case ERR_INVALIDFILE:
          return(ERRVF04);
     default:
          ASSERTM(FALSE,"Error in synFileDetail::translateError()");
     }
     m_errtext=spr("%d",m_err);
     return(ERROOPS);
}


