//contain.cpp
//this file is the implementation file of contain.h
//created by john 1996.2-3 

#include "stdafx.h"
#include "contain.h"

//class CContain
//construct & destruct
CContain::CContain(unsigned short usContainLen)
{ 
 m_UsContainLen = usContainLen ;
 ASSERT(usContainLen!=0);
 m_UsValidContainLen = 0 ; 
 m_PointBuffer = new VP[m_UsContainLen];
 if(NULL == m_PointBuffer)
  {
   AfxMessageBox("Insuffient memory!");
   m_UsContainLen = 0;
   ASSERT(0);
   return;
   }
 }                 

CContain::~CContain() 
{               
 if(NULL!=m_PointBuffer)
    delete m_PointBuffer; 
 }
//operates
BOOL CContain::CanBeAdd()
{
 if (m_UsValidContainLen < m_UsContainLen) return TRUE;
  else return FALSE;
 }
                  
void far * CContain::operator[](unsigned short index)
{ 
 if (index >= m_UsValidContainLen)
  { 
   AfxMessageBox("Invalid index!");
   return NULL;
   }           
 return m_PointBuffer[index];
 }
                          
void CContain::operator += (void far * pTr)
{                                    
 if( !CanBeAdd() )
  { 
   AfxMessageBox("Buffer overflow,it can't be added!");
   return;
   }      
 m_PointBuffer[m_UsValidContainLen] = pTr ;
 m_UsValidContainLen ++;
 return;
 }                  
 
void CContain::operator -- ()
{ 
 if ( m_UsValidContainLen == 0) return;
 m_UsValidContainLen--;
 }                           
 
void CContain::DeleteAt(unsigned short index)
{ 
 if (index >= m_UsValidContainLen)
  { 
   AfxMessageBox("Buffer overflow,it can't be deleted!");
   return;
   }                                                  
 
 for (unsigned i = index; i+1 < m_UsValidContainLen; i++ )
  m_PointBuffer[i] = m_PointBuffer[i+1];
 
 m_UsValidContainLen--; 
   
 } 
 
//class CBigContain 
//construct & destruct   
CBigContain::CBigContain()
{
 m_pFirstBuffer = NULL; 
 m_pLastBuffer = m_pFirstBuffer;
 }
 
CBigContain::~CBigContain()
{               
 BUFFER_CHAIN* pTmpBuffer = m_pFirstBuffer;        
 while(NULL!=pTmpBuffer)
  {
   m_pFirstBuffer = pTmpBuffer;
   pTmpBuffer = pTmpBuffer->pNextBuffer;
   delete m_pFirstBuffer;
   }       
 }

//operations: 
unsigned long CBigContain::GetValidContainLen()
{ 
 unsigned long length = 0;
 BUFFER_CHAIN* pTmpBuffer = m_pFirstBuffer; 
 while ( NULL != pTmpBuffer )       
  { 
   length += (pTmpBuffer->buffer).GetValidContainLen();
   pTmpBuffer = pTmpBuffer->pNextBuffer;
   }  
 return length;  
 }                              
 
void *CBigContain::operator[](unsigned long index) 
{    
 unsigned long length = 0;
 unsigned long lengthBak = 0;
 BUFFER_CHAIN* pTmpBuffer = m_pFirstBuffer;
 BUFFER_CHAIN* pTmpBufferBak = pTmpBuffer; 
 BOOL canGet = FALSE;
 
 while ( NULL != pTmpBuffer )       
  {                               
   pTmpBufferBak = pTmpBuffer; 
   length += (pTmpBuffer->buffer).GetValidContainLen();
   if (length > index) 
    { 
     canGet = TRUE;
     break;
     }          
   pTmpBuffer = pTmpBuffer->pNextBuffer;
   lengthBak = length;
   }
 
 if ( canGet )
  return (pTmpBufferBak->buffer)[(unsigned short)(index-lengthBak)];
 return NULL; 
 
 }
 
void CBigContain::operator += (void *pTr)
{ 
 if ( m_pLastBuffer == NULL ) 
  { 
   m_pFirstBuffer = new BUFFER_CHAIN;
   ASSERT(m_pFirstBuffer!=NULL);
   m_pFirstBuffer->pNextBuffer = NULL;
   m_pLastBuffer = m_pFirstBuffer;
   }                              
 
 if((m_pLastBuffer->buffer).CanBeAdd())
  { 
   (m_pLastBuffer->buffer) += pTr;
   }                              
   else
    { 
     m_pLastBuffer->pNextBuffer = new BUFFER_CHAIN;  
     ASSERT(m_pLastBuffer!=NULL);
     m_pLastBuffer = m_pLastBuffer->pNextBuffer;
     m_pLastBuffer->pNextBuffer = NULL;
     ASSERT((m_pLastBuffer->buffer).CanBeAdd());
     (m_pLastBuffer->buffer) += pTr;
     }
   
 }
 
void CBigContain::operator -- ()
{        
 if(m_pLastBuffer == NULL) return;
 (m_pLastBuffer->buffer)--;
 if ((m_pLastBuffer->buffer).GetValidContainLen() != 0) return;
 
 BUFFER_CHAIN* pTmpBuffer = m_pFirstBuffer;
 BUFFER_CHAIN* pTmpBufferBak = pTmpBuffer;  
                             
 if(m_pFirstBuffer == m_pLastBuffer) {
     delete m_pLastBuffer;
     m_pFirstBuffer = m_pLastBuffer = NULL;
     return;
 }
                                 
 while(pTmpBuffer != m_pLastBuffer)  
  { 
   pTmpBufferBak = pTmpBuffer;
   pTmpBuffer = pTmpBuffer->pNextBuffer;
   }        
   
 delete m_pLastBuffer;
 m_pLastBuffer = pTmpBufferBak;
   
 } 
 
void CBigContain::DeleteAt(unsigned long index)
{ 
 unsigned long length = 0;
 unsigned long lengthBak = 0;
 BUFFER_CHAIN* pTmpBuffer = m_pFirstBuffer;
 BUFFER_CHAIN* pTmpBufferBak = pTmpBuffer; 
 
 BOOL canGet = FALSE;
 
 while ( NULL != pTmpBuffer )       
  { 
   length += (pTmpBuffer->buffer).GetValidContainLen();
   if (length > index) 
    { 
     canGet = TRUE;
     break;
     }          
   pTmpBufferBak = pTmpBuffer;   
   pTmpBuffer = pTmpBuffer->pNextBuffer;
   lengthBak = length;
   }
 
 if(!canGet) return;
 if(pTmpBufferBak == NULL) return;
 (pTmpBufferBak->buffer)--;
 
 }
 