// RichEditCtrlWithLineManagement.cpp : implementation file
//

#include "stdafx.h"
#include "RichEditCtrlWithLineManagement.hpp"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define EDIT_EOLN "\r\n"

/////////////////////////////////////////////////////////////////////////////
// CRichEditCtrlWithLineManagement

//**********************************************************************************
CRichEditCtrlWithLineManagement::CRichEditCtrlWithLineManagement()
	: CRichEditCtrl ()
{
}

//**********************************************************************************
CRichEditCtrlWithLineManagement::~CRichEditCtrlWithLineManagement()
{
}

//**********************************************************************************
CString CRichEditCtrlWithLineManagement::m_fn_csGetLine (long lLineNumber)
{
	static char buf[500];
	
	long lLength = GetLine (lLineNumber, & buf [0], 496);
	// without the eol!
	buf [lLength - strlen (EDIT_EOLN)] = 0;

	return (CString) buf;
}

//**********************************************************************************
void CRichEditCtrlWithLineManagement::m_fn_vDeleteLine (long lLineNumber)
{
	long lLineIndex = LineIndex (lLineNumber);

	if (lLineIndex >= 0)
	{
		long lNextLineIndex = LineIndex (lLineNumber + 1);

		if (lNextLineIndex < 0)
		{
			// last line
			lNextLineIndex = lLineIndex + LineLength (lLineNumber);
		}

		SetSel (lLineIndex, lNextLineIndex);
		ReplaceSel ("");
	}
}

//**********************************************************************************
void CRichEditCtrlWithLineManagement::m_fn_vAddLine (long lLineNumber, CString csLineText)
{
	long lLineIndex = LineIndex (lLineNumber);

	if (lLineIndex >= 0)
	{
		SetSel (lLineIndex, lLineIndex);
		csLineText += EDIT_EOLN;
		ReplaceSel (csLineText);
	}
}

//**********************************************************************************
void CRichEditCtrlWithLineManagement::m_fn_vReplaceLine (long lLineNumber, CString csLineText)
{
	long lLineIndex = LineIndex (lLineNumber);

	if (lLineIndex >= 0)
	{
		long lNextLineIndex = LineIndex (lLineNumber + 1);

		if (lNextLineIndex < 0)
		{
			// last line
			lNextLineIndex = lLineIndex + LineLength (lLineNumber);
		}
		else
		{
			// append as a line
			csLineText += EDIT_EOLN;
		}

		SetSel (lLineIndex, lNextLineIndex);
		ReplaceSel (csLineText);
	}
}

//**********************************************************************************
void CRichEditCtrlWithLineManagement::m_fn_vAppendLine (CString csLineText)
{
	long lLastCharIndex = GetTextLength ();
	SetSel (lLastCharIndex, lLastCharIndex);
	char buf[2];
	GetSelText (& buf [0]);

	csLineText = (CString) buf + EDIT_EOLN + csLineText;
	ReplaceSel (csLineText);
}

//**********************************************************************************
void CRichEditCtrlWithLineManagement::m_fn_vHideLines (CList <long, long> & clHiddenLinesNumbers)
{
	long		lHiddenLineNumber;
	CString		csHiddenLineText;

	// put back the old hidden lines
	POSITION	posNumber = m_clHiddenLinesNumbers . GetHeadPosition ();
	POSITION	posText = m_cslHiddenLines . GetHeadPosition ();
	while (posNumber && posText)
	{
		lHiddenLineNumber = m_clHiddenLinesNumbers . GetNext (posNumber);
		csHiddenLineText = m_cslHiddenLines . GetNext (posText);

		if (lHiddenLineNumber <= GetLineCount ())
			m_fn_vAddLine (lHiddenLineNumber, csHiddenLineText);
		else
			m_fn_vAppendLine (csHiddenLineText);
	}

	// clean up
	m_clHiddenLinesNumbers . RemoveAll ();
	m_cslHiddenLines . RemoveAll ();

	// hide the new ones
	POSITION	pos = clHiddenLinesNumbers . GetHeadPosition ();
	long		lAlreadyHiddenCount = 0;
	long		lLastHiddenLineNumber = -1;
	while (pos)
	{
		lHiddenLineNumber = clHiddenLinesNumbers . GetNext (pos);
		if (lHiddenLineNumber >= 0 && lHiddenLineNumber < GetLineCount () + lAlreadyHiddenCount && lHiddenLineNumber > lLastHiddenLineNumber)
		{
			// assuming ascending order, plus only one appearance, ignore anything breaking the rule
			m_clHiddenLinesNumbers . AddTail (lHiddenLineNumber);
			csHiddenLineText = m_fn_csGetLine (lHiddenLineNumber - lAlreadyHiddenCount);
			m_cslHiddenLines . AddTail (csHiddenLineText);
			m_fn_vDeleteLine (lHiddenLineNumber - lAlreadyHiddenCount);
			// update cycle parameters
			lLastHiddenLineNumber = lHiddenLineNumber;
			lAlreadyHiddenCount ++;
		}
	}
}

