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

#include "stdafx.h"
#include "filectrl.h"

//class CFileCtrl
//construct & destruct
CFileCtrl::CFileCtrl(CString strFileName,unsigned long maxBufferLen)
{ 
 if (maxBufferLen > (unsigned long)(63*1024) || maxBufferLen <10240)
  m_MaxBufferLen = 10240;
  else
   m_MaxBufferLen = maxBufferLen;
  
 m_pBuffer = (unsigned char far*)GlobalAllocPtr(GMEM_MOVEABLE,m_MaxBufferLen);
 if(NULL == m_pBuffer)
  {
   AfxMessageBox("Insuffient memory!");
   m_UcStatus = MEMORYERROR;   
   m_MaxBufferLen = 0;
   ASSERT(0);
   return;
   }
   
 if( strFileName == "" )      
  {
   m_UcStatus = FILENAMEERROR; 
   return;
   }   
   
 m_UcStatus = NOTLOADING;
 m_StrFileName = strFileName; 
 
 //get total file length
 if( !Open( m_StrFileName.GetBuffer(m_StrFileName.GetLength()+1), 
      CFile::modeRead ) ) 
  {
   m_UcStatus = FILEERROR;
   return;
   }
 m_FileLength = GetLength();
 Close();
  
 m_ValidBufferLen = m_FilePos =0;
     
 }                  
 
CFileCtrl::~CFileCtrl()
{ 
 if(NULL!=m_pBuffer)
    GlobalFreePtr(m_pBuffer);
 }                           

//operates
unsigned char CFileCtrl::GetStatus()
{ 
 return m_UcStatus;
 }

unsigned long CFileCtrl::GetFileLength()
{ 
 return m_FileLength;
 }
                         
unsigned char CFileCtrl::operator[](unsigned long index)   
{                 
 if (m_UcStatus == NOTLOADING)  ReadBuffer(index); 
  
 if( (m_UcStatus != LOADING) && (m_UcStatus != NOTLOADING) 
     && (m_UcStatus != ENDOFFILE)) 
  { 
   AfxMessageBox("Ivalid status!");
   return 0;
   } 
   
 if ((index>=m_FilePos) && (index<m_FilePos+m_ValidBufferLen)) 
  return m_pBuffer[index-m_FilePos];
  else
   { 
    ReadBuffer(index); 
    if( (m_UcStatus != LOADING) && (m_UcStatus != NOTLOADING) 
       && (m_UcStatus != ENDOFFILE)) 
    { 
     AfxMessageBox("Ivalid status!");
     return 0;
     }                              
    if ((index>=m_FilePos) && (index<m_FilePos+m_ValidBufferLen)) 
     return m_pBuffer[index-m_FilePos]; 
    AfxMessageBox("Range error!");
    return 0; 
    }
 
 AfxMessageBox("Range error!");
 return 0;
 
 }                 
 
unsigned char CFileCtrl::GetBuffer(unsigned char* & pBuffer,unsigned long & length,
                                   unsigned long index,BOOL bMustFix)
{                                                                       
 if (m_UcStatus == NOTLOADING)  ReadBuffer(index); 
  
 if( (m_UcStatus != LOADING) && (m_UcStatus != NOTLOADING) 
     && (m_UcStatus != ENDOFFILE)) 
   return m_UcStatus;
   
 if (length > m_MaxBufferLen) length = m_MaxBufferLen;
   
 if ((index>=m_FilePos) && (index<m_FilePos+m_ValidBufferLen)) 
  { 
   if(bMustFix)
    if(length>m_FilePos+m_ValidBufferLen-index)
     { 
      ReadBuffer(index);      
      if( (m_UcStatus != LOADING) && (m_UcStatus != NOTLOADING) 
       && (m_UcStatus != ENDOFFILE)) 
      return m_UcStatus;
      }
   pBuffer = m_pBuffer+index-m_FilePos;   
   length = m_FilePos+m_ValidBufferLen-index;
   return READINGOK;
   }
 
 return ENDOFFILE;                                          
                                            
 } 
                                        
