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

#include "surface.hxx"
#include <basegfx/polygon/b2dpolygonclipper.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <comphelper/scopeguard.hxx> 
#include <boost/bind.hpp>

namespace canvas
{

	//////////////////////////////////////////////////////////////////////////////////
	// Surface::Surface
	//////////////////////////////////////////////////////////////////////////////////

	Surface::Surface( const PageManagerSharedPtr&  rPageManager,
					  const IColorBufferSharedPtr& rColorBuffer,
					  const ::basegfx::B2IPoint&   rPos,
					  const ::basegfx::B2ISize&    rSize ) :
		mpColorBuffer(rColorBuffer),
		mpPageManager(rPageManager),
		mpFragment(),
		maSourceOffset(rPos),
		maSize(rSize),
		mbIsDirty(true)
	{
	}

	//////////////////////////////////////////////////////////////////////////////////
	// Surface::~Surface
	//////////////////////////////////////////////////////////////////////////////////

	Surface::~Surface()
	{
		if(mpFragment)
			mpPageManager->free(mpFragment);
	}

	//////////////////////////////////////////////////////////////////////////////////
	// Surface::getUVCoords
	//////////////////////////////////////////////////////////////////////////////////

	void Surface::setColorBufferDirty()
	{
		mbIsDirty=true;
	}

	//////////////////////////////////////////////////////////////////////////////////
	// Surface::getUVCoords
	//////////////////////////////////////////////////////////////////////////////////

	basegfx::B2DRectangle Surface::getUVCoords() const
	{
		::basegfx::B2ISize aPageSize(mpPageManager->getPageSize());
		::basegfx::B2IPoint aDestOffset;
        if( mpFragment )
            aDestOffset = mpFragment->getPos();

		const double pw( aPageSize.getX() );
		const double ph( aPageSize.getY() );
		const double ox( aDestOffset.getX() );
		const double oy( aDestOffset.getY() );
		const double sx( maSize.getX() );
		const double sy( maSize.getY() );

		return ::basegfx::B2DRectangle( ox/pw,
                                        oy/ph,
                                        (ox+sx)/pw,
                                        (oy+sy)/ph );
	}

	//////////////////////////////////////////////////////////////////////////////////
	// Surface::getUVCoords
	//////////////////////////////////////////////////////////////////////////////////

	basegfx::B2DRectangle Surface::getUVCoords( const ::basegfx::B2IPoint& rPos,
												const ::basegfx::B2ISize&  rSize ) const
	{
		::basegfx::B2ISize aPageSize(mpPageManager->getPageSize());

		const double pw( aPageSize.getX() );
		const double ph( aPageSize.getY() );
		const double ox( rPos.getX() );
		const double oy( rPos.getY() );
		const double sx( rSize.getX() );
		const double sy( rSize.getY() );

		return ::basegfx::B2DRectangle( ox/pw,
                                        oy/ph,
                                        (ox+sx)/pw,
                                        (oy+sy)/ph );
	}

	//////////////////////////////////////////////////////////////////////////////////
	// Surface::draw
	//////////////////////////////////////////////////////////////////////////////////

	bool Surface::draw( double                          fAlpha,
						const ::basegfx::B2DPoint&      rPos,
						const ::basegfx::B2DHomMatrix&  rTransform )
	{
		IRenderModuleSharedPtr pRenderModule(mpPageManager->getRenderModule());

        RenderModuleGuard aGuard( pRenderModule );

		prepareRendering();

		// convert size to normalized device coordinates
		const ::basegfx::B2DRectangle& rUV( getUVCoords() );

		const double u1(rUV.getMinX());
		const double v1(rUV.getMinY());
		const double u2(rUV.getMaxX());
		const double v2(rUV.getMaxY());

		// concat transforms
        // 1) offset of surface subarea
        // 2) surface transform
		// 3) translation to output position [rPos]
		// 4) scale to normalized device coordinates
		// 5) flip y-axis
		// 6) translate to account for viewport transform
        basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix(
            maSourceOffset.getX(), maSourceOffset.getY()));
        aTransform = aTransform * rTransform;
		aTransform.translate(::basegfx::fround(rPos.getX()),
                             ::basegfx::fround(rPos.getY()));

