/***************************************************************************
 *                                                                         *
 *   RESSYN.CPP                                                            *
 *                                                                         *
 *   Copyright (c) 1997 Galacticomm, Inc.                                  *
 *                                                                         *
 *                                                                         *
 *   Results Synthesis Class.                                              *
 *                                                  - N.C. Osterc  9/06/98 *
 *                                                                         *
 ***************************************************************************/

#include "ressyn.h"
#include "dnfmgr.h"
#include "majorbbs.h"

#define FILREV "$Revision: 9 $"

#define RESDIR "results/"

enum RESSTATE {AH_RESPARAM, AH_RESAXS, AH_RESQUES, AH_RESDYNA};

enum {RESITEM};

// dynafile stuff

dnfStep dnfResErrSteps[]={
     dnfStep(DNFMAPEND)
};

dnfStep resultsSteps[]={
     dnfStep(DNFTABLE),
          dnfStep(DNFCOLUMN,RESITEM,"LISTITEM"),
     dnfStep(DNFTABLEEND),
     dnfStep(DNFMAPEND)
};

dnfMap dnfResErrMap(PPFIX RESDIR "error.htm","Results Error Steps",dnfResErrSteps);
dnfMap ResultsMap(PPFIX RESDIR "index.htm","Results Steps",resultsSteps);

// class method defs

MARKSOURCE(ressyn);

resultsSynthesis::resultsSynthesis(   // default constructor
                   acthSession *_ses):  // session object
                   pollSynthesis(_ses),
                   m_error(FALSE),
                   m_currentQ(0),
                   m_doingTable(FALSE),
                   m_rowCount(0)
{
     m_ahState=AH_RESPARAM;
     m_pPoll=NULL;
}

resultsSynthesis::~resultsSynthesis()   // destructor
{
     if (m_pPoll != NULL) {
          delete m_pPoll;
          m_pPoll=NULL;
     }
}

const CHAR *
resultsSynthesis::getSynthDir()   // synth directory
{
     return(PPFIX RESDIR);
}

bool
resultsSynthesis::getQNumberParam()   // get qnumber parameter
{
     GETPARAMVAL("qnumber");
     if (m_pValBuf[0] == '\0') {
          m_currentQ=0;
     }
     else {
          m_currentQ=atoi(m_pValBuf);
          if (!m_pPoll->isQuestion(m_currentQ)) {
               ostrstream ostr;
               ostr << m_currentQ << ends;
               setError(ERRINVQN,ostr.str());
               return(FALSE);
          }
     }
     return(TRUE);
}

bool
resultsSynthesis::getPollNameParam() // check the pollname param
{
     GETPARAMVAL("pollname");
     if (m_pValBuf[0] == '\0') {
          setError(ERRNOPN);
     }
     else if (!m_pAPI->isPoll(m_pValBuf)) {
          setError(ERRINVPN);
     }
     else {
          m_pPoll=new poll(m_pValBuf);
          return(TRUE);
     }
     return(FALSE);
}

ACTHCODE
resultsSynthesis::proceed()       // proceed entry point
{
     ACTHCODE retval=ACTHMORE;

     if (!m_cyc.start()) {
          return(retval);
     }

     if ((retval=isUserOK()) != ACTHMORE) {
         return(retval);
     }

     do {
          switch (m_ahState) {
          case AH_RESPARAM:
               if (!getPollNameParam() || !getQNumberParam()) {
                    m_ahState=AH_RESDYNA;
                    m_error=TRUE;
               }
               else {
                    m_ahState=AH_RESAXS;
               }
               break;
          case AH_RESAXS:
               if (!m_usrPtr->hasKey(m_pPoll->getResultKey())
                || m_pPoll->getType() == QUESTIONNAIRE
                || m_pPoll->getAnswerType() == ACCUMULATE) {
                    return(ACTHFORBID);
               }
               else {
                    m_ahState=AH_RESQUES;
               }
               break;
          case AH_RESQUES:
               if (m_pPoll->nextTallied(m_currentQ,&m_talQnum)) {
                    m_pQues=m_pPoll->getQuestion(m_talQnum);
               }
               else {
                    setError(RESDONE);
                    m_error=TRUE;
               }
               m_ahState=AH_RESDYNA;
               break;
          case AH_RESDYNA:
               if (m_dnfPtr == NULL) {
                    if (m_error) {
                         if (handleDynaResp(TRUE,&dnfResErrMap,NULL)
                          == ACTHDONE) {
                              return(ACTHDONE);
                         }
                    }
                    else {
                         if (handleDynaResp(FALSE,NULL,&ResultsMap)
                          == ACTHDONE) {
                              return(ACTHDONE);
                         }
                    }
               }
               dnfSetTemplateTvb(m_dnfPtr);
               if (m_pPoll != NULL) {
                    m_pTvb->setListVariables(m_pPoll,NULL);
               }
               if (m_pQues != NULL) {
                    m_pTvb->setTakeVbs(m_pQues,NULL,FALSE);
               }
               if (m_error) {
                    retval=pollSynthesis::dynafile();
               }
               else {
                    retval=dynafile();
               }
               break;
          }
     } while (retval == ACTHMORE && m_cyc.haveTime());

     return(retval);
}

VOID
resultsSynthesis::setVariables()
{
     if (m_pQues == NULL) {
          m_pTvb->setResultsVbs(NULL,0);
     }
     else  if (m_rowCount >= MAXASTGS) {
          m_pTvb->setResultsVbs(m_pQues,0);
     }
     else {
          m_pTvb->setResultsVbs(m_pQues,m_rowCount);
     }
}

ACTHCODE
resultsSynthesis::dynafile()
{
     ACTHCODE retval=ACTHMORE;

     setVariables();

     switch (m_dnfPtr->process()) {
     case DNFROWBEGIN:
          if (m_pQues != NULL
           && m_rowCount >= MAXASTGS) {
               m_dnfPtr->tableDone();
               m_doingTable=FALSE;
               break;
          }
          if (m_pQues != NULL
           && (strlen(m_pQues->getAnswerString(m_rowCount))) == 0) {
               m_dnfPtr->sayAgain();
               ++m_rowCount;
               break;
          }
          m_doingTable=TRUE;
          setVariables();
          break;
     case DNFROWEND:
          ++m_rowCount;
          break;
     case DNFEND:
          retval=ACTHDONE;
          break;
     }
     return(retval);
}
