#ifndef  __RV_DSMSP_H_INCLUDED_
#define  __RV_DSMSP_H_INCLUDED_

#include "idsm.h"



inline  RvSlice  RV_SLICE( int start, int end )
{
    RvSlice slice;
    slice.start  = start;
    slice.end  = end;

    return slice;
}

//inline RvSequence rsqClone(const RvSequence sequence, RvSequence pDest=NULL)
//{
//    return rsqExtract( sequence, RV_WHOLE_SEQ,  pDest, TRUE );
//}

/////////////////////contour (shape) /////////////////////////////////////////////////

//**************写序列操作:按照顺序写入 **********************************************
#define RV_BEGIN_WRITE_SEQ(sequence, writer )  rvdBeginWrite_(sequence, writer)

#define RV_WRITE_TO_SEQ_EX_(writer, val, bAddHead)  \
{ \
    RvCollectItem*    pTemp =(RvCollectItem*)rmsAlloc((writer)->nodeStore); \
	RV_ASSERT(pTemp);  \
	memset(pTemp, 0, sizeof(RvCollectItem)); \
	/*pTemp->data = (char*)rmsAlloc((writer)->dataStore);*/ \
    /*RV_ASSERT(pTemp->data);*/  \
    pTemp->data = val; /*memcpy(pTemp->data,  (val), (writer)->elemSize);*/ \
	if ((writer)->count == 0){ \
		(writer)->pHead = pTemp;  \
		(writer)->pTail = pTemp;  \
		(writer)->count++; \
	} \
	else{ \
	    RV_ASSERT((writer)->pHead && (writer)->pTail);  \
		if (!(bAddHead)){  \
		   (writer)->pTail->next = pTemp; pTemp->prev = (writer)->pTail; \
		   (writer)->pTail = pTemp;  \
		   (writer)->count++; \
		}\
		else {\
			 (writer)->pHead->prev = pTemp; pTemp->next = (writer)->pHead; \
			 (writer)->pHead = pTemp;  \
			 (writer)->count++; \
	   } \
	} \
} 


#define RV_WRITE_TO_SEQ_(writer, val)    RV_WRITE_TO_SEQ_EX_( writer ,  val , FALSE) 
 

#define RV_END_WRITE_SEQ(sequence, writer) rvdEndWrite_(sequence, writer)


//******************************END OF WRITING SEQUENCE *******************************

//****************************** 队列操作，先进先出 *********************************
#define RV_BEGIN_QUEUE(sequence, writer )  rvdBeginWrite_(sequence, writer)

#define RV_PUSH_TO_QUEUE(writer, val)  \
{ \
    RvCollectItem*    pTemp =(RvCollectItem*)rmsAlloc((writer)->nodeStore); \
	RV_ASSERT(pTemp);  \
	memset(pTemp, 0, sizeof(RvCollectItem)); \
	/*pTemp->data =(char*) rmsAlloc((writer)->dataStore);*/ \
    /*RV_ASSERT(pTemp->data);*/  \
    pTemp->data = (val) ;/* memcpy(pTemp->data,  (val), (writer)->elemSize); */\
	if ((writer)->count == 0){ \
		(writer)->pHead = pTemp;  \
		(writer)->pTail = pTemp;  \
		(writer)->count++; \
	} \
	else{ \
	    RV_ASSERT((writer)->pHead && (writer)->pTail);  \
		(writer)->pTail->next = pTemp; pTemp->prev = (writer)->pTail; \
		(writer)->pTail = pTemp;  \
		(writer)->count++; \
	} \
} 

#define RV_POP_FROM_QUEUE(writer, datatype, val, bReverse)   \
{ \
	if ((writer)->count > 0){  \
	    RV_ASSERT((writer)->pHead && (writer)->pTail);  \
		if (!bReverse) \
        {\
		     val =(datatype) ((writer)->pHead->data) ;/*memcpy((val), (writer)->pHead->data, (writer)->elemSize);*/ \
		    RvCollectItem*    pTemp = (writer)->pHead; \
		    (writer)->pHead = (writer)->pHead->next; \
		    if ((writer)->pHead ) (writer)->pHead->prev = NULL; \
		    (writer)->count--; \
		    if ((writer)->count==0)(writer)->pTail = NULL;  \
		    /*rmsFree((writer)->dataStore, pTemp->data); */\
		    rmsFree((writer)->nodeStore, pTemp); \
        }\
		else \
        {  \
		    val  = (datatype) ((writer)->pTail->data); /*memcpy((val), (writer)->pTail->data, (writer)->elemSize);*/ \
		    RvCollectItem*    pTemp = (writer)->pTail; \
		    (writer)->pTail = (writer)->pTail->prev; \
		    if ((writer)->pTail ) (writer)->pTail->next = NULL; \
		    (writer)->count--; \
		    if ((writer)->count==0)(writer)->pHead = NULL;  \
		    /*rmsFree((writer)->dataStore, pTemp->data);*/ \
		    rmsFree((writer)->nodeStore, pTemp); \
        }  \
	} \
}

