/**************************************************************
 *
 * 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_tools.hxx"

#define _SV_MULTISEL_CXX

#ifdef MI_DEBUG
#define private public
#include <stdio.h>
#endif

#include <tools/debug.hxx>
#include <tools/multisel.hxx>

#include "rtl/ustrbuf.hxx"

#ifdef MI_DEBUG
#define DBG(x) x
#else
#define DBG(x)
#endif

using namespace rtl;

//==================================================================

#ifdef MI_DEBUG

static void Print( const MultiSelection* pSel )
{
	DbgOutf( "TotRange:     %4ld-%4ld\n",
			 pSel->aTotRange.Min(), pSel->aTotRange.Max() );
	if ( pSel->bCurValid )
	{
		DbgOutf( "CurSubSel:    %4ld\n", pSel->nCurSubSel );
		DbgOutf( "CurIndex:     %4ld\n", pSel->nCurIndex );
	}
	DbgOutf( "SelCount:     %4ld\n", pSel->nSelCount );
	DbgOutf( "SubCount:     %4ld\n", pSel->aSels.Count() );
	for ( sal_uIntPtr nPos = 0; nPos < pSel->aSels.Count(); ++nPos )
	{
		DbgOutf( "SubSel #%2ld:   %4ld-%4ld\n", nPos,
				 pSel->aSels.GetObject(nPos)->Min(),
				 pSel->aSels.GetObject(nPos)->Max() );
	}
	DbgOutf( "\n" );
	fclose( pFile );
}

#endif

// -----------------------------------------------------------------------

void MultiSelection::ImplClear()
{
	// no selected indexes
	nSelCount = 0;

	Range* pRange = aSels.First();
	while ( pRange )
	{
		delete pRange;
		pRange = aSels.Next();
	}
	aSels.Clear();
}

// -----------------------------------------------------------------------

sal_uIntPtr MultiSelection::ImplFindSubSelection( long nIndex ) const
{
	// iterate through the sub selections
	sal_uIntPtr n = 0;
	for ( ;
		  n < aSels.Count() && nIndex > aSels.GetObject(n)->Max();
		  ++n ) {} /* empty loop */
	return n;
}

// -----------------------------------------------------------------------

sal_Bool MultiSelection::ImplMergeSubSelections( sal_uIntPtr nPos1, sal_uIntPtr nPos2 )
{
	// didn't a sub selection at nPos2 exist?
	if ( nPos2 >= aSels.Count() )
		return sal_False;

	// did the sub selections touch each other?
	if ( (aSels.GetObject(nPos1)->Max() + 1) == aSels.GetObject(nPos2)->Min() )
	{
		// merge them
		aSels.GetObject(nPos1)->Max() = aSels.GetObject(nPos2)->Max();
		delete aSels.Remove(nPos2);
		return sal_True;
	}

	return sal_False;
}

// -----------------------------------------------------------------------

MultiSelection::MultiSelection():
	aTotRange( 0, -1 ),
	nCurSubSel(0),
	nSelCount(0),
	bCurValid(sal_False),
	bSelectNew(sal_False)
{
}

// -----------------------------------------------------------------------

