///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoAdmScreen.cc  
// ----------------
// Cego admin screen
//
// Design and Implementation by Bjoern Lemke
//     
// (C)opyright 2000-2025 Bjoern Lemke
//
// IMPLEMENTATION MODULE
//
// Class: CegoAdmScreen
// 
// Description: Cursor based administration database administration frontend
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <lfcbase/Tokenizer.h>
#include <lfcbase/File.h>

#include "CegoAdmScreen.h"
#include "CegoXMLdef.h"
#include "CegoDefs.h"

#define INPUT_TYPE_STRING "S"
#define INPUT_TYPE_ID "I"
#define INPUT_TYPE_NUMBER "N"
#define INPUT_TYPE_PWD "P"
#define INPUT_TYPE_MENU "M"

#define MAXTIMELEN "25"
#define MAXNAMELEN "20"
#define MAXSIZELEN "15"
#define MAXIDLEN "10"

#define MAXPATHLEN "50"
#define MAXPASSWDLEN "20"
#define MAXQUERYCOL 25
#define MAXQUERYROW 4
#define QUERYSHORT 36

#define LASTACTIONSIZE 40

// ts status definition
#define TS_DEFINED_STATUS "DEFINED"
#define TS_ONLINE_STATUS "ONLINE"
#define TS_OFFLINE_STATUS "OFFLINE"
#define TS_RECOVERY_STATUS "RECOVERY"
#define TS_INCOMPLETE_STATUS "INCOMPLETE"

#define DEFREFINT 3000

// action defines

#define MSGBOX_WIDTH 60

#define HELPMASK_WIDTH 50
#define HELPMASK_HEIGHT 30

#define KEY_HLP 'h'
#define KEY_ABORT 'a'
#define KEY_NEW 'n'
#define KEY_DELETE 'd'
#define KEY_CONF 'c'
#define KEY_LASTQUERY 'l'
#define KEY_COSTQUERY 'c'

#define ERROR_TITLE "Cego Admin Error"
#define OK_TITLE "Cego Admin Info"

/////////////////////////////////////////////
// ##########  Buffer Pool Panel ##########//
/////////////////////////////////////////////

void CegoAdmScreen::BufferPool::refresh()	
{    
    ListT<ListT<CegoFieldValue> > poolinfo;

    CegoTableObject oe;
    
    _pAH->reqPoolInfo();
    
    _pAH->getPoolInfo(oe, poolinfo);
    
    ListT< ListT<Chain> > poolInfoAll;
    
    ListT<Chain> poolInfoA;
    ListT<CegoFieldValue> *pFVL = poolinfo.First();
    unsigned numAttr=0;
    while ( pFVL && numAttr < 9 )
    {
	Chain key, value;
	
	CegoFieldValue *pFV = pFVL->First();
	if ( pFV )
	{		       
	    key = pFV->valAsChain();
	}
	
	pFV = pFVL->Next();
	if ( pFV )
	{
	    value = pFV->valAsChain();
	}
	
	poolInfoA.Insert(key + VALSEPTOKEN + value);	    	    
	pFVL = poolinfo.Next();
	numAttr++;
    }
    
    poolInfoAll.Insert(poolInfoA);
    
    ListT<Chain> poolInfoB;
    
    while ( pFVL )
    {
	Chain key, value;
	
	CegoFieldValue *pFV = pFVL->First();
	if ( pFV )
	{		       
	    key = pFV->valAsChain();
	}
	
	pFV = pFVL->Next();
	if ( pFV )
	{
	    value = pFV->valAsChain();
	}
	
	poolInfoB.Insert(key + VALSEPTOKEN + value);	    	    
	pFVL = poolinfo.Next();
    }
    
    poolInfoAll.Insert(poolInfoB);
    
    ListT<Chain> titleList;
    titleList.Insert(Chain("Pool A"));
    titleList.Insert(Chain("Pool B"));
    
    setAttrList(titleList, poolInfoAll);
}


/////////////////////////////////////////////
// ##########  Thread Pool Panel ##########//
/////////////////////////////////////////////

CegoAdmScreen::ThreadPool::ThreadPool(CegoAdminHandler* pAH, Screen::Panel* pParent, const Chain& title) : Screen::Select(pParent)
{
    ListT<Chain> poolList;
    poolList.Insert(Chain("Db Pool=1"));
    poolList.Insert(Chain("Admin Pool=2"));
    setItems(title, 20, poolList);
    
    _pAH = pAH;
    
    _pDb = new DbPool(pAH, pParent);
    _pAdm = new AdmPool(pAH, pParent);
}

Screen::Panel* CegoAdmScreen::ThreadPool::onSelect(unsigned selected)
{
    if ( selected == 1 )
	return _pDb;
    else if ( selected == 2 )
	return _pAdm;
    return this;
}

CegoAdmScreen::ThreadPool::DbPool::DbPool(CegoAdminHandler* pAH, Screen::Panel* pParent)
    : Screen::Grid(pParent)
{
    _threadSchema.Insert(Chain("Tid") + VALSEPTOKEN + Chain("r3"));
    _threadSchema.Insert(Chain("CR") + VALSEPTOKEN + Chain("r5"));
    _threadSchema.Insert(Chain("QR") + VALSEPTOKEN + Chain("r10"));
    _threadSchema.Insert(Chain("Load") + VALSEPTOKEN + Chain("r5"));
    _threadSchema.Insert(Chain("SrtAlc") + VALSEPTOKEN + Chain("r10"));
    _threadSchema.Insert(Chain("LastAction") + VALSEPTOKEN + Chain("l") + Chain(LASTACTIONSIZE));
    _threadSchema.Insert(Chain("Status") + VALSEPTOKEN + Chain("l8"));
    
    ListT<Screen::GridColor> colorMap;
    
    colorMap.Insert(Screen::GridColor(Chain("BUSY"), SC_RED));
    colorMap.Insert(Screen::GridColor(Chain("READY"), SC_GREEN));
    colorMap.Insert(Screen::GridColor(Chain("CONNECTED"), SC_YELLOW));
    
    setSchema(Chain("DB Pool"), _threadSchema, colorMap, 0);
    
    _pAH = pAH;
    
    _pAbort = new ThreadAbort(_pAH, this);
    _pQuery = new ThreadQuery(_pAH, this);    
    _pHelp = new Screen::Message(this);
    _pHelp->setInfo(TPDB_HELP_TITLE, TPDB_HELP_TEXT, 6);
}

CegoAdmScreen::ThreadPool::DbPool::~DbPool()
{
    delete _pAbort;
    delete _pQuery;
    delete _pHelp;
}

Screen::Panel* CegoAdmScreen::ThreadPool::DbPool::onSelect(unsigned rowNum)
{
    unsigned threadId = _threadTable[rowNum-1][0].asUnsigned();

    CegoAdminHandler::ResultType res;
    res = _pAH->reqDbThreadHistory(threadId);

    if ( res == CegoAdminHandler::ADM_ERROR )
    {	
	Chain msg;
	_pAH->getMsg(msg);
	return setError(Chain(ERROR_TITLE), msg);
    }

    handleResult();

    _pQuery->setTitle("Last queries for thread " + Chain(threadId));
        
    return _pQuery;
}

Screen::Panel* CegoAdmScreen::ThreadPool::DbPool::onKey(unsigned c, unsigned rowNum)
{
    unsigned threadId = _threadTable[rowNum-1][0].asUnsigned();
    
    if ( c == KEY_ABORT )
    {
	_pAbort->setup(threadId);
	return _pAbort;
    }
    else if ( c == KEY_LASTQUERY )
    {
	CegoAdminHandler::ResultType res;
	res = _pAH->reqQueryHistoryLast(10);
	
	if ( res == CegoAdminHandler::ADM_ERROR )
	{	
	    Chain msg;
	    _pAH->getMsg(msg);
	    return setError(Chain(ERROR_TITLE), msg);
	}
	
	handleResult();

	_pQuery->setTitle("Last queries");
	
	return _pQuery;	
    }
    else if ( c == KEY_COSTQUERY )
    {
	CegoAdminHandler::ResultType res;
	res = _pAH->reqQueryHistoryCost(10);
	
	if ( res == CegoAdminHandler::ADM_ERROR )
	{	
	    Chain msg;
	    _pAH->getMsg(msg);
	    return setError(Chain(ERROR_TITLE), msg);
	}
	
	handleResult();

	_pQuery->setTitle("Most expensive queries");
	return _pQuery;	
    }
    else if ( c == KEY_HLP )
    {
	return _pHelp;
    }
    
    return this;
}

void CegoAdmScreen::ThreadPool::DbPool::handleResult()
{
    CegoTableObject oe;
    ListT<ListT<CegoFieldValue> > info;    
    Chain format;

    _pAH->getDbThreadHistory( oe, info, format);

    ListT<ListT<Chain> > queryHist;
    ListT<Chain> queryFull;
    
    ListT<CegoFieldValue> *pFVL = info.First();
    while ( pFVL )
    {
	ListT<Chain> queryRow;

	// Thread Index
	CegoFieldValue *pFV = pFVL->First();
	if ( pFV )
	    queryRow.Insert(pFV->valAsChain());

	// Timestamp
	pFV = pFVL->Next();
	if ( pFV )
	    queryRow.Insert(pFV->valAsChain());

	// Query
	pFV = pFVL->Next();
	if ( pFV )
	{
	    Chain query = pFV->valAsChain();
	    if ( query.length() > QUERYSHORT - 1 )
		queryRow.Insert(query.subChain(1, QUERYSHORT - 1));
	    else
		queryRow.Insert(query);
	    
	    queryFull.Insert(pFV->valAsChain());
	}
	
	// Cost
	pFV = pFVL->Next();
	if ( pFV )
	    queryRow.Insert(pFV->valAsChain());
	      
	queryHist.Insert(queryRow);
	pFVL = info.Next();
    }
    
    _pQuery->setHistory(queryHist);
    _pQuery->setQueryFull(queryFull);
}

CegoAdmScreen::ThreadPool::DbPool::ThreadQuery::ThreadQuery(CegoAdminHandler* pAH, Screen::Panel* pParent)		
    : Screen::Grid(pParent)
{
    _querySchema.Insert(Chain("Tid") + VALSEPTOKEN + Chain("r3"));
    _querySchema.Insert(Chain("Timestamp") + VALSEPTOKEN + Chain("l20"));
    _querySchema.Insert(Chain("Query") + VALSEPTOKEN + Chain("l") + Chain(QUERYSHORT));
    _querySchema.Insert(Chain("Cst(ms))") + VALSEPTOKEN + Chain("r10"));
    
    ListT<Screen::GridColor> colorMap;
    setSchema(Chain("Thread Query"), _querySchema, colorMap, 0);

    _pQueryInfo = new QueryInfo(this);
    _pAH = pAH;
}

CegoAdmScreen::ThreadPool::DbPool::ThreadQuery::~ThreadQuery()
{
}

Screen::Panel* CegoAdmScreen::ThreadPool::DbPool::ThreadQuery::onSelect(unsigned rowNum)
{
    if ( _queryFull.Size() >= rowNum )
    {
	Chain query = _queryFull[rowNum-1];
	
	Chain formatted;
	unsigned numRow = format(query, formatted);
	
	_pQueryInfo->setQuery(Chain("Query"), formatted, numRow);
	
	return _pQueryInfo;
    }
    return this;
}

void CegoAdmScreen::ThreadPool::DbPool::ThreadQuery::setTitle(const Chain& title)
{
    ListT<Screen::GridColor> colorMap;
    setSchema(title, _querySchema, colorMap, 0);
}

void CegoAdmScreen::ThreadPool::DbPool::ThreadQuery::setHistory( ListT< ListT< Chain> >& queryHist)
{    
    _queryTable = queryHist;
}

void CegoAdmScreen::ThreadPool::DbPool::ThreadQuery::setQueryFull( ListT<Chain>& queryFull)
{    
    _queryFull = queryFull;
}

unsigned CegoAdmScreen::ThreadPool::DbPool::ThreadQuery::format(const Chain& query, Chain& formatted)
{
    Tokenizer tok(query, Chain(" "));
    Chain t;
    unsigned lineLen = 0;
    unsigned numRow=1;
    while ( tok.nextToken(t) )
    {
	formatted += t;
	lineLen+=t.length() + 1;
	if ( lineLen > MAXQUERYCOL )
	{
	    formatted += Chain("\n");
	    numRow++;
	    lineLen=0;
	}
	else
	    formatted += Chain(" ");	
    }

    return numRow;
}

CegoAdmScreen::ThreadPool::DbPool::ThreadAbort::ThreadAbort(CegoAdminHandler* pAH, Screen::Panel* pParent)
    
    : Screen::Confirm(pParent)
{
    _pAH = pAH;
}

CegoAdmScreen::ThreadPool::DbPool::ThreadAbort::~ThreadAbort()
{
}		   

void CegoAdmScreen::ThreadPool::DbPool::ThreadAbort::setup(unsigned threadId)
{    
    _threadId = threadId;
    setInfo(Chain("Abort Thread ") + Chain(threadId) + Chain("?"), Chain("More thread details"));
}

Screen::Panel* CegoAdmScreen::ThreadPool::DbPool::ThreadAbort::onConfirm()
{
    CegoAdminHandler::ResultType res;   
    res = _pAH->reqDbThreadAbort(_threadId);
       
    if ( res == CegoAdminHandler::ADM_ERROR )
    {	
	Chain msg;
	_pAH->getMsg(msg);
	return setError(Chain(ERROR_TITLE), msg);
    }
    
    return _pParent;
}

