/**************************************************************
 *
 * 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_basegfx.hxx"
#include <basegfx/polygon/b2dpolygoncutandtouch.hxx>
#include <osl/diagnose.h>
#include <basegfx/numeric/ftools.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/vector/b2dvector.hxx>
#include <basegfx/range/b2drange.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/curve/b2dcubicbezier.hxx>

#include <vector>
#include <algorithm>

//////////////////////////////////////////////////////////////////////////////
// defines

#define	SUBDIVIDE_FOR_CUT_TEST_COUNT		(50)

//////////////////////////////////////////////////////////////////////////////

namespace basegfx
{
	namespace
	{
		////////////////////////////////////////////////////////////////////////////////

		class temporaryPoint
		{
			B2DPoint							maPoint;		// the new point
			sal_uInt32							mnIndex;		// index after which to insert
			double								mfCut;			// parametric cut description [0.0 .. 1.0]

		public:
			temporaryPoint(const B2DPoint& rNewPoint, sal_uInt32 nIndex, double fCut)
			:	maPoint(rNewPoint),
				mnIndex(nIndex),
				mfCut(fCut)
			{
			}

			bool operator<(const temporaryPoint& rComp) const
			{
				if(mnIndex == rComp.mnIndex)
				{
					return (mfCut < rComp.mfCut);
				}

				return (mnIndex < rComp.mnIndex);
			}

			const B2DPoint& getPoint() const { return maPoint; }
			sal_uInt32 getIndex() const { return mnIndex; }
			double getCut() const { return mfCut; }
		};

		////////////////////////////////////////////////////////////////////////////////

		typedef ::std::vector< temporaryPoint > temporaryPointVector;

		////////////////////////////////////////////////////////////////////////////////

		class temporaryPolygonData
		{
			B2DPolygon								maPolygon;
			B2DRange								maRange;
			temporaryPointVector					maPoints;

		public:
			const B2DPolygon& getPolygon() const { return maPolygon; }
			void setPolygon(const B2DPolygon& rNew) { maPolygon = rNew; maRange = tools::getRange(maPolygon); }
			const B2DRange& getRange() const { return maRange; }
			temporaryPointVector& getTemporaryPointVector() { return maPoints; }
		};

		////////////////////////////////////////////////////////////////////////////////

		B2DPolygon mergeTemporaryPointsAndPolygon(const B2DPolygon& rCandidate, temporaryPointVector& rTempPoints)
		{
			// #i76891# mergeTemporaryPointsAndPolygon redesigned to be able to correctly handle
			// single edges with/without control points
			// #i101491# added counter for non-changing element count
			const sal_uInt32 nTempPointCount(rTempPoints.size());

			if(nTempPointCount)
			{
				B2DPolygon aRetval;
				const sal_uInt32 nCount(rCandidate.count());

				if(nCount)
				{
					// sort temp points to assure increasing fCut values and increasing indices
					::std::sort(rTempPoints.begin(), rTempPoints.end());

					// prepare loop
                    B2DCubicBezier aEdge;
					sal_uInt32 nNewInd(0L);

					// add start point
					aRetval.append(rCandidate.getB2DPoint(0));

					for(sal_uInt32 a(0L); a < nCount; a++)
					{
						// get edge
                        rCandidate.getBezierSegment(a, aEdge);

						if(aEdge.isBezier())
						{
							// control vectors involved for this edge
							double fLeftStart(0.0);

							// now add all points targeted to be at this index
							while(nNewInd < nTempPointCount && rTempPoints[nNewInd].getIndex() == a)
							{
								const temporaryPoint& rTempPoint = rTempPoints[nNewInd++];

								// split curve segment. Splits need to come sorted and need to be < 1.0. Also,
								// since original segment is consumed from left to right, the cut values need
								// to be scaled to the remaining part
								B2DCubicBezier aLeftPart;
								const double fRelativeSplitPoint((rTempPoint.getCut() - fLeftStart) / (1.0 - fLeftStart));
								aEdge.split(fRelativeSplitPoint, &aLeftPart, &aEdge);
								fLeftStart = rTempPoint.getCut();

								// add left bow
								aRetval.appendBezierSegment(aLeftPart.getControlPointA(), aLeftPart.getControlPointB(), rTempPoint.getPoint());
							}

							// add remaining bow
							aRetval.appendBezierSegment(aEdge.getControlPointA(), aEdge.getControlPointB(), aEdge.getEndPoint());
						}
						else
						{
							// add all points targeted to be at this index
							while(nNewInd < nTempPointCount && rTempPoints[nNewInd].getIndex() == a)
							{
								const temporaryPoint& rTempPoint = rTempPoints[nNewInd++];
								const B2DPoint aNewPoint(rTempPoint.getPoint());

								// do not add points double
								if(!aRetval.getB2DPoint(aRetval.count() - 1L).equal(aNewPoint))
								{
									aRetval.append(aNewPoint);
								}
							}

							// add edge end point
							aRetval.append(aEdge.getEndPoint());
						}
					}
				}

				if(rCandidate.isClosed())
				{
					// set closed flag and correct last point (which is added double now).
                    tools::closeWithGeometryChange(aRetval);
				}

				return aRetval;
			}
			else
			{
				return rCandidate;
			}
		}

		////////////////////////////////////////////////////////////////////////////////

		void adaptAndTransferCutsWithBezierSegment(
			const temporaryPointVector& rPointVector, const B2DPolygon& rPolygon,
			sal_uInt32 nInd, temporaryPointVector& rTempPoints)
		{
			// assuming that the subdivision to create rPolygon used aequidistant pieces
			// (as in adaptiveSubdivideByCount) it is now possible to calculate back the
			// cut positions in the polygon to relative cut positions on the original bezier
			// segment.
			const sal_uInt32 nTempPointCount(rPointVector.size());
			const sal_uInt32 nEdgeCount(rPolygon.count() ? rPolygon.count() - 1L : 0L);

			if(nTempPointCount && nEdgeCount)
			{
				for(sal_uInt32 a(0L); a < nTempPointCount; a++)
				{
					const temporaryPoint& rTempPoint = rPointVector[a];
					const double fCutPosInPolygon((double)rTempPoint.getIndex() + rTempPoint.getCut());
					const double fRelativeCutPos(fCutPosInPolygon / (double)nEdgeCount);
					rTempPoints.push_back(temporaryPoint(rTempPoint.getPoint(), nInd, fRelativeCutPos));
				}
			}
		}

		////////////////////////////////////////////////////////////////////////////////

	} // end of anonymous namespace
} // end of namespace basegfx

//////////////////////////////////////////////////////////////////////////////

namespace basegfx
{
	namespace
	{
		////////////////////////////////////////////////////////////////////////////////
		// predefines for calls to this methods before method implementation

		void findCuts(const B2DPolygon& rCandidate, temporaryPointVector& rTempPoints);
		void findTouches(const B2DPolygon& rEdgePolygon, const B2DPolygon& rPointPolygon, temporaryPointVector& rTempPoints);
		void findCuts(const B2DPolygon& rCandidateA, const B2DPolygon& rCandidateB, temporaryPointVector& rTempPointsA, temporaryPointVector& rTempPointsB);

		////////////////////////////////////////////////////////////////////////////////

		void findEdgeCutsTwoEdges(
			const B2DPoint& rCurrA, const B2DPoint& rNextA,
			const B2DPoint& rCurrB, const B2DPoint& rNextB,
			sal_uInt32 nIndA, sal_uInt32 nIndB,
			temporaryPointVector& rTempPointsA, temporaryPointVector& rTempPointsB)
		{
			// no null length edges
			if(!(rCurrA.equal(rNextA) || rCurrB.equal(rNextB)))
			{
				// no common start/end points, this can be no cuts
				if(!(rCurrB.equal(rCurrA) || rCurrB.equal(rNextA) || rNextB.equal(rCurrA) || rNextB.equal(rNextA)))
				{
					const B2DVector aVecA(rNextA - rCurrA);
					const B2DVector aVecB(rNextB - rCurrB);
					double fCut(aVecA.cross(aVecB));

					if(!fTools::equalZero(fCut))
					{
						const double fZero(0.0);
						const double fOne(1.0);
						fCut = (aVecB.getY() * (rCurrB.getX() - rCurrA.getX()) + aVecB.getX() * (rCurrA.getY() - rCurrB.getY())) / fCut;

						if(fTools::more(fCut, fZero) && fTools::less(fCut, fOne))
						{
							// it's a candidate, but also need to test parameter value of cut on line 2
							double fCut2;

							// choose the more precise version
							if(fabs(aVecB.getX()) > fabs(aVecB.getY()))
							{
								fCut2 = (rCurrA.getX() + (fCut * aVecA.getX()) - rCurrB.getX()) / aVecB.getX();
							}
							else
							{
								fCut2 = (rCurrA.getY() + (fCut * aVecA.getY()) - rCurrB.getY()) / aVecB.getY();
							}

							if(fTools::more(fCut2, fZero) && fTools::less(fCut2, fOne))
							{
								// cut is in range, add point. Two edges can have only one cut, but
								// add a cut point to each list. The lists may be the same for
								// self intersections.
								const B2DPoint aCutPoint(interpolate(rCurrA, rNextA, fCut));
								rTempPointsA.push_back(temporaryPoint(aCutPoint, nIndA, fCut));
								rTempPointsB.push_back(temporaryPoint(aCutPoint, nIndB, fCut2));
							}
						}
					}
				}
			}
		}

		////////////////////////////////////////////////////////////////////////////////

		void findCutsAndTouchesAndCommonForBezier(const B2DPolygon& rCandidateA, const B2DPolygon& rCandidateB, temporaryPointVector& rTempPointsA, temporaryPointVector& rTempPointsB)
		{
			// #i76891#
			// This new method is necessary since in findEdgeCutsBezierAndEdge and in findEdgeCutsTwoBeziers
			// it is not sufficient to use findCuts() recursively. This will indeed find the cuts between the
			// segments of the two temporarily adaptive subdivided bezier segments, but not the touches or
			// equal points of them.
			// It would be possible to find the toches using findTouches(), but at last with commpn points
			// the adding of cut points (temporary points) would fail. But for these temporarily adaptive
			// subdivided bezier segments, common points may be not very likely, but the bug shows that it
			// happens.
			// Touch points are a little bit more likely than common points. All in all it is best to use
			// a specialized method here which can profit from knowing that it is working on a special
			// family of B2DPolygons: no curve segments included and not closed.
			OSL_ENSURE(!rCandidateA.areControlPointsUsed() && !rCandidateB.areControlPointsUsed(), "findCutsAndTouchesAndCommonForBezier only works with subdivided polygons (!)");
			OSL_ENSURE(!rCandidateA.isClosed() && !rCandidateB.isClosed(), "findCutsAndTouchesAndCommonForBezier only works with opened polygons (!)");
			const sal_uInt32 nPointCountA(rCandidateA.count());
			const sal_uInt32 nPointCountB(rCandidateB.count());

			if(nPointCountA > 1 && nPointCountB > 1)
			{
				const sal_uInt32 nEdgeCountA(nPointCountA - 1);
				const sal_uInt32 nEdgeCountB(nPointCountB - 1);
				B2DPoint aCurrA(rCandidateA.getB2DPoint(0L));

				for(sal_uInt32 a(0L); a < nEdgeCountA; a++)
				{
					const B2DPoint aNextA(rCandidateA.getB2DPoint(a + 1L));
					const B2DRange aRangeA(aCurrA, aNextA);
					B2DPoint aCurrB(rCandidateB.getB2DPoint(0L));

					for(sal_uInt32 b(0L); b < nEdgeCountB; b++)
					{
						const B2DPoint aNextB(rCandidateB.getB2DPoint(b + 1L));
						const B2DRange aRangeB(aCurrB, aNextB);

						if(aRangeA.overlaps(aRangeB))
						{
							// no null length edges
							if(!(aCurrA.equal(aNextA) || aCurrB.equal(aNextB)))
							{
								const B2DVector aVecA(aNextA - aCurrA);
								const B2DVector aVecB(aNextB - aCurrB);
								double fCutA(aVecA.cross(aVecB));

								if(!fTools::equalZero(fCutA))
								{
									const double fZero(0.0);
									const double fOne(1.0);
									fCutA = (aVecB.getY() * (aCurrB.getX() - aCurrA.getX()) + aVecB.getX() * (aCurrA.getY() - aCurrB.getY())) / fCutA;

									// use range [0.0 .. 1.0[, thus in the loop, all direct aCurrA cuts will be registered
									// as 0.0 cut. The 1.0 cut will be registered in the next loop step
									if(fTools::moreOrEqual(fCutA, fZero) && fTools::less(fCutA, fOne))
									{
										// it's a candidate, but also need to test parameter value of cut on line 2
										double fCutB;

										// choose the more precise version
										if(fabs(aVecB.getX()) > fabs(aVecB.getY()))
										{
											fCutB = (aCurrA.getX() + (fCutA * aVecA.getX()) - aCurrB.getX()) / aVecB.getX();
										}
										else
										{
											fCutB = (aCurrA.getY() + (fCutA * aVecA.getY()) - aCurrB.getY()) / aVecB.getY();
										}

										// use range [0.0 .. 1.0[, thus in the loop, all direct aCurrA cuts will be registered
										// as 0.0 cut. The 1.0 cut will be registered in the next loop step
										if(fTools::moreOrEqual(fCutB, fZero) && fTools::less(fCutB, fOne))
										{
											// cut is in both ranges. Add points for A and B
                                            // #i111715# use fTools::equal instead of fTools::equalZero for better accuracy
											if(fTools::equal(fCutA, fZero))
											{
												// ignore for start point in first edge; this is handled
												// by outer methods and would just produce a double point
												if(a)
												{
													rTempPointsA.push_back(temporaryPoint(aCurrA, a, 0.0));
												}
											}
											else
											{
												const B2DPoint aCutPoint(interpolate(aCurrA, aNextA, fCutA));
												rTempPointsA.push_back(temporaryPoint(aCutPoint, a, fCutA));
											}

                                            // #i111715# use fTools::equal instead of fTools::equalZero for better accuracy
											if(fTools::equal(fCutB, fZero))
											{
												// ignore for start point in first edge; this is handled
												// by outer methods and would just produce a double point
												if(b)
												{
													rTempPointsB.push_back(temporaryPoint(aCurrB, b, 0.0));
												}
											}
											else
											{
												const B2DPoint aCutPoint(interpolate(aCurrB, aNextB, fCutB));
												rTempPointsB.push_back(temporaryPoint(aCutPoint, b, fCutB));
											}
										}
									}
								}
							}
						}

						// prepare next step
						aCurrB = aNextB;
					}

					// prepare next step
					aCurrA = aNextA;
				}
			}
		}

		////////////////////////////////////////////////////////////////////////////////

		void findEdgeCutsBezierAndEdge(
			const B2DCubicBezier& rCubicA,
			const B2DPoint& rCurrB, const B2DPoint& rNextB,
			sal_uInt32 nIndA, sal_uInt32 nIndB,
			temporaryPointVector& rTempPointsA, temporaryPointVector& rTempPointsB)
		{
			// find all cuts between given bezier segment and edge. Add an entry to the tempPoints
			// for each common point with the cut value describing the relative position on given
			// bezier segment and edge.
			B2DPolygon aTempPolygonA;
			B2DPolygon aTempPolygonEdge;
			temporaryPointVector aTempPointVectorA;
			temporaryPointVector aTempPointVectorEdge;

			// create subdivided polygons and find cuts between them
            // Keep adaptiveSubdivideByCount due to needed quality
			aTempPolygonA.reserve(SUBDIVIDE_FOR_CUT_TEST_COUNT + 8);
			aTempPolygonA.append(rCubicA.getStartPoint());
			rCubicA.adaptiveSubdivideByCount(aTempPolygonA, SUBDIVIDE_FOR_CUT_TEST_COUNT);
			aTempPolygonEdge.append(rCurrB);
			aTempPolygonEdge.append(rNextB);

			// #i76891# using findCuts recursively is not sufficient here
			findCutsAndTouchesAndCommonForBezier(aTempPolygonA, aTempPolygonEdge, aTempPointVectorA, aTempPointVectorEdge);

			if(aTempPointVectorA.size())
			{
				// adapt tempVector entries to segment
				adaptAndTransferCutsWithBezierSegment(aTempPointVectorA, aTempPolygonA, nIndA, rTempPointsA);
			}

			// append remapped tempVector entries for edge to tempPoints for edge
			for(sal_uInt32 a(0L); a < aTempPointVectorEdge.size(); a++)
			{
				const temporaryPoint& rTempPoint = aTempPointVectorEdge[a];
				rTempPointsB.push_back(temporaryPoint(rTempPoint.getPoint(), nIndB, rTempPoint.getCut()));
			}
		}

		////////////////////////////////////////////////////////////////////////////////

		void findEdgeCutsTwoBeziers(
			const B2DCubicBezier& rCubicA,
			const B2DCubicBezier& rCubicB,
			sal_uInt32 nIndA, sal_uInt32 nIndB,
			temporaryPointVector& rTempPointsA, temporaryPointVector& rTempPointsB)
		{
			// find all cuts between the two given bezier segments. Add an entry to the tempPoints
			// for each common point with the cut value describing the relative position on given
			// bezier segments.
			B2DPolygon aTempPolygonA;
			B2DPolygon aTempPolygonB;
			temporaryPointVector aTempPointVectorA;
			temporaryPointVector aTempPointVectorB;

			// create subdivided polygons and find cuts between them
            // Keep adaptiveSubdivideByCount due to needed quality
			aTempPolygonA.reserve(SUBDIVIDE_FOR_CUT_TEST_COUNT + 8);
			aTempPolygonA.append(rCubicA.getStartPoint());
			rCubicA.adaptiveSubdivideByCount(aTempPolygonA, SUBDIVIDE_FOR_CUT_TEST_COUNT);
			aTempPolygonB.reserve(SUBDIVIDE_FOR_CUT_TEST_COUNT + 8);
			aTempPolygonB.append(rCubicB.getStartPoint());
			rCubicB.adaptiveSubdivideByCount(aTempPolygonB, SUBDIVIDE_FOR_CUT_TEST_COUNT);

			// #i76891# using findCuts recursively is not sufficient here
			findCutsAndTouchesAndCommonForBezier(aTempPolygonA, aTempPolygonB, aTempPointVectorA, aTempPointVectorB);

			if(aTempPointVectorA.size())
			{
				// adapt tempVector entries to segment
				adaptAndTransferCutsWithBezierSegment(aTempPointVectorA, aTempPolygonA, nIndA, rTempPointsA);
			}

			if(aTempPointVectorB.size())
			{
				// adapt tempVector entries to segment
				adaptAndTransferCutsWithBezierSegment(aTempPointVectorB, aTempPolygonB, nIndB, rTempPointsB);
			}
		}

		////////////////////////////////////////////////////////////////////////////////

		void findEdgeCutsOneBezier(
			const B2DCubicBezier& rCubicA,
			sal_uInt32 nInd, temporaryPointVector& rTempPoints)
		{
			// avoid expensive part of this method if possible
			// TODO: use hasAnyExtremum() method instead when it becomes available
			double fDummy;
			const bool bHasAnyExtremum = rCubicA.getMinimumExtremumPosition( fDummy );
			if( !bHasAnyExtremum )
				return;

			// find all self-intersections on the given bezier segment. Add an entry to the tempPoints
			// for each self intersection point with the cut value describing the relative position on given
			// bezier segment.
			B2DPolygon aTempPolygon;
			temporaryPointVector aTempPointVector;

			// create subdivided polygon and find cuts on it
            // Keep adaptiveSubdivideByCount due to needed quality
			aTempPolygon.reserve(SUBDIVIDE_FOR_CUT_TEST_COUNT + 8);
			aTempPolygon.append(rCubicA.getStartPoint());
			rCubicA.adaptiveSubdivideByCount(aTempPolygon, SUBDIVIDE_FOR_CUT_TEST_COUNT);
			findCuts(aTempPolygon, aTempPointVector);

			if(aTempPointVector.size())
			{
				// adapt tempVector entries to segment
				adaptAndTransferCutsWithBezierSegment(aTempPointVector, aTempPolygon, nInd, rTempPoints);
			}
		}

		////////////////////////////////////////////////////////////////////////////////

		void findCuts(const B2DPolygon& rCandidate, temporaryPointVector& rTempPoints)
		{
			// find out if there are edges with intersections (self-cuts). If yes, add
			// entries to rTempPoints accordingly
			const sal_uInt32 nPointCount(rCandidate.count());

			if(nPointCount)
			{
				const sal_uInt32 nEdgeCount(rCandidate.isClosed() ? nPointCount : nPointCount - 1L);

				if(nEdgeCount)
				{
					const bool bCurvesInvolved(rCandidate.areControlPointsUsed());

					if(bCurvesInvolved)
					{
                        B2DCubicBezier aCubicA;
                        B2DCubicBezier aCubicB;

						for(sal_uInt32 a(0L); a < nEdgeCount - 1L; a++)
						{
                            rCandidate.getBezierSegment(a, aCubicA);
							aCubicA.testAndSolveTrivialBezier();
							const bool bEdgeAIsCurve(aCubicA.isBezier());
							const B2DRange aRangeA(aCubicA.getRange());

							if(bEdgeAIsCurve)
							{
								// curved segments may have self-intersections, do not forget those (!)
								findEdgeCutsOneBezier(aCubicA, a, rTempPoints);
							}

							for(sal_uInt32 b(a + 1L); b < nEdgeCount; b++)
							{
                                rCandidate.getBezierSegment(b, aCubicB);
								aCubicB.testAndSolveTrivialBezier();
								const bool bEdgeBIsCurve(aCubicB.isBezier());
								const B2DRange aRangeB(aCubicB.getRange());

								// only overlapping segments need to be tested
								// consecutive segments touch of course
								bool bOverlap = false;
								if( b > a+1)
									bOverlap = aRangeA.overlaps(aRangeB);
								else
									bOverlap = aRangeA.overlapsMore(aRangeB);
								if( bOverlap)
								{
									if(bEdgeAIsCurve && bEdgeBIsCurve)
									{
										// test for bezier-bezier cuts
										findEdgeCutsTwoBeziers(aCubicA, aCubicB, a, b, rTempPoints, rTempPoints);
									}
									else if(bEdgeAIsCurve)
									{
										// test for bezier-edge cuts
										findEdgeCutsBezierAndEdge(aCubicA, aCubicB.getStartPoint(), aCubicB.getEndPoint(), a, b, rTempPoints, rTempPoints);
									}
									else if(bEdgeBIsCurve)
									{
										// test for bezier-edge cuts
										findEdgeCutsBezierAndEdge(aCubicB, aCubicA.getStartPoint(), aCubicA.getEndPoint(), b, a, rTempPoints, rTempPoints);
									}
									else
									{
										// test for simple edge-edge cuts
										findEdgeCutsTwoEdges(aCubicA.getStartPoint(), aCubicA.getEndPoint(), aCubicB.getStartPoint(), aCubicB.getEndPoint(),
											a, b, rTempPoints, rTempPoints);
									}
								}
							}
						}
					}
					else
					{
						B2DPoint aCurrA(rCandidate.getB2DPoint(0L));

						for(sal_uInt32 a(0L); a < nEdgeCount - 1L; a++)
						{
							const B2DPoint aNextA(rCandidate.getB2DPoint(a + 1L == nPointCount ? 0L : a + 1L));
							const B2DRange aRangeA(aCurrA, aNextA);
							B2DPoint aCurrB(rCandidate.getB2DPoint(a + 1L));

							for(sal_uInt32 b(a + 1L); b < nEdgeCount; b++)
							{
								const B2DPoint aNextB(rCandidate.getB2DPoint(b + 1L == nPointCount ? 0L : b + 1L));
								const B2DRange aRangeB(aCurrB, aNextB);

								// consecutive segments touch of course
								bool bOverlap = false;
								if( b > a+1)
									bOverlap = aRangeA.overlaps(aRangeB);
								else
									bOverlap = aRangeA.overlapsMore(aRangeB);
								if( bOverlap)
								{
									findEdgeCutsTwoEdges(aCurrA, aNextA, aCurrB, aNextB, a, b, rTempPoints, rTempPoints);
								}

								// prepare next step
								aCurrB = aNextB;
							}

							// prepare next step
							aCurrA = aNextA;
						}
					}
				}
			}
		}

		////////////////////////////////////////////////////////////////////////////////

	} // end of anonymous namespace
} // end of namespace basegfx

//////////////////////////////////////////////////////////////////////////////

namespace basegfx
{
	namespace
	{
		////////////////////////////////////////////////////////////////////////////////

		void findTouchesOnEdge(
			const B2DPoint& rCurr, const B2DPoint& rNext, const B2DPolygon& rPointPolygon,
			sal_uInt32 nInd, temporaryPointVector& rTempPoints)
		{
			// find out if points from rPointPolygon are positioned on given edge. If Yes, add
			// points there to represent touches (which may be enter or leave nodes later).
			const sal_uInt32 nPointCount(rPointPolygon.count());

			if(nPointCount)
			{
				const B2DRange aRange(rCurr, rNext);
				const B2DVector aEdgeVector(rNext - rCurr);
				B2DVector aNormalizedEdgeVector(aEdgeVector);
				aNormalizedEdgeVector.normalize();
				bool bTestUsingX(fabs(aEdgeVector.getX()) > fabs(aEdgeVector.getY()));

				for(sal_uInt32 a(0L); a < nPointCount; a++)
				{
					const B2DPoint aTestPoint(rPointPolygon.getB2DPoint(a));

					if(aRange.isInside(aTestPoint))
					{
						if(!aTestPoint.equal(rCurr) && !aTestPoint.equal(rNext))
						{
							const B2DVector aTestVector(aTestPoint - rCurr);

							if(areParallel(aNormalizedEdgeVector, aTestVector))
							{
								const double fCut((bTestUsingX)
									? aTestVector.getX() / aEdgeVector.getX()
									: aTestVector.getY() / aEdgeVector.getY());
								const double fZero(0.0);
								const double fOne(1.0);

								if(fTools::more(fCut, fZero) && fTools::less(fCut, fOne))
								{
									rTempPoints.push_back(temporaryPoint(aTestPoint, nInd, fCut));
								}
							}
						}
					}
				}
			}
		}

		////////////////////////////////////////////////////////////////////////////////

		void findTouchesOnCurve(
			const B2DCubicBezier& rCubicA, const B2DPolygon& rPointPolygon,
			sal_uInt32 nInd, temporaryPointVector& rTempPoints)
		{
			// find all points from rPointPolygon which touch the given bezier segment. Add an entry
			// for each touch to the given pointVector. The cut for that entry is the relative position on
			// the given bezier segment.
			B2DPolygon aTempPolygon;
			temporaryPointVector aTempPointVector;

			// create subdivided polygon and find cuts on it
            // Keep adaptiveSubdivideByCount due to needed quality
			aTempPolygon.reserve(SUBDIVIDE_FOR_CUT_TEST_COUNT + 8);
			aTempPolygon.append(rCubicA.getStartPoint());
			rCubicA.adaptiveSubdivideByCount(aTempPolygon, SUBDIVIDE_FOR_CUT_TEST_COUNT);
			findTouches(aTempPolygon, rPointPolygon, aTempPointVector);

			if(aTempPointVector.size())
			{
				// adapt tempVector entries to segment
				adaptAndTransferCutsWithBezierSegment(aTempPointVector, aTempPolygon, nInd, rTempPoints);
			}
		}

		////////////////////////////////////////////////////////////////////////////////

		void findTouches(const B2DPolygon& rEdgePolygon, const B2DPolygon& rPointPolygon, temporaryPointVector& rTempPoints)
		{
			// find out if points from rPointPolygon touch edges from rEdgePolygon. If yes,
			// add entries to rTempPoints
			const sal_uInt32 nPointCount(rPointPolygon.count());
			const sal_uInt32 nEdgePointCount(rEdgePolygon.count());

			if(nPointCount && nEdgePointCount)
			{
				const sal_uInt32 nEdgeCount(rEdgePolygon.isClosed() ? nEdgePointCount : nEdgePointCount - 1L);
				B2DPoint aCurr(rEdgePolygon.getB2DPoint(0));

				for(sal_uInt32 a(0L); a < nEdgeCount; a++)
				{
					const sal_uInt32 nNextIndex((a + 1) % nEdgePointCount);
					const B2DPoint aNext(rEdgePolygon.getB2DPoint(nNextIndex));

					if(!aCurr.equal(aNext))
					{
						bool bHandleAsSimpleEdge(true);

						if(rEdgePolygon.areControlPointsUsed())
						{
							const B2DPoint aNextControlPoint(rEdgePolygon.getNextControlPoint(a));
							const B2DPoint aPrevControlPoint(rEdgePolygon.getPrevControlPoint(nNextIndex));
							const bool bEdgeIsCurve(!aNextControlPoint.equal(aCurr) || !aPrevControlPoint.equal(aNext));

							if(bEdgeIsCurve)
							{
								bHandleAsSimpleEdge = false;
								const B2DCubicBezier aCubicA(aCurr, aNextControlPoint, aPrevControlPoint, aNext);
								findTouchesOnCurve(aCubicA, rPointPolygon, a, rTempPoints);
							}
						}

						if(bHandleAsSimpleEdge)
						{
							findTouchesOnEdge(aCurr, aNext, rPointPolygon, a, rTempPoints);
						}
					}

					// next step
					aCurr = aNext;
				}
			}
		}

		////////////////////////////////////////////////////////////////////////////////

	} // end of anonymous namespace
} // end of namespace basegfx

//////////////////////////////////////////////////////////////////////////////

namespace basegfx
{
	namespace
	{
		////////////////////////////////////////////////////////////////////////////////

		void findCuts(const B2DPolygon& rCandidateA, const B2DPolygon& rCandidateB, temporaryPointVector& rTempPointsA, temporaryPointVector& rTempPointsB)
		{
			// find out if edges from both polygons cut. If so, add entries to rTempPoints which
			// should be added to the polygons accordingly
			const sal_uInt32 nPointCountA(rCandidateA.count());
			const sal_uInt32 nPointCountB(rCandidateB.count());

			if(nPointCountA && nPointCountB)
			{
				const sal_uInt32 nEdgeCountA(rCandidateA.isClosed() ? nPointCountA : nPointCountA - 1L);
				const sal_uInt32 nEdgeCountB(rCandidateB.isClosed() ? nPointCountB : nPointCountB - 1L);

				if(nEdgeCountA && nEdgeCountB)
				{
					const bool bCurvesInvolved(rCandidateA.areControlPointsUsed() || rCandidateB.areControlPointsUsed());

					if(bCurvesInvolved)
					{
                        B2DCubicBezier aCubicA;
                        B2DCubicBezier aCubicB;

						for(sal_uInt32 a(0L); a < nEdgeCountA; a++)
						{
                            rCandidateA.getBezierSegment(a, aCubicA);
							aCubicA.testAndSolveTrivialBezier();
							const bool bEdgeAIsCurve(aCubicA.isBezier());
							const B2DRange aRangeA(aCubicA.getRange());

							for(sal_uInt32 b(0L); b < nEdgeCountB; b++)
							{
                                rCandidateB.getBezierSegment(b, aCubicB);
								aCubicB.testAndSolveTrivialBezier();
								const bool bEdgeBIsCurve(aCubicB.isBezier());
								const B2DRange aRangeB(aCubicB.getRange());

								// consecutive segments touch of course
								bool bOverlap = false;
								if( b > a+1)
									bOverlap = aRangeA.overlaps(aRangeB);
								else
									bOverlap = aRangeA.overlapsMore(aRangeB);
								if( bOverlap)
								{
									if(bEdgeAIsCurve && bEdgeBIsCurve)
									{
										// test for bezier-bezier cuts
										findEdgeCutsTwoBeziers(aCubicA, aCubicB, a, b, rTempPointsA, rTempPointsB);
									}
									else if(bEdgeAIsCurve)
									{
										// test for bezier-edge cuts
										findEdgeCutsBezierAndEdge(aCubicA, aCubicB.getStartPoint(), aCubicB.getEndPoint(), a, b, rTempPointsA, rTempPointsB);
									}
									else if(bEdgeBIsCurve)
									{
										// test for bezier-edge cuts
										findEdgeCutsBezierAndEdge(aCubicB, aCubicA.getStartPoint(), aCubicA.getEndPoint(), b, a, rTempPointsB, rTempPointsA);
									}
									else
									{
										// test for simple edge-edge cuts
										findEdgeCutsTwoEdges(aCubicA.getStartPoint(), aCubicA.getEndPoint(), aCubicB.getStartPoint(), aCubicB.getEndPoint(),
											a, b, rTempPointsA, rTempPointsB);
									}
								}
							}
						}
					}
					else
					{
						B2DPoint aCurrA(rCandidateA.getB2DPoint(0L));

						for(sal_uInt32 a(0L); a < nEdgeCountA; a++)
						{
							const B2DPoint aNextA(rCandidateA.getB2DPoint(a + 1L == nPointCountA ? 0L : a + 1L));
							const B2DRange aRangeA(aCurrA, aNextA);
							B2DPoint aCurrB(rCandidateB.getB2DPoint(0L));

							for(sal_uInt32 b(0L); b < nEdgeCountB; b++)
							{
								const B2DPoint aNextB(rCandidateB.getB2DPoint(b + 1L == nPointCountB ? 0L : b + 1L));
								const B2DRange aRangeB(aCurrB, aNextB);

								// consecutive segments touch of course
								bool bOverlap = false;
								if( b > a+1)
									bOverlap = aRangeA.overlaps(aRangeB);
								else
									bOverlap = aRangeA.overlapsMore(aRangeB);
								if( bOverlap)
								{
									// test for simple edge-edge cuts
									findEdgeCutsTwoEdges(aCurrA, aNextA, aCurrB, aNextB, a, b, rTempPointsA, rTempPointsB);
								}

								// prepare next step
								aCurrB = aNextB;
							}

							// prepare next step
							aCurrA = aNextA;
						}
					}
				}
			}
		}

		////////////////////////////////////////////////////////////////////////////////

	} // end of anonymous namespace
} // end of namespace basegfx

//////////////////////////////////////////////////////////////////////////////

namespace basegfx
{
	namespace tools
	{
		////////////////////////////////////////////////////////////////////////////////

		B2DPolygon addPointsAtCutsAndTouches(const B2DPolygon& rCandidate)
		{
			if(rCandidate.count())
			{
				temporaryPointVector aTempPoints;

				findTouches(rCandidate, rCandidate, aTempPoints);
				findCuts(rCandidate, aTempPoints);

				return mergeTemporaryPointsAndPolygon(rCandidate, aTempPoints);
			}
			else
			{
				return rCandidate;
			}
		}

		////////////////////////////////////////////////////////////////////////////////

		B2DPolyPolygon addPointsAtCutsAndTouches(const B2DPolyPolygon& rCandidate, bool bSelfIntersections)
		{
			const sal_uInt32 nCount(rCandidate.count());

			if(nCount)
			{
				B2DPolyPolygon aRetval;

				if(1L == nCount)
				{
					if(bSelfIntersections)
					{
						// remove self intersections
						aRetval.append(addPointsAtCutsAndTouches(rCandidate.getB2DPolygon(0L)));
					}
					else
					{
						// copy source
						aRetval = rCandidate;
					}
				}
				else
				{
					// first solve self cuts and self touches for all contained single polygons
					temporaryPolygonData *pTempData = new temporaryPolygonData[nCount];
					sal_uInt32 a, b;

					for(a = 0L; a < nCount; a++)
					{
						if(bSelfIntersections)
						{
							// use polygons with solved self intersections
							pTempData[a].setPolygon(addPointsAtCutsAndTouches(rCandidate.getB2DPolygon(a)));
						}
						else
						{
							// copy given polygons
							pTempData[a].setPolygon(rCandidate.getB2DPolygon(a));
						}
					}

					// now cuts and touches between the polygons
					for(a = 0L; a < nCount; a++)
					{
						for(b = 0L; b < nCount; b++)
						{
							if(a != b)
							{
								// look for touches, compare each edge polygon to all other points
								if(pTempData[a].getRange().overlaps(pTempData[b].getRange()))
								{
									findTouches(pTempData[a].getPolygon(), pTempData[b].getPolygon(), pTempData[a].getTemporaryPointVector());
								}
							}

							if(a < b)
							{
								// look for cuts, compare each edge polygon to following ones
								if(pTempData[a].getRange().overlaps(pTempData[b].getRange()))
								{
									findCuts(pTempData[a].getPolygon(), pTempData[b].getPolygon(), pTempData[a].getTemporaryPointVector(), pTempData[b].getTemporaryPointVector());
								}
							}
						}
					}

					// consolidate the result
					for(a = 0L; a < nCount; a++)
					{
						aRetval.append(mergeTemporaryPointsAndPolygon(pTempData[a].getPolygon(), pTempData[a].getTemporaryPointVector()));
					}

					delete[] pTempData;
				}

				return aRetval;
			}
			else
			{
				return rCandidate;
			}
		}

		////////////////////////////////////////////////////////////////////////////////

		B2DPolygon addPointsAtCutsAndTouches(const B2DPolyPolygon& rMask, const B2DPolygon& rCandidate)
		{
			if(rCandidate.count())
			{
				temporaryPointVector aTempPoints;
				temporaryPointVector aTempPointsUnused;

				for(sal_uInt32 a(0L); a < rMask.count(); a++)
				{
					const B2DPolygon aPartMask(rMask.getB2DPolygon(a));

					findTouches(rCandidate, aPartMask, aTempPoints);
					findCuts(rCandidate, aPartMask, aTempPoints, aTempPointsUnused);
				}

				return mergeTemporaryPointsAndPolygon(rCandidate, aTempPoints);
			}
			else
			{
				return rCandidate;
			}
		}

		////////////////////////////////////////////////////////////////////////////////

		B2DPolyPolygon addPointsAtCutsAndTouches(const B2DPolyPolygon& rMask, const B2DPolyPolygon& rCandidate)
		{
			B2DPolyPolygon aRetval;

			for(sal_uInt32 a(0L); a < rCandidate.count(); a++)
			{
				aRetval.append(addPointsAtCutsAndTouches(rMask, rCandidate.getB2DPolygon(a)));
			}

			return aRetval;
		}

		////////////////////////////////////////////////////////////////////////////////

        B2DPolygon addPointsAtCuts(const B2DPolygon& rCandidate, const B2DPoint& rStart, const B2DPoint& rEnd)
        {
            const sal_uInt32 nCount(rCandidate.count());

            if(nCount && !rStart.equal(rEnd))
            {
                const B2DRange aPolygonRange(rCandidate.getB2DRange());
                const B2DRange aEdgeRange(rStart, rEnd);

                if(aPolygonRange.overlaps(aEdgeRange))
                {
                    const sal_uInt32 nEdgeCount(rCandidate.isClosed() ? nCount : nCount - 1);
				    temporaryPointVector aTempPoints;
				    temporaryPointVector aUnusedTempPoints;
                    B2DCubicBezier aCubic;

                    for(sal_uInt32 a(0); a < nEdgeCount; a++)
                    {
                        rCandidate.getBezierSegment(a, aCubic);
            		    B2DRange aCubicRange(aCubic.getStartPoint(), aCubic.getEndPoint());

                        if(aCubic.isBezier())
                        {
		                    aCubicRange.expand(aCubic.getControlPointA());
		                    aCubicRange.expand(aCubic.getControlPointB());

                            if(aCubicRange.overlaps(aEdgeRange))
                            {
        					    findEdgeCutsBezierAndEdge(aCubic, rStart, rEnd, a, 0, aTempPoints, aUnusedTempPoints);
                            }
                        }
                        else
                        {
                            if(aCubicRange.overlaps(aEdgeRange))
                            {
    						    findEdgeCutsTwoEdges(aCubic.getStartPoint(), aCubic.getEndPoint(), rStart, rEnd, a, 0, aTempPoints, aUnusedTempPoints);
                            }
                        }
                    }

				    return mergeTemporaryPointsAndPolygon(rCandidate, aTempPoints);
                }
            }

            return rCandidate;
        }

        B2DPolyPolygon addPointsAtCuts(const B2DPolyPolygon& rCandidate, const B2DPoint& rStart, const B2DPoint& rEnd)
        {
            B2DPolyPolygon aRetval;

            for(sal_uInt32 a(0); a < rCandidate.count(); a++)
            {
                aRetval.append(addPointsAtCuts(rCandidate.getB2DPolygon(a), rStart, rEnd));
            }

            return aRetval;
        }

        ////////////////////////////////////////////////////////////////////////////////

        B2DPolygon addPointsAtCuts(const B2DPolygon& rCandidate, const B2DPolyPolygon& rPolyMask)
        {
            const sal_uInt32 nCountA(rCandidate.count());
            const sal_uInt32 nCountM(rPolyMask.count());

            if(nCountA && nCountM)
            {
                const B2DRange aRangeA(rCandidate.getB2DRange());
                const B2DRange aRangeM(rPolyMask.getB2DRange());

                if(aRangeA.overlaps(aRangeM))
                {
                    const sal_uInt32 nEdgeCountA(rCandidate.isClosed() ? nCountA : nCountA - 1);
	                temporaryPointVector aTempPointsA;
	                temporaryPointVector aUnusedTempPointsB;

                    for(sal_uInt32 m(0); m < nCountM; m++)
                    {
                        const B2DPolygon aMask(rPolyMask.getB2DPolygon(m));
                        const sal_uInt32 nCountB(aMask.count());

                        if(nCountB)
                        {
                            B2DCubicBezier aCubicA;
                            B2DCubicBezier aCubicB;

                            for(sal_uInt32 a(0); a < nEdgeCountA; a++)
                            {
                                rCandidate.getBezierSegment(a, aCubicA);
                                const bool bCubicAIsCurve(aCubicA.isBezier());
        		                B2DRange aCubicRangeA(aCubicA.getStartPoint(), aCubicA.getEndPoint());

                                if(bCubicAIsCurve)
                                {
	                                aCubicRangeA.expand(aCubicA.getControlPointA());
	                                aCubicRangeA.expand(aCubicA.getControlPointB());
                                }

                                for(sal_uInt32 b(0); b < nCountB; b++)
                                {
                                    aMask.getBezierSegment(b, aCubicB);
                                    const bool bCubicBIsCurve(aCubicB.isBezier());
            		                B2DRange aCubicRangeB(aCubicB.getStartPoint(), aCubicB.getEndPoint());

                                    if(bCubicBIsCurve)
                                    {
	                                    aCubicRangeB.expand(aCubicB.getControlPointA());
	                                    aCubicRangeB.expand(aCubicB.getControlPointB());
                                    }

                                    if(aCubicRangeA.overlaps(aCubicRangeB))
                                    {
                                        if(bCubicAIsCurve && bCubicBIsCurve)
                                        {
	                                        findEdgeCutsTwoBeziers(aCubicA, aCubicB, a, b, aTempPointsA, aUnusedTempPointsB);
                                        }
                                        else if(bCubicAIsCurve)
                                        {
        					                findEdgeCutsBezierAndEdge(aCubicA, aCubicB.getStartPoint(), aCubicB.getEndPoint(), a, b, aTempPointsA, aUnusedTempPointsB);
                                        }
                                        else if(bCubicBIsCurve)
                                        {
        					                findEdgeCutsBezierAndEdge(aCubicB, aCubicA.getStartPoint(), aCubicA.getEndPoint(), b, a, aUnusedTempPointsB, aTempPointsA);
                                        }
                                        else
                                        {
    						                findEdgeCutsTwoEdges(aCubicA.getStartPoint(), aCubicA.getEndPoint(), aCubicB.getStartPoint(), aCubicB.getEndPoint(), a, b, aTempPointsA, aUnusedTempPointsB);
                                        }
                                    }
                                }
                            }
                        }
                    }

				    return mergeTemporaryPointsAndPolygon(rCandidate, aTempPointsA);
                }
            }

            return rCandidate;
        }

        B2DPolyPolygon addPointsAtCuts(const B2DPolyPolygon& rCandidate, const B2DPolyPolygon& rMask)
        {
            B2DPolyPolygon aRetval;

            for(sal_uInt32 a(0); a < rCandidate.count(); a++)
            {
                aRetval.append(addPointsAtCuts(rCandidate.getB2DPolygon(a), rMask));
            }

            return aRetval;
        }

		B2DPolygon addPointsAtCuts(const B2DPolygon& rCandidate)
		{
			if(rCandidate.count())
			{
				temporaryPointVector aTempPoints;

				findCuts(rCandidate, aTempPoints);

				return mergeTemporaryPointsAndPolygon(rCandidate, aTempPoints);
			}
			else
			{
				return rCandidate;
			}
		}

		B2DPolyPolygon addPointsAtCuts(const B2DPolyPolygon& rCandidate, bool bSelfIntersections)
        {
			const sal_uInt32 nCount(rCandidate.count());

			if(nCount)
			{
				B2DPolyPolygon aRetval;

				if(1 == nCount)
				{
					if(bSelfIntersections)
					{
						// remove self intersections
						aRetval.append(addPointsAtCuts(rCandidate.getB2DPolygon(0)));
					}
					else
					{
						// copy source
						aRetval = rCandidate;
					}
				}
				else
				{
					// first solve self cuts for all contained single polygons
					temporaryPolygonData *pTempData = new temporaryPolygonData[nCount];
					sal_uInt32 a, b;

					for(a = 0; a < nCount; a++)
					{
						if(bSelfIntersections)
						{
							// use polygons with solved self intersections
							pTempData[a].setPolygon(addPointsAtCuts(rCandidate.getB2DPolygon(a)));
						}
						else
						{
							// copy given polygons
							pTempData[a].setPolygon(rCandidate.getB2DPolygon(a));
						}
					}

					// now cuts and touches between the polygons
					for(a = 0; a < nCount; a++)
					{
						for(b = 0; b < nCount; b++)
						{
							if(a < b)
							{
								// look for cuts, compare each edge polygon to following ones
								if(pTempData[a].getRange().overlaps(pTempData[b].getRange()))
								{
									findCuts(pTempData[a].getPolygon(), pTempData[b].getPolygon(), pTempData[a].getTemporaryPointVector(), pTempData[b].getTemporaryPointVector());
								}
							}
						}
					}

					// consolidate the result
					for(a = 0L; a < nCount; a++)
					{
						aRetval.append(mergeTemporaryPointsAndPolygon(pTempData[a].getPolygon(), pTempData[a].getTemporaryPointVector()));
					}

					delete[] pTempData;
				}

				return aRetval;
			}
			else
			{
				return rCandidate;
			}
        }

        ////////////////////////////////////////////////////////////////////////////////

	} // end of namespace tools
} // end of namespace basegfx

//////////////////////////////////////////////////////////////////////////////
// eof
