// Windows Template Library - WTL version 8.0
// Copyright (C) Microsoft Corporation. All rights reserved.
//
// This file is a part of the Windows Template Library.
// The use and distribution terms for this software are covered by the
// Microsoft Permissive License (Ms-PL) which can be found in the file
// Ms-PL.txt at the root of this distribution.

#ifndef __ATLFIND_H__
#define __ATLFIND_H__

#pragma once

#ifndef __cplusplus
	#error ATL requires C++ compilation (use a .cpp suffix)
#endif

#ifdef _WIN32_WCE
	#error atlfind.h is not supported on Windows CE
#endif

#ifndef __ATLCTRLS_H__
	#error atlfind.h requires atlctrls.h to be included first
#endif

#ifndef __ATLDLGS_H__
	#error atlfind.h requires atldlgs.h to be included first
#endif

#if !((defined(__ATLMISC_H__) && defined(_WTL_USE_CSTRING)) || defined(__ATLSTR_H__))
	#error atlfind.h requires CString (either from ATL's atlstr.h or WTL's atlmisc.h with _WTL_USE_CSTRING)
#endif


///////////////////////////////////////////////////////////////////////////////
// Classes in this file:
//
// CEditFindReplaceImplBase<T, TFindReplaceDialog>
// CEditFindReplaceImpl<T, TFindReplaceDialog>
// CRichEditFindReplaceImpl<T, TFindReplaceDialog>


namespace WTL
{

///////////////////////////////////////////////////////////////////////////////
// CEditFindReplaceImplBase - Base class for mixin classes that
// help implement Find/Replace for CEdit or CRichEditCtrl based window classes.

template <class T, class TFindReplaceDialog = CFindReplaceDialog>
class CEditFindReplaceImplBase
{
protected:
// Typedefs
	typedef CEditFindReplaceImplBase<T, TFindReplaceDialog> thisClass;

// Data members
	TFindReplaceDialog* m_pFindReplaceDialog;
	_CSTRING_NS::CString m_sFindNext, m_sReplaceWith;
	BOOL m_bFindOnly, m_bFirstSearch, m_bMatchCase, m_bWholeWord, m_bFindDown;
	LONG m_nInitialSearchPos;
	HCURSOR m_hOldCursor;

// Enumerations
	enum TranslationTextItem
	{
		eText_OnReplaceAllMessage   = 0,
		eText_OnReplaceAllTitle     = 1,
		eText_OnTextNotFoundMessage = 2,
		eText_OnTextNotFoundTitle   = 3
	};

public:
// Constructors
	CEditFindReplaceImplBase() :
		m_pFindReplaceDialog(NULL),
		m_bFindOnly(TRUE),
		m_bFirstSearch(TRUE),
		m_bMatchCase(FALSE),
		m_bWholeWord(FALSE),
		m_bFindDown(TRUE),
		m_nInitialSearchPos(0),
		m_hOldCursor(NULL)
	{
	}

// Message Handlers
	BEGIN_MSG_MAP(thisClass)
	ALT_MSG_MAP(1)
		MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
		MESSAGE_HANDLER(TFindReplaceDialog::GetFindReplaceMsg(), OnFindReplaceCmd)
		COMMAND_ID_HANDLER(ID_EDIT_FIND, OnEditFind)
		COMMAND_ID_HANDLER(ID_EDIT_REPEAT, OnEditRepeat)
		COMMAND_ID_HANDLER(ID_EDIT_REPLACE, OnEditReplace)
	END_MSG_MAP()

	LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		if(m_pFindReplaceDialog != NULL)
		{
			m_pFindReplaceDialog->SendMessage(WM_CLOSE);
			ATLASSERT(m_pFindReplaceDialog == NULL);
		}

		bHandled = FALSE;
		return 0;
	}

