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

#include <basegfx/numeric/ftools.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>

#include <boost/mem_fn.hpp>

#include <algorithm>

namespace basegfx
{
	class radixSort {

		//! public interface
		public:

			//! default constructor
			radixSort( void );

			//! destructor
			~radixSort( void );

			bool sort( const float *pInput, sal_uInt32 nNumElements, sal_uInt32 dwStride );

			inline sal_uInt32 *indices( void ) const { return m_indices1; }

		//! private attributes
		private:

			// current size of index list
			sal_uInt32 m_current_size;

			// last known size of index list
			sal_uInt32 m_previous_size;

			// index lists
			sal_uInt32 *m_indices1;
			sal_uInt32 *m_indices2;

			sal_uInt32 m_counter[256*4];
			sal_uInt32 m_offset[256];

		//! private methods
		private:

			bool resize( sal_uInt32 nNumElements );
			inline void reset_indices( void );
			bool prepareCounters( const float *pInput, sal_uInt32 nNumElements, sal_uInt32 dwStride );
	};

	inline radixSort::radixSort( void ) {

		m_indices1 = NULL;
		m_indices2 = NULL;
		m_current_size = 0;
		m_previous_size = 0;

		reset_indices();
	}

	inline radixSort::~radixSort( void ) {

		delete [] m_indices2;
		delete [] m_indices1;
	}

	bool radixSort::resize( sal_uInt32 nNumElements ) {

		if(nNumElements==m_previous_size)
			return true;

		if(nNumElements > m_current_size) {

			// release index lists
			if(m_indices2)
				delete [] m_indices2;
			if(m_indices1)
				delete [] m_indices1;

			// allocate new index lists
			m_indices1 = new sal_uInt32[nNumElements];
			m_indices2 = new sal_uInt32[nNumElements];

			// check for out of memory situation
            if(!m_indices1 || !m_indices2) {
				delete [] m_indices1;
				delete [] m_indices2;
				m_indices1 = NULL;
				m_indices2 = NULL;
				m_current_size = 0;
				return false;
			}

			m_current_size = nNumElements;
		}

		m_previous_size = nNumElements;

		// initialize indices
		reset_indices();

		return true;
	}

	inline void radixSort::reset_indices( void ) {

		for(sal_uInt32 i=0;i<m_current_size;i++)
			m_indices1[i] = i;
	}

	bool radixSort::prepareCounters( const float *pInput, sal_uInt32 nNumElements, sal_uInt32 dwStride ) {

		// clear counters
		sal_uInt32 *ptr = m_counter;
		for(int i=0; i<64; ++i)
        {
			*ptr++ = 0;
			*ptr++ = 0;
			*ptr++ = 0;
			*ptr++ = 0;
			*ptr++ = 0;
			*ptr++ = 0;
			*ptr++ = 0;
			*ptr++ = 0;
			*ptr++ = 0;
			*ptr++ = 0;
			*ptr++ = 0;
			*ptr++ = 0;
			*ptr++ = 0;
			*ptr++ = 0;
			*ptr++ = 0;
			*ptr++ = 0;
		}

		// prepare pointers to relevant memory addresses
		sal_uInt8 *p = (sal_uInt8*)pInput;
		sal_uInt8 *pe = p+(nNumElements*dwStride);
		sal_uInt32 *h0= &m_counter[0];
		sal_uInt32 *h1= &m_counter[256];
		sal_uInt32 *h2= &m_counter[512];
		sal_uInt32 *h3= &m_counter[768];

		sal_uInt32 *Indices = m_indices1;
		float previous_value = *(float *)(((sal_uInt8 *)pInput)+(m_indices1[0]*dwStride));
		bool bSorted = true;
		while(p!=pe) {
			float value = *(float *)(((sal_uInt8 *)pInput)+((*Indices++)*dwStride));
			if(value<previous_value)	{
				bSorted = false;
				break;
			}
			previous_value = value;
			h0[*p++]++;
			h1[*p++]++;
			h2[*p++]++;
			h3[*p++]++;
			p += dwStride-4;
		}
		if(bSorted)
			return true;
		while(p!=pe) {
			h0[*p++]++;
			h1[*p++]++;
			h2[*p++]++;
			h3[*p++]++;
			p += dwStride-4;
		}
		return false;
	}

