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

#include "gcomm.h"
#include "editques.h"
#include "dnfmgr.h"
#include "majorbbs.h"
#include <cstring>

#define FILREV "$Revision: 3 $"

#define EDITQUESDIR "questions/edit/"
#define ISSAVE      (ISPARAM("save"))
#define ISQUES      (ISPARAM("question"))
#define ANSSTGPARAM "ANSSTRING"
#define BRANCHPARAM "BRANCH"

enum {EDITQPARAM, EDITQRESP};

struct qTypes {
     SHORT qtype;
     const CHAR *desc;
};

struct qTypes quesTypeArray[]= {
     {CREDIT,    "CREDIT_CARD"},
     {DATE,      "DATE"},
     {DISONLY,   "DISPLAY_ONLY"},
     {MULTICHC,  "MULTIPLE_CHOICE"},
     {NUMERIC,   "NUMERIC_VALUE"},
     {YESNO,     "YES/NO"},
     {TRUEFALSE ,"TRUE/FALSE"},
     {OPEN_ENDED,"OPEN_ENDED"},
     {USERACCT,  "USER_ACCOUNT"},
     {0,         NULL}
};

struct qTypes accTypeArray[]={
    {ACCFLD_NAME0,     "NAME"},
    {ACCFLD_NAME1,     "NAME"},
    {ACCFLD_ADR_LINE_1,"ADDRESS1"},
    {ACCFLD_ADR_LINE_2,"ADDRESS2"},
    {ACCFLD_ADR_LINE_3,"ADDRESS3"},
    {ACCFLD_ADR_LINE_4,"ADDRESS4"},
    {ACCFLD_PHONE,     "PHONE"},
    {ACCFLD_BDAY,      "BIRTHDAY"},
    {ACCFLD_SEX,       "SEX"},
    {ACCFLD_ANSI,      "ANSI"},
    {ACCFLD_EDITOR,    "EDITOR"},
    {ACCFLD_PASSWORD,  "PASSWORD"},
    {0,                NULL}
};

// dynafile stuff

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

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

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


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

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

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

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

dnfMap dnfEditQErrMap(PPFIX EDITQUESDIR "error.htm","Edit Error Steps"
    ,dnfEditQErrSteps);
dnfMap dnfEditQDefPMap(PPFIX EDITQUESDIR "indexp.htm","Edit Index Steps"
    ,dnfEditQDefPSteps);
dnfMap dnfEditQDefQMap(PPFIX EDITQUESDIR "indexq.htm","Edit Index Steps"
    ,dnfEditQDefQSteps);
dnfMap dnfEditQuesnAnsMap(PPFIX EDITQUESDIR "quesnans.htm","Edit Question"
    ,dnfEditQuesnAnsSteps);
dnfMap dnfEditQuesTxtMap(PPFIX EDITQUESDIR "questext.htm","Edit Question"
    ,dnfEditQuesTxtSteps);
dnfMap dnfEditQuesNoBrMap(PPFIX EDITQUESDIR "quesnobr.htm","Edit Question"
    ,dnfEditQuesNoBrSteps);
dnfMap dnfEditQConfMap(PPFIX EDITQUESDIR "confques.htm","Edit Question"
    ,dnfEditQConfSteps);

// class method defs

MARKSOURCE(editQues);

editQuesSynthesis::editQuesSynthesis( // default constructor
                   acthSession *_ses):// session object
                   pManSynthesis(_ses),
                   m_bCreate(false)
{
     m_ahState=EDITQPARAM;
}

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

bool
editQuesSynthesis::saveQuestion()
{
     bool rc;
     if (m_pPoll->isQuestion(m_pQues->getNumber())) {
          rc=m_pQues->update();
     }
     else {
          rc=m_pQues->create();
     }
     if (!rc) {
          setError(ERRQSAVE);
     }
     return(rc);
}

VOID
editQuesSynthesis::setMap(
dnfMap *map)
{
     m_dnfPtr=dnfCreateHandlerURL(ses,map,PPFIX);
}