//private                                        
void CFileCtrl::ReadBuffer(unsigned long index)
{ 
 if( index >= m_FileLength) 
  {       
   m_ValidBufferLen = 0;   
   m_FilePos = 0;
   m_UcStatus = ENDOFFILE;
   return;
   }
 //open file
 if( !Open( m_StrFileName.GetBuffer(m_StrFileName.GetLength()+1), 
      CFile::modeRead ) )
  {  
   m_UcStatus = FILEERROR;
   return;
   }

 //read file     
 if (Seek(index,CFile::begin) != index) 
  {
   Close();
   m_UcStatus = FILEERROR;
   return;
   } 
   
 m_ValidBufferLen=(unsigned long)Read(m_pBuffer,m_MaxBufferLen);
 m_FilePos = index;
 if(m_ValidBufferLen < m_MaxBufferLen)
   m_UcStatus = ENDOFFILE;       
   else m_UcStatus = LOADING;
 //OK
 Close();
 }

void CFileCtrl::OpenFile(CString strFileName,unsigned long maxBufferLen)
{
 if (maxBufferLen > (unsigned long)(63*1024) || maxBufferLen <10240)
  m_MaxBufferLen = 10240;
  else
   m_MaxBufferLen = maxBufferLen;
  
 m_pBuffer = (unsigned char far*)GlobalAllocPtr(GMEM_MOVEABLE,m_MaxBufferLen);
 if(NULL == m_pBuffer)
  {
   AfxMessageBox("Insuffient memory!");
   m_UcStatus = MEMORYERROR;   
   m_MaxBufferLen = 0;
   ASSERT(0);
   return;
   }
   
 if( strFileName == "" )      
  {
   m_UcStatus = FILENAMEERROR; 
   return;
   }   
   
 m_UcStatus = NOTLOADING;
 m_StrFileName = strFileName; 
 
 //get total file length
 if( !Open( m_StrFileName.GetBuffer(m_StrFileName.GetLength()+1), 
      CFile::modeRead ) ) 
  {
   m_UcStatus = FILEERROR;
   return;
   }
 m_FileLength = GetLength();
 Close();
  
 m_ValidBufferLen = m_FilePos =0;
 }
 
//class CTextFileCtrl 
CTextFileCtrl::CTextFileCtrl(CString fileName,unsigned long maxBufferLen )
              : CFileCtrl(fileName,maxBufferLen)
{
 DWORD dwFileLength = GetFileLength();
 unsigned long tmpPoint = 0;      
 unsigned long tmpLen = 0;
 
 while ( tmpPoint < dwFileLength)
  { 
   while ( tmpPoint < dwFileLength 
          && (tmpPoint+tmpLen < dwFileLength) 
	      && ((*((CFileCtrl*)this))[tmpPoint+tmpLen] != '\r')) 
	tmpLen++;  
   unsigned long * point = new unsigned long;
   *point = tmpPoint;
   m_Buffer += point;	
   
   tmpPoint += tmpLen+1; tmpLen = 0;
   if ( (tmpPoint<dwFileLength)
        && ((*((CFileCtrl*)this))[tmpPoint] == '\n') ) tmpPoint++;
   }        
   
 m_lMaxALine  = 240;
 }                                            
 
CTextFileCtrl::~CTextFileCtrl()
{ 
    
 unsigned long length = m_Buffer.GetValidContainLen();
 for(long i=length-1; i>=0; i--)
  { 
   delete m_Buffer[i];
   m_Buffer--;
   }                                
 }                      
                   
void CTextFileCtrl::SetMaxAline(unsigned long lMaxALine)
{ 
 m_lMaxALine = lMaxALine;
 }                   
                   
CString CTextFileCtrl::operator[](unsigned long index)
{                       
 
 ASSERT( index < GetMaxLines() );
 CString tmpStr="";
 unsigned long * point;
 unsigned long tmpPoint;
 unsigned long fileLength = GetFileLength();
 point = (unsigned long *)m_Buffer[index];
 tmpPoint = *point;
 unsigned char uncCount = 0;
 while ( tmpPoint<fileLength && (*((CFileCtrl*)this))[tmpPoint] != '\r' 
         && uncCount < m_lMaxALine) 
  { 
   if(VK_TAB == (*((CFileCtrl*)this))[tmpPoint]) 
    {   
     tmpStr +="    ";
     tmpPoint++; uncCount+=4;
     }
     else
      {
       tmpStr += ((*((CFileCtrl*)this)))[tmpPoint];
       tmpPoint++; uncCount++;
       }
   }
 return tmpStr;
 }