// TSList.h: interface for the base class: TSList,
//    inherited classes: TSRecordList, TSTreeList, and TSFieldList, and
//    associated class: TSPosition.
//
/////////////////////////////////////////////////////////////////////////

#ifndef TSLIST_H_
#define TSLIST_H_

#include "TSDef.h"
#include "TSObject.h"
#include "TSSocket.h"

#pragma warning( disable: 4710 )  // inlined function not inlined

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Position object for list iteration.
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

  class AFX_EXT_CLASS TSPosition
{

  public:

    TSPosition();
    TSPosition( TSPosition* nextPos, TSPosition* prevPos, TSObject* thisObj );
    TSPosition* next;
    TSPosition* prev;
    TSObject* object;

};

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Base class for all lists.
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

  class AFX_EXT_CLASS TSList
{

  public:

    TSList();
    ~TSList();

    TSPosition* GetFirst();
    TSPosition* GetNext( TSPosition* pos );
    TSPosition* GetPrev( TSPosition* pos );
    TSPosition* GetLast();
    TSPosition* Get( int index );

    int InsertBefore( TSPosition* pos, TSObject* object );
    int InsertAfter( TSPosition* pos, TSObject* object );
    int AddHead( TSObject* object );
    int AddTail( TSObject* object );

    TSObject* GetAt( TSPosition* pos );

    int Length() { return length; }

    TSObject* RemoveObject( int index );
    TSObject* RemoveObject( TSPosition* pos );
    TSObject* RemoveObject( TSObject* pObject );

    int  Duplicate( TSList* newList );
    int  Copy( TSList* sourceList );
    void EmptyList();
    void EmptyAndDestroyList();

    virtual int SocketString( TSString& out );
    TSString StringDump( int recursive, TSString indentation );

  private:

    TSPosition* first;
    TSPosition* last;
    int length;

};

class TSRecord;
class TSInteger;
class TSField;
class TSServer;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Derived list classes.  A derived class was needed so that these classes
 * can define their own way of receiving themselves off of the socket.
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

class AFX_EXT_CLASS TSRecordList : public TSList
{

  public:

    TSRecordList();
    virtual ~TSRecordList();

    TSRecord* GetAt( TSPosition* pos )
              { return (TSRecord*)TSList::GetAt( pos ); }

    virtual TSRecord* FindRecord( int recId);
    virtual TSRecord* FindRecord( const char* fieldName, int searchValue );
    virtual TSRecord* FindRecord( const char* fieldName, double searchValue );
    virtual TSRecord* FindRecord( const char* fieldName, const char* searchValue );
    virtual TSRecord* FindRecord( const char* fieldName, int nTableId, int nFieldType, int nSqlDataType );

    int Receive( TSServer* server, TSSocket* socket );
    virtual int SocketString( TSString& out );
    void SetIsFieldList( BOOL bIsFields ) { m_bIsFieldList = bIsFields; }

  private:

    BOOL m_bIsFieldList;

};

class AFX_EXT_CLASS TSFieldList : public TSList
{

  public:

    TSField* GetAt( TSPosition* pos )
              { return (TSField*)TSList::GetAt( pos ); }
    TSString DumpSchema( TSString indentation );
    TSField* FindFieldByName( const char* fieldName, int fieldType = 0 );

};

class AFX_EXT_CLASS TSTreeList : public TSRecordList
{
  public:

    virtual TSRecord* FindRecord( int recId );
    virtual TSRecord* FindRecord( const char* fieldName, int searchValue );
    virtual TSRecord* FindRecord( const char* fieldName, double searchValue );
    virtual TSRecord* FindRecord( const char* fieldName, const char* searchValue );

};

#endif
