/***************************************************************************
 *                                                                         *
 *   LIBQUEUE.CPP                                                          *
 *                                                                         *
 *   Copyright (c) 1998,1999  Galacticomm, Inc.    All Rights Reserved.    *
 *                                                                         *
 *   Active HTML File Library Joined Library Queue                         *
 *   Implementation                                                        *
 *                                                                         *
 *                                                - Phil Henning 01/05/99  *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"
#include "majorbbs.h"
#include "galacth.h"
#include "filtdef.h"
#include "libqueue.h"
#include "filagent.h"

#define FILREV "$Revision: 4 $"

filLibMap::filLibMap()
{
     m_iter=m_map.end();
}

filLibMap::~filLibMap()
{
}

VOID
filLibMap::Init(                   // initialize the lib map
const struct fllib* pLib,          // ptr to lib or NULL for all libs
acthUserID* usr)                   // acthuser doing request
{
     m_usr=usr;
     if (pLib != NULL) {
          addLibToMap(pLib);
          addChildLibs(pLib);
     }
     else {
          for (int i=0 ; i < numoflib ; i++) {
               pLib=liboff(i);
               if (!(pLib->flags&FLGDOS) && checkLib(pLib)) {
                    addLibToMap(pLib);
               }
          }
     }
}

VOID
filLibMap::addChildLibs(           // add child libs
const struct fllib* pLib)          // for this library
{
     struct fllib* pCLib;

     for (int i=0 ; i < numoflib ; i++) {
          pCLib=liboff(i);
          if (isChildOf(pLib->libname,pCLib)
            && checkLib(pCLib)) {
               addLibToMap(pCLib);
          }
     }
}

bool
filLibMap::checkLib(               // check if user has access
const struct fllib* pLib)          // lib to check
{
     return (
          ahHasLibKey(m_usr,pLib,pLib->keyreq)
          && (!(pLib->flags&FLGHID) || checkParents(pLib))
     );
}

bool
filLibMap::checkParents(           // check parent libs
const struct fllib* pLib)          // of this lib
{
     struct fllib* libptr;
     for (int i=0 ; i < FLNMCATS ; i++) {
          if (pLib->cat[i][0] != '\0'
            && (libptr=libfind(pLib->cat[i])) != NULL
            && ahHasLibKey(m_usr,libptr,libptr->keyreq)) {
               return(true);
          }
     }
     return(false);
}


VOID
filLibMap::addLibToMap(                 // add lib to map
const struct fllib* pLib)               // lib to add
{
     string libname=pLib->libname;
     pair<STRSTORE,string> libPair(STRSTORE(libname),libname);
     m_map.insert(libPair);
}

const CHAR*
filLibMap::getFirstJoinedLibName()      // get name of first lib
{
     if (m_map.begin() == m_map.end()) {
          return(NULL);
     }
     return((*(m_map.begin())).second.c_str());
}


const CHAR*
filLibMap::getLastJoinedLibName()       // get name of last lib
{
     LIBMAP::iterator iter;
     iter=m_map.end();
     iter--;
     if (m_iter == m_map.end()) {
          return(NULL);
     }
     return((*iter).second.c_str());
}


const CHAR*
filLibMap::getCurrentJoinedLibName()    // get name of current lib
{
     if (m_iter == m_map.end()) {
          return(NULL);
     }
     return((*m_iter).second.c_str());
}


bool                                    // was there another lib?
filLibMap::getNextJoinedLib(            // go to next lib after libCurrent
INT direction,                          // direction to seek
CHAR* libCurrent)                       // ptr to receive name of next lib
{
     ASSERT(libCurrent != NULL);
     const CHAR* libname=Find(direction,libCurrent);
     if (libname != NULL) {
          stlcpy(libCurrent,libname,FLNAMESZ);
          return(true);
     }
     return(false);
}

const CHAR*                             // name of lib
filLibMap::Find(                        // find a lib
INT direction,                          // direction to seek
const CHAR* libname)                    // partial lib name
{
     m_iter=m_map.find(STRSTORE(string(libname)));
     if (m_iter == m_map.end() && direction != DIR_EQ) {
          // find gt or lt...
          m_iter=m_map.begin();
          while (m_iter != m_map.end()) {
               INT rc=stricmp((*m_iter).second.c_str(),libname);
               if (direction&DIR_GT) {
                    if (direction&DIR_GE && rc >= 0) {
                         break;
                    }
                    else if (rc > 0) {
                         break;
                    }
                    else {
                         ++m_iter;
                    }
               }
               else {
                    // DIR_LT
                    if (direction&DIR_LE && rc <= 0) {
                         break;
                    }
                    else if (rc < 0) {
                         break;
                    }
                    else {
                         --m_iter;
                    }
               }
          }
     }
     if (m_iter == m_map.end()) {
          return(NULL);
     }
     return((*m_iter).second.c_str());
}

VOID
filLibMap::seekBegin()             // go to first lib
{
     m_iter=m_map.begin();
}

VOID
filLibMap::seekEnd()               // go to last lib
{
     m_iter=m_map.end();
     m_iter--;
}

INT
filLibMap::GetNumberLibs()         // get the number of libs in map
{
     return((INT)(m_map.size()));
}

filLibMap
filLibMap::operator++ ()           // next lib
{
     m_iter++;
     return(*this);
}

filLibMap
filLibMap::operator++ (int)        // next lib
{
     m_iter++;
     return(*this);
}

filLibMap
filLibMap::operator-- ()           // previous lib
{
     m_iter--;
     return(*this);
}

filLibMap
filLibMap::operator-- (int)        // previous lib
{
     m_iter--;
     return(*this);
}