	LRESULT OnFindReplaceCmd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
	{
		T* pT = static_cast<T*>(this);

		TFindReplaceDialog* pDialog = TFindReplaceDialog::GetNotifier(lParam);
		if(pDialog == NULL)
		{
			ATLASSERT(FALSE);
			::MessageBeep(MB_ICONERROR);
			return 1;
		}
		ATLASSERT(pDialog == m_pFindReplaceDialog);

		LPFINDREPLACE findReplace = (LPFINDREPLACE)lParam;
		if((m_pFindReplaceDialog != NULL) && (findReplace != NULL))
		{
			if(pDialog->FindNext())
			{
				pT->OnFindNext(pDialog->GetFindString(), pDialog->SearchDown(),
					pDialog->MatchCase(), pDialog->MatchWholeWord());
			}
			else if(pDialog->ReplaceCurrent())
			{
				pT->OnReplaceSel(pDialog->GetFindString(),
					pDialog->SearchDown(), pDialog->MatchCase(), pDialog->MatchWholeWord(),
					pDialog->GetReplaceString());
			}
			else if(pDialog->ReplaceAll())
			{
				pT->OnReplaceAll(pDialog->GetFindString(), pDialog->GetReplaceString(),
					pDialog->MatchCase(), pDialog->MatchWholeWord());
			}
			else if(pDialog->IsTerminating())
			{
				// Dialog is going away (but hasn't gone away yet)
				// OnFinalMessage will "delete this"
				pT->OnTerminatingFindReplaceDialog(m_pFindReplaceDialog);
				m_pFindReplaceDialog = NULL;
			}
		}

		return 0;
	}

	LRESULT OnEditFind(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		T* pT = static_cast<T*>(this);
		pT->FindReplace(TRUE);

		return 0;
	}

	LRESULT OnEditRepeat(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		T* pT = static_cast<T*>(this);

		// If the user is holding down SHIFT when hitting F3, we'll
		// search in reverse. Otherwise, we'll search forward.
		// (be sure to have an accelerator mapped to ID_EDIT_REPEAT
		// for both F3 and Shift+F3)
		m_bFindDown = !((::GetKeyState(VK_SHIFT) & 0x8000) == 0x8000);

		if(m_sFindNext.IsEmpty())
		{
			pT->FindReplace(TRUE);
		}
		else
		{
			if(!pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown))
				pT->TextNotFound(m_sFindNext);
		}

		return 0;
	}

	LRESULT OnEditReplace(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& bHandled)
	{
		T* pT = static_cast<T*>(this);

		DWORD style = pT->GetStyle();
		if((style & ES_READONLY) != ES_READONLY)
		{
			pT->FindReplace(FALSE);
		}
		else
		{
			// Don't allow replace when the edit control is read only
			bHandled = FALSE;
		}

		return 0;
	}

