/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"

#include <svtools/xtextedt.hxx>
#include <vcl/svapp.hxx>  // International
#include <unotools/textsearch.hxx>
#include <com/sun/star/util/SearchOptions.hpp>
#include <com/sun/star/util/SearchFlags.hpp>

using namespace ::com::sun::star;



// -------------------------------------------------------------------------
// class ExtTextEngine
// -------------------------------------------------------------------------
ExtTextEngine::ExtTextEngine() : maGroupChars( String::CreateFromAscii( "(){}[]", 6 ) )
{
}

ExtTextEngine::~ExtTextEngine()
{
}

TextSelection ExtTextEngine::MatchGroup( const TextPaM& rCursor ) const
{
	TextSelection aSel( rCursor );
	sal_uInt16 nPos = rCursor.GetIndex();
	sal_uLong nPara = rCursor.GetPara();
	sal_uLong nParas = GetParagraphCount();
	if ( ( nPara < nParas ) && ( nPos < GetTextLen( nPara ) ) )
	{
		sal_uInt16 nMatchChar = maGroupChars.Search( GetText( rCursor.GetPara() ).GetChar( nPos ) );
		if ( nMatchChar != STRING_NOTFOUND )
		{
			if ( ( nMatchChar % 2 ) == 0 )
			{
				// Vorwaerts suchen...
				sal_Unicode nSC = maGroupChars.GetChar( nMatchChar );
				sal_Unicode nEC = maGroupChars.GetChar( nMatchChar+1 );

				sal_uInt16 nCur = nPos+1;
				sal_uInt16 nLevel = 1;
				while ( nLevel && ( nPara < nParas ) )
				{
					XubString aStr = GetText( nPara );
					while ( nCur < aStr.Len() )
					{
						if ( aStr.GetChar( nCur ) == nSC )
							nLevel++;
						else if ( aStr.GetChar( nCur ) == nEC )
						{
							nLevel--;
							if ( !nLevel )
								break;	// while nCur...
						}
						nCur++;
					}

					if ( nLevel )
					{
						nPara++;
						nCur = 0;
					}
				}
				if ( nLevel == 0 )	// gefunden
				{
					aSel.GetStart() = rCursor;
					aSel.GetEnd() = TextPaM( nPara, nCur+1 );
				}
			}
			else
			{
				// Rueckwaerts suchen...
				xub_Unicode nEC = maGroupChars.GetChar( nMatchChar );
				xub_Unicode nSC = maGroupChars.GetChar( nMatchChar-1 );

				sal_uInt16 nCur = rCursor.GetIndex()-1;
				sal_uInt16 nLevel = 1;
				while ( nLevel )
				{
					if ( GetTextLen( nPara ) )
					{
						XubString aStr = GetText( nPara );
						while ( nCur )
						{
							if ( aStr.GetChar( nCur ) == nSC )
							{
								nLevel--;
								if ( !nLevel )
									break;	// while nCur...
							}
							else if ( aStr.GetChar( nCur ) == nEC )
								nLevel++;

							nCur--;
						}
					}

					if ( nLevel )
					{
						if ( nPara )
						{
							nPara--;
							nCur = GetTextLen( nPara )-1;	// egal ob negativ, weil if Len()
						}
						else
							break;
					}
				}

				if ( nLevel == 0 )	// gefunden
				{
					aSel.GetStart() = rCursor;
					aSel.GetStart().GetIndex()++;	// hinter das Zeichen
					aSel.GetEnd() = TextPaM( nPara, nCur );
				}
			}
		}
	}
	return aSel;
}