//**********************************************************************************
/*
void CRichEditCtrlWithLineManagement::m_fn_vMarkLines (CList <long, long> & clLineNumbers, COLORREF rgbMarkColor)
{
	m_rgbMarkColor = rgbMarkColor;

	POSITION pos = clLineNumbers . GetHeadPosition (); 
}
*/

//**********************************************************************************
void CRichEditCtrlWithLineManagement::m_fn_vSetSelLine (long lLineNumber)
{
	long lHiddenLineNumber;
	long lRealLineNumber = lLineNumber;

	POSITION pos = m_clHiddenLinesNumbers . GetHeadPosition ();
	while (pos)
	{
		lHiddenLineNumber = m_clHiddenLinesNumbers . GetNext (pos);
		if (lHiddenLineNumber < lLineNumber)
			lRealLineNumber --;
		else
			break;
	}

	long lIndex = LineIndex (lRealLineNumber);

	SetSel (lIndex, lIndex);
	// scroll to the sel line
	// scroll to the sel line
//Stefan Dumitrean 8-06-98 (new scroll)
//	CPoint clCurPos = GetCharPos (lIndex);
	//Sets scroll position
//	clCurPos . x=0;
//	((CScrollView *) GetParent ()) -> ScrollToPosition (clCurPos);
//End Stefan Dumitrean 8-06-98

}

//**********************************************************************************
void CRichEditCtrlWithLineManagement::m_fn_vMarkLine (long lLineNumber)
{
	long lHiddenLineNumber;
	long lRealLineNumber = lLineNumber;

	POSITION pos = m_clHiddenLinesNumbers . GetHeadPosition ();
	while (pos)
	{
		lHiddenLineNumber = m_clHiddenLinesNumbers . GetNext (pos);
		if (lHiddenLineNumber < lLineNumber)
			lRealLineNumber --;
		else
			break;
	}

	long lIndexStart = LineIndex (lRealLineNumber);
	long lIndexEnd = LineIndex (lRealLineNumber + 1);

	SetSel (lIndexStart, lIndexEnd);
}

//**********************************************************************************
long CRichEditCtrlWithLineManagement::m_fn_lGetSelLine (void)
{
	long lStartIndex, lEndIndex;
	GetSel (lStartIndex, lEndIndex);

	// get the sel line nb
	long lCurLine = 0;
	long lLineCount = GetLineCount ();
	long lCurIndex = 0;

	while (lCurLine < lLineCount && lCurIndex <= lStartIndex)
	{
		lCurLine ++;
		lCurIndex = LineIndex (lCurLine);
	}

	lCurLine --;
	if (lCurLine < 0)
		lCurLine = 0;

	// update with hidden lines
	long lHiddenLineNumber;

	POSITION pos = m_clHiddenLinesNumbers . GetHeadPosition ();
	while (pos)
	{
		lHiddenLineNumber = m_clHiddenLinesNumbers . GetNext (pos);
		if (lHiddenLineNumber <= lCurLine)
			lCurLine ++;
		else
			break;
	}

	return lCurLine;
}

BEGIN_MESSAGE_MAP(CRichEditCtrlWithLineManagement, CRichEditCtrl)
	//{{AFX_MSG_MAP(CRichEditCtrlWithLineManagement)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CRichEditCtrlWithLineManagement message handlers