// Operations (overrideable)
	TFindReplaceDialog* CreateFindReplaceDialog(BOOL bFindOnly, // TRUE for Find, FALSE for FindReplace
			LPCTSTR lpszFindWhat,
			LPCTSTR lpszReplaceWith = NULL,
			DWORD dwFlags = FR_DOWN,
			HWND hWndParent = NULL)
	{
		// You can override all of this in a derived class

		TFindReplaceDialog* findReplaceDialog = new TFindReplaceDialog();
		if(findReplaceDialog == NULL)
		{
			::MessageBeep(MB_ICONHAND);
		}
		else
		{
			HWND hWndFindReplace = findReplaceDialog->Create(bFindOnly,
				lpszFindWhat, lpszReplaceWith, dwFlags, hWndParent);
			if(hWndFindReplace == NULL)
			{
				delete findReplaceDialog;
				findReplaceDialog = NULL;
			}
			else
			{
				findReplaceDialog->SetActiveWindow();
				findReplaceDialog->ShowWindow(SW_SHOW);
			}
		}

		return findReplaceDialog;
	}

	void AdjustDialogPosition(HWND hWndDialog)
	{
		ATLASSERT((hWndDialog != NULL) && ::IsWindow(hWndDialog));

		T* pT = static_cast<T*>(this);
		LONG nStartChar = 0, nEndChar = 0;
		// Send EM_GETSEL so we can use both Edit and RichEdit
		// (CEdit::GetSel uses int&, and CRichEditCtrlT::GetSel uses LONG&)
		::SendMessage(pT->m_hWnd, EM_GETSEL, (WPARAM)&nStartChar, (LPARAM)&nEndChar);
		POINT point = pT->PosFromChar(nStartChar);
		::ClientToScreen(pT->GetParent(), &point);
		CRect rect;
		::GetWindowRect(hWndDialog, &rect);
		if(rect.PtInRect(point))
		{
			if(point.y > rect.Height())
			{
				rect.OffsetRect(0, point.y - rect.bottom - 20);
			}
			else
			{
				int nVertExt = GetSystemMetrics(SM_CYSCREEN);
				if(point.y + rect.Height() < nVertExt)
					rect.OffsetRect(0, 40 + point.y - rect.top);
			}

			::MoveWindow(hWndDialog, rect.left, rect.top, rect.Width(), rect.Height(), TRUE);
		}
	}

	DWORD GetFindReplaceDialogFlags(void) const
	{
		DWORD dwFlags = 0;

		if(m_bFindDown)
			dwFlags |= FR_DOWN;
		if(m_bMatchCase)
			dwFlags |= FR_MATCHCASE;
		if(m_bWholeWord)
			dwFlags |= FR_WHOLEWORD;

		return dwFlags;
	}

	void FindReplace(BOOL bFindOnly)
	{
		T* pT = static_cast<T*>(this);
		m_bFirstSearch = TRUE;
		if(m_pFindReplaceDialog != NULL)
		{
			if(m_bFindOnly == bFindOnly)
			{
				m_pFindReplaceDialog->SetActiveWindow();
				m_pFindReplaceDialog->ShowWindow(SW_SHOW);
				return;
			}
			else
			{
				m_pFindReplaceDialog->SendMessage(WM_CLOSE);
				ATLASSERT(m_pFindReplaceDialog == NULL);
			}
		}

		ATLASSERT(m_pFindReplaceDialog == NULL);

		_CSTRING_NS::CString findNext;
		pT->GetSelText(findNext);
		// if selection is empty or spans multiple lines use old find text
		if(findNext.IsEmpty() || (findNext.FindOneOf(_T("\n\r")) != -1))
			findNext = m_sFindNext;
		_CSTRING_NS::CString replaceWith = m_sReplaceWith;
		DWORD dwFlags = pT->GetFindReplaceDialogFlags();

		m_pFindReplaceDialog = pT->CreateFindReplaceDialog(bFindOnly,
			findNext, replaceWith, dwFlags, pT->operator HWND());
		ATLASSERT(m_pFindReplaceDialog != NULL);
		if(m_pFindReplaceDialog != NULL)
			m_bFindOnly = bFindOnly;
	}

	BOOL SameAsSelected(LPCTSTR lpszCompare, BOOL bMatchCase, BOOL /*bWholeWord*/)
	{
		T* pT = static_cast<T*>(this);

		// check length first
		size_t nLen = lstrlen(lpszCompare);
		LONG nStartChar = 0, nEndChar = 0;
		// Send EM_GETSEL so we can use both Edit and RichEdit
		// (CEdit::GetSel uses int&, and CRichEditCtrlT::GetSel uses LONG&)
		::SendMessage(pT->m_hWnd, EM_GETSEL, (WPARAM)&nStartChar, (LPARAM)&nEndChar);
		if(nLen != (size_t)(nEndChar - nStartChar))
			return FALSE;

		// length is the same, check contents
		_CSTRING_NS::CString selectedText;
		pT->GetSelText(selectedText);

		return (bMatchCase && selectedText.Compare(lpszCompare) == 0) ||
			(!bMatchCase && selectedText.CompareNoCase(lpszCompare) == 0);
	}

	void TextNotFound(LPCTSTR lpszFind)
	{
		T* pT = static_cast<T*>(this);
		m_bFirstSearch = TRUE;
		pT->OnTextNotFound(lpszFind);
	}

	_CSTRING_NS::CString GetTranslationText(enum TranslationTextItem eItem) const
	{
		_CSTRING_NS::CString text;
		switch(eItem)
		{
		case eText_OnReplaceAllMessage:
			text = _T("Replaced %d occurances of \"%s\" with \"%s\"");
			break;
		case eText_OnReplaceAllTitle:
			text = _T("Replace All");
			break;
		case eText_OnTextNotFoundMessage:
			text = _T("Unable to find the text \"%s\"");
			break;
		case eText_OnTextNotFoundTitle:
			text = _T("Text not found");
			break;
		}

		return text;
	}