sal_Bool ExtTextEngine::Search( TextSelection& rSel, const util::SearchOptions& rSearchOptions, sal_Bool bForward )
{
	TextSelection aSel( rSel );
	aSel.Justify();

	sal_Bool bSearchInSelection = (0 != (rSearchOptions.searchFlag & util::SearchFlags::REG_NOT_BEGINOFLINE) );

	TextPaM aStartPaM( aSel.GetEnd() );
	if ( aSel.HasRange() && ( ( bSearchInSelection && bForward ) || ( !bSearchInSelection && !bForward ) ) )
	{
		aStartPaM = aSel.GetStart();
	}

	bool bFound = false;
	sal_uLong nStartNode, nEndNode;

	if ( bSearchInSelection )
		nEndNode = bForward ? aSel.GetEnd().GetPara() : aSel.GetStart().GetPara();
	else
		nEndNode = bForward ? (GetParagraphCount()-1) : 0;

	nStartNode = aStartPaM.GetPara();

	util::SearchOptions aOptions( rSearchOptions );
	aOptions.Locale = Application::GetSettings().GetLocale();
	utl::TextSearch aSearcher( rSearchOptions );

	// ueber die Absaetze iterieren...
	for ( sal_uLong nNode = nStartNode;
			bForward ?  ( nNode <= nEndNode) : ( nNode >= nEndNode );
			bForward ? nNode++ : nNode-- )
	{
		String aText = GetText( nNode );
		sal_uInt16 nStartPos = 0;
		sal_uInt16 nEndPos = aText.Len();
		if ( nNode == nStartNode )
		{
			if ( bForward )
				nStartPos = aStartPaM.GetIndex();
			else
				nEndPos = aStartPaM.GetIndex();
		}
		if ( ( nNode == nEndNode ) && bSearchInSelection )
		{
			if ( bForward )
				nEndPos = aSel.GetEnd().GetIndex();
			else
				nStartPos = aSel.GetStart().GetIndex();
		}

		if ( bForward )
			bFound = aSearcher.SearchFrwrd( aText, &nStartPos, &nEndPos );
		else
			bFound = aSearcher.SearchBkwrd( aText, &nEndPos, &nStartPos );

		if ( bFound )
		{
			rSel.GetStart().GetPara() = nNode;
			rSel.GetStart().GetIndex() = nStartPos;
			rSel.GetEnd().GetPara() = nNode;
			rSel.GetEnd().GetIndex() = nEndPos;
			// Ueber den Absatz selektieren?
			// Select over the paragraph?
			// FIXME  This should be max long...
			if( nEndPos == sal::static_int_cast<sal_uInt16>(-1) ) // sal_uInt16 for 0 and -1 !
			{
				if ( (rSel.GetEnd().GetPara()+1) < GetParagraphCount() )
				{
					rSel.GetEnd().GetPara()++;
					rSel.GetEnd().GetIndex() = 0;
				}
				else
				{
					rSel.GetEnd().GetIndex() = nStartPos;
					bFound = false;
				}
			}

			break;
		}

		if ( !bForward && !nNode )	// Bei rueckwaertsuche, wenn nEndNode = 0:
			break;
	}

	return bFound;
}


// -------------------------------------------------------------------------
// class ExtTextView
// -------------------------------------------------------------------------
ExtTextView::ExtTextView( ExtTextEngine* pEng, Window* pWindow )
	: TextView( pEng, pWindow )
{
}

ExtTextView::~ExtTextView()
{
}

sal_Bool ExtTextView::MatchGroup()
{
	TextSelection aTmpSel( GetSelection() );
	aTmpSel.Justify();
	if ( ( aTmpSel.GetStart().GetPara() != aTmpSel.GetEnd().GetPara() ) ||
		 ( ( aTmpSel.GetEnd().GetIndex() - aTmpSel.GetStart().GetIndex() ) > 1 ) )
	{
		return sal_False;
	}

	TextSelection aMatchSel = ((ExtTextEngine*)GetTextEngine())->MatchGroup( aTmpSel.GetStart() );
	if ( aMatchSel.HasRange() )
		SetSelection( aMatchSel );

	return aMatchSel.HasRange() ? sal_True : sal_False;
}

sal_Bool ExtTextView::Search( const util::SearchOptions& rSearchOptions, sal_Bool bForward )
{
	sal_Bool bFound = sal_False;
	TextSelection aSel( GetSelection() );
	if ( ((ExtTextEngine*)GetTextEngine())->Search( aSel, rSearchOptions, bForward ) )
	{
		bFound = sal_True;
		// Erstmal den Anfang des Wortes als Selektion einstellen,
		// damit das ganze Wort in den sichtbaren Bereich kommt.
		SetSelection( aSel.GetStart() );
		ShowCursor( sal_True, sal_False );
	}
	else
	{
		aSel = GetSelection().GetEnd();
	}

	SetSelection( aSel );
	ShowCursor();

	return bFound;
}