void CegoAdmScreen::ThreadPool::DbPool::refresh()
{
    ListT<ListT<CegoFieldValue> > dbthreadinfo;
    
    CegoAdminHandler::ResultType res;
    CegoTableObject oe;
    Chain format;    
    
    res = _pAH->reqDbThreadInfo();

    if ( res == CegoAdminHandler::ADM_ERROR )
    {	
	Chain msg;
	_pAH->getMsg(msg);
	setStatus(msg);
	return;
    }

    _pAH->getDbThreadInfo(oe, dbthreadinfo, format);
    
    _threadTable.Empty();
    
    ListT<CegoFieldValue> *pFVL = dbthreadinfo.First();
    while ( pFVL )
    {
	ListT<Chain> threadRow;

	// Thread Index
	CegoFieldValue *pFV = pFVL->First();
	if ( pFV )
	    threadRow.Insert(pFV->valAsChain());
	
        // # connection request 
	pFV = pFVL->Next();
	if ( pFV )
	    threadRow.Insert(pFV->valAsChain());

	// # query request 
	pFV = pFVL->Next();
	if ( pFV )
	    threadRow.Insert(pFV->valAsChain());

	// load 
	pFV = pFVL->Next();
	if ( pFV )
	    threadRow.Insert(pFV->valAsChain());

	// allocated sort 
	pFV = pFVL->Next();
	if ( pFV )
	    threadRow.Insert(pFV->valAsChain());

	// last action 
	pFV = pFVL->Next();
	if ( pFV )
	{
	    Chain lastAction = pFV->valAsChain();
	    if ( lastAction.length() > LASTACTIONSIZE - 1)
		lastAction = lastAction.subChain(1, LASTACTIONSIZE - 1);
	    threadRow.Insert(lastAction);
	}

	// status
	pFV = pFVL->Next();
	if ( pFV )
	    threadRow.Insert(pFV->valAsChain());
	
	
	_threadTable.Insert(threadRow);
	pFVL = dbthreadinfo.Next();
    }
}

CegoAdmScreen::ThreadPool::AdmPool::AdmPool(CegoAdminHandler* pAH, Screen::Panel* pParent)
    : Screen::Grid(pParent)
{   
    _threadSchema.Insert(Chain("Tid") + VALSEPTOKEN + Chain("r3"));
    _threadSchema.Insert(Chain("Req") + VALSEPTOKEN + Chain("r8"));
    _threadSchema.Insert(Chain("Load") + VALSEPTOKEN + Chain("r5"));
    _threadSchema.Insert(Chain("Status") + VALSEPTOKEN + Chain("l8"));
    
    ListT<Screen::GridColor> colorMap;
    setSchema(Chain("Admin Pool"), _threadSchema, colorMap, 0);
    
    _pAH = pAH;
}

void CegoAdmScreen::ThreadPool::AdmPool::refresh()
{
    ListT<ListT<CegoFieldValue> > admthreadinfo;
    
    CegoAdminHandler::ResultType res;
    CegoTableObject oe;
    Chain format;    
    
    res = _pAH->reqAdmThreadInfo();

    if ( res == CegoAdminHandler::ADM_ERROR )
    {	
	Chain msg;
	_pAH->getMsg(msg);
	setStatus(msg);
	return;
    }

    _pAH->getAdmThreadInfo(oe, admthreadinfo, format);

    _threadTable.Empty();
	
    ListT<CegoFieldValue> *pFVL = admthreadinfo.First();
    while ( pFVL )
    {
	ListT<Chain> threadRow;
	
	CegoFieldValue *pFV = pFVL->First();
	while ( pFV )
	{
	    threadRow.Insert(pFV->valAsChain());
	    pFV = pFVL->Next();
	}
	
	_threadTable.Insert(threadRow);
	pFVL = admthreadinfo.Next();
    }
}

//////////////////////////////////////////
// ##########  Tableset Panel ##########//
//////////////////////////////////////////

CegoAdmScreen::TableSet::TableSet(CegoAdminHandler* pAH, Screen::Panel* pParent, const Chain& title)
	    : Screen::Grid(pParent)
{
    
    _tsSchema.Insert(Chain("Name") + VALSEPTOKEN + Chain("l10"));
    _tsSchema.Insert(Chain("State") + VALSEPTOKEN + Chain("l12"));
    _tsSchema.Insert(Chain("Arch") + VALSEPTOKEN + Chain("l5"));
    _tsSchema.Insert(Chain("Sys") + VALSEPTOKEN + Chain("r6"));
    _tsSchema.Insert(Chain("Tmp") + VALSEPTOKEN + Chain("r6"));
    _tsSchema.Insert(Chain("App") + VALSEPTOKEN + Chain("r6"));
    
    ListT<Screen::GridColor> colorMap;
    setSchema(Chain("Tableset"), _tsSchema, colorMap, 0);
    
    _pAdd = new Add(pAH, this, Chain("Tableset Edit"));
    _pAction = new Action(pAH, this);
    _pHelp = new Screen::Message(this);
    _pHelp->setInfo(TS_HELP_TITLE, TS_HELP_TEXT,5);
    _pAH = pAH;    
}

CegoAdmScreen::TableSet::~TableSet()
{
    delete _pAdd;
    delete _pAction;
    delete _pHelp;
}

Screen::Panel* CegoAdmScreen::TableSet::onSelect(unsigned selected)
{
    _pAction->setTableSet(_tsTable[selected-1][0], _tsTable[selected-1][1], _tsTable[selected-1][3]);
    return _pAction;
}

Screen::Panel* CegoAdmScreen::TableSet::onKey(unsigned c, unsigned rowNUm)
{    
    if ( c == KEY_NEW )
    {
	_pAdd->reset();
	return _pAdd;
    }
    else if ( c == KEY_HLP )
    {
	return _pHelp;
    }
    return this;
}

void CegoAdmScreen::TableSet::refresh()
{
    CegoAdminHandler::ResultType res;    
    res = _pAH->reqGetTableSetList(true);
    
    while ( res == CegoAdminHandler::ADM_INFO )
    {
	res = _pAH->nextInfo();	    
    }
    
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);
    }

    CegoTableObject oe;	
    ListT<ListT<CegoFieldValue> > tsList;
    _pAH->getTableSetList(oe, tsList, true);

    _tsTable.Empty();
    
    ListT<CegoFieldValue> *pFVL = tsList.First();
    while ( pFVL )
    {
	ListT<Chain> tsRow;
	
	CegoFieldValue *pFV = pFVL->First();
	while ( pFV )
	{
	    tsRow.Insert(pFV->valAsChain());
	    pFV = pFVL->Next();
	}
	
	_tsTable.Insert(tsRow);
	pFVL = tsList.Next();
    }
}

//////////////////////////
// Tableset Panel - Add //
//////////////////////////

CegoAdmScreen::TableSet::Add::Add(CegoAdminHandler* pAH, Screen::Panel* pParent, const Chain& title)
		: Screen::Form(pParent)
{
    
    ListT<Chain> attrList; 
    attrList.Insert( Chain("Name") + ATTRSEPTOKEN + INPUT_TYPE_ID + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + Chain("TabNetName"));
    attrList.Insert( Chain("Root Path") + ATTRSEPTOKEN + INPUT_TYPE_STRING + ATTRSEPTOKEN + MAXPATHLEN + ATTRSEPTOKEN + Chain("./RootPath"));
    attrList.Insert( Chain("SystemSpace") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXSIZELEN + ATTRSEPTOKEN + Chain("100"));
    attrList.Insert( Chain("TempSpace") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXSIZELEN + ATTRSEPTOKEN + Chain("100"));
    attrList.Insert( Chain("AppSpace") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXSIZELEN + ATTRSEPTOKEN + Chain("500"));
    attrList.Insert( Chain("LogSize") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXSIZELEN + ATTRSEPTOKEN + Chain("1000000"));
    attrList.Insert( Chain("LogNum") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXSIZELEN + ATTRSEPTOKEN + Chain("3"));
    attrList.Insert( Chain("Sort Area Size") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXSIZELEN + ATTRSEPTOKEN + Chain("1000000"));
    attrList.Insert( Chain("BranchId") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXSIZELEN + ATTRSEPTOKEN + Chain("0"));

    setAttrList(title, attrList, 15);
    
    _pAH = pAH;    
}

CegoAdmScreen::TableSet::Add::~Add()
{
}
	    
Screen::Panel* CegoAdmScreen::TableSet::Add::onConfirm(const ListT<Chain>& valList)
{
    Chain tableSet = valList[0];
    Chain tsRoot = valList[1];
    unsigned sysSize = valList[2].asUnsigned();
    unsigned tmpSize = valList[3].asUnsigned();
    unsigned appSize = valList[4].asUnsigned();
    unsigned logSize = valList[5].asUnsigned();
    unsigned logNum = valList[6].asUnsigned();
    unsigned long long sortAreaSize = valList[7].asUnsignedLongLong();
    unsigned branchId = valList[8].asUnsigned();
    
    CegoAdminHandler::ResultType res;
    res = _pAH->reqDefineTableSet(tableSet,
				  tsRoot,
				  sysSize,
				  tmpSize,
				  appSize,
				  logSize,
				  logNum, 
				  sortAreaSize,
				  branchId);
    
    Chain msg;
    _pAH->getMsg(msg);
    
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	return setError(Chain(ERROR_TITLE), msg);
    }
    
    return _pParent;
}

///////////////////////
// Tableset - Action //
///////////////////////

CegoAdmScreen::TableSet::Action::Action(CegoAdminHandler* pAH, Screen::Panel* pParent)
		: Screen::Select(pParent)
{
    _pAH = pAH;
    _pEdit = new Edit(_pAH, pParent);
    _pFilePanel = new FilePanel(_pAH, pParent);
    _pInfoPanel = new InfoPanel(_pAH, pParent);
    _pArch = new Archlog(_pAH, pParent);
    _pBackup = new Backup(_pAH, pParent);
    _pRestore = new Restore(pAH, pParent);
    _pRecover = new Recover(pAH, pParent);
    _pXPort = new XPort(_pAH, pParent);
    _pDrop = new Drop(_pAH, pParent);
    _pQueryCache = new QueryCache(_pAH, pParent);
    _pTableCache = new TableCache(_pAH, pParent);
    _pParameter = new Parameter(_pAH, pParent);    
}

CegoAdmScreen::TableSet::Action::~Action()
{
    delete _pEdit;
    delete _pFilePanel;
    delete _pInfoPanel;
    delete _pArch;
    delete _pXPort;
    delete _pBackup;
    delete _pRestore;
    delete _pRecover;
    delete _pDrop;
    delete _pQueryCache;
    delete _pTableCache;
}

void CegoAdmScreen::TableSet::Action::setTableSet(const Chain& tableSet, const Chain& tsState, const Chain& archMode)
{
    _archMode = archMode;
    _tableSet = tableSet;
    ListT<Chain> items;
    
    items.Insert(Chain("Info=0"));

    if ( tsState == Chain(TS_RECOVERY_STATUS) )
    {
	items.Insert(Chain("Stop recovery=16"));
    }
    else if ( tsState == Chain(TS_ONLINE_STATUS) )
    {
	items.Insert(Chain("Stop=1"));
	items.Insert(Chain("Export=2"));
	items.Insert(Chain("Import=3"));
	items.Insert(Chain("Datafile=12"));
	items.Insert(Chain("Archlog=13"));
	items.Insert(Chain("Backup=14"));	    
    }
    else if ( tsState == Chain(TS_OFFLINE_STATUS) )
    {
	items.Insert(Chain("Start=4"));
	items.Insert(Chain("Drop=5"));
	items.Insert(Chain("QueryCache=6"));
	items.Insert(Chain("TableCache=7"));
	items.Insert(Chain("Parameter=8"));
	items.Insert(Chain("Start recovery=15"));
	items.Insert(Chain("Restore=17"));
	items.Insert(Chain("Recover=18"));
	items.Insert(Chain("Datafile=12"));
	items.Insert(Chain("Archlog=13"));
	items.Insert(Chain("Backup=14"));
    }
    else if ( tsState == Chain(TS_DEFINED_STATUS) )
    {
	items.Insert(Chain("Edit=9"));
	items.Insert(Chain("Create=10"));
	items.Insert(Chain("Remove=11"));
	items.Insert(Chain("Datafile=12"));
	items.Insert(Chain("Archlog=13"));
    }
    else if ( tsState == Chain(TS_INCOMPLETE_STATUS) )
    {
	items.Insert(Chain("Recover=18"));
    }
    	    
    setItems(_tableSet + Chain(" - ") + tsState, 50, items);

    _pInfoPanel->setup(_tableSet);
    _pArch->setup(_tableSet, _archMode);
    _pFilePanel->setup(_tableSet);
    _pBackup->setup(_tableSet, tsState);
    _pRestore->setup(_tableSet);
    _pRecover->setup(_tableSet);
    _pDrop->setup(_tableSet);
    _pQueryCache->setup(_tableSet);
    _pTableCache->setup(_tableSet);
    _pParameter->setup(_tableSet);
    _pEdit->setup(_tableSet);
}

