
#ifndef TSLIST_H_
#define TSLIST_H_

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

/*
 * 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 *newList);
    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( const char* fieldName, int nTableId, int nFieldType, int nSqlDataType );
    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);

    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