ACTHCODE
editQuesSynthesis::proceed()        // proceed entry point
{
     ACTHCODE retval;
     if ((retval=isUserOK()) != ACTHMORE) {
          return(retval);
     }

     if (m_cyc.start()) {
          do {
               switch (m_ahState) {
               case EDITQPARAM:
                    if (getPollNameParam() && getNumberParam()) {
                         if (ISSAVE && !ISQUES && getQTypeParam() && getAccFieldParam()
                          && getNextParam() && getPrevParam()
                          && getXmtDataParam() && getBranchParam()
                          && getChoicesParam() && getDefClsParam()) {
                              if (!saveQuestion()) {
                                   setMap(&dnfEditQErrMap);
                              }
                              else if (m_pQues->getQType() != MULTICHC) {
                                   setMap(&dnfEditQuesTxtMap);
                              }
                              else if (m_pQues->getFlags()&BRANCH) {
                                   setMap(&dnfEditQuesnAnsMap);
                              }
                              else {
                                   setMap(&dnfEditQuesNoBrMap);
                              }
                         }
                         else if (ISSAVE && ISQUES && getQTextParam()
                          && getAnsStringxParam() && getBranchxParam()) {
                              if (!saveQuestion()) {
                                   setMap(&dnfEditQErrMap);
                              }
                              else {
                                   setMap(&dnfEditQConfMap);
                              }
                         }
                         else if (ISSAVE) {
                              setMap(&dnfEditQErrMap);
                         }
                         else if (ISQUES
                          && m_pPoll->isQuestion(m_pQues->getNumber())) {
                              if (m_pQues->getQType() != MULTICHC) {
                                   setMap(&dnfEditQuesTxtMap);
                              }
                              else if (m_pQues->getFlags()&BRANCH) {
                                   setMap(&dnfEditQuesnAnsMap);
                              }
                              else {
                                   setMap(&dnfEditQuesNoBrMap);
                              }
                         }
                         else {
                              if (m_pPoll->getType() == QUEST) {
                                   setMap(&dnfEditQDefQMap);
                              }
                              else {
                                   setMap(&dnfEditQDefPMap);
                              }
                         }
                    }
                    else {
                         setMap(&dnfEditQErrMap);
                    }
                    m_ahState=EDITQRESP;
                    break;
               case EDITQRESP:
                    initRequest();
                    if (m_bCreate) {
                         t_QIsCreate=1;
                    }
                    if (m_pPoll != NULL && m_pAPI->isPoll(m_pPoll->getName())) {
                         m_pTvb->setPollEditVbs(m_pPoll);
                         if (m_pPoll->isQuestion(m_pQues->getNumber())) {
                              m_pTvb->setQuesEditVbs(m_pQues);
                              m_pTvb->setQuesListVbs(m_pQues);
                         }
                         else {
                              if (m_pQues->getNumber() < MAXQUES-1) {
                                  t_Next=m_pQues->getNumber()+2;
                              }
                              if (m_pQues->getNumber() > 0) {
                                  t_Prev=m_pQues->getPrevious()+1;
                              }
                              t_QNumber=m_pQues->getNumber();
                              t_QNumDisplay=m_pQues->getNumber()+1;
                         }
                    }
                    retval=dynafile();
                    break;
               }
          } while (m_cyc.haveTime() && retval != ACTHDONE);
     }
     return(retval);
}

bool
editQuesSynthesis::getPollNameParam()
{
     bool rc=false;
     GETPARAMVAL("pollname");
     if (m_pValBuf[0] == '\0') {
          setError(PVALNFND,"pollname");
     }
     else if (!m_pAPI->isPoll(m_pValBuf)) {
          setError(POLLNFND,m_pValBuf);
     }
     else {
          m_pPoll=new poll(m_pValBuf);
          rc=true;
     }
     return(rc);
}