Screen::Panel* CegoAdmScreen::TableSet::Action::onSelect(unsigned selected)
{    
    unsigned action = getSelectedValue().asUnsigned();
    
    switch ( action )
    {
    case 0:
    {
	return _pInfoPanel;	     
    }
    case 1:
    {
	CegoAdminHandler::ResultType res;
	res = _pAH->reqStopTableSet(_tableSet);
	
	Chain msg;
	_pAH->getMsg(msg);
	
	if ( res == CegoAdminHandler::ADM_ERROR )
	{
	    return setError(Chain(ERROR_TITLE), msg);
	}
	break;
    }
    case 2:
    {
	_pXPort->setup(_tableSet, true);
	return _pXPort;
    }
    case 3:
    {
	_pXPort->setup(_tableSet, false);
	return _pXPort;	     
    }
    case 4:
    {
	bool doCleanup=false;
	bool doForceload=false;
	bool cpDump=false;
	bool noInit=false;
	
	CegoAdminHandler::ResultType res;
	res = _pAH->reqStartTableSet(_tableSet, doCleanup, doForceload, cpDump, noInit);
	
	Chain msg;
	_pAH->getMsg(msg);
	
	if ( res == CegoAdminHandler::ADM_ERROR )
	{
	    return setError(Chain(ERROR_TITLE), msg);
	}
	break;
    }
    case 5:
    {
	return _pDrop;
    }
    case 6:
    {
	return _pQueryCache;
    }
    case 7:
    {
	return _pTableCache;
    }
    case 8:
    {
	return _pParameter;
    }   
    case 9:
    {
	return _pEdit;
    }
    case 10:
    {
	CegoAdminHandler::ResultType res;
	res = _pAH->reqCreateTableSet(_tableSet);
		
	Chain msg;
	_pAH->getMsg(msg);
	
	if ( res == CegoAdminHandler::ADM_ERROR )
	{
	    return setError(Chain(ERROR_TITLE), msg);
	}
	break;
    }
    case 11:
    {
	CegoAdminHandler::ResultType res;
	res = _pAH->reqRemoveTableSet(_tableSet);
	    
	Chain msg;
	_pAH->getMsg(msg);
	if ( res == CegoAdminHandler::ADM_ERROR )
	{
	    return setError(Chain(ERROR_TITLE), msg);
	}
	break;
    }
    case 12:
    {
	return _pFilePanel;
    }
    case 13:
    {
	return _pArch;
    }
    case 14:
    {
	return _pBackup;
    }
    case 15:
    {
	
	CegoAdminHandler::ResultType res;
	res = _pAH->reqStartRecovery(_tableSet);
	
	Chain msg;
	_pAH->getMsg(msg);
	
	if ( res == CegoAdminHandler::ADM_ERROR )
	{
	    return setError(Chain(ERROR_TITLE), msg);
	}
	break;
    }
    case 16:
    {
	
	CegoAdminHandler::ResultType res;
	res = _pAH->reqStopRecovery(_tableSet);
	
	Chain msg;
	_pAH->getMsg(msg);
	
	if ( res == CegoAdminHandler::ADM_ERROR )
	{
	    return setError(Chain(ERROR_TITLE), msg);
	}
	break;
    }
    case 17:
    {
	return _pRestore;
    }
    case 18:
    {
	return _pRecover;
    }
    }

    return _pParent;
}

//////////////////////////////
// Tableset - Action - Edit //
//////////////////////////////

CegoAdmScreen::TableSet::Action::Edit::Edit(CegoAdminHandler* pAH, Screen::Panel* pParent)
		: Screen::Form(pParent)
{   
    _pAH = pAH;    
}

CegoAdmScreen::TableSet::Action::Edit::~Edit()
{
}

void CegoAdmScreen::TableSet::Action::Edit::setup(const Chain& tableSet)
{
    _tableSet = tableSet;
    
    ListT< ListT<CegoFieldValue> > tsInfo;
    
    CegoAdminHandler::ResultType res;
    CegoTableObject oe;	
    
    res = _pAH->reqGetDetailedTSInfo(_tableSet);	
    
    while ( res == CegoAdminHandler::ADM_INFO )
    {
	res = _pAH->nextInfo();	    
    }
    
    _pAH->getDetailedTableSetInfo(oe, tsInfo);

    Chain defTableSet;
    Chain rootPath;
    Chain sysSize;
    Chain tempSize;
    Chain appSize;
    Chain logSize;
    Chain sortAreaSize;
    Chain logNum;
    Chain branchId;
    
    ListT<CegoFieldValue> *pFVL = tsInfo.First();
    while ( pFVL )
    {
	Chain key, value;
	
	CegoFieldValue *pFV = pFVL->First();
	if ( pFV )
	{		       
	    key = pFV->valAsChain();
	}
	
	pFV = pFVL->Next();
	if ( pFV )
	{
	    value = pFV->valAsChain();
	}
	if ( key == Chain(INFO_TABLESET) )
	{
	    defTableSet = value;
	}
	else if ( key == Chain(INFO_ROOTPATH) )
	{
	    rootPath = value;
	}
	else if ( key == Chain(INFO_SYSTEMPAGETOTAL))
	{
	    sysSize = value;
	}
	else if ( key == Chain(INFO_TEMPPAGETOTAL))
	{
	    tempSize = value;
	}
	else if ( key == Chain(INFO_APPPAGETOTAL))
	{
	    appSize = value;
	}
	else if ( key == Chain(INFO_SORTAREASIZE))
	{
	    sortAreaSize = value;
	}
	else if ( key == Chain(INFO_LOGSIZE))
	{
	    logSize = value;
	}
	else if ( key == Chain(INFO_LOGNUM))
	{
	    logNum = value;
	}
	else if ( key == Chain(INFO_BRANCHID))
	{
	    branchId = value;
	}

	pFVL = tsInfo.Next();
    }
    
    ListT<Chain> attrList; 
    attrList.Insert( Chain("Name") + ATTRSEPTOKEN + INPUT_TYPE_ID + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + defTableSet);
    attrList.Insert( Chain("Root Path") + ATTRSEPTOKEN + INPUT_TYPE_STRING + ATTRSEPTOKEN + MAXPATHLEN + ATTRSEPTOKEN + rootPath);
    attrList.Insert( Chain("SystemSpace") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXSIZELEN + ATTRSEPTOKEN + sysSize);
    attrList.Insert( Chain("TempSpace") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXSIZELEN + ATTRSEPTOKEN + tempSize);
    attrList.Insert( Chain("AppSpace") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXSIZELEN + ATTRSEPTOKEN + appSize);
    attrList.Insert( Chain("LogSize") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXSIZELEN + ATTRSEPTOKEN + logSize);
    attrList.Insert( Chain("LogNum") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXSIZELEN + ATTRSEPTOKEN + logNum);
    attrList.Insert( Chain("SortAreaSize") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXSIZELEN + ATTRSEPTOKEN + sortAreaSize);
    attrList.Insert( Chain("BranchId") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXSIZELEN + ATTRSEPTOKEN + branchId);
    setAttrList(_tableSet, attrList, 20);
}

Screen::Panel* CegoAdmScreen::TableSet::Action::Edit::onConfirm(const ListT<Chain>& valList)
{
    Chain tableSet = valList[0];
    Chain tsRoot = valList[1];
    unsigned sysSize = valList[2].asUnsigned();
    unsigned tmpSize = valList[3].asUnsigned();
    unsigned appSize = valList[4].asUnsigned();
    unsigned logSize = valList[5].asUnsigned();
    unsigned logNum = valList[6].asUnsigned();
    unsigned long long sortAreaSize = valList[7].asUnsignedLongLong();
    unsigned branchId = valList[8].asUnsigned();
    
    // to edit tableset in state DEFINED, we just remove the whole tableset and define it new
    
    CegoAdminHandler::ResultType res;
    res = _pAH->reqRemoveTableSet(_tableSet);
    
    Chain msg;
    _pAH->getMsg(msg);
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	return setError(Chain(ERROR_TITLE), msg);
    }

    res = _pAH->reqDefineTableSet(tableSet,
				  tsRoot,
				  sysSize,
				  tmpSize,
				  appSize,
				  logSize,
				  logNum, 
				  sortAreaSize,
				  branchId);
    
    _pAH->getMsg(msg);
    
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	return setError(Chain(ERROR_TITLE), msg);
    }
    
    return _pParent;
}


//////////////////////////////
// Tableset - Action - Info //
//////////////////////////////

CegoAdmScreen::TableSet::Action::InfoPanel::InfoPanel(CegoAdminHandler* pAH, Screen::Panel* pParent)
    : Screen::Attribute(pParent, Attribute::OVERLAY)
{
    _pAH = pAH;    
}

void CegoAdmScreen::TableSet::Action::InfoPanel::setup(const Chain& tableSet)
{
    _tableSet = tableSet;
}
	    
void CegoAdmScreen::TableSet::Action::InfoPanel::refresh()
{
    ListT< ListT<CegoFieldValue> > tsInfo;
    
    CegoAdminHandler::ResultType res;
    CegoTableObject oe;	
    
    res = _pAH->reqGetDetailedTSInfo(_tableSet);	
    
    while ( res == CegoAdminHandler::ADM_INFO )
    {
	res = _pAH->nextInfo();	    
    }
    
    _pAH->getDetailedTableSetInfo(oe, tsInfo);
    
    ListT<Chain> tsMonInfo1;
    ListT<Chain> tsMonInfo2;
    
    ListT<CegoFieldValue> *pFVL = tsInfo.First();
    unsigned row=1;
    while ( pFVL )
    {
	Chain key, value;
	
	CegoFieldValue *pFV = pFVL->First();
	if ( pFV )
	{		       
	    key = pFV->valAsChain();
	}
	
	pFV = pFVL->Next();
	if ( pFV )
	{
	    value = pFV->valAsChain();
	}
	
	if ( row < 20 )
	    tsMonInfo1.Insert(key + VALSEPTOKEN + value);
	else
	    tsMonInfo2.Insert(key + VALSEPTOKEN + value);
	
	
	pFVL = tsInfo.Next();
	row++;
    }
    
    ListT< ListT<Chain> > attrInfo;
    
    attrInfo.Insert(tsMonInfo1);
    attrInfo.Insert(tsMonInfo2);

    ListT<Chain> titleList;

    titleList.Insert(_tableSet + Chain(" - Base 1"));
    titleList.Insert(_tableSet + Chain(" - Base 2"));
    
    res = _pAH->reqShowQueryCache(_tableSet);

    while ( res == CegoAdminHandler::ADM_INFO )
    {
	res = _pAH->nextInfo();	    
    }
        
    ListT<ListT<CegoFieldValue> > cacheInfo;
    
    Chain format;
    if ( _pAH->getCacheInfo(oe, cacheInfo, format) )
    {
	ListT<Chain> monInfo;
	
	ListT<CegoFieldValue> *pFVL = cacheInfo.First();
	
	while ( pFVL )
	{
	    Chain key, value;
	    
	    CegoFieldValue *pFV = pFVL->First();
	    if ( pFV )
	    {		       
		key = pFV->valAsChain();
	    }
	    
	    pFV = pFVL->Next();
	    if ( pFV )
	    {
		value = pFV->valAsChain();
	    }
	    	    
	    monInfo.Insert(key + VALSEPTOKEN + value);	
	    
	    pFVL = cacheInfo.Next();
	}
   
	attrInfo.Insert(monInfo);
		
	titleList.Insert(_tableSet + Chain(" - QueryCache"));
    }

    res = _pAH->reqShowTableCache(_tableSet);

    while ( res == CegoAdminHandler::ADM_INFO )
    {
	res = _pAH->nextInfo();	    
    }
    
    if ( _pAH->getCacheInfo(oe, cacheInfo, format) )
    {
	ListT<Chain> monInfo;
	
	ListT<CegoFieldValue> *pFVL = cacheInfo.First();
	
	while ( pFVL )
	{
	    Chain key, value;
	    
	    CegoFieldValue *pFV = pFVL->First();
	    if ( pFV )
	    {		       
		key = pFV->valAsChain();
	    }
	    
	    pFV = pFVL->Next();
	    if ( pFV )
	    {
		value = pFV->valAsChain();
	    }
	        
	    monInfo.Insert(key + VALSEPTOKEN + value);	
	    
	    pFVL = cacheInfo.Next();
	}
   
	attrInfo.Insert(monInfo);
		
	titleList.Insert(_tableSet + Chain(" - TableCache"));
    }
    
    setAttrList(titleList, attrInfo);
}

/////////////////////////////////
// Tableset - Action - Archlog //
/////////////////////////////////

CegoAdmScreen::TableSet::Action::Archlog::Archlog(CegoAdminHandler* pAH, Screen::Panel* pParent)
    : Screen::Grid(pParent)
{
    _alSchema.Insert(Chain("Name") + VALSEPTOKEN + Chain("l15"));
    _alSchema.Insert(Chain("Path") + VALSEPTOKEN + Chain("l50"));
    _alSchema.Insert(Chain("NumFile") + VALSEPTOKEN + Chain("r10"));
    _alSchema.Insert(Chain("NumArch") + VALSEPTOKEN + Chain("r10"));
    
    _pAdd = new Add(pAH, this);
    _pConf = new Conf(pAH, this);
    _pDelete = new Delete(pAH, this);

    _pHelp = new Screen::Message(this);
    _pHelp->setInfo(AL_HELP_TITLE, AL_HELP_TEXT,5);
    
    _pAH = pAH;
}

CegoAdmScreen::TableSet::Action::Archlog::~Archlog()
{
    delete _pAdd;
    delete _pConf;
    delete _pDelete;
    delete _pHelp;
}

void CegoAdmScreen::TableSet::Action::Archlog::setup(const Chain& tableSet, const Chain& archMode)
{
    _archMode = archMode;
    _tableSet = tableSet;

    ListT<Screen::GridColor> colorMap;
    setSchema(tableSet + Chain(" Archlog Info"), _alSchema, colorMap, 0);

    _pAdd->setup(tableSet);
    _pConf->setup(tableSet, archMode);    
}

Screen::Panel* CegoAdmScreen::TableSet::Action::Archlog::onSelect(unsigned rowNum)
{
    return this;
}

Screen::Panel* CegoAdmScreen::TableSet::Action::Archlog::onKey(unsigned c, unsigned rowNum)
{
    if ( c == KEY_NEW )
    {
	_pAdd->reset();
	return _pAdd;
    }
    else if ( c == KEY_CONF )
    {
	return _pConf;
    }
    else if ( c == KEY_DELETE )
    {
	Chain alId = _alTable[rowNum-1][0];

	_pDelete->setup(_tableSet, alId);
	return _pDelete;
    }
    else if ( c == KEY_HLP )
    {
	return _pHelp;
    }
    
    return _pParent;
}

ListT< ListT<Chain> > CegoAdmScreen::TableSet::Action::Archlog::getData()
{
    return _alTable;
}

