// Aqsis
// Copyright (c) 1997 - 2001, Paul C. Gregory
//
// Contact: pgregory@aqsis.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

/**
 * Copyright (C) 2006-2007  NTT DATA CORPORATION
 * 
 * Version: 1.0.0 2007/04/01
 *  
 */
package net.cellcomputing.himawari.library;

import net.cellcomputing.himawari.accessory.Vector;



/**
 * 
 *	Individual topology element class.
 *	Holds information about mesh neighbourhoods allowing easy data aextraction about mesh topology.
 * 
 * @author NTT DATA Corporation
 */
public strictfp class CqLath {
	
	///	Constructor.
	public CqLath()
	{
		m_pClockwiseVertex	= null;
		m_pClockwiseFacet	= null;
		m_pParentFacet		= null;
		m_pChildVertex		= null;
		m_pMidVertex		= null;
		m_pFaceVertex		= null;
		m_VertexIndex		= 0;
		m_FaceVertexIndex	= 0;
	}
	
	public CqLath( int iV, int iFV )
	{
		m_pClockwiseVertex	= null;
		m_pClockwiseFacet	= null;
		m_pParentFacet		= null;
		m_pChildVertex		= null;
		m_pMidVertex		= null;
		m_pFaceVertex		= null;
		m_VertexIndex		= iV;
		m_FaceVertexIndex	= iFV;
	}
	
	///	Destructor.
//	~CqLath()	{}
	
	/// Get a pointer to the lath representing the facet that this one was created from.
	public CqLath	pParentFacet()	{return(m_pParentFacet);}
	/// Get a pointer to the lath representing this vertex at the next level.
	public CqLath	pChildVertex()	{return(m_pChildVertex);}
	/// Get a pointer to the lath representing the midpoint vertex of this edge at the next level.
	public CqLath	pMidVertex()	{return(m_pMidVertex);}
	/// Get a pointer to the lath representing the midpoint vertex of this face at the next level.
	public CqLath	pFaceVertex()	{return(m_pFaceVertex);}
	
	/// Get the index of the vertex this lath references.
	public int	VertexIndex()		{return(m_VertexIndex);}
	/// Get the index of the vertex this lath references.
	public int	FaceVertexIndex()	{return(m_FaceVertexIndex);}
	
	/// Set the pointer to the next lath clockwise about the vertex.
	public void SetpClockwiseVertex(CqLath pLath)
	{m_pClockwiseVertex=pLath;}
	/// Set the pointer to the next lath clockwise about the facet.
	public void SetpClockwiseFacet(CqLath pLath)
	{m_pClockwiseFacet=pLath;}
	/// Set the pointer to the lath representing the facet that this one was created from.
	public void SetpParentFacet(CqLath pLath)
	{m_pParentFacet=pLath;}
	/// Set the pointer to the lath representing this vertex at the next level.
	public void SetpChildVertex(CqLath pLath)
	{m_pChildVertex=pLath;}
	/// Set the pointer to the lath representing the midpoint vertex of this edge at the next level.
	public void SetpMidVertex(CqLath pLath)	{m_pMidVertex=pLath;}
	/// Set the pointer to the lath representing the midpoint vertex of this face at the next level.
	public void SetpFaceVertex(CqLath pLath)	{m_pFaceVertex=pLath;}
	
	/// Set the index of the vertex this lath refers to.
	public void SetVertexIndex(int iV)	{m_VertexIndex=iV;}
	/// Set the index of the face vertex this lath refers to.
	public void SetFaceVertexIndex(int iV)	{m_FaceVertexIndex=iV;}
	
	// Basic neighbourhood operators.
	
	/**
	 *	Get the next lath clockwise around the facet.
	 *	Get a pointer to the next lath in a clockwise direction around the
	 *	associated facet. This information is inherent in the data structures.
	 *
	 *	@return	Pointer to the lath.
	 */
	public CqLath cf()
	{
		// Inherent in the data structure.
		return(m_pClockwiseFacet);
	}
	
	/**
	 *	Get the next lath clockwise about the vertex.
	 *	Get a pointer to the next lath in a clockwise direction about the
	 *	associated vertex. This information is inherent in the data structure.
	 *
	 *	@return	Pointer to the lath.
	 */
	public CqLath cv()
	{
		// Inherent in the data strucure.
		return(m_pClockwiseVertex);
	}
	
	/**
	 *	Get the edge companion lath.
	 *	Get a pointer to the lath which represents the same edge but in the
	 *	opposite direction, i.e. refers to the opposite vertex.
	 *
	 *	@return	Pointer to the lath.
	 */
	public CqLath ec()
	{
		// If the associated edge is boundary there is no companion.
		assert(null != cf());
		if(null != cv())
			return(cv().cf());
		else
			return(null);
	}
	
	/**
	 *	Get the lath counter clockwise about the vertex.
	 *	Get a pointer to the next lath in a counter clockwise direction about the
	 *	associated vertex. This function is constant in all cases.
	 *
	 *	@return	Pointer to the lath.
	 */
	public CqLath ccv()
	{
		// If the associated edge is boundary, we will need to search backwards.
		assert(null != cf());
		if(null != cf().ec())
			return(cf().ec());
		else
			return(null);
	}
	
	/**
	 *	Get the lath counter clockwise about the facet.
	 *	Get a pointer to the next lath in a counter clockwise direction about the
	 *	associated facet. This function is constant in all cases excepth where the
	 *	associated edge is a boundary edge, in which case it is linear in the
	 *	number of edges in the associated facet.
	 *
	 *	@return	Pointer to the lath.
	 */
	public CqLath ccf()
	{
		// If the associated edge is boundary, we will need to search backwards.
		if(null != ec() && null != ec().cv())
			return(ec().cv());
		else
			return ccfBoundary();
	}
	
	// Data access primitives
	
	/**
	 *	Get the faces surrounding an edge.
	 *	Get a list of laths representing the faces surrounding an edge, will
	 *	return just one if the edge is a boundary.
	 *
	 *	@return	Pointer to an array of lath pointers.
	 */
	public void Qef(Vector<CqLath> Result)
	{
		Result.setSize(null != ec()? 2 : 1);
		// Laths representing the two faces bounding an edge are given by L and L.ec(). If edge
		// is a boundary, only L is passed back.
		CqLath pTmpLath = this;
		Result.set( 0, pTmpLath );
		
		if(null != ec())
			Result.set( 1, ec() );
	}
	
	
	/**
	 *	Get the vertices surounding an edge.
	 *	Get a list of laths representing the vertices making up an edge.
	 *
	 *	@return	Pointer to an array of lath pointers.
	 */
	public void Qev(Vector<CqLath> Result)
	{
		Result.setSize(2);
		// Laths representing the two vertices of the associated edge are given by
		// L and L.ccf(). Note we use cf here because itis guarunteed, whereas ec is not.
		CqLath pTmpLath = this;
		Result.set( 0, pTmpLath );
		Result.set( 1, ccf() );
	}
	
	
	/**
	 *	Get the vertices surrounding a facet.
	 *	Get a list of laths representing the vertices which make up the facet this
	 *	lath represents.
	 *
	 *	@return	Pointer to an array of lath pointers.
	 */
	public void Qfv(Vector<CqLath> Result)
	{
		Qfe(Result);
	}
	
	/**
	 *	Get the edges surrounding a facet.
	 *	Get a list of laths representing the esges making up a facet.
	 *
	 *	@return	Pointer to an array of lath pointers.
	 */
	public void Qfe(Vector<CqLath> Result)
	{
		int len = 1;
		CqLath pNext = cf();
		CqLath pNexta = pNext;
		while(this != pNext)
		{
			assert(null != pNext);
			len++;
			pNext = pNext.cf();
		}
		
		Result.setSize(len);
		// Laths representing the edges of the associated facet are obtained by following
		// clockwise links around the face.
		CqLath pTmpLath = this;
		Result.set( 0, pTmpLath );
		
		int index = 1;
		while(this != pNexta)
		{
			Result.set( index++, pNexta );
			pNexta = pNexta.cf();
		}
	}
	
	
	/**
	 *	Get the edges emanating from a vertex.
	 *	Get a list of laths representing the edges which emanate from the vertex
	 *	this lath represents.
	 *
	 *	@return	Pointer to an array of lath pointers.
	 */
	public void Qve(Vector<CqLath> Result)
	{
		int len = cQve();
		
		CqLath pNext = cv();
		CqLath pLast = this;
		
		Result.setSize(len);
		int index = 0;
		// Laths representing the edges that radiate from the associated vertex are obtained by
		// following the clockwise vertex links around the vertex.
		CqLath pTmpLath = this;
		Result.set( index++, pTmpLath );
		
		while(null != pNext && this != pNext)
		{
			Result.set( index++, pNext );
			pLast = pNext;
			pNext = pNext.cv();
		}
		
		// If we hit a boundary, add the ec of this boundary edge and start again going backwards.
		// @warning Adding ccf for the boundary edge means that the lath represents a different vertex.
		if(null == pNext)
		{
			pLast = this;
			pNext = ccv();
			// We know we are going to hit a boundary in this direction as well so we can just look for that
			// case as a terminator.
			while(null != pNext)
			{
				Result.set( index++, pNext );
				pLast = pNext;
				pNext = pNext.ccv();
			}
			// We have hit the boundary going the other way, so add the ccf of this boundary edge.
			Result.set( index++, pLast.cf() );
		}
	}
	
	
	
	/**
	 *	Get the vertices emanating from this vertex.
	 *	Get a list of laths representing the vertices emanating from the vertex
	 *	this lath represents.
	 *
	 *	@return	Pointer to an array of lath pointers.
	 */
	public void Qvv(Vector<CqLath> Result)
	{
		Qve(Result);
		
		// We can get the laths for the vertices surrounding a vertex by getting the cf() for each
		// lath in Qev. Note we must check first if the lath in Qve represents the same vertex as this
		// as if there is a boundary case, the lath on the clockwise boundary will already point to the
		// opposite vertex.
		CqLath iLath;
		for( int i=0; i<Result.size(); i++ )
		{
			iLath = Result.elementAt( i );
			
			if((iLath).VertexIndex() == VertexIndex())
				Result.setElementAt( (iLath).ccf(), i );
//				(iLath) = (iLath).ccf();
		}
	}
	
	
	/**
	 *	Get the facets which share this vertex.
	 *	Get a list of laths which represent the facets which share the vertex this
	 *	lath represents.
	 *
	 *	@return	Pointer to an array of lath pointers.
	 */
	public void Qvf(Vector<CqLath> Result)
	{
		int len = cQvf();
		
		CqLath pNext = cv();
		
		Result.setSize(len);
		int index = 0;
		
		// Laths representing the edges that radiate from the associated vertex are obtained by
		// following the clockwise vertex links around the vertex.
		CqLath pTmpLath = this;
		Result.set( index++, pTmpLath );
		
		while(null != pNext && this != pNext)
		{
			Result.set( index++, pNext );
			pNext = pNext.cv();
		}
		
		// If we hit a boundary, start again going backwards.
		if(null == pNext)
		{
			pNext = ccv();
			// We know we are going to hit a boundary in this direction as well so we can just look for that
			// case as a terminator.
			while(null != pNext)
			{
				Result.set( index++, pNext );
				pNext = pNext.ccv();
			}
		}
	}
	
	
	/**
	 *	Get the edges emanating from this edge.
	 *	Get a list of laths which represent the edges which share a vertex with
	 *	the edge this lath represents.
	 *
	 *	@return	Pointer to an array of lath pointers.
	 */
	public void Qee(Vector<CqLath> Result)
	{
		Result.clear();
		Vector<CqLath> ResQve1 = new Vector<CqLath>();
		Qve(ResQve1);
		Vector<CqLath> ResQve2 = new Vector<CqLath>();
		ccf().Qve(ResQve2);
		
		// The laths representing the edges radiating from the two vertices of the edge this lath represents
		// can be implemented by taking the union of Qve for this and cf() and removing the duplicate cf() if
		// it exists.
//		Result.swap(ResQve1);
//		Vector<CqLath> tmp = new Vector<CqLath>( Result );//FindBugs 2006/03/10
		Result.addAll( ResQve1 );		//事前にclearしているのでAddAllでよいでしょう
//		ResQve1 = new Vector<CqLath>( tmp );//FindBugs 2006/03/10
//		tmp.clear(); //FindBugs 2006/03/10
		
		//Result.insert(Result.end(), ResQve1.begin(), ResQve1.end());
		
//		Vector<CqLath>::iterator iLath;
		int len2 = 0;
		for( CqLath iLath : ResQve2 )
		{
			if(ec() != iLath && this != iLath)
				len2++;
		}
		
		int index = Result.size();
		Result.setSize( Result.size() + len2 );
		for( CqLath iLath : ResQve2 )
		{
			if(ec() != iLath && this != iLath)
				Result.set( index++, iLath );
		}
	}
	
	
	/**
	 *	Get the facets which surround this facet.
	 *	Get a list of laths which represent the faces which share either a vertex
	 *	or an edge with the facet this lath represents.
	 *
	 *	@return	Pointer to an array of lath pointers.
	 */
	public void Qff(Vector<CqLath> Result)
	{
		Vector<CqLath> ResQfe = new Vector<CqLath>();
		Qfe(ResQfe);
		
		// The laths representing the edges radiating from the two vertices of the edge this lath represents
		// can be implemented by taking the union of Qve for this and cf() and removing the duplicate ec() if
		// it exists.
//		Vector<CqLath>::iterator iLath;
		int len = 0;
		for( CqLath iLath : ResQfe )
			len += iLath.cQve();
		
//		Result.setSize(0);
//		Result.reserve(len);
//		int index = 0;
		
		for(CqLath iLath : ResQfe)
		{
			Vector<CqLath> ResQev = new Vector<CqLath>();
			iLath.Qve(ResQev);
//			Vector<CqLath>::iterator iEdge;
			for(CqLath iEdge : ResQev)
			{
				CqLath pNew = iEdge;
				// Search for the new candidate by traversing the cf lists for all laths currrently in the
				// result list.
				boolean fValid = true;
//				Vector<CqLath>::iterator iCurr;
				for(CqLath iCurr : Result)
				{
					CqLath pVisited = iCurr;
					CqLath pStart = pVisited;
					do
					{
						if(pVisited == pNew)
						{
							fValid=false;
							break;
						}
						pVisited = pVisited.cf();
					}while(pVisited != pStart);
				}
				if(fValid)	Result.add(pNew);
			}
		}
	}
	
	
	/**
	 *	Get the number of vertices surrounding a facet.
	 *	Get a count of laths representing the vertices which make up the facet this
	 *	lath represents.
	 *
	 *	@return	Count of laths.
	 */
	public int cQfv()
	{
		// Laths representing the edges of the associated facet are obtained by following
		// clockwise links around the face.
		int c = 1;	// Start with this one.
		
		CqLath pNext = cf();
		while(this != pNext)
		{
			assert(null != pNext);
			c++;
			pNext = pNext.cf();
		}
		return( c );
	}
	
	
	/**
	 *	Get the number of vertices emanating from this vertex.
	 *	Get a count of laths representing the vertices emanating from the vertex
	 *	this lath represents.
	 *
	 *	@return	Count of laths.
	 */
	public int cQvv()
	{
		int c = 1; // Start with this
		// Laths representing the edges that radiate from the associated vertex are obtained by
		// following the clockwise vertex links around the vertex.
		CqLath pNext = cv();
//		CqLath pLast = this;	//読み取られていなかった
		while(null != pNext && this != pNext)
		{
			c++;
//			pLast = pNext;
			pNext = pNext.cv();
		}
		
		// If we hit a boundary, add the ec of this boundary edge and start again going backwards.
		// @warning Adding ccf for the boundary edge means that the lath represents a different vertex.
		if(null == pNext)
		{
//			pLast = this;
			pNext = ccv();
			// We know we are going to hit a boundary in this direction as well so we can just look for that
			// case as a terminator.
			while(null != pNext)
			{
				assert( pNext != this );
				c++;
//				pLast = pNext;
				pNext = pNext.ccv();
			}
			// We have hit the boundary going the other way, so add the ccf of this boundary edge.
			c++;
		}
		return( c );
	}
	
	
//	------------------------------------------------------------------------------
	/**
	 *	Get the edges emanating from a vertex.
	 *	Get a list of laths representing the edges which emanate from the vertex
	 *	this lath represents.
	 *
	 *	@return	Pointer to an array of lath pointers.
	 */
	public int cQve()
	{
		int len = 1;
		
		CqLath pNext = cv();
//		CqLath pLast = this;	//読み取られていなかった
		while(null != pNext && this != pNext)
		{
			len++;
//			pLast = pNext;
			pNext = pNext.cv();
		}
		
		// If we hit a boundary, add the ec of this boundary edge and start again going backwards.
		// @warning Adding ccf for the boundary edge means that the lath represents a different vertex.
		if(null == pNext)
		{
//			pLast = this;
			pNext = ccv();
			// We know we are going to hit a boundary in this direction as well so we can just look for that
			// case as a terminator.
			while(null != pNext)
			{
				assert( pNext != this );
				len++;
//				pLast = pNext;
				pNext = pNext.ccv();
			}
			// We have hit the boundary going the other way, so add the ccf of this boundary edge.
			len++;
		}
		return(len);
	}
	
	
//	------------------------------------------------------------------------------
	/**
	 *	Get the count of facets which share this vertex.
	 *	Get a count of laths which represent the facets which share the vertex this
	 *	lath represents.
	 *
	 *	@return	Pointer to an array of lath pointers.
	 */
	public int cQvf()
	{
		int len = 1;
		
		CqLath pNext = cv();
		while(null != pNext && this != pNext)
		{
			len++;
			pNext = pNext.cv();
		}
		
		// If we hit a boundary, start again going backwards.
		if(null == pNext)
		{
			pNext = ccv();
			// We know we are going to hit a boundary in this direction as well so we can just look for that
			// case as a terminator.
			while(null != pNext)
			{
				len++;
				pNext = pNext.ccv();
			}
		}
		return(len);
	}
	
	public  boolean isBoundaryFacet()
	{
		// Check if any of the vertices are boundary, if so then this facet must be.
		Vector<CqLath> aQfv = new Vector<CqLath>();
		Qfv(aQfv);
//		Vector<CqLath>::iterator iVert;
		for( CqLath iVert  : aQfv )
			if( iVert.isBoundaryVertex() )
				return( true );
		return( false );
	}
	
	public boolean isBoundaryEdge()
	{
		// If this edge has no companion it must be boundary.
		if( null == ec() )
			return( true );
		return( false );
	}
	
	public boolean isBoundaryVertex()
	{
		// Check if the ccv loop is closed, if not must be boundary.
		CqLath pNext = ccv();
		while( pNext != this )
		{
			if( null == pNext )
				return( true );
			pNext = pNext.ccv();
		}
		return( false );
	}
	
//	///	Declared private to prevent copying.
//	private CqLath(final CqLath From){}
//	
//	///	Declared private to prevent copying.
//	private CqLath assignment(final CqLath From){
//		return null;
//	}
	
	/**
	 *	Get the lath counter clockwise about the facet.
	 *	Get a pointer to the next lath in a counter clockwise direction about the
	 *	associated facet, where the associated edge is a boundary edge.
	 *	@return	Pointer to the lath.
	 */
	private CqLath ccfBoundary()
	{
//		The associated edge is boundary, we will need to search backwards.
		CqLath pLdash=cf();
		while(true)
		{
			CqLath temp = pLdash.cf();
			if(this == temp || null == temp)
				break;
			pLdash=temp;
		}
//		while(this != pLdash.cf() && null != pLdash.cf())
//		pLdash=pLdash.cf();
		assert(this == pLdash.cf());
		return(pLdash);
	}
	
	private CqLath	m_pClockwiseVertex;
	private CqLath	m_pClockwiseFacet;
	
	// Hierarchical subdivision data
	private CqLath m_pParentFacet;		///< Pointer to the facet that was subdivided to produce this one.
	private CqLath m_pChildVertex;		///< Pointer to the child point that represents this point at the next level.
	private CqLath	m_pMidVertex;		///< Pointer to the point that represents the midpoint of this edge at the next level.
	private CqLath	m_pFaceVertex;		///< Pointer to the point that represents the midpoint of this face at the next level.
	
	private int	m_VertexIndex;
	private int	m_FaceVertexIndex;
	
}