// Overrideable Handlers
	void OnFindNext(LPCTSTR lpszFind, BOOL bFindDown, BOOL bMatchCase, BOOL bWholeWord)
	{
		T* pT = static_cast<T*>(this);

		m_sFindNext = lpszFind;
		m_bMatchCase = bMatchCase;
		m_bWholeWord = bWholeWord;
		m_bFindDown = bFindDown;

		if(!pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown))
			pT->TextNotFound(m_sFindNext);
		else
			pT->AdjustDialogPosition(m_pFindReplaceDialog->operator HWND());
	}

	void OnReplaceSel(LPCTSTR lpszFind, BOOL bFindDown, BOOL bMatchCase, BOOL bWholeWord, LPCTSTR lpszReplace)
	{
		T* pT = static_cast<T*>(this);

		m_sFindNext = lpszFind;
		m_sReplaceWith = lpszReplace;
		m_bMatchCase = bMatchCase;
		m_bWholeWord = bWholeWord;
		m_bFindDown = bFindDown;

		if(pT->SameAsSelected(m_sFindNext, m_bMatchCase, m_bWholeWord))
			pT->ReplaceSel(m_sReplaceWith);

		if(!pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown))
			pT->TextNotFound(m_sFindNext);
		else
			pT->AdjustDialogPosition(m_pFindReplaceDialog->operator HWND());
	}

	void OnReplaceAll(LPCTSTR lpszFind, LPCTSTR lpszReplace, BOOL bMatchCase, BOOL bWholeWord)
	{
		T* pT = static_cast<T*>(this);

		m_sFindNext = lpszFind;
		m_sReplaceWith = lpszReplace;
		m_bMatchCase = bMatchCase;
		m_bWholeWord = bWholeWord;
		m_bFindDown = TRUE;

		// no selection or different than what looking for
		if(!pT->SameAsSelected(m_sFindNext, m_bMatchCase, m_bWholeWord))
		{
			if(!pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown))
			{
				pT->TextNotFound(m_sFindNext);
				return;
			}
		}

		pT->OnReplaceAllCoreBegin();

		int replaceCount=0;
		do
		{
			++replaceCount;
			pT->ReplaceSel(m_sReplaceWith);
		} while(pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown));

		pT->OnReplaceAllCoreEnd(replaceCount);
	}

	void OnReplaceAllCoreBegin()
	{
		T* pT = static_cast<T*>(this);

		m_hOldCursor = ::SetCursor(::LoadCursor(NULL, IDC_WAIT));

		pT->HideSelection(TRUE, FALSE);

	}

	void OnReplaceAllCoreEnd(int replaceCount)
	{
		T* pT = static_cast<T*>(this);
		pT->HideSelection(FALSE, FALSE);

		::SetCursor(m_hOldCursor);

		_CSTRING_NS::CString message = pT->GetTranslationText(eText_OnReplaceAllMessage);
		if(message.GetLength() > 0)
		{
			_CSTRING_NS::CString formattedMessage;
			formattedMessage.Format(message,
				replaceCount, m_sFindNext, m_sReplaceWith);
			if(m_pFindReplaceDialog != NULL)
			{
				m_pFindReplaceDialog->MessageBox(formattedMessage,
					pT->GetTranslationText(eText_OnReplaceAllTitle),
					MB_OK | MB_ICONINFORMATION | MB_APPLMODAL);
			}
			else
			{
				pT->MessageBox(formattedMessage,
					pT->GetTranslationText(eText_OnReplaceAllTitle),
					MB_OK | MB_ICONINFORMATION | MB_APPLMODAL);
			}
		}
	}

	void OnTextNotFound(LPCTSTR lpszFind)
	{
		T* pT = static_cast<T*>(this);
		_CSTRING_NS::CString message = pT->GetTranslationText(eText_OnTextNotFoundMessage);
		if(message.GetLength() > 0)
		{
			_CSTRING_NS::CString formattedMessage;
			formattedMessage.Format(message, lpszFind);
			if(m_pFindReplaceDialog != NULL)
			{
				m_pFindReplaceDialog->MessageBox(formattedMessage,
					pT->GetTranslationText(eText_OnTextNotFoundTitle),
					MB_OK | MB_ICONINFORMATION | MB_APPLMODAL);
			}
			else
			{
				pT->MessageBox(formattedMessage,
					pT->GetTranslationText(eText_OnTextNotFoundTitle),
					MB_OK | MB_ICONINFORMATION | MB_APPLMODAL);
			}
		}
		else
		{
			::MessageBeep(MB_ICONHAND);
		}
	}

	void OnTerminatingFindReplaceDialog(TFindReplaceDialog*& /*findReplaceDialog*/)
	{
	}
};


///////////////////////////////////////////////////////////////////////////////
// CEditFindReplaceImpl - Mixin class for implementing Find/Replace for CEdit
// based window classes.

// Chain to CEditFindReplaceImpl message map. Your class must also derive from CEdit.
// Example:
// class CMyEdit : public CWindowImpl<CMyEdit, CEdit>,
//                 public CEditFindReplaceImpl<CMyEdit>
// {
// public:
//      BEGIN_MSG_MAP(CMyEdit)
//              // your handlers...
//              CHAIN_MSG_MAP_ALT(CEditFindReplaceImpl<CMyEdit>, 1)
//      END_MSG_MAP()
//      // other stuff...
// };