void CegoAdmScreen::TableSet::Action::Archlog::refresh()
{
    CegoAdminHandler::ResultType res;
    res = _pAH->reqGetDetailedTSInfo(_tableSet);	
    
    while ( res == CegoAdminHandler::ADM_INFO )
    {
	res = _pAH->nextInfo();	    
    }

    CegoTableObject oe;
    ListT< ListT<CegoFieldValue> > tsInfo;
    _pAH->getDetailedTableSetInfo(oe, tsInfo);

    ListT<CegoFieldValue> *pFVL = tsInfo.First();
    while ( pFVL )
    {
	Chain key;
	
	CegoFieldValue *pFV = pFVL->First();
	if ( pFV )
	{		       
	    key = pFV->valAsChain();
	}

	if ( key == Chain("ArchMode") )
	{
	    pFV = pFVL->Next();
	    if ( pFV )
	    {

		Chain archMode = pFV->valAsChain();
		
		ListT<Screen::GridColor> colorMap;
		setSchema(_tableSet + Chain(" Archlog Info - ") + archMode, _alSchema, colorMap, 0);

	    }
	    break;
	}
	
	pFVL = tsInfo.Next();
    }

    res = _pAH->reqGetArchLogInfo(_tableSet);    
    while ( res == CegoAdminHandler::ADM_INFO )
    {
	res = _pAH->nextInfo();	    
    }
    
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);
	
	setStatus(msg);
    }

    ListT<ListT<CegoFieldValue> > archLogInfo;	
    _pAH->getArchLogInfo(oe, archLogInfo);

    pFVL = archLogInfo.First();

    _alTable.Empty();
    
    while ( pFVL )
    {
	ListT<Chain> alRow;
	
	CegoFieldValue *pFV = pFVL->First();
	while (pFV )
	{
	    alRow.Insert(pFV->valAsChain());
	    pFV = pFVL->Next();
	}
	
	_alTable.Insert(alRow);
	
	pFVL = archLogInfo.Next();
    }    
}

CegoAdmScreen::TableSet::Action::Archlog::Add::Add(CegoAdminHandler* pAH, Screen::Panel* pParent)
    : Screen::Form(pParent)
{
    ListT<Chain> attrList;
    attrList.Insert( Chain("ArchId") + ATTRSEPTOKEN + INPUT_TYPE_STRING + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + Chain("ALID"));
    attrList.Insert( Chain("Path") + ATTRSEPTOKEN + INPUT_TYPE_STRING + ATTRSEPTOKEN + MAXPATHLEN + ATTRSEPTOKEN + Chain("./FilePath"));
     
    setAttrList(Chain("Add file"), attrList, 15);
        
    _pAH = pAH;
}

CegoAdmScreen::TableSet::Action::Archlog::Add::~Add()
{
}

void CegoAdmScreen::TableSet::Action::Archlog::Add::setup(const Chain& tableSet)
{
    _tableSet = tableSet;
}	    

Screen::Panel* CegoAdmScreen::TableSet::Action::Archlog::Add::onConfirm(const ListT<Chain>& valList)
{
    Chain archId = valList[0];
    Chain archPath = valList[1];

    CegoAdminHandler::ResultType res;    
    res = _pAH->reqAddArchLog(_tableSet, archId, archPath);
    
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);
    
	return setError(Chain(ERROR_TITLE), msg);
    }
    
    return _pParent;
}

Screen::Panel* CegoAdmScreen::TableSet::Action::Archlog::Add::onCancel()
{
    return _pParent;
}

CegoAdmScreen::TableSet::Action::Archlog::Conf::Conf(CegoAdminHandler* pAH, Screen::Panel* pParent)
    : Screen::Form(pParent)
{    
    _pAH = pAH;
}

CegoAdmScreen::TableSet::Action::Archlog::Conf::~Conf()    
{
}
		    
void CegoAdmScreen::TableSet::Action::Archlog::Conf::setup(const Chain& tableSet, const Chain& archMode)
{
    Chain valString;
    if ( archMode == Chain(XML_ON_VALUE) )
	valString = Chain("Enabled") + VALSEPTOKEN + Chain("1");
    else
	valString = Chain("Disabled") + VALSEPTOKEN + Chain("2");
    
    Chain modeMenuString = valString + LISTSEPTOKEN
	+ Chain("Enabled") + VALSEPTOKEN + Chain("1") + LISTSEPTOKEN
	+ Chain("Disabled") + VALSEPTOKEN + Chain("2");

    ListT<Chain> attrList;
    attrList.Insert( Chain("Status") + ATTRSEPTOKEN + INPUT_TYPE_MENU + ATTRSEPTOKEN + MAXIDLEN + ATTRSEPTOKEN + modeMenuString);

    setAttrList(Chain("Toggle archlog"), attrList, 10);

    _tableSet = tableSet;
}

Screen::Panel* CegoAdmScreen::TableSet::Action::Archlog::Conf::onConfirm(const ListT<Chain>& valList)
{
    Chain mode = valList[0];

    CegoAdminHandler::ResultType res;   
    if ( mode == Chain("1"))
    {
	res = _pAH->reqEnableArchLog(_tableSet);
    }
    else
    {
	res = _pAH->reqDisableArchLog(_tableSet);
    }
    
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);    
	return setError(Chain(ERROR_TITLE), msg);
    }

    return _pParent;
}

Screen::Panel* CegoAdmScreen::TableSet::Action::Archlog::Conf::onCancel()
{
    return _pParent;
}

CegoAdmScreen::TableSet::Action::Archlog::Delete::Delete(CegoAdminHandler* pAH, Screen::Panel* pParent)
    : Screen::Confirm(pParent)
{    
    _pAH = pAH;
}

CegoAdmScreen::TableSet::Action::Archlog::Delete::~Delete()    
{
}
		    
void CegoAdmScreen::TableSet::Action::Archlog::Delete::setup(const Chain& tableSet, const Chain& al)
{
    _tableSet = tableSet;
    _al = al;

    setInfo(Chain("Deleting archive location ") + tableSet + Chain(" - ") + al, Chain(""));
}

Screen::Panel* CegoAdmScreen::TableSet::Action::Archlog::Delete::onConfirm()
{
    CegoAdminHandler::ResultType res;   
    res = _pAH->reqRemoveArchLog(_tableSet, _al);
    
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);
        
	return setError(Chain(ERROR_TITLE), msg);
    }

    return _pParent;
}

Screen::Panel* CegoAdmScreen::TableSet::Action::Archlog::Delete::onCancel()
{
    return _pParent;
}

////////////////////////////////
// Tableset - Action - Backup //
////////////////////////////////

CegoAdmScreen::TableSet::Action::Backup::Backup(CegoAdminHandler* pAH, Screen::Panel* pParent)
    : Screen::Grid(pParent)
{
    _buSchema.Insert(Chain("Name") + VALSEPTOKEN + Chain("l10"));
    _buSchema.Insert(Chain("Timestamp") + VALSEPTOKEN + Chain("r25"));
    
    ListT<Screen::GridColor> colorMap;
    setSchema(Chain("Backup Info"), _buSchema, colorMap, 0);
    
    _pAdd = new Add(pAH, this);
    _pAH = pAH;
    _doRefresh = false;
}

void CegoAdmScreen::TableSet::Action::Backup::setup(const Chain& tableSet, const Chain& tsState)
{ 
    _tableSet = tableSet;
    _tsState = tsState;
    _doRefresh = true;
}

Screen::Panel* CegoAdmScreen::TableSet::Action::Backup::onSelect(unsigned rowNum)
{
    return this;    
}

Screen::Panel* CegoAdmScreen::TableSet::Action::Backup::onKey(unsigned c, unsigned rowNum)
{
    if ( c == KEY_NEW )
    {
	_pAdd->setup(_tableSet, _tsState);
	_doRefresh = true;
	return _pAdd;
    }
    return _pParent;
}

ListT< ListT<Chain> > CegoAdmScreen::TableSet::Action::Backup::getData()
{
    return _buTable;
}

void CegoAdmScreen::TableSet::Action::Backup::refresh()
{
    if ( _doRefresh == false )
	return;
    
    CegoAdminHandler::ResultType res;
    Chain pit;
    res = _pAH->reqListBackup(_tableSet, pit);
    
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);	
	setStatus(msg);
	return;
    }
    
    CegoTableObject oe;
    ListT<ListT<CegoFieldValue> > buInfo;
    
    _pAH->getBackupInfo(oe, buInfo);
        		
    _buTable.Empty();
		   
    ListT<CegoFieldValue> *pFVL = buInfo.First();
    while ( pFVL )
    {
	ListT<Chain> buRow;
	
	CegoFieldValue *pFV = pFVL->First();
	while ( pFV )
	{
	    buRow.Insert(pFV->valAsChain());
	    pFV = pFVL->Next();
	}
	
	_buTable.Insert(buRow);
	pFVL = buInfo.Next();
    }

    _doRefresh = false;
}

CegoAdmScreen::TableSet::Action::Backup::Add::Add(CegoAdminHandler* pAH, Screen::Panel* pParent)
    : Screen::Confirm(pParent)
{
    _pAH = pAH;
}

void CegoAdmScreen::TableSet::Action::Backup::Add::setup(const Chain& tableSet, const Chain& tsState)
{
    _tableSet = tableSet;
    _tsState = tsState;
    setInfo(Chain("Start backup for tableset ") + _tableSet, Chain());
}	    

Screen::Panel* CegoAdmScreen::TableSet::Action::Backup::Add::onConfirm()
{
    // perform backup here
    
    CegoAdminHandler::ResultType res;
    
    Chain buMsg("Backup via CegoAdmScreen");

    if ( _tsState == Chain(TS_ONLINE_STATUS) )
    {
	res = _pAH->reqBeginBackup(_tableSet, buMsg);	
	if ( res == CegoAdminHandler::ADM_ERROR )
	{
	    Chain msg;
	    _pAH->getMsg(msg);
	    return setError(Chain(ERROR_TITLE),  msg);	
	}
    }
	    
    res = _pAH->reqExecuteBackup(_tableSet, buMsg);
    
    Chain errLog;
    while ( res == CegoAdminHandler::ADM_INFO )
    {
	Chain msg;
	_pAH->getMsg(msg);
	errLog += msg + Chain("\n");
	setStatus(msg);
	res = _pAH->nextInfo();	    
    }

    if ( _tsState == Chain(TS_ONLINE_STATUS) )
    {
	
	if ( res == CegoAdminHandler::ADM_ERROR )
	{
	    Chain msg;
	    _pAH->getMsg(msg);
	    
	    errLog += msg;
	    
	    // try to end backup 
	    res = _pAH->reqEndBackup(_tableSet, buMsg, false);
	    
	    if ( res == CegoAdminHandler::ADM_ERROR )
	    {
		_pAH->getMsg(msg);
		return setError(Chain(ERROR_TITLE), msg);
	    }
	    
	    return setError(Chain(ERROR_TITLE),  errLog);
	}
	
	res = _pAH->reqEndBackup(_tableSet, buMsg, false);
	
    }

    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);
	return setError(Chain(ERROR_TITLE), msg);
    }
    else
    {
	Chain msg;
	msg = Chain("Backup finished succesful");
	setStatus(msg);
    }

    return _pParent;
}

CegoAdmScreen::TableSet::Action::Restore::Restore(CegoAdminHandler* pAH, Screen::Panel* pParent)
    : Screen::Form(pParent)
{
    _pAH = pAH;
}
		    
void CegoAdmScreen::TableSet::Action::Restore::setup(const Chain& tableSet)
{   
    _tableSet = tableSet;

    CegoAdminHandler::ResultType res;
    Chain pit;
    res = _pAH->reqListBackup(_tableSet, pit);


    while ( res == CegoAdminHandler::ADM_INFO )
    {
	res = _pAH->nextInfo();	    
    }
    
    CegoTableObject oe;
    ListT<ListT<CegoFieldValue> > buInfo;
    
    _pAH->getBackupInfo(oe, buInfo);

    Chain buList;
    
    ListT<CegoFieldValue> *pFVL = buInfo.First();

    Chain lastBuId;
    Chain lastBuDate;
    while ( pFVL )
    {
	
	CegoFieldValue *pFV = pFVL->First();

	Chain buId;
	Chain buDate;
	
	if ( pFV )
	{
	     buId = (pFV->valAsChain());
	     lastBuId=buId;
	}
	pFV = pFVL->Next();
	if ( pFV )
	{
	     buDate = (pFV->valAsChain());
	     lastBuDate=buDate;
	}

	buList += buDate + VALSEPTOKEN + buId;
	
	pFVL = buInfo.Next();

	if ( pFVL ) 
	    buList += LISTSEPTOKEN;
       
    }

    Chain buAll = lastBuDate + VALSEPTOKEN + lastBuId + LISTSEPTOKEN + buList;
    
    ListT<Chain> attrList;
    attrList.Insert( Chain("Backup") + ATTRSEPTOKEN + INPUT_TYPE_MENU + ATTRSEPTOKEN + MAXTIMELEN + ATTRSEPTOKEN + buAll);
    
    setAttrList(Chain("Restore tableset ") + tableSet + Chain(" ?"),
		attrList, 25);   
}

Screen::Panel* CegoAdmScreen::TableSet::Action::Restore::onConfirm(const ListT<Chain>& valList)
{
    Chain buId = valList[0];
   
    setStatus(Chain("Restoring backup ") + buId);

    
    CegoAdminHandler::ResultType res;
    res = _pAH->reqRestore(_tableSet, buId);
    
    while ( res == CegoAdminHandler::ADM_INFO )
    {	
	Chain msg;
	_pAH->getMsg(msg);
	setStatus(msg);
	res = _pAH->nextInfo();
    }
    
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);	
	return setError(Chain(ERROR_TITLE), msg);
    }

    Chain msg;
    _pAH->getMsg(msg);	
	
    Screen::Message* pResult = new Screen::Message(_pParent);
    pResult->setInfo(Chain("Restore finished"), msg, 2);
    return pResult;        
}


CegoAdmScreen::TableSet::Action::Recover::Recover(CegoAdminHandler* pAH, Screen::Panel* pParent)
    : Screen::Form(pParent)
{
    _pAH = pAH;
}
		    
void CegoAdmScreen::TableSet::Action::Recover::setup(const Chain& tableSet)
{   
    _tableSet = tableSet;


    ListT<Chain> attrList;
    Chain pit;
    attrList.Insert( Chain("Pit") + ATTRSEPTOKEN + INPUT_TYPE_STRING + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + pit);
    attrList.Insert( Chain("LSN") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + "0");
    
    setAttrList(Chain("Recover tableset ") + tableSet + Chain(" ?"),
		attrList, 15);   
}

