/*TITLE declarations for logical layer classes*/

/****keyword-flag*** "%v %f %n" */
/* "13 6-May-98,8:40:02 NEWQUANT.H" */

class FreeSpaceArrayPtr
{
protected:
class FreeSpaceArray //body class
{
friend FreeSpaceArrayPtr;
protected:
SVector<FreeSpaceBlockPtr> m_BlockPtr;
ArrayIndex m_FreeSpaceListCount;
ArrayIndex m_FreeSpaceListBlockCount;
ArrayIndex m_CurrentLowestFreeBlock;
ArrayIndex m_QuantumBlockNumberAdjustment;
int m_ReferenceCount;

public:
	FreeSpaceArray();
	FreeSpaceArray(QuantumFile *p_QuantumFile);
	~FreeSpaceArray();
QFreeSpaceEntry Get(ArrayIndex p_Index);
void Set(ArrayIndex p_Index, QFreeSpaceEntry p_Entry);
QuantumNumber FindEmptyBlock();
QuantumNumber FindSpaceForItem(ObjectNumber p_ObjectNumber, ArrayIndex p_ItemSize);
ArrayIndex QGetFreeSpaceListCount() {return m_FreeSpaceListCount;}
};
FreeSpaceArray *m_FSA;

public:
FreeSpaceArrayPtr();
FreeSpaceArrayPtr(const FreeSpaceArrayPtr& p_FSAP);
FreeSpaceArrayPtr(QuantumFile *p_QuantumFile);
FreeSpaceArray *operator->();
FreeSpaceArrayPtr& operator=(const FreeSpaceArrayPtr& p_FSAP);
~FreeSpaceArrayPtr();
};

class MainObjectArrayPtr
{
protected:
class MainObjectArray
{
friend MainObjectArrayPtr;
protected:
QuantumFile *m_QuantumFile;
SVector<MainObjectBlockPtr> m_BlockPtr;
ObjectNumber m_MainObjectCount;
ArrayIndex m_MainObjectBlockCount;
ArrayIndex m_CurrentLowestFreeObject;
int m_ReferenceCount;

public:
MainObjectArray();
MainObjectArray(QuantumFile *p_QuantumFile);
~MainObjectArray();

MainObjectEntry Get(ArrayIndex p_Index);

void Set(ArrayIndex p_Index, MainObjectEntry p_Entry);

ObjectNumber FindAvailableObject();

ObjectNumber GetMainObjectCount() {return m_MainObjectCount;}

ModifiableElement GetModifiableElement(ArrayIndex p_MainObjectNumber, 
	ArrayIndex p_ElementIndex);

AccessVector<Ulong> GetAccessVectorUlong(
        ArrayIndex p_MainObjectNumber, ArrayIndex p_ElementIndex);

void SetModified(ArrayIndex p_MainObjectNumber,
	ArrayIndex p_ElementIndex);

int PutElement(ObjectNumber p_MainObjectNumber, 
	ArrayIndex p_ElementIndex, ModifiableElement p_Element);

void CreateMainObject(ModifiableElement p_ObjectName, 
	ObjectNumber p_ObjectNumber, ArrayIndex p_ElementCount=100,
	ArrayIndex p_MaxElementCount=UINT_MAX-1);

ArrayIndex GetMainObjectElementCount(ArrayIndex p_MainObjectNumber);

ArrayIndex GetMainObjectMaxElementCount(ArrayIndex p_MainObjectNumber);

ObjectNumber FindObjectByName(ModifiableElement p_ObjectName);

ArrayIndex GrowMainObject(ObjectNumber p_ObjectNumber, ArrayIndex p_NewElementCount);
};

MainObjectArray *m_MOA;

public:
MainObjectArrayPtr();
MainObjectArrayPtr(const MainObjectArrayPtr& p_MOAP);
MainObjectArrayPtr(QuantumFile *p_QuantumFile);
MainObjectArray *operator->();
MainObjectArrayPtr& operator=(const MainObjectArrayPtr& p_MOAP);
~MainObjectArrayPtr();
}; // end of MainObjectArray


class FlexArrayRef;

class FlexArray
{
protected:
	MainObjectArrayPtr m_MOA;
	ObjectNumber m_MOAIndex;
	ArrayIndex m_ElementCount;
	ArrayIndex m_MaxElementCount;
public:
	FlexArray();

    FlexArray(QuantumFile *p_QF, ModifiableElement p_ArrayName, 
	ArrayIndex p_ElementCount=1, ArrayIndex p_MaxElementCount=UINT_MAX-1);

    FlexArray(MainObjectArrayPtr p_MOA, ObjectNumber p_MOAIndex);

    FlexArrayRef operator[](ArrayIndex p_ElementIndex);
    
    void Open(QuantumFile *p_QF, ModifiableElement p_ArrayName, 
	ArrayIndex p_ElementCount=1, ArrayIndex p_MaxElementCount=UINT_MAX-1);

    ArrayIndex GetSize() {return m_ElementCount;}
};

class FlexArrayRef
{
private:
	MainObjectArrayPtr &m_MOA;
	ObjectNumber m_MOAIndex;
	ArrayIndex m_ElementIndex;

private: //prevent compiler warnings
	FlexArrayRef& operator=(const FlexArrayRef&);

public:
	FlexArrayRef(MainObjectArrayPtr &p_MOA, ObjectNumber p_MOAIndex, ArrayIndex p_ElementIndex);
	FlexArrayRef& operator=(ModifiableElement p_ROE);
	operator ModifiableElement();
};