template <class T, class TFindReplaceDialog = CFindReplaceDialog>
class CEditFindReplaceImpl : public CEditFindReplaceImplBase<T, TFindReplaceDialog>
{
protected:
	typedef CEditFindReplaceImpl<T, TFindReplaceDialog> thisClass;
	typedef CEditFindReplaceImplBase<T, TFindReplaceDialog> baseClass;

// Data members
	LPTSTR m_pShadowBuffer;     // Special shadow buffer only used in some cases.
	UINT m_nShadowSize;
	int m_bShadowBufferNeeded;  // TRUE, FALSE, < 0 => Need to check

public:
// Constructors
	CEditFindReplaceImpl() :
		m_pShadowBuffer(NULL),
		m_nShadowSize(0),
		m_bShadowBufferNeeded(-1)
	{
	}

	virtual ~CEditFindReplaceImpl()
	{
		if(m_pShadowBuffer != NULL)
		{
			delete [] m_pShadowBuffer;
			m_pShadowBuffer = NULL;
		}
	}

// Message Handlers
	BEGIN_MSG_MAP(thisClass)
	ALT_MSG_MAP(1)
		CHAIN_MSG_MAP_ALT(baseClass, 1)
	END_MSG_MAP()

// Operations
	// Supported only for RichEdit, so this does nothing for Edit
	void HideSelection(BOOL /*bHide*/ = TRUE, BOOL /*bChangeStyle*/ = FALSE)
	{
	}

// Operations (overrideable)
	BOOL FindTextSimple(LPCTSTR lpszFind, BOOL bMatchCase, BOOL bWholeWord, BOOL bFindDown = TRUE)
	{
		T* pT = static_cast<T*>(this);

		ATLASSERT(lpszFind != NULL);
		ATLASSERT(*lpszFind != _T('\0'));

		UINT nLen = pT->GetBufferLength();
		int nStartChar = 0, nEndChar = 0;
		pT->GetSel(nStartChar, nEndChar);
		UINT nStart = nStartChar;
		int iDir = bFindDown ? +1 : -1;

		// can't find a match before the first character
		if(nStart == 0 && iDir < 0)
			return FALSE;

		LPCTSTR lpszText = pT->LockBuffer();

		bool isDBCS = false;
#ifdef _MBCS
		CPINFO info = { 0 };
		::GetCPInfo(::GetOEMCP(), &info);
		isDBCS = (info.MaxCharSize > 1);
#endif

		if(iDir < 0)
		{
			// always go back one for search backwards
			nStart -= int((lpszText + nStart) - ::CharPrev(lpszText, lpszText + nStart));
		}
		else if(nStartChar != nEndChar && pT->SameAsSelected(lpszFind, bMatchCase, bWholeWord))
		{
			// easy to go backward/forward with SBCS
#ifndef _UNICODE
			if(::IsDBCSLeadByte(lpszText[nStart]))
				nStart++;
#endif
			nStart += iDir;
		}

		// handle search with nStart past end of buffer
		UINT nLenFind = ::lstrlen(lpszFind);
		if(nStart + nLenFind - 1 >= nLen)
		{
			if(iDir < 0 && nLen >= nLenFind)
			{
				if(isDBCS)
				{
					// walk back to previous character n times
					nStart = nLen;
					int n = nLenFind;
					while(n--)
					{
						nStart -= int((lpszText + nStart) - ::CharPrev(lpszText, lpszText + nStart));
					}
				}
				else
				{
					// single-byte character set is easy and fast
					nStart = nLen - nLenFind;
				}
				ATLASSERT(nStart + nLenFind - 1 <= nLen);
			}
			else
			{
				pT->UnlockBuffer();
				return FALSE;
			}
		}

		// start the search at nStart
		LPCTSTR lpsz = lpszText + nStart;
		typedef int (WINAPI* CompareProc)(LPCTSTR str1, LPCTSTR str2);
		CompareProc pfnCompare = bMatchCase ? lstrcmp : lstrcmpi;

		if(isDBCS)
		{
			// double-byte string search
			LPCTSTR lpszStop = NULL;
			if(iDir > 0)
			{
				// start at current and find _first_ occurrance
				lpszStop = lpszText + nLen - nLenFind + 1;
			}
			else
			{
				// start at top and find _last_ occurrance
				lpszStop = lpsz;
				lpsz = lpszText;
			}

			LPCTSTR lpszFound = NULL;
			while(lpsz <= lpszStop)
			{
#ifndef _UNICODE
				if(!bMatchCase || (*lpsz == *lpszFind && (!::IsDBCSLeadByte(*lpsz) || lpsz[1] == lpszFind[1])))
#else
				if(!bMatchCase || (*lpsz == *lpszFind && lpsz[1] == lpszFind[1]))
#endif
				{
					LPTSTR lpch = (LPTSTR)(lpsz + nLenFind);
					TCHAR chSave = *lpch;
					*lpch = _T('\0');
					int nResult = (*pfnCompare)(lpsz, lpszFind);
					*lpch = chSave;
					if(nResult == 0)
					{
						lpszFound = lpsz;
						if(iDir > 0)
							break;
					}
				}
				lpsz = ::CharNext(lpsz);
			}
			pT->UnlockBuffer();

			if(lpszFound != NULL)
			{
				int n = (int)(lpszFound - lpszText);
				pT->SetSel(n, n + nLenFind);
				return TRUE;
			}
		}
		else
		{
			// single-byte string search
			UINT nCompare;
			if(iDir < 0)
				nCompare = (UINT)(lpsz - lpszText) + 1;
			else
				nCompare = nLen - (UINT)(lpsz - lpszText) - nLenFind + 1;

			while(nCompare > 0)
			{
				ATLASSERT(lpsz >= lpszText);
				ATLASSERT(lpsz + nLenFind - 1 <= lpszText + nLen - 1);

				LPSTR lpch = (LPSTR)(lpsz + nLenFind);
				char chSave = *lpch;
				*lpch = '\0';
				int nResult = (*pfnCompare)(lpsz, lpszFind);
				*lpch = chSave;
				if(nResult == 0)
				{
					pT->UnlockBuffer();
					int n = (int)(lpsz - lpszText);
					pT->SetSel(n, n + nLenFind);
					return TRUE;
				}

				// restore character at end of search
				*lpch = chSave;

				// move on to next substring
				nCompare--;
				lpsz += iDir;
			}
			pT->UnlockBuffer();
		}

		return FALSE;
	}