	bool radixSort::sort( const float *pInput, sal_uInt32 nNumElements, sal_uInt32 dwStride ) {

		if(!(pInput))
			return false;
		if(!(nNumElements))
			return false;
		if(!(resize(nNumElements)))
			return false;

		// prepare radix counters, return if already sorted
		if(prepareCounters(pInput,nNumElements,dwStride))
			return true;

		// count number of negative values
		sal_uInt32 num_negatives = 0;
		sal_uInt32 *h3= &m_counter[768];
		for(sal_uInt32 i=128;i<256;i++)
			num_negatives += h3[i];

		// perform passes, one for each byte
		for(sal_uInt32 j=0;j<4;j++) {

			// ignore this pass if all values have the same byte
			bool bRun = true;
			sal_uInt32 *current_counter = &m_counter[j<<8];
			sal_uInt8 unique_value = *(((sal_uInt8*)pInput)+j);
			if(current_counter[unique_value]==nNumElements)
				bRun=false;

			// does the incoming byte contain the sign bit?
			sal_uInt32 i;
			if(j!=3) {
				if(bRun) {
					m_offset[0] = 0;
					for(i=1;i<256;i++)
						m_offset[i] = m_offset[i-1] + current_counter[i-1];
					sal_uInt8 *InputBytes = (sal_uInt8 *)pInput;
					sal_uInt32 *Indices = m_indices1;
					sal_uInt32 *IndicesEnd = &m_indices1[nNumElements];
					InputBytes += j;
					while(Indices!=IndicesEnd) {
						sal_uInt32 id = *Indices++;
						m_indices2[m_offset[InputBytes[id*dwStride]]++] = id;
					}
					sal_uInt32 *Tmp	= m_indices1;
					m_indices1 = m_indices2;
					m_indices2 = Tmp;
				}
			}
			else {
				if(bRun) {
					m_offset[0] = num_negatives;
					for(i=1;i<128;i++)
						m_offset[i] = m_offset[i-1] + current_counter[i-1];
					m_offset[255] = 0;
					for(i=0;i<127;i++)
						m_offset[254-i] = m_offset[255-i] + current_counter[255-i];
					for(i=128;i<256;i++)
						m_offset[i] += current_counter[i];
					for(i=0;i<nNumElements;i++) {
						sal_uInt32 Radix = (*(sal_uInt32 *)(((sal_uInt8 *)pInput)+(m_indices1[i]*dwStride)))>>24;
						if(Radix<128) m_indices2[m_offset[Radix]++] = m_indices1[i];
						else m_indices2[--m_offset[Radix]] = m_indices1[i];
					}
					sal_uInt32 *Tmp	= m_indices1;
					m_indices1 = m_indices2;
					m_indices2 = Tmp;
				}
				else {
					if(unique_value>=128) {
						for(i=0;i<nNumElements;i++)
							m_indices2[i] = m_indices1[nNumElements-i-1];
						sal_uInt32 *Tmp	= m_indices1;
						m_indices1 = m_indices2;
						m_indices2 = Tmp;
					}
				}
			}
		}

		return true;
	}

	//************************************************************
	// Internal vertex storage of B2DPolyPolygonRasterConverter
	//************************************************************

    inline B2DPolyPolygonRasterConverter::Vertex::Vertex() :
        aP1(),
        aP2(),
        bDownwards( true )
    {
    }

    inline B2DPolyPolygonRasterConverter::Vertex::Vertex( const B2DPoint& rP1, const B2DPoint& rP2, bool bDown ) :
        aP1( rP1 ),
        aP2( rP2 ),
        bDownwards( bDown )
    {
    }


	//************************************************************
	// Helper class for holding horizontal line segments during raster
	// conversion
	//************************************************************