MultiSelection::MultiSelection( const UniString& rString, sal_Unicode cRange, sal_Unicode cSep ):
	aTotRange(0,RANGE_MAX),
	nCurSubSel(0),
	nSelCount(0),
	bCurValid(sal_False),
	bSelectNew(sal_False)
{
	// Dies ist nur ein Schnellschuss und sollte bald optimiert,
	// an die verschiedenen Systeme (UNIX etc.)
	// und die gewuenschte Eingabe-Syntax angepasst werden.

	UniString			aStr( rString );
	sal_Unicode*		pStr   = aStr.GetBufferAccess();
	sal_Unicode*		pOld = pStr;
	sal_Bool				bReady = sal_False;
	sal_Bool				bUntil = sal_False;
	xub_StrLen			nCut   = 0;

	// Hier normieren wir den String, sodass nur Ziffern,
	// Semikola als Trenn- und Minus als VonBis-Zeichen
	// uebrigbleiben, z.B. "99-117;55;34;-17;37-43"
	while ( *pOld )
	{
		switch( *pOld )
		{
			case '0':
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				DBG_ASSERT( *pOld != cRange, "digit for range char not allowed" );
				DBG_ASSERT( *pOld != cSep, "digit for separator not allowed" );
				if( bReady )
				{
					*pStr++ = ';';
					nCut++;
					bReady = sal_False;
				}
				*pStr++ = *pOld;
				nCut++;
				bUntil = sal_False;
				break;

			case '-':
			case ':':
			case '/':
				if ( *pOld != cSep )
				{
					if ( !bUntil )
					{
						*pStr++ = '-';
						nCut++;
						bUntil = sal_True;
					}
					bReady = sal_False;
				}
				else
					bReady = sal_True;
				break;

			case ' ':
				DBG_ASSERT( *pOld != cRange, "SPACE for range char not allowed" );
				DBG_ASSERT( *pOld != cSep, "SPACE for separator not allowed" );
				bReady = !bUntil;
				break;

			default:
				if ( *pOld == cRange )
				{
					if ( !bUntil )
					{
						*pStr++ = '-';
						nCut++;
						bUntil = sal_True;
					}
					bReady = sal_False;
				}
				else
					bReady = sal_True;
				break;
		}

		pOld++;
	}
	aStr.ReleaseBufferAccess( nCut );

	// Jetzt wird der normierte String ausgewertet ..
	UniString			aNumStr;
	Range				aRg( 1, RANGE_MAX );
	const sal_Unicode*	pCStr = aStr.GetBuffer();
	long				nPage = 1;
	long				nNum  = 1;
	bUntil = sal_False;
	while ( *pCStr )
	{
		switch ( *pCStr )
		{
			case '0':
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				aNumStr += *pCStr;
				break;
			case ';':
				nNum = aNumStr.ToInt32();
				if ( bUntil )
				{
					if ( !aNumStr.Len() )
						nNum = RANGE_MAX;
					aRg.Min() = nPage;
					aRg.Max() = nNum;
					aRg.Justify();
					Select( aRg );
				}
				else
					Select( nNum );
				nPage = 0;
				aNumStr.Erase();
				bUntil = sal_False;
				break;

			case '-':
				nPage = aNumStr.ToInt32();
				aNumStr.Erase();
				bUntil = sal_True;
				break;
		}

		pCStr++;
	}

	nNum = aNumStr.ToInt32();
	if ( bUntil )
	{
		if ( !aNumStr.Len() )
			nNum = RANGE_MAX;
		aRg.Min() = nPage;
		aRg.Max() = nNum;
		aRg.Justify();
		Select( aRg );
	}
	else
		Select( nNum );
}

// -----------------------------------------------------------------------

MultiSelection::MultiSelection( const MultiSelection& rOrig ) :
	aTotRange(rOrig.aTotRange),
	nSelCount(rOrig.nSelCount),
	bCurValid(rOrig.bCurValid),
	bSelectNew(sal_False)
{
	if ( bCurValid )
	{
		nCurSubSel = rOrig.nCurSubSel;
		nCurIndex = rOrig.nCurIndex;
	}

	// copy the sub selections
	for ( sal_uIntPtr n = 0; n < rOrig.aSels.Count(); ++n )
		aSels.Insert( new Range( *rOrig.aSels.GetObject(n) ), LIST_APPEND );
}

// -----------------------------------------------------------------------

MultiSelection::MultiSelection( const Range& rRange ):
	aTotRange(rRange),
	nCurSubSel(0),
	nSelCount(0),
	bCurValid(sal_False),
	bSelectNew(sal_False)
{
}

// -----------------------------------------------------------------------

MultiSelection::~MultiSelection()
{
	Range* pRange = aSels.First();
	while ( pRange )
	{
		delete pRange;
		pRange = aSels.Next();
	}
}

// -----------------------------------------------------------------------