Screen::Panel* CegoAdmScreen::TableSet::Action::Recover::onConfirm(const ListT<Chain>& valList)
{
    Chain pit = valList[0];
    Chain lsn = valList[1];
    
    unsigned long long targetLsn = lsn.asUnsignedLongLong();
    
    setStatus(Chain("Recovering backup to ") + pit + Chain("/") + Chain(targetLsn));

    
    CegoAdminHandler::ResultType res;
    res = _pAH->reqRecover(_tableSet, pit, targetLsn);
        
    while ( res == CegoAdminHandler::ADM_INFO )
    {
	Chain msg;
	_pAH->getMsg(msg);
	setStatus(msg);
	res = _pAH->nextInfo();
    }
    
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);
	return setError(Chain(ERROR_TITLE), msg);
    }
    	
    Chain msg;
    _pAH->getMsg(msg);

    Screen::Message* pResult = new Screen::Message(_pParent);
    pResult->setInfo(Chain("Recovery finished"), msg, 2);
    return pResult;
    
}



//////////////////////////////////
// Tableset - Action - Datafile //
//////////////////////////////////

CegoAdmScreen::TableSet::Action::FilePanel::FilePanel(CegoAdminHandler* pAH, Screen::Panel* pParent)
    : Screen::Grid(pParent)
{    
    _fileSchema.Insert(Chain("Name") + VALSEPTOKEN + Chain("l30"));
    _fileSchema.Insert(Chain("Type") + VALSEPTOKEN + Chain("r15"));
    _fileSchema.Insert(Chain("Size") + VALSEPTOKEN + Chain("r15"));
    _fileSchema.Insert(Chain("Used") + VALSEPTOKEN + Chain("r15"));
        
    _pAddFile = new AddFilePanel(pAH, this);
    
    _pAH = pAH;
}

void CegoAdmScreen::TableSet::Action::FilePanel::setup(const Chain& tableSet)
{
    _tableSet = tableSet;

    // get root path

    CegoAdminHandler::ResultType res;	
    res = _pAH->reqGetDetailedTSInfo(_tableSet);	
    
    while ( res == CegoAdminHandler::ADM_INFO )
    {
	res = _pAH->nextInfo();	    
    }
    
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);
	setStatus(msg);
	return;
    }
    
    CegoTableObject oe;
    ListT< ListT<CegoFieldValue> > tsInfo;
    _pAH->getDetailedTableSetInfo(oe, tsInfo);
    
    ListT<CegoFieldValue> *pFVL = tsInfo.First();
    while ( pFVL )
    {
	Chain key;
	
	CegoFieldValue *pFV = pFVL->First();
	if ( pFV )
	{		       
	    key = pFV->valAsChain();
	}
	
	if ( key == Chain(INFO_ROOTPATH) )
	{
	    pFV = pFVL->Next();
	    if ( pFV )
	    {
		_rootPath = pFV->valAsChain();
	    }
	    break;
	}
	
	pFVL = tsInfo.Next();
    }

    _doRefresh=true;
}

Screen::Panel* CegoAdmScreen::TableSet::Action::FilePanel::onKey(unsigned c, unsigned rowNum)
{	      		
    if ( c == KEY_NEW )
    {
	_pAddFile->setup(_tableSet, _rootPath);
	_doRefresh=true;
	return _pAddFile;
    }
    return this;
}

void CegoAdmScreen::TableSet::Action::FilePanel::refresh()
{
    if ( _doRefresh == false )
	return;
    
    CegoAdminHandler::ResultType res;	
    res = _pAH->reqGetDetailedTSInfo(_tableSet);	
    
    while ( res == CegoAdminHandler::ADM_INFO )
    {
	res = _pAH->nextInfo();	    
    }
    
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);
	setStatus(msg);
	return;
    }

    CegoTableObject oe;
    ListT<ListT<CegoFieldValue> > fileInfo;
    Chain format;
    _pAH->getDataFileInfo(oe, fileInfo, format);
    
    unsigned maxPathLen=0;
    ListT<CegoFieldValue> *pFVL = fileInfo.First();	
    while ( pFVL )
    {	    
	CegoFieldValue *pFV = pFVL->First();
	if (pFV )
	{		
	    Chain fileName=(char*)pFV->valAsChain();
	    if ( (unsigned)fileName.length() > maxPathLen )
		maxPathLen = fileName.length();		
	}
	pFVL = fileInfo.Next();	
    }
    
    _fileTable.Empty();
    
    pFVL = fileInfo.First();
    
    while ( pFVL )
    {
	ListT<Chain> fiRow;
	
	CegoFieldValue *pFV = pFVL->First();
	
	File f(pFV->valAsChain());
	fiRow.Insert(f.getShortName());
	
	pFV = pFVL->Next();
	while (pFV )
	{
	    fiRow.Insert(pFV->valAsChain());
	    pFV = pFVL->Next();
	}
	
	_fileTable.Insert(fiRow);
	
	pFVL = fileInfo.Next();
    }
    
    ListT<Screen::GridColor> colorMap;
    setSchema(_tableSet + Chain(" File Info - Root Path ") + _rootPath, _fileSchema, colorMap, 0);

    _doRefresh=false;
}

CegoAdmScreen::TableSet::Action::FilePanel::AddFilePanel::AddFilePanel(CegoAdminHandler* pAH, Screen::Panel* pParent)
    : Screen::Form(pParent)
{   
    Chain typeMenuString = Chain("app") + VALSEPTOKEN + Chain(XML_APPFILE_VALUE)
	+ LISTSEPTOKEN + Chain("app") + VALSEPTOKEN + Chain(XML_APPFILE_VALUE)
	+ LISTSEPTOKEN + Chain("temp") + VALSEPTOKEN + Chain(XML_TEMPFILE_VALUE)
	+ LISTSEPTOKEN + Chain("sys") + VALSEPTOKEN + Chain(XML_SYSFILE_VALUE);
    
    ListT<Chain> attrList;
    attrList.Insert( Chain("Type") + ATTRSEPTOKEN + INPUT_TYPE_MENU + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + typeMenuString);
    attrList.Insert( Chain("FileName") + ATTRSEPTOKEN + INPUT_TYPE_STRING + ATTRSEPTOKEN + MAXPATHLEN + ATTRSEPTOKEN + Chain("<FileName>"));
    attrList.Insert( Chain("NumPages") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXSIZELEN + ATTRSEPTOKEN + Chain("1000"));
        
    setAttrList(Chain("Add file"), attrList, 15);
    
    _pAH = pAH;   
}

void CegoAdmScreen::TableSet::Action::FilePanel::AddFilePanel::setup(const Chain& tableSet, const Chain& rootPath)
{
    _tableSet = tableSet;
    _rootPath = rootPath;
}	    

Screen::Panel* CegoAdmScreen::TableSet::Action::FilePanel::AddFilePanel::onConfirm(const ListT<Chain>& valList)
{
    Chain fileType = valList[0];
    Chain dataFile = valList[1];
    Chain numPages = valList[2];
    
    CegoAdminHandler::ResultType res;    
    res = _pAH->reqAddDataFile(_tableSet, fileType, _rootPath + Chain("/") + dataFile, numPages.asUnsigned());
    
    Chain msg;
    _pAH->getMsg(msg);
    
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	return setError(Chain(ERROR_TITLE), msg);
    }
    
    return _pParent;
}

///////////////////////////////
// Tableset - Action - Xport //
///////////////////////////////

CegoAdmScreen::TableSet::Action::XPort::XPort(CegoAdminHandler* pAH, Screen::Panel* pParent)
    : Screen::Form(pParent)
{    
    _pAH = pAH;
}

CegoAdmScreen::TableSet::Action::XPort::~XPort()
{
}

void CegoAdmScreen::TableSet::Action::XPort::setup(const Chain& tableSet, bool isExport)
{
    _tableSet = tableSet;
    _isExport = isExport;
    
    Chain modeMenuString = Chain("xml") + VALSEPTOKEN + Chain("XML") + LISTSEPTOKEN
	+ Chain("xml") + VALSEPTOKEN + Chain("XML") + LISTSEPTOKEN
	+ Chain("bin") + VALSEPTOKEN + Chain("BIN") + LISTSEPTOKEN
	+ Chain("plain") + VALSEPTOKEN + Chain("PLAIN");
    
    ListT<Chain> attrList;
    attrList.Insert( Chain("Mode") + ATTRSEPTOKEN + INPUT_TYPE_MENU + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + modeMenuString);
    attrList.Insert( Chain("File") + ATTRSEPTOKEN + INPUT_TYPE_STRING + ATTRSEPTOKEN + MAXPATHLEN + ATTRSEPTOKEN + Chain());

    if ( _isExport )
	setAttrList(_tableSet + Chain(" Export"), attrList, 30);
    else
	setAttrList(_tableSet + Chain(" Import"), attrList, 30);
}

Screen::Panel* CegoAdmScreen::TableSet::Action::XPort::onConfirm(const ListT<Chain>& valList)
{
    Chain mode = valList[0];
    Chain xportFile = valList[1];

    CegoAdminHandler::ResultType res;

    bool isStructure = false;

    Chain xport;
    
    if ( _isExport )
    {
	xport = Chain("export");
	res = _pAH->reqExportTableSet(_tableSet, isStructure, xportFile, mode);
    }
    else
    {
	xport = Chain("import");
	res = _pAH->reqImportTableSet(_tableSet, isStructure, xportFile, mode);
    }
    
    while ( res == CegoAdminHandler::ADM_INFO )
    {
	Chain msg;
	_pAH->getMsg(msg);
	
	setStatus(_tableSet + Chain(" ") + xport + Chain(" : ") + msg.truncRight(Chain("\r")));
	res = _pAH->nextInfo();	    
    }
    
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);
	return setError(Chain(ERROR_TITLE), msg);
    }

    setStatus(_tableSet + Chain(" ") + xport + Chain(" finished"));

    return _pParent;
}

////////////////////////////////////
// Tableset - Action - QueryCache //
////////////////////////////////////

CegoAdmScreen::TableSet::Action::QueryCache::QueryCache(CegoAdminHandler* pAH, Screen::Panel* pParent)
    : Screen::Form(pParent)
{    
    _pAH = pAH;
}

CegoAdmScreen::TableSet::Action::QueryCache::~QueryCache()
{
}

void CegoAdmScreen::TableSet::Action::QueryCache::setup(const Chain& tableSet)
{
    _tableSet = tableSet;

    ListT< ListT<CegoFieldValue> > tsInfo;
    CegoAdminHandler::ResultType res;
    CegoTableObject oe;
   
    res = _pAH->reqGetDetailedTSInfo(_tableSet);
   
    while ( res == CegoAdminHandler::ADM_INFO )
    {
        res = _pAH->nextInfo();
    }

    _pAH->getDetailedTableSetInfo(oe, tsInfo);
   
    unsigned maxEntry=0;
    unsigned maxSize=0;
    unsigned threshold=0;
    unsigned hashRange=0;
    Chain status;
   
    ListT<CegoFieldValue> *pFVL = tsInfo.First();
    while ( pFVL )
    {
        Chain key, value;

        CegoFieldValue *pFV = pFVL->First();
        if ( pFV )
        {
            key = pFV->valAsChain();
        }
       
        pFV = pFVL->Next();
        if ( pFV )
        {
            value = pFV->valAsChain();
        }
        if ( key == Chain(INFO_QUERYCACHE) )
            status = value;
        else if ( key == Chain(INFO_QUERYCACHEMAXENTRY) )
            maxEntry=value.asUnsigned();
        else if ( key == Chain(INFO_QUERYCACHEMAXSIZE) )
            maxSize=value.asUnsigned();
        else if ( key == Chain(INFO_QUERYCACHETHRESHOLD) )
            threshold=value.asUnsigned();
        else if ( key == Chain(INFO_QUERYCACHEHASHRANGE) )
            hashRange=value.asUnsigned();
       
        pFVL = tsInfo.Next();
    }

    Chain statusMenuString = status + VALSEPTOKEN + status + LISTSEPTOKEN
	+ Chain(XML_ON_VALUE) + VALSEPTOKEN + Chain(XML_ON_VALUE) + LISTSEPTOKEN
	+ Chain(XML_OFF_VALUE) + VALSEPTOKEN + Chain(XML_OFF_VALUE);

    ListT<Chain> attrList;
    attrList.Insert( Chain("Status") + ATTRSEPTOKEN + INPUT_TYPE_MENU + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + statusMenuString);
    attrList.Insert( Chain("MaxNum") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + Chain(maxEntry));
    attrList.Insert( Chain("MaxSize") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + Chain(maxSize));
    attrList.Insert( Chain("Threshold") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + Chain(threshold));
    attrList.Insert( Chain("HashLen") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + Chain(hashRange));
    
    setAttrList(_tableSet + Chain(" Query Cache"), attrList, 30);
}

Screen::Panel* CegoAdmScreen::TableSet::Action::QueryCache::onConfirm(const ListT<Chain>& valList)
{
    Chain status = valList[0];
    unsigned maxEntry = valList[1].asUnsigned();
    unsigned maxSize = valList[2].asUnsigned();
    unsigned threshold = valList[3].asUnsigned();
    unsigned hashRange = valList[4].asUnsigned();
    
    CegoAdminHandler::ResultType res;
    res = _pAH->reqSetQueryCacheParam(_tableSet, maxEntry, maxSize, threshold, hashRange);
       
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);
	return setError(Chain(ERROR_TITLE), msg);
    }
    
    if ( status == Chain(XML_ON_VALUE) )
	res = _pAH->reqEnableQueryCache(_tableSet);
    else
	res = _pAH->reqDisableQueryCache(_tableSet);

    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);
	return setError(Chain(ERROR_TITLE), msg);
    }

    return _pParent;
}

////////////////////////////////////
// Tableset - Action - TableCache //
////////////////////////////////////

