/**************************************************************
 *
 * 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 <osl/diagnose.h>

#include <basegfx/curve/b2dcubicbezier.hxx>

#include <basegfx/tools/debugplotter.hxx>
#include <boost/bind.hpp>


namespace basegfx
{
    namespace
    {
        void outputHeader( const ::rtl::OString& rTitle,
                           ::std::ostream* 		 pStm )
        {
            // output gnuplot setup
            if( pStm )
            {
                *pStm << "#!/usr/bin/gnuplot -persist" << ::std::endl <<
                    "#" << ::std::endl <<
                    "# automatically generated by basegfx, don't change!" << ::std::endl <<
                    "#" << ::std::endl <<
                    "#   --- " << rTitle.getStr() << " ---" << ::std::endl <<
                    "#" << ::std::endl <<
                    "set parametric" << ::std::endl <<
                    "# set terminal postscript eps enhanced color " << ::std::endl <<
                    "# set output \"plot.eps\"" << ::std::endl <<
                    // This function plots a cubic bezier curve. P,q,r,s
                    // are the control point elements of the corresponding
                    // output coordinate component (i.e. x components for
                    // the x plot, and y components for the y plot)
                    "cubicBezier(p,q,r,s,t) = p*(1-t)**3+q*3*(1-t)**2*t+r*3*(1-t)*t**2+s*t**3" << ::std::endl <<
                    // This function plots the derivative of a cubic
                    // bezier curve. P,q,r,s are the control point
                    // components of the _original_ curve
                    "cubicBezDerivative(p,q,r,s,t) = 3*(q-p)*(1-t)**2+6*(r-q)*(1-t)*t+3*(s-r)*t**2" << ::std::endl <<
                    // Plot a line's component of a line between a and b
                    // (where a and b should be the corresponding
                    // components of the line's start and end point,
                    // respectively)
                    "line(p,q,r) = p*(1-t)+q*t" << ::std::endl <<
                    // Plot a line's x component of a line in implicit
                    // form ax + by + c = 0
                    "implicitLineX(a,b,c,t) = a*-c + t*-b" << ::std::endl <<
                    // Plot a line's y component of a line in implicit
                    // form ax + by + c = 0
                    "implicitLineY(a,b,c,t) = b*-c + t*a" << ::std::endl <<
                    "pointmarkx(c,t) = c-0.03*t" << ::std::endl <<										 // hack for displaying single points in parametric form
                    "pointmarky(c,t) = c+0.03*t" << ::std::endl <<										 // hack for displaying single points in parametric form
                    "# end of setup" << ::std::endl;
            }
            else
            {
                OSL_TRACE( "#!/usr/bin/gnuplot -persist\n",
                           "#\n",
                           "# automatically generated by basegfx, don't change!\n",
                           "#\n",
                           "#   --- %s ---\n",
                           "#\n",
                           "set parametric\n",
                           // This function plots a cubic bezier curve. P,q,r,s
                           // are the control point elements of the corresponding
                           // output coordinate component (i.e. x components for
                           // the x plot, and y components for the y plot)
                           "cubicBezier(p,q,r,s,t) = p*(1-t)**3+q*3*(1-t)**2*t+r*3*(1-t)*t**2+s*t**3\n",
                           // This function plots the derivative of a cubic
                           // bezier curve. P,q,r,s are the control point
                           // components of the _original_ curve
                           "cubicBezDerivative(p,q,r,s,t) = 3*(q-p)*(1-t)**2+6*(r-q)*(1-t)*t+3*(s-r)*t**2\n",
                           // Plot a line's component of a line between a and b
                           // (where a and b should be the corresponding
                           // components of the line's start and end point,
                           // respectively)
                           "line(p,q,r) = p*(1-t)+q*t\n",
                           // Plot a line's x component of a line in implicit
                           // form ax + by + c = 0
                           "implicitLineX(a,b,c,t) = a*-c + t*-b\n",
                           // Plot a line's y component of a line in implicit
                           // form ax + by + c = 0
                           "implicitLineY(a,b,c,t) = b*-c + t*a\n",
                           "pointmarkx(c,t) = c-0.03*t\n",										 // hack for displaying single points in parametric form
                           "pointmarky(c,t) = c+0.03*t\n",										 // hack for displaying single points in parametric form
                           "# end of setup\n",
                           rTitle.getStr() );
            }
        }

        class Writer
        {
        public:
            Writer( ::std::ostream* pStm ) :
                mpStream( pStm )
            {
            }

            void outputPoint( const ::std::pair< B2DPoint, ::rtl::OString >& rElem )
            {
                if( mpStream )
                    *mpStream << " " << rElem.first.getX() << "\t" << rElem.first.getY() << ::std::endl;
                else
                    OSL_TRACE( " %f\t%f\n", rElem.first.getX(), rElem.first.getY() );
            }

            void outputVector( const ::std::pair< B2DVector, ::rtl::OString >& rElem )
            {
                if( mpStream )
                    *mpStream << " " << rElem.first.getX() << "\t" << rElem.first.getY() << ::std::endl << ::std::endl;
                else
                    OSL_TRACE( " %f\t%f\n\n", rElem.first.getX(), rElem.first.getY() );
            }

            void outputRect( const ::std::pair< B2DRange, ::rtl::OString >& rElem )
            {
                const double nX0( rElem.first.getMinX() );
                const double nY0( rElem.first.getMinY() );
                const double nX1( rElem.first.getMaxX() );
                const double nY1( rElem.first.getMaxY() );

                if( mpStream )
                    *mpStream << " "
                              << nX0 << "\t" << nY0 << "\t"
                              << nX1 << "\t" << nY0 << "\t"
                              << nX1 << "\t" << nY1 << "\t"
                              << nX0 << "\t" << nY1 << "\t"
                              << nX0 << "\t" << nY0 << ::std::endl << ::std::endl;

                else
                    OSL_TRACE( " %f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\n\n",
                               nX0, nY0,
                               nX1, nY0,
                               nX1, nY1,
                               nX0, nY1,
                               nX0, nY0 );
            }

        private:
            ::std::ostream* 	mpStream;
        };
    }

    DebugPlotter::DebugPlotter( const sal_Char* pTitle ) :
        maTitle( pTitle ),
        maPoints(),
        maVectors(),
        maRanges(),
        maPolygons(),
        mpOutputStream(NULL)
    {
    }

    DebugPlotter::DebugPlotter( const sal_Char* pTitle,
                                ::std::ostream& rOutputStream ) :
        maTitle( pTitle ),
        maPoints(),
        maVectors(),
        maRanges(),
        maPolygons(),
        mpOutputStream(&rOutputStream)
    {
    }

    DebugPlotter::~DebugPlotter()
    {
        const bool bHavePoints( !maPoints.empty() );
        const bool bHaveVectors( !maVectors.empty() );
        const bool bHaveRanges( !maRanges.empty() );
        const bool bHavePolygons( !maPolygons.empty() );

        if( bHavePoints ||
            bHaveVectors ||
            bHaveRanges ||
            bHavePolygons )
        {
            outputHeader( maTitle, mpOutputStream );

            print( "\n\n# parametric primitive output\n"
                   "plot [t=0:1] \\\n" );

            // output plot declarations for used entities
            bool bNeedColon( false );
            if( bHavePoints )
            {
                print( " '-' using ($1):($2) title \"Points\" with points" );
                bNeedColon = true;
            }
            if( bHaveVectors )
            {
                if( bNeedColon )
                    print( ", \\\n" );

                print( " '-' using ($1):($2) title \"Vectors\" with lp" );
                bNeedColon = true;
            }
            if( bHaveRanges )
            {
                if( bNeedColon )
                    print( ", \\\n" );

                print( " '-' using ($1):($2) title \"Ranges\" with lines" );
                bNeedColon = true;
            }
            if( bHavePolygons )
            {
                const ::std::size_t nSize( maPolygons.size() );
                for( ::std::size_t i=0; i<nSize; ++i )
                {
                    if( maPolygons.at(i).first.areControlPointsUsed() )
                    {
                        const B2DPolygon& rCurrPoly( maPolygons.at(i).first );

                        const sal_uInt32 nCount( rCurrPoly.count() );
                        for( sal_uInt32 k=0; k<nCount; ++k )
                        {
                            if( bNeedColon )
                                print( ", \\\n" );

                            const B2DPoint& rP0( rCurrPoly.getB2DPoint(k) );
                            const B2DPoint& rP1( rCurrPoly.getNextControlPoint(k) );
                            const B2DPoint& rP2( rCurrPoly.getPrevControlPoint((k + 1) % nCount) );
                            const B2DPoint& rP3( k+1<nCount ? rCurrPoly.getB2DPoint(k+1) : rCurrPoly.getB2DPoint(k) );

                            if( mpOutputStream )
                                *mpOutputStream << "  cubicBezier("
                                                << rP0.getX() << ","
                                    << rP1.getX() << ","
                                    << rP2.getX() << ","
                                    << rP3.getX() << ",t), \\\n   cubicBezier("
                                    << rP0.getY() << ","
                                    << rP1.getY() << ","
                                    << rP2.getY() << ","
                                    << rP3.getY() << ",t)";
                            else
                                OSL_TRACE( "  cubicBezier(%f,%f,%f,%f,t), \\\n"
                                           "   cubicBezier(%f,%f,%f,%f,t)",
                                           rP0.getX(),
                                           rP1.getX(),
                                           rP2.getX(),
                                           rP3.getX(),
                                           rP0.getY(),
                                           rP1.getY(),
                                           rP2.getY(),
                                           rP3.getY() );

                            bNeedColon = true;
                        }
                    }
                    else
                    {
                        if( bNeedColon )
                            print( ", \\\n" );

                        if( mpOutputStream )
                            *mpOutputStream << " '-' using ($1):($2) title \"Polygon "
                                            << maPolygons.at(i).second.getStr() << "\" with lp";
                        else
                            OSL_TRACE( " '-' using ($1):($2) title \"Polygon %s\" with lp",
                                       maPolygons.at(i).second.getStr() );

                        bNeedColon = true;
                    }
                }
            }

            if( bHavePoints )
            {
                Writer aWriter( mpOutputStream );

                ::std::for_each( maPoints.begin(),
                                 maPoints.end(),
                                 ::boost::bind( &Writer::outputPoint,
                                                ::boost::ref( aWriter ),
                                                _1 ) );
                print( "e\n" );
            }

            if( bHaveVectors )
            {
                Writer aWriter( mpOutputStream );

                ::std::for_each( maVectors.begin(),
                                 maVectors.end(),
                                 ::boost::bind( &Writer::outputVector,
                                                ::boost::ref( aWriter ),
                                                _1 ) );
                print( "e\n" );
            }

            if( bHaveRanges )
            {
                Writer aWriter( mpOutputStream );

                ::std::for_each( maRanges.begin(),
                                 maRanges.end(),
                                 ::boost::bind( &Writer::outputRect,
                                                ::boost::ref( aWriter ),
                                                _1 ) );
                print( "e\n" );
            }

            if( bHavePolygons )
            {
                const ::std::size_t nSize( maPolygons.size() );
                for( ::std::size_t i=0; i<nSize; ++i )
                {
                    if( !maPolygons.at(i).first.areControlPointsUsed() )
                    {
                        const B2DPolygon& rCurrPoly( maPolygons.at(i).first );

                        const sal_uInt32 nCount( rCurrPoly.count() );
                        for( sal_uInt32 k=0; k<nCount; ++k )
                        {
                            const B2DPoint& rP( rCurrPoly.getB2DPoint(k) );

                            if( mpOutputStream )
                                *mpOutputStream << " " << rP.getX() << "," << rP.getY();
                            else
                                OSL_TRACE( " %f,%f",
                                           rP.getX(),
                                           rP.getX() );
                        }

                        print( "\ne\n" );
                    }
                }
            }
        }
    }

    void DebugPlotter::plot( const B2DPoint& rPoint,
                             const sal_Char* pTitle )
    {
        maPoints.push_back( ::std::make_pair( rPoint,
                                              ::rtl::OString( pTitle ) ) );
    }

    void DebugPlotter::plot( const B2DVector&	rVec,
                             const sal_Char* 	pTitle )
    {
        maVectors.push_back( ::std::make_pair( rVec,
                                               ::rtl::OString( pTitle ) ) );
    }

    void DebugPlotter::plot( const B2DCubicBezier&	rBezier,
                             const sal_Char* 		pTitle )
    {
        B2DPolygon aPoly;
        aPoly.append(rBezier.getStartPoint());
		aPoly.appendBezierSegment(rBezier.getControlPointA(), rBezier.getControlPointB(), rBezier.getEndPoint());
        maPolygons.push_back( ::std::make_pair( aPoly,
                                                ::rtl::OString( pTitle ) ) );
    }

    void DebugPlotter::plot( const B2DRange& rRange,
                             const sal_Char* pTitle )
    {
        maRanges.push_back( ::std::make_pair( rRange,
                                              ::rtl::OString( pTitle ) ) );
    }

    void DebugPlotter::plot( const B2DPolygon&	rPoly,
                             const sal_Char* 	pTitle )
    {
        maPolygons.push_back( ::std::make_pair( rPoly,
                                                ::rtl::OString( pTitle ) ) );
    }

    void DebugPlotter::plot( const B2DPolyPolygon&	rPoly,
                             const sal_Char* 		pTitle )
    {
        const ::rtl::OString aTitle( pTitle );
        const sal_uInt32 nCount( rPoly.count() );
        for( sal_uInt32 i=0; i<nCount; ++i )
            maPolygons.push_back( ::std::make_pair( rPoly.getB2DPolygon( i ),
                                                    aTitle ) );
    }

    void DebugPlotter::print( const sal_Char* pStr )
    {
        if( mpOutputStream )
            *mpOutputStream << pStr;
        else
            OSL_TRACE( pStr );
    }
}