		/*
			######################################
			######################################
			######################################
			
			    		   Y
			    		   ^+1
			    		   |
			       2	   |	   3
			    	 x------------x
			    	 |	   |	  |
			 		 |	   |	  |
			   ------|-----O------|------>X
			   -1  	 |	   |	  |		+1
			    	 |	   |	  |
			    	 x------------x
			        1      |       0
			    	 	   |
			    		   |-1
			
			######################################
			######################################
			######################################
		*/

		const ::basegfx::B2DPoint& p0(aTransform * ::basegfx::B2DPoint(maSize.getX(),maSize.getY()));
		const ::basegfx::B2DPoint& p1(aTransform * ::basegfx::B2DPoint(0.0,maSize.getY()));
		const ::basegfx::B2DPoint& p2(aTransform * ::basegfx::B2DPoint(0.0,0.0));
		const ::basegfx::B2DPoint& p3(aTransform * ::basegfx::B2DPoint(maSize.getX(),0.0));

		canvas::Vertex vertex;
		vertex.r = 1.0f;
		vertex.g = 1.0f;
		vertex.b = 1.0f;
		vertex.a = static_cast<float>(fAlpha);
		vertex.z = 0.0f;

        {
            pRenderModule->beginPrimitive( canvas::IRenderModule::PRIMITIVE_TYPE_QUAD );

            // issue an endPrimitive() when leaving the scope
            const ::comphelper::ScopeGuard aScopeGuard(
                boost::bind( &::canvas::IRenderModule::endPrimitive,
                             ::boost::ref(pRenderModule) ) );

            vertex.u=static_cast<float>(u2); vertex.v=static_cast<float>(v2);
            vertex.x=static_cast<float>(p0.getX()); vertex.y=static_cast<float>(p0.getY());
            pRenderModule->pushVertex(vertex);

            vertex.u=static_cast<float>(u1); vertex.v=static_cast<float>(v2);
            vertex.x=static_cast<float>(p1.getX()); vertex.y=static_cast<float>(p1.getY());
            pRenderModule->pushVertex(vertex);

            vertex.u=static_cast<float>(u1); vertex.v=static_cast<float>(v1);
            vertex.x=static_cast<float>(p2.getX()); vertex.y=static_cast<float>(p2.getY());
            pRenderModule->pushVertex(vertex);

            vertex.u=static_cast<float>(u2); vertex.v=static_cast<float>(v1);
            vertex.x=static_cast<float>(p3.getX()); vertex.y=static_cast<float>(p3.getY());
            pRenderModule->pushVertex(vertex);
        }