CegoAdmScreen::TableSet::Action::TableCache::TableCache(CegoAdminHandler* pAH, Screen::Panel* pParent)
    : Screen::Form(pParent)
{    
    _pAH = pAH;
}

CegoAdmScreen::TableSet::Action::TableCache::~TableCache()
{
}

void CegoAdmScreen::TableSet::Action::TableCache::setup(const Chain& tableSet)
{
    _tableSet = tableSet;

    ListT< ListT<CegoFieldValue> > tsInfo;
    CegoAdminHandler::ResultType res;
    CegoTableObject oe;
   
    res = _pAH->reqGetDetailedTSInfo(_tableSet);
   
    while ( res == CegoAdminHandler::ADM_INFO )
    {
        res = _pAH->nextInfo();
    }

    _pAH->getDetailedTableSetInfo(oe, tsInfo);
   
    unsigned maxEntry=0;
    unsigned maxSize=0;
    unsigned hashRange=0;
    Chain cacheFilter;
    Chain status;
   
    ListT<CegoFieldValue> *pFVL = tsInfo.First();
    while ( pFVL )
    {
        Chain key, value;

        CegoFieldValue *pFV = pFVL->First();
        if ( pFV )
        {
            key = pFV->valAsChain();
        }
       
        pFV = pFVL->Next();
        if ( pFV )
        {
            value = pFV->valAsChain();
        }
        if ( key == Chain(INFO_TABLECACHE) )
            status = value;
        else if ( key == Chain(INFO_TABLECACHEFILTER) )
            cacheFilter=value;	
        else if ( key == Chain(INFO_TABLECACHEMAXENTRY) )
            maxEntry=value.asUnsigned();
        else if ( key == Chain(INFO_TABLECACHEMAXSIZE) )
            maxSize=value.asUnsigned();
        else if ( key == Chain(INFO_TABLECACHEHASHRANGE) )
            hashRange=value.asUnsigned();
       
        pFVL = tsInfo.Next();
    }

    Chain statusMenuString = status + VALSEPTOKEN + status + LISTSEPTOKEN
	+ Chain(XML_ON_VALUE) + VALSEPTOKEN + Chain(XML_ON_VALUE) + LISTSEPTOKEN
	+ Chain(XML_OFF_VALUE) + VALSEPTOKEN + Chain(XML_OFF_VALUE);

    ListT<Chain> attrList;
    attrList.Insert( Chain("Status") + ATTRSEPTOKEN + INPUT_TYPE_MENU + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + statusMenuString);
    attrList.Insert( Chain("Filter") + ATTRSEPTOKEN + INPUT_TYPE_STRING + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + cacheFilter);
    attrList.Insert( Chain("MaxNum") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + Chain(maxEntry));
    attrList.Insert( Chain("MaxSize") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + Chain(maxSize));
    attrList.Insert( Chain("HashLen") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + Chain(hashRange));
    
    setAttrList(_tableSet + Chain(" Query Cache"), attrList, 30);
}

Screen::Panel* CegoAdmScreen::TableSet::Action::TableCache::onConfirm(const ListT<Chain>& valList)
{
    Chain status = valList[0];
    Chain cacheFilter = valList[1];
    unsigned maxEntry = valList[2].asUnsigned();
    unsigned maxSize = valList[3].asUnsigned();
    unsigned hashRange = valList[4].asUnsigned();
    
    CegoAdminHandler::ResultType res;
    res = _pAH->reqSetTableCacheParam(_tableSet, cacheFilter, maxEntry, maxSize, hashRange);
       
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);
	return setError(Chain(ERROR_TITLE), msg);
    }
    
    if ( status == Chain(XML_ON_VALUE) )
	res = _pAH->reqEnableTableCache(_tableSet);
    else
	res = _pAH->reqDisableTableCache(_tableSet);

    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);
	return setError(Chain(ERROR_TITLE), msg);
    }

    return _pParent;
}


///////////////////////////////////
// Tableset - Action - Parameter //
///////////////////////////////////

CegoAdmScreen::TableSet::Action::Parameter::Parameter(CegoAdminHandler* pAH, Screen::Panel* pParent)
    : Screen::Form(pParent)
{    
    _pAH = pAH;
}

CegoAdmScreen::TableSet::Action::Parameter::~Parameter()
{
}

void CegoAdmScreen::TableSet::Action::Parameter::setup(const Chain& tableSet)
{
    _tableSet = tableSet;

    ListT< ListT<CegoFieldValue> > tsInfo;
    CegoAdminHandler::ResultType res;
    CegoTableObject oe;
   
    res = _pAH->reqGetDetailedTSInfo(_tableSet);
   
    while ( res == CegoAdminHandler::ADM_INFO )
    {
        res = _pAH->nextInfo();
    }

    _pAH->getDetailedTableSetInfo(oe, tsInfo);
   
    unsigned checkpoint=0;
    unsigned long long sortAreaSize=0;
    Chain initFile;
    Chain autoCorrect;
    Chain appendMode;   
   
    ListT<CegoFieldValue> *pFVL = tsInfo.First();
    while ( pFVL )
    {
        Chain key, value;

        CegoFieldValue *pFV = pFVL->First();
        if ( pFV )
        {
            key = pFV->valAsChain();
        }
       
        pFV = pFVL->Next();
        if ( pFV )
        {
	    if ( pFV->isNull() )
		value=Chain("");
	    else
		value = pFV->valAsChain();
        }
	
        if ( key == Chain(INFO_SORTAREASIZE) )
            sortAreaSize = value.asUnsignedLongLong();
        else if ( key == Chain(INFO_AUTOCORRECT) )
            autoCorrect=value;
	else if ( key == Chain(INFO_APPENDMODE) )
	    appendMode=value;
        else if ( key == Chain(INFO_TSINITFILE) )
            initFile=value;
        else if ( key == Chain(INFO_CHECKPOINT) )
            checkpoint=value.asUnsigned();

        pFVL = tsInfo.Next();
    }
   
    Chain acMenuString = autoCorrect + VALSEPTOKEN + autoCorrect + LISTSEPTOKEN
	+ Chain(XML_ON_VALUE) + VALSEPTOKEN + Chain(XML_ON_VALUE) + LISTSEPTOKEN
	+ Chain(XML_OFF_VALUE) + VALSEPTOKEN + Chain(XML_OFF_VALUE);

    Chain amMenuString = appendMode + VALSEPTOKEN + appendMode + LISTSEPTOKEN
	+ Chain(XML_ON_VALUE) + VALSEPTOKEN + Chain(XML_ON_VALUE) + LISTSEPTOKEN
	+ Chain(XML_OFF_VALUE) + VALSEPTOKEN + Chain(XML_OFF_VALUE);

    ListT<Chain> attrList;
    attrList.Insert( Chain("AutoCorrect") + ATTRSEPTOKEN + INPUT_TYPE_MENU + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + acMenuString);
    attrList.Insert( Chain("AppendMode") + ATTRSEPTOKEN + INPUT_TYPE_MENU + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + amMenuString);
    attrList.Insert( Chain("SortAreaSize") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + Chain(sortAreaSize));
    attrList.Insert( Chain("Checkpoint Interval") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + Chain(checkpoint));
    attrList.Insert( Chain("InitFile") + ATTRSEPTOKEN + INPUT_TYPE_STRING + ATTRSEPTOKEN + MAXPATHLEN + ATTRSEPTOKEN + initFile);
    
    setAttrList(_tableSet + Chain(" Parameter"), attrList, 35);
}

Screen::Panel* CegoAdmScreen::TableSet::Action::Parameter::onConfirm(const ListT<Chain>& valList)
{
    Chain autoCorrect = valList[0];
    Chain appendMode = valList[1];
    unsigned long long sortAreaSize = valList[2].asUnsignedLongLong();
    unsigned checkpoint = valList[3].asUnsigned();
    Chain initFile = valList[4];

    CegoAdminHandler::ResultType res;

    // setup auto correct
    if ( autoCorrect == Chain(XML_ON_VALUE) )
	res = _pAH->reqSetAutoCorrect(_tableSet, Chain(XML_DIRECT_VALUE));
    else
	res = _pAH->reqSetAutoCorrect(_tableSet, Chain(XML_OFF_VALUE));
   
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);
	return setError(Chain(ERROR_TITLE), msg);
    }

    // setup append mode
    if ( appendMode == Chain(XML_ON_VALUE) )
	res = _pAH->reqEnableAppendMode(_tableSet);
    else
	res = _pAH->reqDisableAppendMode(_tableSet);
   
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);
	return setError(Chain(ERROR_TITLE), msg);
    }

    // setup sort area size

    res = _pAH->reqSetTSSortAreaSize(_tableSet, sortAreaSize);
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);
	return setError(Chain(ERROR_TITLE), msg);
    }
    
    // setup checkpoint interval
    res = _pAH->reqSetCheckpoint(_tableSet, checkpoint);
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);
	return setError(Chain(ERROR_TITLE), msg);
    }
    
    // setup init file
    res = _pAH->reqSetTSInitFile(_tableSet, initFile);
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);
	return setError(Chain(ERROR_TITLE), msg);
    }

    return _pParent;
}

//////////////////////////////
// Tableset - Action - Drop //
//////////////////////////////

CegoAdmScreen::TableSet::Action::Drop::Drop(CegoAdminHandler* pAH, Screen::Panel* pParent) : Screen::Confirm(pParent)
{
    _pAH = pAH;
}

CegoAdmScreen::TableSet::Action::Drop::~Drop()
{
}

void CegoAdmScreen::TableSet::Action::Drop::setup(const Chain& tableSet)
{
     setInfo(Chain("Drop tableset ") + tableSet + Chain("?"), Chain());   
    _tableSet = tableSet;
}

Screen::Panel* CegoAdmScreen::TableSet::Action::Drop::onConfirm()
{
    CegoAdminHandler::ResultType res;
    res = _pAH->reqDropTableSet(_tableSet);
    
    Chain msg;
    _pAH->getMsg(msg);
    
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	return setError(Chain(ERROR_TITLE), msg);
    }

    return _pParent;
}


//////////
// User //
//////////


CegoAdmScreen::User::User(CegoAdminHandler* pAH, Screen::Panel* pParent)
	    : Screen::Grid(pParent)
{    
    _userSchema.Insert(Chain("Name") + VALSEPTOKEN + Chain("l10"));
    _userSchema.Insert(Chain("Role") + VALSEPTOKEN + Chain("l20"));
    _userSchema.Insert(Chain("Trc") + VALSEPTOKEN + Chain("r4"));
    _userSchema.Insert(Chain("#R") + VALSEPTOKEN + Chain("r10"));
    _userSchema.Insert(Chain("#Q") + VALSEPTOKEN + Chain("r10"));
    
    ListT<Screen::GridColor> colorMap;		
    setSchema(Chain("Users"), _userSchema, colorMap, 0);
    
    _pAH = pAH;
    _pAdd = new Add(pAH, this);
    _pAction = new Action(pAH, this);
    _pHelp = new Screen::Message(this);
    _pHelp->setInfo(USR_HELP_TITLE, USR_HELP_TEXT,5);

}

CegoAdmScreen::User::~User()
{
    delete _pAdd;
    delete _pAction;
    delete _pHelp;
}

Screen::Panel* CegoAdmScreen::User::onSelect(unsigned selectedRow)
{
    SetT<Chain> roleSet = roleString2Set(_userTable[selectedRow-1][1]);

    bool isTrace = _userTable[selectedRow-1][2] == Chain("ON");

    _pAction->setup(_userTable[selectedRow-1][0], roleSet, isTrace);
    return _pAction;
}

Screen::Panel* CegoAdmScreen::User::onKey(unsigned c, unsigned rowNum)
{
    if ( c == KEY_NEW )
    {
	_pAdd->reset();
	return _pAdd;
    }
    else if ( c == KEY_HLP )
    {
	return _pHelp;
    }
    return this;
}

ListT< ListT<Chain> > CegoAdmScreen::User::getData()
{
    return _userTable;
}

void CegoAdmScreen::User::refresh()
{   
    _pAH->reqShowUser();
    
    CegoTableObject oe;
    ListT<ListT<CegoFieldValue> > userList;
    
    _pAH->getUserInfo(oe, userList);
			
    _userTable.Empty();

    ListT<CegoFieldValue> *pFVL = userList.First();
    while ( pFVL )
    {
	ListT<Chain> userRow;
	
	CegoFieldValue *pFV = pFVL->First();
		
	while ( pFV )
	{
	    userRow.Insert(pFV->valAsChain());	  	    
	    pFV = pFVL->Next();
	}
	
	_userTable.Insert(userRow);
	pFVL = userList.Next();
    }
}

SetT<Chain> CegoAdmScreen::User::roleString2Set(const Chain& roleString)
{
    Tokenizer t(roleString, Chain(","));
    
    Chain role;
    SetT<Chain> roleSet;
    
    while ( t.nextToken(role))
	roleSet.Insert(role);

    return roleSet;		
}

////////////////
// User - Add //
////////////////
   
CegoAdmScreen::User::Add::Add(CegoAdminHandler* pAH, Screen::Panel* pParent)
    : Screen::Form(pParent)
{	
    _pAH = pAH;
    ListT<Chain> attrList; 
    attrList.Insert( Chain("Name") + ATTRSEPTOKEN + INPUT_TYPE_ID + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + Chain());
    
    attrList.Insert(Chain("Passwd") + ATTRSEPTOKEN + INPUT_TYPE_PWD + ATTRSEPTOKEN + MAXPASSWDLEN + ATTRSEPTOKEN + Chain());
    setAttrList(Chain("Create new user"), attrList, 15);   
}
	    
CegoAdmScreen::User::Add::~Add()
{
}

Screen::Panel* CegoAdmScreen::User::Add::onConfirm(const ListT<Chain>& valList)
{
    Chain *pUser = valList.First();
    Chain *pPwd = valList.Next();
    
    CegoAdminHandler::ResultType res;
    
    res = _pAH->reqAddUser(*pUser, *pPwd);
    
    Chain msg;
    _pAH->getMsg(msg);
    
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	return setError(Chain(ERROR_TITLE), msg);
    }
    
    return _pParent;
}