	namespace
    {
        class ImplLineNode
        {
		public:
            sal_Int32	mnYCounter;
            float		mfXPos;
            float		mfXDelta;
            bool		mbDownwards;

        public:
            /**rP1 and rP2 must not have equal y values, when rounded
               to integer!
            */
            ImplLineNode(const B2DPoint& rP1, const B2DPoint& rP2, bool bDown) :
                mnYCounter( fround(rP2.getY()) - fround(rP1.getY()) ),
                mfXPos( (float)(rP1.getX()) ),
                mfXDelta((float) ((rP2.getX() - rP1.getX()) / mnYCounter) ),
                mbDownwards( bDown )
            {
            }

            /// get current x position
            const float& getXPos() const
            {
                return mfXPos;
            }

            /// returns true, if line ends on this Y value
            float nextLine()
            {
                if(mnYCounter>=0)
                {
                    // go one step in Y
                    mfXPos += mfXDelta;
                    --mnYCounter;
					return mfXDelta;
                }

				return 0.0f;
            }

            bool isEnded()
            {
                return mnYCounter<=0;
            }

            bool isDownwards()
            {
                return mbDownwards;
            }
        };
    }

    typedef ::std::vector<ImplLineNode> VectorOfLineNodes;


	//************************************************************
	//   Base2D PolyPolygon Raster Converter (Rasterizer)
	//************************************************************

    namespace
    {
        struct VertexComparator
        {
            bool operator()( const B2DPolyPolygonRasterConverter::Vertex& rLHS,
                             const B2DPolyPolygonRasterConverter::Vertex& rRHS )
            {
                return rLHS.aP1.getX() < rRHS.aP1.getX();
            }
        };
    }

    void B2DPolyPolygonRasterConverter::init()
    {
        if(!maPolyPolyRectangle.isEmpty())
        {
            const sal_Int32	nMinY( fround(maPolyPolyRectangle.getMinY()) );
            const sal_Int32 nScanlines(fround(maPolyPolyRectangle.getMaxY()) - nMinY);

            maScanlines.resize( nScanlines+1 );

            // add all polygons
            for( sal_uInt32 i(0), nCount(maPolyPolygon.count());
                 i < nCount;
                 ++i )
            {
                // add all vertices
                const B2DPolygon& rPoly( maPolyPolygon.getB2DPolygon(i) );
                for( sal_uInt32 k(0), nVertices(rPoly.count());
                     k<nVertices;
                     ++k )
                {
                    const B2DPoint& rP1( rPoly.getB2DPoint(k) );
                    const B2DPoint& rP2( rPoly.getB2DPoint( (k + 1) % nVertices ) );

                    const sal_Int32 nVertexYP1( fround(rP1.getY()) );
                    const sal_Int32 nVertexYP2( fround(rP2.getY()) );

                    // insert only vertices which are not strictly
                    // horizontal. Note that the ImplLineNode relies on
                    // this.
                    if(nVertexYP1 != nVertexYP2)
                    {
                        if( nVertexYP2 < nVertexYP1 )
                        {
                            const sal_Int32 nStartScanline(nVertexYP2 - nMinY);

                            // swap edges
                            maScanlines[ nStartScanline ].push_back( Vertex(rP2, rP1, false) );
                        }
                        else
                        {
                            const sal_Int32 nStartScanline(nVertexYP1 - nMinY);

                            maScanlines[ nStartScanline ].push_back( Vertex(rP1, rP2, true) );
                        }
                    }
                }
            }

            // now sort all scanlines, with increasing x coordinates
            VectorOfVertexVectors::iterator aIter( maScanlines.begin() );
            VectorOfVertexVectors::iterator aEnd( maScanlines.end() );
            while( aIter != aEnd )
            {
                ::std::sort( aIter->begin(),
                             aIter->end(),
                             VertexComparator() );
                ++aIter;
            }
        }
    }

    B2DPolyPolygonRasterConverter::B2DPolyPolygonRasterConverter( const B2DPolyPolygon& rPolyPoly ) :
        maPolyPolygon( rPolyPoly ),
        maPolyPolyRectangle( tools::getRange( rPolyPoly ) ),
        maScanlines()
    {
        init();
    }