MultiSelection& MultiSelection::operator= ( const MultiSelection& rOrig )
{
	aTotRange = rOrig.aTotRange;
	bCurValid = rOrig.bCurValid;
	if ( bCurValid )
	{
		nCurSubSel = rOrig.nCurSubSel;
		nCurIndex = rOrig.nCurIndex;
	}

	// clear the old and copy the sub selections
	ImplClear();
	for ( sal_uIntPtr n = 0; n < rOrig.aSels.Count(); ++n )
		aSels.Insert( new Range( *rOrig.aSels.GetObject(n) ), LIST_APPEND );
	nSelCount = rOrig.nSelCount;

	return *this;
}

// -----------------------------------------------------------------------

sal_Bool MultiSelection::operator== ( MultiSelection& rWith )
{
	if ( aTotRange != rWith.aTotRange || nSelCount != rWith.nSelCount ||
		 aSels.Count() != rWith.aSels.Count() )
		return sal_False;

	// compare the sub seletions
	for ( sal_uIntPtr n = 0; n < aSels.Count(); ++n )
		if ( *aSels.GetObject(n) != *rWith.aSels.GetObject(n) )
			return sal_False;
	return sal_True;
}

// -----------------------------------------------------------------------

void MultiSelection::SelectAll( sal_Bool bSelect )
{
	DBG(DbgOutf( "::SelectAll(%s)\n", bSelect ? "sal_True" : "sal_False" ));

	ImplClear();
	if ( bSelect )
	{
		aSels.Insert( new Range(aTotRange), LIST_APPEND );
		nSelCount = aTotRange.Len();
	}

	DBG(Print( this ));
}

// -----------------------------------------------------------------------

sal_Bool MultiSelection::Select( long nIndex, sal_Bool bSelect )
{
	DBG_ASSERT( aTotRange.IsInside(nIndex), "selected index out of range" );

	// out of range?
	if ( !aTotRange.IsInside(nIndex) )
		return sal_False;

	// find the virtual target position
	sal_uIntPtr nSubSelPos = ImplFindSubSelection( nIndex );

	if ( bSelect )
	{
		// is it included in the found sub selection?
		if ( nSubSelPos < aSels.Count() &&
			 aSels.GetObject(nSubSelPos)->IsInside( nIndex ) )
			// already selected, nothing to do
			return sal_False;

		// it will become selected
		++nSelCount;

		// is it at the end of the previous sub selection
		if ( nSubSelPos > 0 &&
			 aSels.GetObject(nSubSelPos-1)->Max() == (nIndex-1) )
		{
			// expand the previous sub selection
			aSels.GetObject(nSubSelPos-1)->Max() = nIndex;

			// try to merge the previous sub selection
			ImplMergeSubSelections( nSubSelPos-1, nSubSelPos );
		}
		// is is at the beginning of the found sub selection
		else if ( nSubSelPos < aSels.Count() &&
				  aSels.GetObject(nSubSelPos)->Min() == (nIndex+1) )
			// expand the found sub selection
			aSels.GetObject(nSubSelPos)->Min() = nIndex;
		else
		{
			// create a new sub selection
			aSels.Insert( new Range( nIndex, nIndex ), nSubSelPos );
			if ( bCurValid && nCurSubSel >= nSubSelPos )
				++nCurSubSel;
		}
	}
	else
	{
		// is it excluded from the found sub selection?
		if ( nSubSelPos >= aSels.Count() ||
			 !aSels.GetObject(nSubSelPos)->IsInside( nIndex ) )
		{
			// not selected, nothing to do
			DBG(Print( this ));
			return sal_False;
		}

		// it will become deselected
		--nSelCount;

		// is it the only index in the found sub selection?
		if ( aSels.GetObject(nSubSelPos)->Len() == 1 )
		{
			// remove the complete sub selection
			delete aSels.Remove( nSubSelPos );
			DBG(Print( this ));
			return sal_True;
		}

		// is it at the beginning of the found sub selection?
		if ( aSels.GetObject(nSubSelPos)->Min() == nIndex )
			++aSels.GetObject(nSubSelPos)->Min();
		// is it at the end of the found sub selection?
		else if ( aSels.GetObject(nSubSelPos)->Max() == nIndex )
			--aSels.GetObject(nSubSelPos)->Max();
		// it is in the middle of the found sub selection?
		else
		{
			// split the sub selection
			aSels.Insert(
				new Range( aSels.GetObject(nSubSelPos)->Min(), nIndex-1 ),
				nSubSelPos );
			aSels.GetObject(nSubSelPos+1)->Min() = nIndex + 1;
		}
	}

	DBG(Print( this ));

	return sal_True;
}