bool
editQuesSynthesis::getNumberParam()
{
     SHORT sval;
     bool gotopen=m_pPoll->firstOpenQues(&sval);
     GETPARAMVAL("number");
     if (m_pValBuf[0] != '\0') {
          sval=atoi(m_pValBuf);
          if (sval < 0 || sval >= MAXQUES) {
               setError(INVVAL,"number");
               return(false);
          }
     }
     else if (!gotopen) {
          setError(NOMQUES);
          return(false);
     }
     else if (ISQUES) {
          setError(QUESNFND,m_pValBuf);
          return(false);
     }
     if (m_pPoll->isQuestion(sval)) {
          m_pQues=new question(m_pPoll->getName(),sval);
     }
     else {
          m_bCreate=true;
          m_pQues=new question(m_pPoll->getName());
          m_pQues->setNumber(sval);
          if (sval < MAXQUES-1) {
               m_pQues->setNext(sval+1);
          }
          if (sval > 0) {
               m_pQues->setPrevious(sval-1);
          }
     }
     return(true);
}

bool
editQuesSynthesis::getQTypeParam()
{
     bool rc=false;
     GETPARAMVAL("qtype");
     if (m_pValBuf[0] == '\0') {
          setError(NOPARAM,"qtype");
     }
     else {
          INT i=0;
          while (quesTypeArray[i].desc != NULL) {
               if (sameas(m_pValBuf,quesTypeArray[i].desc)) {
                    m_pQues->setQType(quesTypeArray[i].qtype);
                    m_pQues->setMinMaxDefaults();
                    rc=true;
                    break;
               }
               ++i;
          }
          if (!rc) {
               setError(INVVAL,"question type");
          }
     }
     return(rc);
}

bool
editQuesSynthesis::getAccFieldParam()
{
     bool rc=true;
     if (m_pQues->getQType() == USERACCT) {
          GETPARAMVAL("accfield");
          if (m_pValBuf[0] == '\0') {
               setError(NOPARAM,"Account Field");
               rc=false;
          }
          else {
               INT i=0;
               while (accTypeArray[i].desc != NULL) {
                    if (sameas(m_pValBuf,accTypeArray[i].desc)) {
                         m_pQues->setAccountField(accTypeArray[i].qtype);
                         rc=true;
                         break;
                    }
                    ++i;
               }
               if (!rc) {
                    setError(INVVAL,"account field");
               }
          }
     }
     return(rc);
}

bool
editQuesSynthesis::getNextParam()
{
     bool rc=false;
     if (m_pQues->getNumber() < MAXQUES-1) {
          GETPARAMVAL("next");
          if (m_pValBuf[0] == '\0') {
               setError(NOPARAM,"Next Question");
          }
          else {
               SHORT sval=atoi(m_pValBuf);
               if (sval < 1 || sval > MAXQUES) {
                    setError(INVVAL,"Next Question");
               }
               else {
                    m_pQues->setNext(sval-1);
                    rc=true;
               }
          }
     }
     else {
          rc=true;
     }
     return(rc);
}

bool
editQuesSynthesis::getPrevParam()
{
     bool rc=false;
     if (m_pQues->getNumber() > 0) {
          GETPARAMVAL("prev");
          if (m_pValBuf[0] == '\0') {
               setError(NOPARAM,"Previous question");
          }
          else {
               SHORT sval=atoi(m_pValBuf);
               if (sval < 1 || sval > MAXQUES) {
                    setError(INVVAL,"previous question");
               }
               else {
                    m_pQues->setPrevious(sval-1);
                    rc=true;
               }
          }
     }
     else {
          rc=true;
     }
     return(rc);
}

bool
editQuesSynthesis::getXmtDataParam()
{
     bool rc=true;
     GETPARAMVAL("xmtdata");
     if (m_pValBuf[0] == '\0') {
          setError(NOPARAM,"Exempt Data From Storage");
          rc=false;
     }
     else {
          SHORT flags=m_pQues->getFlags();
          if (sameas(m_pValBuf,"YES")) {
               flags|=EXMPT;
               m_pQues->setFlags(flags);
          }
          else if (sameas(m_pValBuf,"NO")) {
               flags&=~EXMPT;
               m_pQues->setFlags(flags);
          }
          else {
               setError(INVVAL,"xmtdata");
               rc=false;
          }
     }
     return(rc);
}