    namespace
    {
        B2DRectangle getCombinedBounds( const B2DPolyPolygon& rPolyPolyRaster,
                                        const B2DRectangle&   rRasterArea )
        {
            B2DRectangle aRect( tools::getRange( rPolyPolyRaster ) );
            aRect.expand( rRasterArea );

            return aRect;
        }
    }

    B2DPolyPolygonRasterConverter::B2DPolyPolygonRasterConverter( const B2DPolyPolygon& rPolyPolyRaster,
                                                                  const B2DRectangle&   rRasterArea ) :
        maPolyPolygon( rPolyPolyRaster ),
        maPolyPolyRectangle(
            getCombinedBounds( rPolyPolyRaster,
                               rRasterArea ) ),
        maScanlines()
    {
        init();
    }

    B2DPolyPolygonRasterConverter::~B2DPolyPolygonRasterConverter()
    {
    }

    namespace
    {
        class LineNodeGenerator
        {
        public:
            LineNodeGenerator( VectorOfLineNodes& rActiveVertices ) :
                mrActiveVertices( rActiveVertices )
            {
            }

            void operator()( const B2DPolyPolygonRasterConverter::Vertex& rVertex )
            {
                mrActiveVertices.push_back( ImplLineNode(rVertex.aP1,
                                                         rVertex.aP2,
                                                         rVertex.bDownwards) );
            }

        private:
            VectorOfLineNodes& mrActiveVertices;
        };

        struct LineNodeComparator
        {
            bool operator()( const ImplLineNode& rLHS, const ImplLineNode& rRHS )
            {
                return rLHS.getXPos() < rRHS.getXPos();
            }
        };
    }