// -----------------------------------------------------------------------

void MultiSelection::Select( const Range& rIndexRange, sal_Bool bSelect )
{
	Range* pRange;
	long nOld;

	sal_uIntPtr nTmpMin = rIndexRange.Min();
	sal_uIntPtr nTmpMax = rIndexRange.Max();
	sal_uIntPtr nCurMin = FirstSelected();
	sal_uIntPtr nCurMax = LastSelected();
	DBG_ASSERT(aTotRange.IsInside(nTmpMax), "selected index out of range" );
	DBG_ASSERT(aTotRange.IsInside(nTmpMin), "selected index out of range" );

	// gesamte Selektion ersetzen ?
	if( nTmpMin <= nCurMin && nTmpMax >= nCurMax )
	{
		ImplClear();
		if ( bSelect )
		{
			aSels.Insert( new Range(rIndexRange), LIST_APPEND );
			nSelCount = rIndexRange.Len();
		}
		return;
	}
	// links erweitern ?
	if( nTmpMax < nCurMin )
	{
		if( bSelect )
		{
			// ersten Range erweitern ?
			if( nCurMin > (nTmpMax+1)  )
			{
				pRange = new Range( rIndexRange );
				aSels.Insert( pRange, (sal_uIntPtr)0 );
				nSelCount += pRange->Len();
			}
			else
			{
				pRange = aSels.First();
				nOld = pRange->Min();
				pRange->Min() = (long)nTmpMin;
				nSelCount += ( nOld - nTmpMin );
			}
			bCurValid = sal_False;
		}
		return;
	}
	// rechts erweitern ?
	else if( nTmpMin > nCurMax )
	{
		if( bSelect )
		{
			// letzten Range erweitern ?
			if( nTmpMin > (nCurMax+1) )
			{
				pRange = new Range( rIndexRange );
				aSels.Insert( pRange, LIST_APPEND );
				nSelCount += pRange->Len();
			}
			else
			{
				pRange = aSels.Last();
				nOld = pRange->Max();
				pRange->Max() = (long)nTmpMax;
				nSelCount += ( nTmpMax - nOld );
			}
			bCurValid = sal_False;
		}
		return;
	}

	//HACK(Hier muss noch optimiert werden)
	while( nTmpMin <= nTmpMax )
	{
		Select( nTmpMin, bSelect );
		nTmpMin++;
	}
}

// -----------------------------------------------------------------------

sal_Bool MultiSelection::IsSelected( long nIndex ) const
{
	// find the virtual target position
	sal_uIntPtr nSubSelPos = ImplFindSubSelection( nIndex );

	return nSubSelPos < aSels.Count() &&
		   aSels.GetObject(nSubSelPos)->IsInside(nIndex);
}

// -----------------------------------------------------------------------

void MultiSelection::Insert( long nIndex, long nCount )
{
	DBG(DbgOutf( "::Insert(%ld, %ld)\n", nIndex, nCount ));

	// find the virtual target position
	sal_uIntPtr nSubSelPos = ImplFindSubSelection( nIndex );

	// did we need to shift the sub selections?
	if ( nSubSelPos < aSels.Count() )
	{
		// did we insert an unselected into an existing sub selection?
		if ( !bSelectNew && aSels.GetObject(nSubSelPos)->Min() != nIndex &&
				  aSels.GetObject(nSubSelPos)->IsInside(nIndex) )
		{
			// split the sub selection
			aSels.Insert(
				new Range( aSels.GetObject(nSubSelPos)->Min(), nIndex-1 ),
				nSubSelPos );
			++nSubSelPos;
			aSels.GetObject(nSubSelPos)->Min() = nIndex;
		}

		// did we append an selected to an existing sub selection?
		else if ( bSelectNew && nSubSelPos > 0 &&
			 aSels.GetObject(nSubSelPos)->Max() == nIndex-1 )
			// expand the previous sub selection
			aSels.GetObject(nSubSelPos-1)->Max() += nCount;

		// did we insert an selected into an existing sub selection?
		else if ( bSelectNew && aSels.GetObject(nSubSelPos)->Min() == nIndex )
		{
			// expand the sub selection
			aSels.GetObject(nSubSelPos)->Max() += nCount;
			++nSubSelPos;
		}

		// shift the sub selections behind the inserting position
		for ( sal_uIntPtr nPos = nSubSelPos; nPos < aSels.Count(); ++nPos )
		{
			aSels.GetObject(nPos)->Min() += nCount;
			aSels.GetObject(nPos)->Max() += nCount;
		}
	}

	bCurValid = sal_False;
	aTotRange.Max() += nCount;
	if ( bSelectNew )
		nSelCount += nCount;

	DBG(Print( this ));
}