#define RV_IS_QUEUE_EMPTY(writer)       ((writer)->count==0)

#define RV_END_QUEUE(sequence, writer )    rvdEndWrite_(sequence, writer)

 //******************END OF QUEUE *******************************************************



//*****************读序列操作 ********************************************************
#define RV_BEGIN_READ_SEQ_EX(sequence, reader, bReverse)   rvdBeginRead_(sequence,  reader ,  bReverse )
#define RV_BEGIN_READ_SEQ(sequence, reader)  RV_BEGIN_READ_SEQ_EX(sequence, reader, FALSE)


#define RV_READ_FR_SEQ_EX_(reader, datatype, val,  backward) \
{    \
	RV_ASSERT((reader)->current);  \
	val =(datatype) ((reader)->current->data);/*memcpy((val), (reader)->current->data, (reader)->elemSize);*/  \
	if (!(backward)) (reader)->current =(RvCollectItem*) ((reader)->current->next);  \
	else  (reader)->current = (RvCollectItem*)((reader)->current->prev);  \
}


#define RV_READ_FR_SEQ_(reader, datatype, val )    RV_READ_FR_SEQ_EX_(reader, datatype, val,  FALSE)

#define RV_IS_SEQ_END(reader)    (NULL == ((reader)->current))

#define RV_END_READ_SEQ(sequence, reader )   rvdEndRead_(sequence, reader) 
 

#define RV_SEQ_GET_CUR_VAL(reader, val_out) \
{ \
   RV_ASSERT((reader)->current); \
   memcpy((val_out), (reader)->current->data, (reader)->elemSize); \
}

#define RV_SEQ_GET_ITEM(reader, val_out, type) \
{ \
     val_out = ((type)( (reader)->current->data)); \
}


#define RV_SEQ_UPD_CUR_VAL(reader, val_in) \
{ \
   RV_ASSERT((reader)->current); \
   memcpy((reader)->current->data , (val_in), (reader)->elemSize); \
}

#define RV_SEQ_SEEK_NEXT(reader ) \
{    \
	RV_ASSERT((reader)->current); \
	(reader)->current =(RvCollectItem*) ((reader)->current->next);  \
}
 

#define RV_SEQ_SEEK_PREV(reader) \
{    \
	RV_ASSERT((reader)->current); \
	(reader)->current = (reader)->current->prev;  \
}

//************************ END OF READING SEQUENCE*****************************************


//********************************* RvClust ****************************************************//

 
#define RV_BEGIN_READ_CLUSTER(cluster, reader )  rvdBeginRead_(cluster, reader)

#define RV_READ_FR_CLUSTER(reader, val) \
{    \
	RV_ASSERT((reader)->current);  \
	memcpy((val), ( (char*)((reader)->current->data) )  + (reader)->blockIndex * (reader)->elemSize, (reader)->elemSize);  \
    (reader)->blockIndex++;  \
	(reader)->index ++ ;  \
	RV_ASSERT((reader)->delta > 0); \
    if ( (reader)->blockIndex >= (reader)->delta){ \
	    (reader)->current = (reader)->current->next;  \
		(reader)->blockIndex = 0;  \
	} \
}

#define RV_IS_CLUSTER_END(reader)             (((reader)->index >= (reader)->count) )


#define RV_END_READ_CLUSTER(cluster, reader)   rvdEndRead_(cluster, reader) 
 
 


#define RV_BEGIN_WRITE_CLUSTER(cluster, writer )  rvdBeginWrite_(cluster, writer)


#define RV_WRITE_TO_CLUSTER(writer, val)  \
{ \
    RV_ASSERT((writer)->current) ;\
    memcpy(((char*)((writer)->current->data))  + (writer)->index * (writer)->elemSize,  (val), (writer)->elemSize); \
    (writer)->index++; \
    if ((writer)->index >= (writer)->delta){  \
	       RvCollectItem* pTmp = (RvCollectItem*)MPM_ALLOC(sizeof(RvCollectItem)); \
	       RV_ASSERT(pTmp); \
	       pTmp->prev = pTmp->next = NULL; \
	       pTmp->data =(char*) MPM_ALLOC((writer)->elemSize * (writer)->delta); \
		   RV_ASSERT(pTmp->data); \
  	       (writer)->current->next = pTmp; \
		   pTmp->prev = (writer)->current; \
		   (writer)->current  = pTmp ;  \
	       (writer)->index=0;  \
		   (writer)->blockCount++; \
	}  \
	(writer)->count++; \
} 


#define RV_END_WRITE_CLUSTER(cluster, writer)   rvdEndWrite_(cluster, writer)


//***********************cluster*****************************************************

HANDLE DSM_API RV_BEGIN_READ_TREE(RvTree tree, BOOL  bDepthFirst);
BOOL   DSM_API RV_IS_TREE_END(HANDLE hReader);
void*  DSM_API RV_GET_TREE_DATA(HANDLE hReader);
void   DSM_API RV_END_READ_TREE(HANDLE hReader);





#endif
