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



#include "errhdl.hxx"			// fuers ASSERT
#include "error.h"				// fuers ASSERT
#include "ndindex.hxx"

#ifdef DBG_UTIL
int SwNodeIndex::nSerial = 0;
#endif


SwNodeRange::SwNodeRange( const SwNodeIndex &rS, const SwNodeIndex &rE )
	: aStart( rS ), aEnd( rE )
{}

SwNodeRange::SwNodeRange( const SwNodeRange &rRange )
	: aStart( rRange.aStart ), aEnd( rRange.aEnd )
{}

SwNodeRange::SwNodeRange( SwNodes& rNds, sal_uLong nSttIdx, sal_uLong nEndIdx )
	: aStart( rNds, nSttIdx ), aEnd( rNds, nEndIdx )
{}


SwNodeRange::SwNodeRange( const SwNodeIndex& rS, long nSttDiff,
						  const SwNodeIndex& rE, long nEndDiff )
	: aStart( rS, nSttDiff ), aEnd( rE, nEndDiff )
{}

SwNodeRange::SwNodeRange( const SwNode& rS, long nSttDiff,
						  const SwNode& rE, long nEndDiff )
	: aStart( rS, nSttDiff ), aEnd( rE, nEndDiff )
{}


SwNodeIndex::SwNodeIndex( SwNodes& rNds, sal_uLong nIdx )
	: pNd( rNds[ nIdx ] ), pNext( 0 ), pPrev( 0 )
{
	rNds.RegisterIndex( *this );

#ifdef DBG_UTIL
	MySerial = ++nSerial;		// nur in der nicht PRODUCT-Version
#endif
}


SwNodeIndex::SwNodeIndex( const SwNodeIndex& rIdx, long nDiff )
	: pNext( 0 ), pPrev( 0 )
{
	if( nDiff )
		pNd = rIdx.GetNodes()[ rIdx.GetIndex() + nDiff ];
	else
		pNd = rIdx.pNd;

	pNd->GetNodes().RegisterIndex( *this );
#ifdef DBG_UTIL
	MySerial = ++nSerial;		// nur in der nicht PRODUCT-Version
#endif
}


SwNodeIndex::SwNodeIndex( const SwNode& rNd, long nDiff )
	: pNext( 0 ), pPrev( 0 )
{
	if( nDiff )
		pNd = rNd.GetNodes()[ rNd.GetIndex() + nDiff ];
	else
		pNd = (SwNode*)&rNd;

	pNd->GetNodes().RegisterIndex( *this );
#ifdef DBG_UTIL
	MySerial = ++nSerial;		// nur in der nicht PRODUCT-Version
#endif
}


void SwNodeIndex::Remove()
{
	pNd->GetNodes().DeRegisterIndex( *this );
}

SwNodeIndex& SwNodeIndex::operator=( const SwNodeIndex& rIdx )
{
	if( &pNd->GetNodes() != &rIdx.pNd->GetNodes() )
	{
		pNd->GetNodes().DeRegisterIndex( *this );
		pNd = rIdx.pNd;
		pNd->GetNodes().RegisterIndex( *this );
	}
	else
		pNd = rIdx.pNd;
	return *this;
}

SwNodeIndex& SwNodeIndex::operator=( const SwNode& rNd )
{
	if( &pNd->GetNodes() != &rNd.GetNodes() )
	{
		pNd->GetNodes().DeRegisterIndex( *this );
		pNd = (SwNode*)&rNd;
		pNd->GetNodes().RegisterIndex( *this );
	}
	else
		pNd = (SwNode*)&rNd;
	return *this;
}

SwNodeIndex& SwNodeIndex::Assign( SwNodes& rNds, sal_uLong nIdx )
{
	if( &pNd->GetNodes() != &rNds )
	{
		pNd->GetNodes().DeRegisterIndex( *this );
		pNd = rNds[ nIdx ];
		pNd->GetNodes().RegisterIndex( *this );
	}
	else
		pNd = rNds[ nIdx ];
	return *this;
}

SwNodeIndex& SwNodeIndex::Assign( const SwNode& rNd, long nOffset )
{
	if( &pNd->GetNodes() != &rNd.GetNodes() )
	{
		pNd->GetNodes().DeRegisterIndex( *this );
		pNd = (SwNode*)&rNd;
		pNd->GetNodes().RegisterIndex( *this );
	}
	else
		pNd = (SwNode*)&rNd;

	if( nOffset )
		pNd = pNd->GetNodes()[ pNd->GetIndex() + nOffset ];

	return *this;
}