// -----------------------------------------------------------------------

void MultiSelection::Remove( long nIndex )
{
	DBG(DbgOutf( "::Remove(%ld)\n", nIndex ));

	// find the virtual target position
	sal_uIntPtr nSubSelPos = ImplFindSubSelection( nIndex );

	// did we remove from an existing sub selection?
	if ( nSubSelPos < aSels.Count() &&
		 aSels.GetObject(nSubSelPos)->IsInside(nIndex) )
	{
		// does this sub selection only contain the index to be deleted
		if ( aSels.GetObject(nSubSelPos)->Len() == 1 )
			// completely remove the sub selection
			aSels.Remove(nSubSelPos);
		else
			// shorten this sub selection
			--( aSels.GetObject(nSubSelPos++)->Max() );

		// adjust the selected counter
		--nSelCount;
	}

	// shift the sub selections behind the removed index
	for ( sal_uIntPtr nPos = nSubSelPos; nPos < aSels.Count(); ++nPos )
	{
		--( aSels.GetObject(nPos)->Min() );
		--( aSels.GetObject(nPos)->Max() );
	}

	bCurValid = sal_False;
	aTotRange.Max() -= 1;

	DBG(Print( this ));
}

// -----------------------------------------------------------------------

void MultiSelection::Append( long nCount )
{
	long nPrevLast = aTotRange.Max();
	aTotRange.Max() += nCount;
	if ( bSelectNew )
	{
		nSelCount += nCount;
		aSels.Insert( new Range( nPrevLast+1, nPrevLast + nCount ),
					  LIST_APPEND );
		if ( aSels.Count() > 1 )
			ImplMergeSubSelections( aSels.Count() - 2, aSels.Count() );
	}
}

// -----------------------------------------------------------------------

long MultiSelection::ImplFwdUnselected()
{
	if ( !bCurValid )
		return SFX_ENDOFSELECTION;

	if ( ( nCurSubSel < aSels.Count() ) &&
		 ( aSels.GetObject(nCurSubSel)->Min() <= nCurIndex ) )
		nCurIndex = aSels.GetObject(nCurSubSel++)->Max() + 1;

	if ( nCurIndex <= aTotRange.Max() )
		return nCurIndex;
	else
		return SFX_ENDOFSELECTION;
}

// -----------------------------------------------------------------------

long MultiSelection::ImplBwdUnselected()
{
	if ( !bCurValid )
		return SFX_ENDOFSELECTION;

	if ( aSels.GetObject(nCurSubSel)->Max() < nCurIndex )
		return nCurIndex;

	nCurIndex = aSels.GetObject(nCurSubSel--)->Min() - 1;
	if ( nCurIndex >= 0 )
		return nCurIndex;
	else
		return SFX_ENDOFSELECTION;
}

// -----------------------------------------------------------------------

long MultiSelection::FirstSelected( sal_Bool bInverse )
{
	bInverseCur = bInverse;
	nCurSubSel = 0;

	if ( bInverseCur )
	{
		bCurValid = nSelCount < sal_uIntPtr(aTotRange.Len());
		if ( bCurValid )
		{
			nCurIndex = 0;
			return ImplFwdUnselected();
		}
	}
	else
	{
		bCurValid = aSels.Count() > 0;
		if ( bCurValid )
			return nCurIndex = aSels.GetObject(0)->Min();
	}

	return SFX_ENDOFSELECTION;
}