		return !(pRenderModule->isError());
	}

	//////////////////////////////////////////////////////////////////////////////////
	// Surface::drawRectangularArea
	//////////////////////////////////////////////////////////////////////////////////

	bool Surface::drawRectangularArea(
						double                         fAlpha,
                        const ::basegfx::B2DPoint&     rPos,
						const ::basegfx::B2DRectangle& rArea,
						const ::basegfx::B2DHomMatrix& rTransform )
	{
        if( rArea.isEmpty() )
            return true; // immediate exit for empty area

		IRenderModuleSharedPtr pRenderModule(mpPageManager->getRenderModule());

		RenderModuleGuard aGuard( pRenderModule );

		prepareRendering();

		// these positions are relative to the texture
		::basegfx::B2IPoint aPos1(
			::basegfx::fround(rArea.getMinimum().getX()),
			::basegfx::fround(rArea.getMinimum().getY()));
		::basegfx::B2IPoint aPos2(
			::basegfx::fround(rArea.getMaximum().getX()),
			::basegfx::fround(rArea.getMaximum().getY()) );

		// clip the positions to the area this surface covers
		aPos1.setX(::std::max(aPos1.getX(),maSourceOffset.getX()));
		aPos1.setY(::std::max(aPos1.getY(),maSourceOffset.getY()));
		aPos2.setX(::std::min(aPos2.getX(),maSourceOffset.getX()+maSize.getX()));
		aPos2.setY(::std::min(aPos2.getY(),maSourceOffset.getY()+maSize.getY()));

		// if the resulting area is empty, return immediately
		::basegfx::B2IVector aSize(aPos2 - aPos1);
		if(aSize.getX() <= 0 || aSize.getY() <= 0)
			return true;

        ::basegfx::B2IPoint aDestOffset;
        if( mpFragment )
            aDestOffset = mpFragment->getPos();

		// convert size to normalized device coordinates
		const ::basegfx::B2DRectangle& rUV( 
            getUVCoords(aPos1 - maSourceOffset + aDestOffset,
                        aSize) );
		const double u1(rUV.getMinX());
		const double v1(rUV.getMinY());
		const double u2(rUV.getMaxX());
		const double v2(rUV.getMaxY());

		// concatenate transforms
        // 1) offset of surface subarea
        // 2) surface transform
		// 3) translation to output position [rPos]
        basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix(aPos1.getX(), aPos1.getY()));
        aTransform = aTransform * rTransform;
		aTransform.translate(::basegfx::fround(rPos.getX()),
                             ::basegfx::fround(rPos.getY()));


		/*
			######################################
			######################################
			######################################
			
			    		   Y
			    		   ^+1
			    		   |
			       2	   |	   3
			    	 x------------x
			    	 |	   |	  |
			 		 |	   |	  |
			   ------|-----O------|------>X
			   -1  	 |	   |	  |		+1
			    	 |	   |	  |
			    	 x------------x
			        1      |       0
			    	 	   |
			    		   |-1
			
			######################################
			######################################
			######################################
		*/

		const ::basegfx::B2DPoint& p0(aTransform * ::basegfx::B2DPoint(aSize.getX(),aSize.getY()));
		const ::basegfx::B2DPoint& p1(aTransform * ::basegfx::B2DPoint(0.0,			aSize.getY()));
		const ::basegfx::B2DPoint& p2(aTransform * ::basegfx::B2DPoint(0.0,			0.0));
		const ::basegfx::B2DPoint& p3(aTransform * ::basegfx::B2DPoint(aSize.getX(),0.0));

		canvas::Vertex vertex;
		vertex.r = 1.0f;
		vertex.g = 1.0f;
		vertex.b = 1.0f;
		vertex.a = static_cast<float>(fAlpha);
		vertex.z = 0.0f;

        {
            pRenderModule->beginPrimitive( canvas::IRenderModule::PRIMITIVE_TYPE_QUAD );

            // issue an endPrimitive() when leaving the scope
            const ::comphelper::ScopeGuard aScopeGuard(
                boost::bind( &::canvas::IRenderModule::endPrimitive,
                             ::boost::ref(pRenderModule) ) );

            vertex.u=static_cast<float>(u2); vertex.v=static_cast<float>(v2);
            vertex.x=static_cast<float>(p0.getX()); vertex.y=static_cast<float>(p0.getY());
            pRenderModule->pushVertex(vertex);

            vertex.u=static_cast<float>(u1); vertex.v=static_cast<float>(v2);
            vertex.x=static_cast<float>(p1.getX()); vertex.y=static_cast<float>(p1.getY());
            pRenderModule->pushVertex(vertex);

            vertex.u=static_cast<float>(u1); vertex.v=static_cast<float>(v1);
            vertex.x=static_cast<float>(p2.getX()); vertex.y=static_cast<float>(p2.getY());
            pRenderModule->pushVertex(vertex);

            vertex.u=static_cast<float>(u2); vertex.v=static_cast<float>(v1);
            vertex.x=static_cast<float>(p3.getX()); vertex.y=static_cast<float>(p3.getY());
            pRenderModule->pushVertex(vertex);
        }

		return !(pRenderModule->isError());
	}

	//////////////////////////////////////////////////////////////////////////////////
	// Surface::drawWithClip
	//////////////////////////////////////////////////////////////////////////////////

	bool Surface::drawWithClip( double                          fAlpha,
								const ::basegfx::B2DPoint&      rPos,
								const ::basegfx::B2DPolygon&    rClipPoly,
								const ::basegfx::B2DHomMatrix&  rTransform )
	{
		IRenderModuleSharedPtr pRenderModule(mpPageManager->getRenderModule());

		RenderModuleGuard aGuard( pRenderModule );

		prepareRendering();

		// untransformed surface rectangle, relative to the whole
		// image (note: this surface might actually only be a tile of
		// the whole image, with non-zero maSourceOffset)
		const double x1(maSourceOffset.getX());
		const double y1(maSourceOffset.getY());
		const double w(maSize.getX());
		const double h(maSize.getY());
		const double x2(x1+w);
		const double y2(y1+h);
		const ::basegfx::B2DRectangle aSurfaceClipRect(x1,y1,x2,y2);

		// concatenate transforms
		// we use 'fround' here to avoid rounding errors. the vertices will
		// be transformed by the overall transform and uv coordinates will
		// be calculated from the result, and this is why we need to use
		// integer coordinates here...
        basegfx::B2DHomMatrix aTransform;
        aTransform = aTransform * rTransform;
		aTransform.translate(::basegfx::fround(rPos.getX()),
                             ::basegfx::fround(rPos.getY()));

		/*
			######################################
			######################################
			######################################
			
			    		   Y
			    		   ^+1
			    		   |
			       2	   |	   3
			    	 x------------x
			    	 |	   |	  |
			 		 |	   |	  |
			   ------|-----O------|------>X
			   -1  	 |	   |	  |		+1
			    	 |	   |	  |
			    	 x------------x
			        1      |       0
			    	 	   |
			    		   |-1
			
			######################################
			######################################
			######################################
		*/

		// uv coordinates that map the surface rectangle
		// to the destination rectangle.
		const ::basegfx::B2DRectangle& rUV( getUVCoords() );

		basegfx::B2DPolygon rTriangleList(basegfx::tools::clipTriangleListOnRange(rClipPoly,
                                                                                  aSurfaceClipRect));

		// Push vertices to backend renderer
		if(const sal_uInt32 nVertexCount = rTriangleList.count())
		{
			canvas::Vertex vertex;
			vertex.r = 1.0f;
			vertex.g = 1.0f;
			vertex.b = 1.0f;
			vertex.a = static_cast<float>(fAlpha);
			vertex.z = 0.0f;

#if defined(TRIANGLE_LOG) && defined(DBG_UTIL)
			OSL_TRACE( "Surface::draw(): numvertices %d numtriangles %d\n",
						nVertexCount,
						nVertexCount/3 );
#endif

			pRenderModule->beginPrimitive( canvas::IRenderModule::PRIMITIVE_TYPE_TRIANGLE );
	        
			// issue an endPrimitive() when leaving the scope   
			const ::comphelper::ScopeGuard aScopeGuard(
				boost::bind( &::canvas::IRenderModule::endPrimitive,
								::boost::ref(pRenderModule) ) );

			for(sal_uInt32 nIndex=0; nIndex<nVertexCount; ++nIndex) 
			{
				const basegfx::B2DPoint &aPoint = rTriangleList.getB2DPoint(nIndex);
				basegfx::B2DPoint aTransformedPoint(aTransform * aPoint);
				const double tu(((aPoint.getX()-aSurfaceClipRect.getMinX())*rUV.getWidth()/w)+rUV.getMinX());
                const double tv(((aPoint.getY()-aSurfaceClipRect.getMinY())*rUV.getHeight()/h)+rUV.getMinY());
				vertex.u=static_cast<float>(tu); 
				vertex.v=static_cast<float>(tv);
				vertex.x=static_cast<float>(aTransformedPoint.getX());
				vertex.y=static_cast<float>(aTransformedPoint.getY());
				pRenderModule->pushVertex(vertex);
			}
		}

		return !(pRenderModule->isError());
	}

	//////////////////////////////////////////////////////////////////////////////////
	// Surface::prepareRendering
	//////////////////////////////////////////////////////////////////////////////////

	void Surface::prepareRendering()
	{
		mpPageManager->validatePages();

		// clients requested to draw from this surface, therefore one
		// of the above implemented concrete rendering operations
		// was triggered. we therefore need to ask the pagemanager
		// to allocate some space for the fragment we're dedicated to.
		if(!(mpFragment))
		{
			mpFragment = mpPageManager->allocateSpace(maSize);
            if( mpFragment )
            {
			    mpFragment->setColorBuffer(mpColorBuffer);
    			mpFragment->setSourceOffset(maSourceOffset);
            }
		}

        if( mpFragment )
        {
		    // now we need to 'select' the fragment, which will in turn
		    // pull informations from the image on demand.
		    // in case this fragment is still not located on any of the
		    // available pages ['naked'], we force the page manager to
		    // do it now, no way to defer this any longer...
		    if(!(mpFragment->select(mbIsDirty)))
			    mpPageManager->nakedFragment(mpFragment);

        }
	    mbIsDirty=false;
	}

	//////////////////////////////////////////////////////////////////////////////////
	// End of file
	//////////////////////////////////////////////////////////////////////////////////
}