sal_uInt16 ExtTextView::Replace( const util::SearchOptions& rSearchOptions, sal_Bool bAll, sal_Bool bForward )
{
	sal_uInt16 nFound = 0;

	if ( !bAll )
	{
		if ( GetSelection().HasRange() )
		{
			InsertText( rSearchOptions.replaceString );
			nFound = 1;
			Search( rSearchOptions, bForward );	// gleich zum naechsten
		}
		else
		{
			if( Search( rSearchOptions, bForward ) )
				nFound = 1;
		}
	}
	else
	{
		// Der Writer ersetzt alle, vom Anfang bis Ende...

		ExtTextEngine* pTextEngine = (ExtTextEngine*)GetTextEngine();

		// HideSelection();
		TextSelection aSel;

		sal_Bool bSearchInSelection = (0 != (rSearchOptions.searchFlag & util::SearchFlags::REG_NOT_BEGINOFLINE) );
		if ( bSearchInSelection )
		{
			aSel = GetSelection();
			aSel.Justify();
		}

		TextSelection aSearchSel( aSel );

		sal_Bool bFound = pTextEngine->Search( aSel, rSearchOptions, sal_True );
		if ( bFound )
			pTextEngine->UndoActionStart();
		while ( bFound )
		{
			nFound++;

			TextPaM aNewStart = pTextEngine->ImpInsertText( aSel, rSearchOptions.replaceString );
			aSel = aSearchSel;
			aSel.GetStart() = aNewStart;
			bFound = pTextEngine->Search( aSel, rSearchOptions, sal_True );
		}
		if ( nFound )
		{
			SetSelection( aSel.GetStart() );
			pTextEngine->FormatAndUpdate( this );
			pTextEngine->UndoActionEnd();
		}
	}
	return nFound;
}

sal_Bool ExtTextView::ImpIndentBlock( sal_Bool bRight )
{
	sal_Bool bDone = sal_False;

	TextSelection aSel = GetSelection();
	aSel.Justify();

	HideSelection();
	GetTextEngine()->UndoActionStart();

	sal_uLong nStartPara = aSel.GetStart().GetPara();
	sal_uLong nEndPara = aSel.GetEnd().GetPara();
	if ( aSel.HasRange() && !aSel.GetEnd().GetIndex() )
	{
		nEndPara--;	// den dann nicht einruecken...
	}

	for ( sal_uLong nPara = nStartPara; nPara <= nEndPara; nPara++ )
	{
		if ( bRight )
		{
			// Tabs hinzufuegen
			GetTextEngine()->ImpInsertText( TextPaM( nPara, 0 ), '\t' );
			bDone = sal_True;
		}
		else
		{
			// Tabs/Blanks entfernen
			String aText = GetTextEngine()->GetText( nPara );
			if ( aText.Len() && (
					( aText.GetChar( 0 ) == '\t' ) ||
					( aText.GetChar( 0 ) == ' ' ) ) )
			{
				GetTextEngine()->ImpDeleteText( TextSelection( TextPaM( nPara, 0 ), TextPaM( nPara, 1 ) ) );
				bDone = sal_True;
			}
		}
	}

	GetTextEngine()->UndoActionEnd();

	sal_Bool bRange = aSel.HasRange();
	if ( bRight )
	{
		aSel.GetStart().GetIndex()++;
		if ( bRange && ( aSel.GetEnd().GetPara() == nEndPara ) )
			aSel.GetEnd().GetIndex()++;
	}
	else
	{
		if ( aSel.GetStart().GetIndex() )
			aSel.GetStart().GetIndex()--;
		if ( bRange && aSel.GetEnd().GetIndex() )
			aSel.GetEnd().GetIndex()--;
	}

	ImpSetSelection( aSel );
	GetTextEngine()->FormatAndUpdate( this );

	return bDone;
}

sal_Bool ExtTextView::IndentBlock()
{
	return ImpIndentBlock( sal_True );
}

sal_Bool ExtTextView::UnindentBlock()
{
	return ImpIndentBlock( sal_False );
}