// -----------------------------------------------------------------------

long MultiSelection::LastSelected()
{
	nCurSubSel = aSels.Count() - 1;
	bCurValid = aSels.Count() > 0;

	if ( bCurValid )
		return nCurIndex = aSels.GetObject(nCurSubSel)->Max();

	return SFX_ENDOFSELECTION;
}

// -----------------------------------------------------------------------

long MultiSelection::NextSelected()
{
	if ( !bCurValid )
		return SFX_ENDOFSELECTION;

	if ( bInverseCur )
	{
		++nCurIndex;
		return ImplFwdUnselected();
	}
	else
	{
		// is the next index in the current sub selection too?
		if ( nCurIndex < aSels.GetObject(nCurSubSel)->Max() )
			return ++nCurIndex;

		// are there further sub selections?
		if ( ++nCurSubSel < aSels.Count() )
			return nCurIndex = aSels.GetObject(nCurSubSel)->Min();

		// we are at the end!
		return SFX_ENDOFSELECTION;
	}
}

// -----------------------------------------------------------------------

long MultiSelection::PrevSelected()
{
	if ( !bCurValid )
		return SFX_ENDOFSELECTION;

	if ( bInverseCur )
	{
		--nCurIndex;
		return ImplBwdUnselected();
	}
	else
	{
		// is the previous index in the current sub selection too?
		if ( nCurIndex > aSels.GetObject(nCurSubSel)->Min() )
			return --nCurIndex;

		// are there previous sub selections?
		if ( nCurSubSel > 0 )
		{
			--nCurSubSel;
			return nCurIndex = aSels.GetObject(nCurSubSel)->Max();
		}

		// we are at the beginning!
		return SFX_ENDOFSELECTION;
	}
}

// -----------------------------------------------------------------------

void MultiSelection::SetTotalRange( const Range& rTotRange )
{
	aTotRange = rTotRange;

	// die untere Bereichsgrenze anpassen
	Range* pRange = aSels.GetObject( 0 );
	while( pRange )
	{
		if( pRange->Max() < aTotRange.Min() )
		{
			delete pRange;
			aSels.Remove( (sal_uIntPtr)0 );
		}
		else if( pRange->Min() < aTotRange.Min() )
		{
			pRange->Min() = aTotRange.Min();
			break;
		}
		else
			break;

		pRange = aSels.GetObject( 0 );
	}

	// die obere Bereichsgrenze anpassen
	sal_uIntPtr nCount = aSels.Count();
	while( nCount )
	{
		pRange = aSels.GetObject( nCount - 1 );
		if( pRange->Min() > aTotRange.Max() )
		{
			delete pRange;
			aSels.Remove( (sal_uIntPtr)(nCount - 1) );
		}
		else if( pRange->Max() > aTotRange.Max() )
		{
			pRange->Max() = aTotRange.Max();
			break;
		}
		else
			break;

		nCount = aSels.Count();
	}

	// Selection-Count neu berechnen
	nSelCount = 0;
	pRange = aSels.First();
	while( pRange )
	{
		nSelCount += pRange->Len();
		pRange = aSels.Next();
	}

	bCurValid = sal_False;
	nCurIndex = 0;
}

// -----------------------------------------------------------------------
//
// StringRangeEnumerator
//
// -----------------------------------------------------------------------
StringRangeEnumerator::StringRangeEnumerator( const rtl::OUString& i_rInput,
                                              sal_Int32 i_nMinNumber,
                                              sal_Int32 i_nMaxNumber,
                                              sal_Int32 i_nLogicalOffset
                                              )
    : mnCount( 0 )
    , mnMin( i_nMinNumber )
    , mnMax( i_nMaxNumber )
    , mnOffset( i_nLogicalOffset )
{
    setRange( i_rInput );
}

bool StringRangeEnumerator::checkValue( sal_Int32 i_nValue, const std::set< sal_Int32 >* i_pPossibleValues ) const
{
    if( mnMin >= 0 && i_nValue < mnMin )
        return false;
    if( mnMax >= 0 && i_nValue > mnMax )
        return false;
    if( i_nValue < 0 )
        return false;
    if( i_pPossibleValues && i_pPossibleValues->find( i_nValue ) == i_pPossibleValues->end() )
        return false;
    return true;
}