    void B2DPolyPolygonRasterConverter::rasterConvert( FillRule eFillRule )
    {
        if( maScanlines.empty() )
            return; // no scanlines at all -> bail out

        const sal_Int32	nMinY( fround(maPolyPolyRectangle.getMinY()) );
        const sal_Int32 nScanlines(fround(maPolyPolyRectangle.getMaxY()) - nMinY);

        // Vector of currently active vertices. A vertex is active, if
        // it crosses or touches the current scanline.
        VectorOfLineNodes	aActiveVertices;

		// mickey's optimized version...
		radixSort   rs;
		std::size_t nb(0);
        std::size_t nb_previous(0);
		bool        bSort(false);

        // process each scanline
        for( sal_Int32 y(0); y <= nScanlines; ++y )
        {
            // add vertices which start at current scanline into
            // active vertex vector
            ::std::for_each( maScanlines[y].begin(),
                             maScanlines[y].end(),
                             LineNodeGenerator( aActiveVertices ) );
			nb = aActiveVertices.size();
			if(nb != nb_previous)
            {
				nb_previous = nb;
				bSort = true;
			}

            // sort with increasing X
			if(bSort)
            {
				bSort = false;

                if( nb )
                {
                    rs.sort(&aActiveVertices[0].mfXPos,
                            nb,
                            sizeof(ImplLineNode));
                }
			}

            const std::size_t nLen( nb );
            if( !nLen )
            {
                // empty scanline - call derived with an 'off' span
                // for the full width
                span( maPolyPolyRectangle.getMinX(),
                      maPolyPolyRectangle.getMaxX(),
                      nMinY + y,
                      false );
            }
            else
            {
                const sal_Int32 nCurrY( nMinY + y );

                // scanline not empty - forward all scans to derived,
                // according to selected fill rule

                // TODO(P1): Maybe allow these 'off' span calls to be
                // switched off (or all 'on' span calls, depending on
                // use case scenario)

				// sorting didn't change the order of the elements
				// in memory but prepared a list of indices in sorted order.
				// thus we now process the nodes with an additional indirection.
				sal_uInt32 *sorted = rs.indices();

                // call derived with 'off' span for everything left of first active span
                if( aActiveVertices[sorted[0]].getXPos() > maPolyPolyRectangle.getMinX() )
                {
                    span( maPolyPolyRectangle.getMinX(),
                          aActiveVertices[sorted[0]].getXPos(),
                          nCurrY,
                          false );
                }

                switch( eFillRule )
                {
                    default:
                        OSL_ENSURE(false,
                                   "B2DPolyPolygonRasterConverter::rasterConvert(): Unexpected fill rule");
                        return;

                    case FillRule_EVEN_ODD:
                        // process each span in current scanline, with
                        // even-odd fill rule
                        for( ::std::size_t i(0), nLength(aActiveVertices.size());
                             i+1 < nLength;
                             ++i )
                        {
							sal_uInt32 nIndex = sorted[i];
							sal_uInt32 nNextIndex = sorted[i+1];
                            span( aActiveVertices[nIndex].getXPos(),
                                  aActiveVertices[nNextIndex].getXPos(),
                                  nCurrY,
                                  i % 2 == 0 );

                            float delta = aActiveVertices[nIndex].nextLine();
							if(delta > 0.0f)
                            {
								if(aActiveVertices[nIndex].getXPos() > aActiveVertices[nNextIndex].getXPos())
									bSort = true;
							}
							else if(delta < 0.0f)
                            {
								if(i)
                                {
									sal_uInt32 nPrevIndex = sorted[i-1];
									if(aActiveVertices[nIndex].getXPos() < aActiveVertices[nPrevIndex].getXPos())
										bSort = true;
								}
							}
                        }
                        break;

                    case FillRule_NONZERO_WINDING_NUMBER:
                        // process each span in current scanline, with
                        // non-zero winding numbe fill rule
                        sal_Int32 nWindingNumber(0);
                        for( ::std::size_t i(0), nLength(aActiveVertices.size());
                             i+1 < nLength;
                             ++i )
                        {
							sal_uInt32 nIndex = sorted[i];
							sal_uInt32 nNextIndex = sorted[i+1];
                            nWindingNumber += -1 + 2*aActiveVertices[nIndex].isDownwards();

                            span( aActiveVertices[nIndex].getXPos(),
                                  aActiveVertices[nNextIndex].getXPos(),
                                  nCurrY,
                                  nWindingNumber != 0 );

                            float delta = aActiveVertices[nIndex].nextLine();
							if(delta > 0.0f)
                            {
								if(aActiveVertices[nIndex].getXPos() > aActiveVertices[nNextIndex].getXPos())
									bSort = true;
							}
							else if(delta < 0.0f)
                            {
								if(i)
                                {
									sal_uInt32 nPrevIndex = sorted[i-1];
									if(aActiveVertices[nIndex].getXPos() < aActiveVertices[nPrevIndex].getXPos())
										bSort = true;
								}
							}
                        }
                        break;
                }

                // call derived with 'off' span for everything right of last active span
                if( aActiveVertices[sorted[nb-1]].getXPos()+1.0 < maPolyPolyRectangle.getMaxX() )
                {
                    span( aActiveVertices[sorted[nb-1]].getXPos()+1.0,
                          maPolyPolyRectangle.getMaxX(),
                          nCurrY,
                          false );
                }

                // also call nextLine on very last line node
				sal_uInt32 nIndex = sorted[nb-1];
                float delta = aActiveVertices[nIndex].nextLine();
				if(delta < 0.0f)
                {
					if(nb)
                    {
						sal_uInt32 nPrevIndex = sorted[nb-2];
						if(aActiveVertices[nIndex].getXPos() < aActiveVertices[nPrevIndex].getXPos())
							bSort = true;
					}
				}
            }

            // remove line nodes which have ended on the current scanline
            aActiveVertices.erase( ::std::remove_if( aActiveVertices.begin(),
                                                     aActiveVertices.end(),
                                                     ::boost::mem_fn( &ImplLineNode::isEnded ) ),
                                   aActiveVertices.end() );
			nb = aActiveVertices.size();
			if(nb != nb_previous)
            {
				nb_previous = nb;
				bSort = true;
			}
        }
	}
}
// eof