	LPCTSTR LockBuffer() const
	{
		const T* pT = static_cast<const T*>(this);

		ATLASSERT(pT->m_hWnd != NULL);

		BOOL useShadowBuffer = pT->UseShadowBuffer();
		if(useShadowBuffer)
		{
			if(m_pShadowBuffer == NULL || pT->GetModify())
			{
				ATLASSERT(m_pShadowBuffer != NULL || m_nShadowSize == 0);
				UINT nSize = pT->GetWindowTextLength() + 1;
				if(nSize > m_nShadowSize)
				{
					// need more room for shadow buffer
					T* pThisNoConst = const_cast<T*>(pT);
					delete[] m_pShadowBuffer;
					pThisNoConst->m_pShadowBuffer = NULL;
					pThisNoConst->m_nShadowSize = 0;
					pThisNoConst->m_pShadowBuffer = new TCHAR[nSize];
					pThisNoConst->m_nShadowSize = nSize;
				}

				// update the shadow buffer with GetWindowText
				ATLASSERT(m_nShadowSize >= nSize);
				ATLASSERT(m_pShadowBuffer != NULL);
				pT->GetWindowText(m_pShadowBuffer, nSize);
			}

			return m_pShadowBuffer;
		}

		HLOCAL hLocal = pT->GetHandle();
		ATLASSERT(hLocal != NULL);
		LPCTSTR lpszText = (LPCTSTR)::LocalLock(hLocal);
		ATLASSERT(lpszText != NULL);

		return lpszText;
	}

	void UnlockBuffer() const
	{
		const T* pT = static_cast<const T*>(this);

		ATLASSERT(pT->m_hWnd != NULL);

		BOOL useShadowBuffer = pT->UseShadowBuffer();
		if(!useShadowBuffer)
		{
			HLOCAL hLocal = pT->GetHandle();
			ATLASSERT(hLocal != NULL);
			::LocalUnlock(hLocal);
		}
	}

	UINT GetBufferLength() const
	{
		const T* pT = static_cast<const T*>(this);

		ATLASSERT(pT->m_hWnd != NULL);
		UINT nLen = 0;
		LPCTSTR lpszText = pT->LockBuffer();
		if(lpszText != NULL)
			nLen = ::lstrlen(lpszText);
		pT->UnlockBuffer();

		return nLen;
	}