bool StringRangeEnumerator::insertRange( sal_Int32 i_nFirst, sal_Int32 i_nLast, bool bSequence, bool bMayAdjust )
{
    bool bSuccess = true;
    if( bSequence )
    {
        if( i_nFirst == -1 )
            i_nFirst = mnMin;
        if( i_nLast == -1 )
            i_nLast = mnMax;
        if( bMayAdjust )
        {
            if( i_nFirst < mnMin )
                i_nFirst = mnMin;
            if( i_nFirst > mnMax )
                i_nFirst = mnMax;
            if( i_nLast < mnMin )
                i_nLast = mnMin;
            if( i_nLast > mnMax )
                i_nLast = mnMax;
        }
        if( checkValue( i_nFirst ) && checkValue( i_nLast ) )
        {
            maSequence.push_back( Range( i_nFirst, i_nLast ) );
            sal_Int32 nNumber = i_nLast - i_nFirst;
            nNumber = nNumber < 0 ? -nNumber : nNumber;
            mnCount += nNumber + 1;
        }
        else
            bSuccess = false;
    }
    else
    {
        if( i_nFirst >= 0 )
        {
            if( checkValue( i_nFirst ) )
            {
                maSequence.push_back( Range( i_nFirst, i_nFirst ) );
                mnCount++;
            }
            else
                bSuccess = false;
        }
        if( i_nLast >= 0 )
        {
            if( checkValue( i_nLast ) )
            {
                maSequence.push_back( Range( i_nLast, i_nLast ) );
                mnCount++;
            }
            else
                bSuccess = false;
        }
    }

    return bSuccess;
}

bool StringRangeEnumerator::setRange( const rtl::OUString& i_rNewRange, bool i_bStrict )
{
    mnCount = 0;
    maSequence.clear();

    // we love special cases
    if( i_rNewRange.getLength() == 0 )
    {
        if( mnMin >= 0 && mnMax >= 0 )
        {
            insertRange( mnMin, mnMax, mnMin != mnMax, ! i_bStrict );
        }
        return true;
    }

    const sal_Unicode* pInput = i_rNewRange.getStr();
    rtl::OUStringBuffer aNumberBuf( 16 );
    sal_Int32 nLastNumber = -1, nNumber = -1;
    bool bSequence = false;
    bool bSuccess = true;
    while( *pInput )
    {
        while( *pInput >= sal_Unicode('0') && *pInput <= sal_Unicode('9') )
            aNumberBuf.append( *pInput++ );
        if( aNumberBuf.getLength() )
        {
            if( nNumber != -1 )
            {
                if( bSequence )
                {
                    if( ! insertRange( nLastNumber, nNumber, true, ! i_bStrict ) && i_bStrict )
                    {
                        bSuccess = false;
                        break;
                    }
                    nLastNumber = -1;
                }
                else
                {
                    if( ! insertRange( nNumber, nNumber, false, ! i_bStrict ) && i_bStrict )
                    {
                        bSuccess = false;
                        break;
                    }
                }
            }
            nNumber = aNumberBuf.makeStringAndClear().toInt32();
            nNumber += mnOffset;
        }
        bool bInsertRange = false;
        if( *pInput == sal_Unicode('-') )
        {
            nLastNumber = nNumber;
            nNumber = -1;
            bSequence = true;
        }
        else if( *pInput == ' ' )
        {
        }
        else if( *pInput == sal_Unicode(',') || *pInput == sal_Unicode(';') )
            bInsertRange = true;
        else if( *pInput )
        {

            bSuccess = false;
            break; // parse error
        }

        if( bInsertRange )
        {
            if( ! insertRange( nLastNumber, nNumber, bSequence, ! i_bStrict ) && i_bStrict )
            {
                bSuccess = false;
                break;
            }
            nNumber = nLastNumber = -1;
            bSequence = false;
        }
        if( *pInput )
            pInput++;
    }
    // insert last entries
    insertRange( nLastNumber, nNumber, bSequence, ! i_bStrict );

    return bSuccess;
}