Screen::Panel* CegoAdmScreen::User::Add::onCancel()
{    
    return _pParent;
}

///////////////////
// User - Action //
///////////////////

CegoAdmScreen::User::Action::Action(CegoAdminHandler* pAH, Screen::Panel* pParent)
    : Screen::Select(pParent)
{    
    _pPwd = new Passwd(pAH, pParent);
    _pAssign = new Assign(pAH, pParent);
    _pDelete = new Delete(pAH, pParent);

    _pAH = pAH;
}

CegoAdmScreen::User::Action::~Action()
{    
    delete _pPwd;
}
	
void CegoAdmScreen::User::Action::setup(const Chain& user, const SetT<Chain>& userRoleSet, bool isTrace)
{
    _user = user;
    _isTrace = isTrace;
    _userRoleSet = userRoleSet;
    
    ListT<Chain> items;
    items.Insert(Chain("Set Password=1"));
    items.Insert(Chain("Assign Role=2"));
    items.Insert(Chain("Remove Role=3"));
    items.Insert(Chain("Toggle Trace=4"));
    items.Insert(Chain("Delete=5"));
    
    setItems(Chain("User ") + user, 20, items);
}

Screen::Panel* CegoAdmScreen::User::Action::onSelect(unsigned selected)
{    
    unsigned userAction = getSelectedValue().asUnsigned();
        
    switch ( userAction )
    {
    case 1:
    {
	_pPwd->setUser(_user);
	return _pPwd;
    }
    case 2:
    {	
	CegoAdminHandler::ResultType res;
	res = _pAH->reqListRole();
	
	if ( res == CegoAdminHandler::ADM_ERROR )
	{
	    Chain msg;
	    _pAH->getMsg(msg);
	    return setError(Chain(ERROR_TITLE), msg);
	}
	
	CegoTableObject oe;
	ListT<ListT<CegoFieldValue> > roleList;	
	_pAH->getRoleList(oe, roleList);

	SetT<Chain> roleSet;
	ListT<CegoFieldValue> *pFVL = roleList.First();
	while ( pFVL )
	{
	    ListT<Chain> roleRow;
	    
	    CegoFieldValue *pFV = pFVL->First();
	    if ( pFV )
	    {
		roleSet.Insert(pFV->valAsChain());
	    }
	    pFVL = roleList.Next();
	}

	roleSet.Insert(Chain(ROLE_ADMIN));
		
	// roleSet -= _userRoleSet; 
	
	_pAssign->setup(_user, roleSet, true);
	return _pAssign;
    }
    case 3:
    {       	
	_pAssign->setup(_user, _userRoleSet, false);
	return _pAssign;
    }
    case 4:
    {
	CegoAdminHandler::ResultType res;
	if ( _isTrace )
	{
	    res = _pAH->reqUserTrace(_user, false);
	}
	else
	{
	    res = _pAH->reqUserTrace(_user, true);
	}
	if ( res == CegoAdminHandler::ADM_ERROR )
	{
	    Chain msg;
	    _pAH->getMsg(msg);
	    return setError(Chain(ERROR_TITLE), msg);
	}
	break;
    }
    case 5:
    {
	_pDelete->setup(_user);
	return _pDelete;
    }
    }
    return _pParent;
}

///////////////////
// User - Passwd //
///////////////////

CegoAdmScreen::User::Action::Passwd::Passwd(CegoAdminHandler* pAH, Screen::Panel* pParent)
    : Screen::Form(pParent)
{
    _pAH = pAH;
    ListT<Chain> attrList; 
    attrList.Insert(Chain("Passwd") + ATTRSEPTOKEN + INPUT_TYPE_PWD + ATTRSEPTOKEN + MAXPASSWDLEN + ATTRSEPTOKEN + Chain());
    setAttrList(Chain("Setting password"), attrList, 15);		  
}
		
CegoAdmScreen::User::Action::Passwd::~Passwd()
{
}
		
void CegoAdmScreen::User::Action::Passwd::setUser(const Chain& user)
{
    _user = user;
};

Screen::Panel* CegoAdmScreen::User::Action::Passwd::onConfirm(const ListT<Chain>& valList)
{   
    Chain *pPwd = valList.First();
    
    CegoAdminHandler::ResultType res;
    
    res = _pAH->reqChangePwd(_user, *pPwd);
    
    Chain msg;
    _pAH->getMsg(msg);
    
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	return setError(Chain(ERROR_TITLE), msg);
    }
    
    return _pParent;
}

Screen::Panel* CegoAdmScreen::User::Action::Passwd::onCancel()
{    
    return _pParent;
}

///////////////////
// User - Assign //
///////////////////

CegoAdmScreen::User::Action::Assign::Assign(CegoAdminHandler* pAH, Screen::Panel* pParent) : Screen::Form(pParent)
{
    _pAH = pAH;
}

CegoAdmScreen::User::Action::Assign::~Assign()
{
}

void CegoAdmScreen::User::Action::Assign::setup(const Chain& user, const SetT<Chain> roleSet, bool isAssign)
{
    _isAssign = isAssign;
    _user = user;
    
    Chain roleMenu;

    Chain *pRole = roleSet.First();

    if ( pRole )
    {
	roleMenu += *pRole + VALSEPTOKEN + *pRole;
	roleMenu += LISTSEPTOKEN;

	while ( pRole )
	{	    
	    roleMenu += *pRole + VALSEPTOKEN + *pRole;
	    
	    pRole = roleSet.Next();
	    if ( pRole )
		roleMenu += LISTSEPTOKEN;
	}
    }

    ListT<Chain> attrList;
    attrList.Insert( Chain("Role") + ATTRSEPTOKEN + INPUT_TYPE_MENU + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + roleMenu);

    if ( isAssign )
	setAttrList(Chain("Assign role"), attrList, 20);
    else	
	setAttrList(Chain("Remove role"), attrList, 20);
}

Screen::Panel* CegoAdmScreen::User::Action::Assign::onConfirm(const ListT<Chain>& valList)
{
    Chain role = valList[0];
    
    CegoAdminHandler::ResultType res; 

    if ( _isAssign )
	res = _pAH->reqAssignRole(_user, role);
    else	
	res = _pAH->reqRemoveRole(_user, role);
       
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);
	return setError(Chain(ERROR_TITLE), msg);
    }

    return _pParent;
}

///////////////////
// User - Delete //
///////////////////

CegoAdmScreen::User::Action::Delete::Delete(CegoAdminHandler* pAH, Screen::Panel* pParent) : Screen::Confirm(pParent)
{
    _pAH = pAH;
}

CegoAdmScreen::User::Action::Delete::~Delete()
{
}

void CegoAdmScreen::User::Action::Delete::setup(const Chain& user)
{
    _user = user;
    setInfo(Chain("Delete user ") + _user + Chain("?"), Chain());
}

Screen::Panel* CegoAdmScreen::User::Action::Delete::onConfirm()
{
    CegoAdminHandler::ResultType res;
			
    res = _pAH->reqRemoveUser(_user);

    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);
	return setError(Chain(ERROR_TITLE), msg);
    }

    return _pParent;
}


//////////////////////////////////////////
// ##########  Role Panel ##########//
//////////////////////////////////////////

CegoAdmScreen::Role::Role(CegoAdminHandler* pAH, Screen::Panel* pParent)
    : Screen::Grid(pParent)
{
    _pAH = pAH;
    
    _roleSchema.Insert(Chain("Name") + VALSEPTOKEN + Chain("l10"));
    
    ListT<Screen::GridColor> colorMap;		
    setSchema(Chain("Roles"), _roleSchema, colorMap, 0);
    
    _pAdd = new Add(pAH, this);
    _pAction = new Action(pAH, this);   
    _pHelp = new Screen::Message(this);
    _pHelp->setInfo(RL_HELP_TITLE, RL_HELP_TEXT,5);

}

CegoAdmScreen::Role::~Role()
{
    delete _pAdd;
    delete _pAction;
    delete _pHelp;
}

Screen::Panel* CegoAdmScreen::Role::onSelect(unsigned selectedRow)
{
    _pAction->setRole(_roleTable[selectedRow-1][0]);
    return _pAction;
}

Screen::Panel* CegoAdmScreen::Role::onKey(unsigned c, unsigned rowNum)
{
    if ( c == KEY_NEW )
    {
	_pAdd->reset();
	return _pAdd;
    }
    else if ( c == KEY_HLP )
    {
	return _pHelp;
    }

    return this;
}

ListT< ListT<Chain> > CegoAdmScreen::Role::getData()
{
    return _roleTable;
}

void CegoAdmScreen::Role::refresh()
{
    CegoAdminHandler::ResultType res;	
    res = _pAH->reqListRole();

    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);
	setStatus(msg);
	return;
    }
    
    CegoTableObject oe;
    ListT<ListT<CegoFieldValue> > roleList;	
    _pAH->getRoleList(oe, roleList);

    ListT<Chain> roleSchema;
    roleSchema.Insert(Chain("Name") + VALSEPTOKEN + Chain("50"));

    _roleTable.Empty();
    
    ListT<CegoFieldValue> *pFVL = roleList.First();
    while ( pFVL )
    {
	ListT<Chain> roleRow;
	
	CegoFieldValue *pFV = pFVL->First();
	if ( pFV )
	{
	    roleRow.Insert(pFV->valAsChain());		
	}
	pFVL = roleList.Next();
	
	_roleTable.Insert(roleRow);
    }
}

CegoAdmScreen::Role::Add::Add(CegoAdminHandler* pAH, Screen::Panel* pParent)
    : Screen::Form(pParent)
{
    ListT<Chain> attrList; 
    attrList.Insert( Chain("Name") + ATTRSEPTOKEN + INPUT_TYPE_ID + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + Chain());
    setAttrList(Chain("Add role"), attrList, 15);

    _pAH = pAH;
}

CegoAdmScreen::Role::Add::~Add()
{
}

Screen::Panel* CegoAdmScreen::Role::Add::onConfirm(const ListT<Chain>& valList)
{    
    Chain *pRole = valList.First();   
    CegoAdminHandler::ResultType res;
    
    res = _pAH->reqCreateRole(*pRole);
    
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);	
	return setError(Chain(ERROR_TITLE), msg);
    }
    
    return _pParent;
}

Screen::Panel* CegoAdmScreen::Role::Add::onCancel()
{		
    return _pParent;
}

CegoAdmScreen::Role::Action::Action(CegoAdminHandler* pAH, Screen::Panel* pParent)
    : Screen::Select(pParent)
{
    _pPerm = new Perm(pAH, pParent);
    _pAssign = new Assign(pAH, pParent);
    _pDelete = new Delete(pAH, pParent);

    _pAH = pAH;
}

CegoAdmScreen::Role::Action::~Action()
{
    delete _pPerm;
    delete _pAssign;
    delete _pDelete;
}
	    
void CegoAdmScreen::Role::Action::setRole(const Chain& role)
{
    _role = role;
    
    ListT<Chain> items;
    items.Insert(Chain("Permission=1"));
    items.Insert(Chain("Delete=2"));
    items.Insert(Chain("Assign=3"));
    
    setItems(Chain("Role ") + _role, 20, items);

    _pPerm->setup(_role);
    _pDelete->setup(_role);
}
	    
Screen::Panel* CegoAdmScreen::Role::Action::onSelect(unsigned selected)
{
    unsigned action = getSelectedValue().asUnsigned();
    
    switch ( action )
    {
    case 1:
    {	
	return _pPerm;	     
    }
    case 2:
    {
	return _pDelete;	     
    }
    case 3:
    {
	_pAH->reqShowUser();
	
	CegoTableObject oe;
	ListT<ListT<CegoFieldValue> > userList;
	
	_pAH->getUserInfo(oe, userList);
	
	ListT<Chain> users;

	ListT<CegoFieldValue> *pFVL = userList.First();
	while ( pFVL )
	{
	    ListT<Chain> userRow;
	    
	    CegoFieldValue *pFV = pFVL->First();

	    if ( pFV )
		users.Insert(pFV->valAsChain());
	    

	    pFVL = userList.Next();
	}
	
	_pAssign->setup(_role, users);
	return _pAssign;
    }
    }
    return _pParent;    
}

CegoAdmScreen::Role::Action::Perm::Perm(CegoAdminHandler* pAH, Screen::Panel* pParent) : Screen::Grid(pParent)
{
    _pAH = pAH;
    _pEdit = new Edit(_pAH, this); 
    _pHelp = new Screen::Message(this);
    _pHelp->setInfo(PRM_HELP_TITLE, PRM_HELP_TEXT,5);

}

CegoAdmScreen::Role::Action::Perm::~Perm()
{
    delete _pEdit;
    delete _pHelp;
}

void CegoAdmScreen::Role::Action::Perm::setup(const Chain& role)
{
    ListT<Chain> permSchema;
    permSchema.Insert(Chain("PermId") + VALSEPTOKEN + Chain("l15"));
    permSchema.Insert(Chain("TableSet") + VALSEPTOKEN + Chain("l15"));
    permSchema.Insert(Chain("Filter") + VALSEPTOKEN + Chain("l15"));
    permSchema.Insert(Chain("Permission") + VALSEPTOKEN + Chain("l15"));
    
    ListT<Screen::GridColor> colorMap;
    
    setSchema(Chain("Role ") + role + Chain(" Permission"), permSchema, colorMap, 0);

    _role = role;
    _pEdit->setup(_role);
}

Screen::Panel* CegoAdmScreen::Role::Action::Perm::onSelect(unsigned rowNum)
{
    ListT<Chain> valList;
    valList.Insert(_permTable[rowNum-1][0]);
    valList.Insert(_permTable[rowNum-1][1]);
    valList.Insert(_permTable[rowNum-1][2]);
    valList.Insert(_permTable[rowNum-1][3]);
    
    _pEdit->setValueList(valList);

    return _pEdit;
}