	LONG EndOfLine(LPCTSTR lpszText, UINT nLen, UINT nIndex) const
	{
		LPCTSTR lpsz = lpszText + nIndex;
		LPCTSTR lpszStop = lpszText + nLen;
		while(lpsz < lpszStop && *lpsz != _T('\r'))
			++lpsz;
		return LONG(lpsz - lpszText);
	}

	LONG GetSelText(_CSTRING_NS::CString& strText) const
	{
		const T* pT = static_cast<const T*>(this);

		int nStartChar = 0, nEndChar = 0;
		pT->GetSel(nStartChar, nEndChar);
		ATLASSERT((UINT)nEndChar <= pT->GetBufferLength());
		LPCTSTR lpszText = pT->LockBuffer();
		LONG nLen = pT->EndOfLine(lpszText, nEndChar, nStartChar) - nStartChar;
		SecureHelper::memcpy_x(strText.GetBuffer(nLen), nLen * sizeof(TCHAR), lpszText + nStartChar, nLen * sizeof(TCHAR));
		strText.ReleaseBuffer(nLen);
		pT->UnlockBuffer();

		return nLen;
	}

	BOOL UseShadowBuffer(void) const
	{
		const T* pT = static_cast<const T*>(this);

		if(pT->m_bShadowBufferNeeded < 0)
		{
			T* pThisNoConst = const_cast<T*>(pT);

			OSVERSIONINFO ovi = { 0 };
			ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
			::GetVersionEx(&ovi);

			bool bWin9x = (ovi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
			if(bWin9x)
			{
				// Windows 95, 98, ME
				// Under Win9x, it is necessary to maintain a shadow buffer.
				// It is only updated when the control contents have been changed.
				pThisNoConst->m_bShadowBufferNeeded = TRUE;
			}
			else
			{
				// Windows NT, 2000, XP, etc.
				pThisNoConst->m_bShadowBufferNeeded = FALSE;

#ifndef _UNICODE
				// On Windows XP (or later), if common controls version 6 is in use
				// (such as via theming), then EM_GETHANDLE will always return a UNICODE string.
				// If theming is enabled and Common Controls version 6 is in use,
				// you're really not suppose to superclass or subclass common controls
				// with an ANSI windows procedure (so its best to only theme if you use UNICODE).
				// Using a shadow buffer uses GetWindowText instead, so it solves
				// this problem for us (although it makes it a little less efficient).

				if((ovi.dwMajorVersion == 5 && ovi.dwMinorVersion >= 1) || (ovi.dwMajorVersion > 5))
				{
					// We use DLLVERSIONINFO_private so we don't have to depend on shlwapi.h
					typedef struct _DLLVERSIONINFO_private
					{
						DWORD cbSize;
						DWORD dwMajorVersion;
						DWORD dwMinorVersion;
						DWORD dwBuildNumber;
						DWORD dwPlatformID;
					} DLLVERSIONINFO_private;

					HMODULE hModule = ::LoadLibrary("comctl32.dll");
					if(hModule != NULL)
					{
						typedef HRESULT (CALLBACK *LPFN_DllGetVersion)(DLLVERSIONINFO_private *);
						LPFN_DllGetVersion fnDllGetVersion = (LPFN_DllGetVersion)::GetProcAddress(hModule, "DllGetVersion");
						if(fnDllGetVersion != NULL)
						{
							DLLVERSIONINFO_private version = { 0 };
							version.cbSize = sizeof(DLLVERSIONINFO_private);
							if(SUCCEEDED(fnDllGetVersion(&version)))
							{
								if(version.dwMajorVersion >= 6)
								{
									pThisNoConst->m_bShadowBufferNeeded = TRUE;

									ATLTRACE2(atlTraceUI, 0, _T("Warning: You have compiled for MBCS/ANSI but are using common controls version 6 or later (likely through a manifest file).\r\n"));
									ATLTRACE2(atlTraceUI, 0, _T("If you use common controls version 6 or later, you should only do so for UNICODE builds.\r\n"));
								}
							}
						}

						::FreeLibrary(hModule);
						hModule = NULL;
					}
				}
#endif // !_UNICODE
			}
		}

		return (pT->m_bShadowBufferNeeded == TRUE);
	}
};


///////////////////////////////////////////////////////////////////////////////
// CRichEditFindReplaceImpl - Mixin class for implementing Find/Replace for CRichEditCtrl
// based window classes.

// Chain to CRichEditFindReplaceImpl message map. Your class must also derive from CRichEditCtrl.
// Example:
// class CMyRichEdit : public CWindowImpl<CMyRichEdit, CRichEditCtrl>,
//                     public CRichEditFindReplaceImpl<CMyRichEdit>
// {
// public:
//      BEGIN_MSG_MAP(CMyRichEdit)
//              // your handlers...
//              CHAIN_MSG_MAP_ALT(CRichEditFindReplaceImpl<CMyRichEdit>, 1)
//      END_MSG_MAP()
//      // other stuff...
// };

template <class T, class TFindReplaceDialog = CFindReplaceDialog>
class CRichEditFindReplaceImpl : public CEditFindReplaceImplBase<T, TFindReplaceDialog>
{
protected:
	typedef CRichEditFindReplaceImpl<T, TFindReplaceDialog> thisClass;
	typedef CEditFindReplaceImplBase<T, TFindReplaceDialog> baseClass;

public:
	BEGIN_MSG_MAP(thisClass)
	ALT_MSG_MAP(1)
		CHAIN_MSG_MAP_ALT(baseClass, 1)
	END_MSG_MAP()

// Operations (overrideable)
	BOOL FindTextSimple(LPCTSTR lpszFind, BOOL bMatchCase, BOOL bWholeWord, BOOL bFindDown = TRUE)
	{
		T* pT = static_cast<T*>(this);

		ATLASSERT(lpszFind != NULL);
		FINDTEXTEX ft = { 0 };

		pT->GetSel(ft.chrg);
		if(m_bFirstSearch)
		{
			if(bFindDown)
				m_nInitialSearchPos = ft.chrg.cpMin;
			else
				m_nInitialSearchPos = ft.chrg.cpMax;
			m_bFirstSearch = FALSE;
		}

#if (_RICHEDIT_VER >= 0x0200)
		ft.lpstrText = (LPTSTR)lpszFind;
#else // !(_RICHEDIT_VER >= 0x0200)
		USES_CONVERSION;
		ft.lpstrText = T2A((LPTSTR)lpszFind);
#endif // !(_RICHEDIT_VER >= 0x0200)

		if(ft.chrg.cpMin != ft.chrg.cpMax) // i.e. there is a selection
		{
			if(bFindDown)
			{
				ft.chrg.cpMin++;
			}
			else
			{
				// won't wraparound backwards
				ft.chrg.cpMin = __max(ft.chrg.cpMin, 0);
			}
		}

		DWORD dwFlags = bMatchCase ? FR_MATCHCASE : 0;
		dwFlags |= bWholeWord ? FR_WHOLEWORD : 0;

		ft.chrg.cpMax = pT->GetTextLength() + m_nInitialSearchPos;

		if(bFindDown)
		{
			if(m_nInitialSearchPos >= 0)
				ft.chrg.cpMax = pT->GetTextLength();

			dwFlags |= FR_DOWN;
			ATLASSERT(ft.chrg.cpMax >= ft.chrg.cpMin);
		}
		else
		{
			if(m_nInitialSearchPos >= 0)
				ft.chrg.cpMax = 0;

			dwFlags &= ~FR_DOWN;
			ATLASSERT(ft.chrg.cpMax <= ft.chrg.cpMin);
		}

		BOOL bRet = FALSE;

		if(pT->FindAndSelect(dwFlags, ft) != -1)
		{
			bRet = TRUE;   // we found the text
		}
		else if(m_nInitialSearchPos > 0)
		{
			// if the original starting point was not the beginning
			// of the buffer and we haven't already been here
			if(bFindDown)
			{
				ft.chrg.cpMin = 0;
				ft.chrg.cpMax = m_nInitialSearchPos;
			}
			else
			{
				ft.chrg.cpMin = pT->GetTextLength();
				ft.chrg.cpMax = m_nInitialSearchPos;
			}
			m_nInitialSearchPos = m_nInitialSearchPos - pT->GetTextLength();

			bRet = (pT->FindAndSelect(dwFlags, ft) != -1) ? TRUE : FALSE;
		}

		return bRet;
	}

	long FindAndSelect(DWORD dwFlags, FINDTEXTEX& ft)
	{
		T* pT = static_cast<T*>(this);
		LONG index = pT->FindText(dwFlags, ft);
		if(index != -1) // i.e. we found something
			pT->SetSel(ft.chrgText);

		return index;
	}
};

}; // namespace WTL

#endif // __ATLFIND_H__