bool StringRangeEnumerator::hasValue( sal_Int32 i_nValue, const std::set< sal_Int32 >* i_pPossibleValues ) const
{
    if( i_pPossibleValues && i_pPossibleValues->find( i_nValue ) == i_pPossibleValues->end() )
        return false;
    size_t n = maSequence.size();
    for( size_t i= 0; i < n; ++i )
    {
        const StringRangeEnumerator::Range rRange( maSequence[i] );
        if( rRange.nFirst < rRange.nLast )
        {
            if( i_nValue >= rRange.nFirst && i_nValue <= rRange.nLast )
                return true;
        }
        else
        {
            if( i_nValue >= rRange.nLast && i_nValue <= rRange.nFirst )
                return true;
        }
    }
    return false;
}

StringRangeEnumerator::Iterator& StringRangeEnumerator::Iterator::operator++()
{
    if( nRangeIndex >= 0 && nCurrent >= 0 && pEnumerator )
    {
        const StringRangeEnumerator::Range& rRange( pEnumerator->maSequence[nRangeIndex] );
        bool bRangeChange = false;
        if( rRange.nLast < rRange.nFirst )
        {
            // backward range
            if( nCurrent > rRange.nLast )
                nCurrent--;
            else
                bRangeChange = true;
        }
        else
        {
            // forward range
            if( nCurrent < rRange.nLast )
                nCurrent++;
            else
                bRangeChange = true;
        }
        if( bRangeChange )
        {
            nRangeIndex++;
            if( size_t(nRangeIndex) == pEnumerator->maSequence.size() )
            {
                // reached the end
                nRangeIndex = nCurrent = -1;
            }
            else
                nCurrent = pEnumerator->maSequence[nRangeIndex].nFirst;
        }
        if( nRangeIndex != -1 && nCurrent != -1 )
        {
            if( ! pEnumerator->checkValue( nCurrent, pPossibleValues ) )
                return ++(*this);
        }
    }
    return *this;
}

sal_Int32 StringRangeEnumerator::Iterator::operator*() const
{
    return nCurrent;
}

bool StringRangeEnumerator::Iterator::operator==( const Iterator& i_rCompare ) const
{
    return i_rCompare.pEnumerator == pEnumerator && i_rCompare.nRangeIndex == nRangeIndex && i_rCompare.nCurrent == nCurrent;
}

StringRangeEnumerator::Iterator StringRangeEnumerator::begin( const std::set< sal_Int32 >* i_pPossibleValues ) const
{
    StringRangeEnumerator::Iterator it( this,
                                        i_pPossibleValues,
                                        maSequence.empty() ? -1 : 0,
                                        maSequence.empty() ? -1 : maSequence[0].nFirst );
    if( ! checkValue(*it, i_pPossibleValues ) )
        ++it;
    return it;
}

StringRangeEnumerator::Iterator StringRangeEnumerator::end( const std::set< sal_Int32 >* i_pPossibleValues ) const
{
    return StringRangeEnumerator::Iterator( this, i_pPossibleValues, -1, -1 );
}

bool StringRangeEnumerator::getRangesFromString( const OUString& i_rPageRange,
                                                 std::vector< sal_Int32 >& o_rPageVector,
                                                 sal_Int32 i_nMinNumber,
                                                 sal_Int32 i_nMaxNumber,
                                                 sal_Int32 i_nLogicalOffset,
                                                 std::set< sal_Int32 >* i_pPossibleValues
                                               )
{
    StringRangeEnumerator aEnum;
    aEnum.setMin( i_nMinNumber );
    aEnum.setMax( i_nMaxNumber );
    aEnum.setLogicalOffset( i_nLogicalOffset );

    bool bRes = aEnum.setRange( i_rPageRange );
    if( bRes )
    {
        o_rPageVector.clear();
        o_rPageVector.reserve( aEnum.size() );
        for( StringRangeEnumerator::Iterator it = aEnum.begin( i_pPossibleValues );
             it != aEnum.end( i_pPossibleValues ); ++it )
        {
            o_rPageVector.push_back( *it );
        }
    }

    return bRes;
}
