/**************************************************************
 * 
 * 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/raster/rasterconvert3d.hxx>
#include <basegfx/polygon/b3dpolygon.hxx>
#include <basegfx/polygon/b3dpolypolygon.hxx>
#include <basegfx/point/b3dpoint.hxx>

//////////////////////////////////////////////////////////////////////////////
// implementations of the 3D raster converter

namespace basegfx
{
    void RasterConverter3D::addArea(const B3DPolygon& rFill, const B3DHomMatrix* pViewToEye)
    {
	    const sal_uInt32 nPointCount(rFill.count());

	    for(sal_uInt32 a(0); a < nPointCount; a++)
	    {
		    addEdge(rFill, a, (a + 1) % nPointCount, pViewToEye);
	    }
    }

    void RasterConverter3D::addArea(const B3DPolyPolygon& rFill, const B3DHomMatrix* pViewToEye)
    {
	    const sal_uInt32 nPolyCount(rFill.count());

	    for(sal_uInt32 a(0); a < nPolyCount; a++)
	    {
		    addArea(rFill.getB3DPolygon(a), pViewToEye);
	    }
    }

    RasterConverter3D::RasterConverter3D()
    :	InterpolatorProvider3D(),
	    maLineEntries()
    {}

    RasterConverter3D::~RasterConverter3D()
    {}

    void RasterConverter3D::rasterconvertB3DArea(sal_Int32 nStartLine, sal_Int32 nStopLine)
    {
	    if(maLineEntries.size())
	    {
		    OSL_ENSURE(nStopLine >= nStartLine, "nStopLine is bigger than nStartLine (!)");

            // sort global entries by Y, X once. After this, the vector
		    // is seen as frozen. Pointers to it's entries will be used in the following code.
		    ::std::sort(maLineEntries.begin(), maLineEntries.end());

		    // local parameters
		    ::std::vector< RasterConversionLineEntry3D >::iterator aCurrentEntry(maLineEntries.begin());
		    ::std::vector< RasterConversionLineEntry3D* > aCurrentLine;
		    ::std::vector< RasterConversionLineEntry3D* > aNextLine;
		    ::std::vector< RasterConversionLineEntry3D* >::iterator aRasterConversionLineEntry3D;
		    sal_uInt32 nPairCount(0);

		    // get scanlines first LineNumber as start
		    sal_Int32 nLineNumber(::std::max(aCurrentEntry->getY(), nStartLine));

		    while((aCurrentLine.size() || aCurrentEntry != maLineEntries.end()) && (nLineNumber < nStopLine))
		    {
			    // add all entries which start at current line to current scanline
			    while(aCurrentEntry != maLineEntries.end())
			    {
				    const sal_Int32 nCurrentLineNumber(aCurrentEntry->getY());

				    if(nCurrentLineNumber > nLineNumber)
				    {
					    // line is below current one, done (since array is sorted)
					    break;
				    }
				    else
				    {
					    // less or equal. Line is above or at current one. Advance it exactly to
					    // current line
					    const sal_uInt32 nStep(nLineNumber - nCurrentLineNumber);

					    if(!nStep || aCurrentEntry->decrementRasterConversionLineEntry3D(nStep))
					    {
						    // add when exactly on current line or when incremet to it did not 
						    // completely consume it
						    if(nStep)
						    {
							    aCurrentEntry->incrementRasterConversionLineEntry3D(nStep, *this);
						    }

						    aCurrentLine.push_back(&(*(aCurrentEntry)));
					    }
				    }

				    aCurrentEntry++;
			    }

			    // sort current scanline using comparator. Only X is used there
			    // since all entries are already in one processed line. This needs to be done
			    // every time since not only new spans may have benn added or old removed,
			    // but incrementing may also have changed the order
			    ::std::sort(aCurrentLine.begin(), aCurrentLine.end(), lineComparator());

			    // process current scanline
			    aRasterConversionLineEntry3D = aCurrentLine.begin();
			    aNextLine.clear();
			    nPairCount = 0;

			    while(aRasterConversionLineEntry3D != aCurrentLine.end())
			    {
				    RasterConversionLineEntry3D& rPrevScanRasterConversionLineEntry3D(**aRasterConversionLineEntry3D++);

				    // look for 2nd span
				    if(aRasterConversionLineEntry3D != aCurrentLine.end())
				    {
					    // work on span from rPrevScanRasterConversionLineEntry3D to aRasterConversionLineEntry3D, fLineNumber is valid
					    processLineSpan(rPrevScanRasterConversionLineEntry3D, **aRasterConversionLineEntry3D, nLineNumber, nPairCount++);
				    }

				    // increment to next line
				    if(rPrevScanRasterConversionLineEntry3D.decrementRasterConversionLineEntry3D(1))
				    {
					    rPrevScanRasterConversionLineEntry3D.incrementRasterConversionLineEntry3D(1, *this);
					    aNextLine.push_back(&rPrevScanRasterConversionLineEntry3D);
				    }
			    }

			    // copy back next scanline if count has changed
			    if(aNextLine.size() != aCurrentLine.size())
			    {
				    aCurrentLine = aNextLine;
			    }

			    // increment fLineNumber
			    nLineNumber++;
		    }
	    }
    }

    void RasterConverter3D::addEdge(const B3DPolygon& rFill, sal_uInt32 a, sal_uInt32 b, const B3DHomMatrix* pViewToEye)
    {
	    B3DPoint aStart(rFill.getB3DPoint(a));
	    B3DPoint aEnd(rFill.getB3DPoint(b));
	    sal_Int32 nYStart(fround(aStart.getY()));
	    sal_Int32 nYEnd(fround(aEnd.getY()));

	    if(nYStart != nYEnd)
	    {
		    if(nYStart > nYEnd)
		    {
			    ::std::swap(aStart, aEnd);
			    ::std::swap(nYStart, nYEnd);
			    ::std::swap(a, b);
		    }

		    const sal_uInt32 nYDelta(nYEnd - nYStart);
		    const double fInvYDelta(1.0 / nYDelta);
		    maLineEntries.push_back(RasterConversionLineEntry3D(
			    aStart.getX(), (aEnd.getX() - aStart.getX()) * fInvYDelta,
			    aStart.getZ(), (aEnd.getZ() - aStart.getZ()) * fInvYDelta,
			    nYStart, nYDelta));

		    // if extra interpolation data is used, add it to the last created entry
		    RasterConversionLineEntry3D& rEntry = maLineEntries[maLineEntries.size() - 1];

		    if(rFill.areBColorsUsed())
		    {
			    rEntry.setColorIndex(addColorInterpolator(rFill.getBColor(a), rFill.getBColor(b), fInvYDelta));
		    }

		    if(rFill.areNormalsUsed())
		    {
			    rEntry.setNormalIndex(addNormalInterpolator(rFill.getNormal(a), rFill.getNormal(b), fInvYDelta));
		    }

		    if(rFill.areTextureCoordinatesUsed())
		    {
			    if(pViewToEye)
			    {
				    const double fEyeA(((*pViewToEye) * aStart).getZ());
				    const double fEyeB(((*pViewToEye) * aEnd).getZ());

				    rEntry.setInverseTextureIndex(addInverseTextureInterpolator(
					    rFill.getTextureCoordinate(a), 
					    rFill.getTextureCoordinate(b), 
					    fEyeA, fEyeB, fInvYDelta));
			    }
			    else
			    {
				    rEntry.setTextureIndex(addTextureInterpolator(
					    rFill.getTextureCoordinate(a), 
					    rFill.getTextureCoordinate(b), 
					    fInvYDelta));
			    }
		    }
	    }
    }

    void RasterConverter3D::rasterconvertB3DEdge(const B3DPolygon& rLine, sal_uInt32 nA, sal_uInt32 nB, sal_Int32 nStartLine, sal_Int32 nStopLine, sal_uInt16 nLineWidth)
    {
        B3DPoint aStart(rLine.getB3DPoint(nA));
        B3DPoint aEnd(rLine.getB3DPoint(nB));
        const double fZBufferLineAdd(0x00ff);
		static bool bForceToPolygon(false);

        if(nLineWidth > 1 || bForceToPolygon)
        {
            // this is not a hairline anymore, in most cases since it's an oversampled
            // hairline to get e.g. AA for Z-Buffering. Create fill geometry.
            if(!aStart.equal(aEnd))
            {
		        reset();
		        maLineEntries.clear();
                
                B2DVector aVector(aEnd.getX() - aStart.getX(), aEnd.getY() - aStart.getY());
                aVector.normalize();
            	const B2DVector aPerpend(getPerpendicular(aVector) * ((static_cast<double>(nLineWidth) + 0.5) * 0.5));
                const double fZStartWithAdd(aStart.getZ() + fZBufferLineAdd);
                const double fZEndWithAdd(aEnd.getZ() + fZBufferLineAdd);

                B3DPolygon aPolygon;
                aPolygon.append(B3DPoint(aStart.getX() + aPerpend.getX(), aStart.getY() + aPerpend.getY(), fZStartWithAdd));
                aPolygon.append(B3DPoint(aEnd.getX() + aPerpend.getX(), aEnd.getY() + aPerpend.getY(), fZEndWithAdd));
                aPolygon.append(B3DPoint(aEnd.getX() - aPerpend.getX(), aEnd.getY() - aPerpend.getY(), fZEndWithAdd));
                aPolygon.append(B3DPoint(aStart.getX() - aPerpend.getX(), aStart.getY() - aPerpend.getY(), fZStartWithAdd));
                aPolygon.setClosed(true);

                addArea(aPolygon, 0);
            }
        }
        else
        {
            // it's a hairline. Use direct RasterConversionLineEntry creation to
            // rasterconvert lines as similar to areas as possible to avoid Z-Fighting
	        sal_Int32 nYStart(fround(aStart.getY()));
	        sal_Int32 nYEnd(fround(aEnd.getY()));

	        if(nYStart == nYEnd)
	        {
		        // horizontal line, check X
		        const sal_Int32 nXStart(static_cast<sal_Int32>(aStart.getX()));
		        const sal_Int32 nXEnd(static_cast<sal_Int32>(aEnd.getX()));

		        if(nXStart != nXEnd)
		        {
			        reset();
			        maLineEntries.clear();
    				
			        // horizontal line, create vertical entries. These will be sorted by
			        // X anyways, so no need to distinguish the case here
			        maLineEntries.push_back(RasterConversionLineEntry3D(
				        aStart.getX(), 0.0,
				        aStart.getZ() + fZBufferLineAdd, 0.0,
				        nYStart, 1));
			        maLineEntries.push_back(RasterConversionLineEntry3D(
				        aEnd.getX(), 0.0,
				        aEnd.getZ() + fZBufferLineAdd, 0.0,
				        nYStart, 1));
		        }
	        }
	        else
	        {
		        reset();
		        maLineEntries.clear();

		        if(nYStart > nYEnd)
		        {
			        ::std::swap(aStart, aEnd);
			        ::std::swap(nYStart, nYEnd);
		        }

		        const sal_uInt32 nYDelta(static_cast<sal_uInt32>(nYEnd - nYStart));
		        const double fInvYDelta(1.0 / nYDelta);

		        // non-horizontal line, create two parallell entries. These will be sorted by
		        // X anyways, so no need to distinguish the case here
		        maLineEntries.push_back(RasterConversionLineEntry3D(
			        aStart.getX(), (aEnd.getX() - aStart.getX()) * fInvYDelta,
			        aStart.getZ() + fZBufferLineAdd, (aEnd.getZ() - aStart.getZ()) * fInvYDelta,
			        nYStart, nYDelta));

		        RasterConversionLineEntry3D& rEntry = maLineEntries[maLineEntries.size() - 1];

		        // need to choose a X-Distance for the 2nd edge which guarantees all pixels 
		        // of the line to be set. This is exactly the X-Increment for one Y-Step.
		        // Same is true for Z, so in both cases, add one increment to them. To also
		        // guarantee one pixel per line, add a minimum of one for X.
		        const double fDistanceX(fabs(rEntry.getX().getInc()) >= 1.0 ? rEntry.getX().getInc() : 1.0);

		        maLineEntries.push_back(RasterConversionLineEntry3D(
			        rEntry.getX().getVal() + fDistanceX, rEntry.getX().getInc(),
			        rEntry.getZ().getVal() + rEntry.getZ().getInc(), rEntry.getZ().getInc(),
			        nYStart, nYDelta));
	        }
        }

        if(maLineEntries.size())
        {
	        rasterconvertB3DArea(nStartLine, nStopLine);
        }
    }

    void RasterConverter3D::rasterconvertB3DPolyPolygon(const B3DPolyPolygon& rFill, const B3DHomMatrix* pViewToEye, sal_Int32 nStartLine, sal_Int32 nStopLine)
    {
	    reset();
	    maLineEntries.clear();
	    addArea(rFill, pViewToEye);
	    rasterconvertB3DArea(nStartLine, nStopLine);
    }

    void RasterConverter3D::rasterconvertB3DPolygon(const B3DPolygon& rLine, sal_Int32 nStartLine, sal_Int32 nStopLine, sal_uInt16 nLineWidth)
    {
	    const sal_uInt32 nPointCount(rLine.count());

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

		    for(sal_uInt32 a(0); a < nEdgeCount; a++)
		    {
			    rasterconvertB3DEdge(rLine, a, (a + 1) % nPointCount, nStartLine, nStopLine, nLineWidth);
		    }
	    }
    }
} // end of namespace basegfx

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