bool
editQuesSynthesis::getBranchParam()
{
     GETPARAMVAL("branch");
     bool rc=true;
     if (m_pQues->getQType() == MULTICHC) {
          if (m_pValBuf[0] == '\0') {
               setError(NOPARAM,"Branching");
               rc=false;
          }
          else {
               SHORT flags=m_pQues->getFlags();
               if (sameas(m_pValBuf,"YES")) {
                    flags|=BRANCH;
                    m_pQues->setFlags(flags);
               }
               else if (sameas(m_pValBuf,"NO")) {
                    flags&=~BRANCH;
                    m_pQues->setFlags(flags);
               }
               else {
                    setError(INVVAL,"branch");
                    rc=false;
               }
          }
     }
     return(rc);
}

bool
editQuesSynthesis::getDefClsParam()
{
     GETPARAMVAL("defcls");
     bool rc=true;
     if (m_pValBuf[0] == '\0') {
          setError(NOPARAM,"Clear Screen");
          rc=false;
     }
     else {
          SHORT flags=m_pQues->getFlags();
          if (sameas(m_pValBuf,"YES")) {
               flags|=CLRSCN;
               m_pQues->setFlags(flags);
          }
          else if (sameas(m_pValBuf,"NO")) {
               flags&=~CLRSCN;
               m_pQues->setFlags(flags);
          }
          else {
               setError(INVVAL,"defcls");
               rc=false;
          }
     }
     return(rc);
}


bool
editQuesSynthesis::getChoicesParam()
{
     GETPARAMVAL("choices");
     bool rc=true;
     if (m_pQues->getQType() == MULTICHC && !(m_pQues->getFlags()&BRANCH)) {
          SHORT sval=atoi(m_pValBuf);
          if (sval < 1 || sval > MAXASTGS) {
               setError(INVVAL,"choices");
               rc=false;
          }
          else {
               m_pQues->setNumAnswers(sval);
          }
     }
     else {
          m_pQues->setNumAnswers(1);
     }
     return(rc);
}

bool
editQuesSynthesis::getQTextParam()
{
     GETPARAMVAL("qtext");
     bool rc=false;
     if (m_pValBuf[0] == '\0') {
          setError(NOPARAM,"question text");
     }
     else {
          if (strlen(m_pValBuf) > TXTSIZ) {
               setError(TOOLONG,"question text",spr("%d",TXTSIZ));
          }
          else {
               m_pQues->setTextMsg(m_pValBuf);
               rc=true;
          }
     }
     return(rc);
}

bool
editQuesSynthesis::getAnsStringxParam()
{
     bool rc=true;
     bool setone=false;
     string paramName;
     if (m_pQues->getQType() == MULTICHC) {
          for (INT i=1; i <= MAXASTGS; i++) {
               paramName="";
               paramName+=ANSSTGPARAM;
               paramName+=ltoa(i);
               GETPARAMVAL(paramName.c_str());
               if (m_pValBuf[0] != '\0') {
                    setone=true; // setting if error - check below fails
                    if (strlen(m_pValBuf) > ANSSTGLEN) {
                         setError(TOOLONG,"answer string",spr("%d",ANSSTGLEN));
                         rc=false;
                         break;
                    }
                    m_pQues->setAnswerString(i-1,m_pValBuf);
               }
          }
          if (!setone) {
               setError(NOPARAM,"Answer String");
               rc=false;
          }
     }
     return(rc);
}

bool
editQuesSynthesis::getBranchxParam()
{
     bool rc=true;
     bool setone=false;
     string paramName;
     if (m_pQues->getQType() == MULTICHC && m_pQues->getFlags()&BRANCH) {
          for (INT i=1; i <= MAXASTGS; i++) {
               paramName="";
               paramName+=BRANCHPARAM;
               paramName+=ltoa(i);
               GETPARAMVAL(paramName.c_str());
               if (m_pValBuf[0] == '\0'
                && strlen(m_pQues->getAnswerString(i-1)) > 0) {
                    setError(NOBRANCH,spr("%d",i));
                    rc=false;
                    break;
               }
               else if (m_pValBuf[0] != '\0') {
                    SHORT sval=atoi(m_pValBuf);
                    if (sval <= m_pQues->getNumber()+1 || sval > MAXQUES) {
                         setError(INVVAL,paramName.c_str());
                         rc=false;
                         break;
                    }
                    else {
                         m_pQues->setBranch(i-1,sval-1);
                    }
               }
          }
     }
     return(rc);
}