Screen::Panel* CegoAdmScreen::Role::Action::Perm::onKey(unsigned c, unsigned rowNum)
{
    if ( c == KEY_NEW )
    {
	_pEdit->clear();
	return _pEdit;
    }
    else if ( c == KEY_DELETE )
    {
	Chain permId = _permTable[rowNum-1][0];

	CegoAdminHandler::ResultType res;
	res = _pAH->reqRemovePermission(_role, permId);
		
	if ( res == CegoAdminHandler::ADM_ERROR )
	{
	    Chain msg;
	    _pAH->getMsg(msg);       
	    return setError(Chain(ERROR_TITLE), msg);
	}

	refresh();
	
	return this;
    }
    else if ( c == KEY_HLP )
    {
	return _pHelp;
    }

    return this;
}

ListT< ListT<Chain> > CegoAdmScreen::Role::Action::Perm::getData()
{
    return _permTable;
}

void CegoAdmScreen::Role::Action::Perm::refresh()
{
    _pAH->reqShowRole(_role);
    
    CegoTableObject oe;
    ListT<ListT<CegoFieldValue> > permInfo;
	
    _pAH->getRoleInfo(oe, permInfo);

    Chain msg;
    _pAH->getMsg(msg);
	
    _permTable.Empty();
	
    ListT<CegoFieldValue> *pFVL = permInfo.First();
    while ( pFVL )
    {
	ListT<Chain> permRow;
	
	CegoFieldValue *pFV = pFVL->First();
	while ( pFV )
	{
	    permRow.Insert(pFV->valAsChain());
	    pFV = pFVL->Next();
	}
	
	_permTable.Insert(permRow);
	pFVL = permInfo.Next();
    }
}

CegoAdmScreen::Role::Action::Perm::Edit::Edit(CegoAdminHandler* pAH, Panel* pParent) : Screen::Form(pParent)
{
    Chain rightMenuString = Chain("ALL") + VALSEPTOKEN + Chain("ALL")
	+ LISTSEPTOKEN + Chain("READ") + VALSEPTOKEN + Chain("READ")
	+ LISTSEPTOKEN + Chain("WRITE") + VALSEPTOKEN + Chain("WRITE")
	+ LISTSEPTOKEN + Chain("MODIFY") + VALSEPTOKEN + Chain("MODIFY")
	+ LISTSEPTOKEN + Chain("EXEC") + VALSEPTOKEN + Chain("EXEC")
	+ LISTSEPTOKEN + Chain("ALL") + VALSEPTOKEN + Chain("ALL");

    ListT<Chain> attrList;
    attrList.Insert(Chain("PermId") + ATTRSEPTOKEN + INPUT_TYPE_ID + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + Chain("PERMID"));
    attrList.Insert(Chain("TableSet") + ATTRSEPTOKEN + INPUT_TYPE_ID + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + Chain("TS"));
    attrList.Insert(Chain("Filter") + ATTRSEPTOKEN + INPUT_TYPE_STRING + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + Chain("ALL"));
    attrList.Insert( Chain("Right") + ATTRSEPTOKEN + INPUT_TYPE_MENU + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + rightMenuString);

    setAttrList(Chain("Set permission"), attrList, 20);

    _pAH = pAH;
}

CegoAdmScreen::Role::Action::Perm::Edit::~Edit()
{
}

void CegoAdmScreen::Role::Action::Perm::Edit::clear()
{
    ListT<Chain> valList;
    valList.Insert(Chain());
    valList.Insert(Chain());
    valList.Insert(Chain());
    valList.Insert(Chain("ALL")); 
    setValueList(valList);
}

void CegoAdmScreen::Role::Action::Perm::Edit::setup(const Chain& role)
{
    _role = role;
}

Screen::Panel* CegoAdmScreen::Role::Action::Perm::Edit::onConfirm(const ListT<Chain>& valList)
{
    Chain permId = valList[0];
    Chain tableSet = valList[1];
    Chain filterPerm = valList[2];
    Chain right = valList[3];
    
    CegoAdminHandler::ResultType res;
    
    res = _pAH->reqSetPermission(_role, permId, tableSet, filterPerm, right);
        
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);
	return setError(Chain(ERROR_TITLE), msg);
    }
    return _pParent;
}

Screen::Panel* CegoAdmScreen::Role::Action::Perm::Edit::onCancel()
{
    return _pParent;
}

CegoAdmScreen::Role::Action::Assign::Assign(CegoAdminHandler* pAH, Screen::Panel* pParent) : Screen::Form(pParent)
{
    _pAH = pAH;
}

CegoAdmScreen::Role::Action::Assign::~Assign()
{   
}

void CegoAdmScreen::Role::Action::Assign::setup(const Chain& role, ListT<Chain> userList)
{
    Chain userMenu;

    Chain *pUser = userList.First();

    if ( pUser )
    {
	userMenu += *pUser + VALSEPTOKEN + *pUser;
	userMenu += LISTSEPTOKEN;

	while ( pUser )
	{	    
	    userMenu += *pUser + VALSEPTOKEN + *pUser;
	    
	    pUser = userList.Next();
	    if ( pUser )
		userMenu += LISTSEPTOKEN;
	}
    }

    ListT<Chain> attrList;
    attrList.Insert( Chain("User") + ATTRSEPTOKEN + INPUT_TYPE_MENU + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + userMenu);

    setAttrList(Chain("Assign role to"), attrList, 20);

    _role = role;
}

Screen::Panel* CegoAdmScreen::Role::Action::Assign::onConfirm(const ListT<Chain>& valList)
{
    Chain userName = valList[0];
    
    CegoAdminHandler::ResultType res; 
    
    res = _pAH->reqAssignRole(userName, _role);
       
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);

	return setError(Chain(ERROR_TITLE), msg);
    }

    return _pParent;
}


CegoAdmScreen::Role::Action::Delete::Delete(CegoAdminHandler* pAH, Screen::Panel* pParent) : Screen::Confirm(pParent)
{
    _pAH = pAH;
}

CegoAdmScreen::Role::Action::Delete::~Delete()
{
}

void CegoAdmScreen::Role::Action::Delete::setup(const Chain& role)
{
    setInfo(Chain("Delete role ") + role + Chain("?"), Chain());
    _role = role;
}

Screen::Panel* CegoAdmScreen::Role::Action::Delete::onConfirm()
{   
    CegoAdminHandler::ResultType res;
    
    res = _pAH->reqDropRole(_role);
    
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	_pAH->getMsg(msg);		
	return setError(Chain(ERROR_TITLE),  msg);
    }

    return _pParent;
}

Screen::Panel* CegoAdmScreen::Role::Action::Delete::onCancel()
{
    return _pParent;
}

////////////
// Setup  //
////////////

CegoAdmScreen::Setup::Setup(CegoAdmScreen* pScreen, CegoAdminHandler* pAH, Screen::Panel* pParent, const Chain& title)
    : Screen::Select(pParent)
{
    ListT<Chain> setupList;
    setupList.Insert(Chain("LogManager=1"));
    setupList.Insert(Chain("BackupManager=2"));
    setupList.Insert(Chain("Refresh=3"));
    
    setItems(title, 20, setupList);
    
    _pLogMng = new LogMng(pAH, pParent, Chain("Log Manager"));
    _pBackupMng = new BackupMng(pAH, pParent, Chain("Backup Manager"));
    _pRefresh = new Refresh(pScreen, pParent);
}

CegoAdmScreen::Setup::~Setup()
{
    delete _pLogMng;
    delete _pBackupMng;
    delete _pRefresh;
}

Screen::Panel* CegoAdmScreen::Setup::onSelect(unsigned selected)
{
    if ( selected == 1 )
    {
	_pLogMng->setup();
	return _pLogMng;
    }
    else if ( selected == 2 )
    {
	_pBackupMng->setup();
	return _pBackupMng;
    }
    else if ( selected == 3 )
	return _pRefresh;
    
    return this;
}

CegoAdmScreen::Setup::LogMng::LogMng(CegoAdminHandler* pAH, Screen::Panel* pParent, const Chain& title)
    : Screen::Form(pParent)
{
    ListT<Chain> attrList; 
    attrList.Insert( Chain("LogManager") + ATTRSEPTOKEN + INPUT_TYPE_STRING + ATTRSEPTOKEN + MAXPATHLEN + ATTRSEPTOKEN + Chain());
    attrList.Insert( Chain("Timeout") + ATTRSEPTOKEN + INPUT_TYPE_NUMBER + ATTRSEPTOKEN + MAXNAMELEN + ATTRSEPTOKEN + Chain("60"));
    setAttrList(title, attrList, 30);

    _pAH = pAH;
}

void CegoAdmScreen::Setup::LogMng::setup()
{   
    CegoAdminHandler::ResultType res;
    res = _pAH->reqShowLogMng();

    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	setStatus(msg);
	return;
    }

    CegoTableObject oe;
    ListT<ListT<CegoFieldValue> > lmInfo;
    
    _pAH->getLogMngInfo(oe, lmInfo);

    Chain logManager;
    Chain logTimeout;
    
    ListT<CegoFieldValue> *pFVL = lmInfo.First();
    if ( pFVL )
    {	
	CegoFieldValue *pFV = pFVL->First();
	if ( pFV )
	{		       
	    logManager = pFV->valAsChain();
	}

	pFV = pFVL->Next();
	if ( pFV )
	{
	    logTimeout = pFV->valAsChain();
	}
    }

    ListT<Chain> valList;
    valList.Insert(logManager);
    valList.Insert(logTimeout);
    
    setValueList(valList);
    setStatus("Logmng=" + logManager);
}
   
Screen::Panel* CegoAdmScreen::Setup::LogMng::onConfirm(const ListT<Chain>& valList)
{
    Chain logManager = valList[0];
    unsigned logTimeout = valList[1].asUnsigned();
    
    CegoAdminHandler::ResultType res;

    res = _pAH->reqSetLogMng(logManager, logTimeout);
    
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;    
	_pAH->getMsg(msg);
	return setError(Chain(ERROR_TITLE), msg);
    }

    return _pParent;
}
	    
CegoAdmScreen::Setup::BackupMng::BackupMng(CegoAdminHandler* pAH, Screen::Panel* pParent, const Chain& title)
    : Screen::Form(pParent)
{
    _pAH = pAH;
    ListT<Chain> attrList; 
    attrList.Insert( Chain("BackupManager") + ATTRSEPTOKEN + INPUT_TYPE_STRING + ATTRSEPTOKEN + MAXPATHLEN + ATTRSEPTOKEN + Chain());
    setAttrList(title, attrList, 30);
}
	    
Screen::Panel* CegoAdmScreen::Setup::BackupMng::onConfirm(const ListT<Chain>& valList)
{   
    Chain buManager = valList[0];
    
    CegoAdminHandler::ResultType res;
    
    res = _pAH->reqSetBackupMng(buManager);
    
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;    
	_pAH->getMsg(msg);
	return setError(Chain(ERROR_TITLE), msg);
    }
    return _pParent;
}

void CegoAdmScreen::Setup::BackupMng::setup()
{   
    CegoAdminHandler::ResultType res;
    res = _pAH->reqShowBackupMng();
    
    if ( res == CegoAdminHandler::ADM_ERROR )
    {
	Chain msg;
	setStatus(msg);
	return;
    }
    
    CegoTableObject oe;
    ListT<ListT<CegoFieldValue> > lmInfo;
    
    _pAH->getBackupMngInfo(oe, lmInfo);

    Chain backupManager;
    
    ListT<CegoFieldValue> *pFVL = lmInfo.First();
    if ( pFVL )
    {	
	CegoFieldValue *pFV = pFVL->First();
	if ( pFV )
	{		       
	    backupManager = pFV->valAsChain();
	}	    
    }

    ListT<Chain> valList;
    valList.Insert(backupManager);
    setValueList(valList);
}

CegoAdmScreen::Setup::Refresh:: Refresh(Screen* pScreen, Screen::Panel* pParent)
    : Screen::Select(pParent)
{
    ListT<Chain> items;
    items.Insert(Chain("1 sec=1000"));
    items.Insert(Chain("3 sec=3000"));
    items.Insert(Chain("10 sec=10000"));
    
    setItems(Chain("Refresh Interval"), 20, items);
    
    _pScreen = pScreen;
}

Screen::Panel* CegoAdmScreen::Setup::Refresh::onSelect(unsigned selected)
{    
    unsigned interval = getSelectedValue().asUnsigned();   
    _pScreen->setTimeout(interval);
    return _pParent;
}

////////////////////////////////
// Main class implementation  //
////////////////////////////////

CegoAdmScreen::CegoAdmScreen(CegoAdminHandler *pAH) : Screen()
{
    _pAH = pAH;
    
    setTimeout(3000);
		
    _pMenu = new AdminMenu();

    _pBufferPool = new BufferPool(_pAH, _pMenu);
    _pMenu->regItem(Chain("BufferPool"), (Screen::Panel*)_pBufferPool);

    _pThreadPool = new ThreadPool(_pAH, _pMenu, Chain("ThreadPool"));
    _pMenu->regItem(Chain("ThreadPool"), (Screen::Panel*)_pThreadPool);

    _pTableSet = new TableSet(_pAH, _pMenu, Chain("TableSet"));
    _pMenu->regItem(Chain("TableSet"), (Screen::Panel*)_pTableSet);
    
    _pUser = new User(_pAH, _pMenu);
    _pMenu->regItem(Chain("User"), (Screen::Panel*)_pUser);

    _pRole = new Role(_pAH, _pMenu);
    _pMenu->regItem(Chain("Role"), (Screen::Panel*)_pRole);
   
    _pSetup = new Setup(this, _pAH, _pMenu, Chain("Setup"));
    _pMenu->regItem(Chain("Setup"), (Screen::Panel*)_pSetup);
    
    _pMenu->regItem(Chain("Quit"), (Screen::Panel*)0);
    
    setRoot(_pMenu);
}

CegoAdmScreen::~CegoAdmScreen()
{
    delete _pSetup;
    delete _pBufferPool;
    delete _pThreadPool;
    delete _pTableSet;
    delete _pUser;
    delete _pRole;
    delete _pMenu;
}
