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

#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/vector/b2dvector.hxx>
#include <basegfx/range/b2drange.hxx>
#include <basegfx/curve/b2dcubicbezier.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>

#include <algorithm>


namespace basegfx
{
    namespace testtools
    {
        Plotter::Plotter( ::std::ostream& rOutputStream ) :
            mrOutputStream(rOutputStream),
            maPoints(),
            mbFirstElement( true )
        {
            // output gnuplot setup. We switch gnuplot to parametric
            // mode, therefore every plot has at least _two_
            // functions: one for the x and one for the y value, both
            // depending on t.
            mrOutputStream << "#!/usr/bin/gnuplot -persist" << ::std::endl 
                           << "#" << ::std::endl
                           << "# automatically generated by basegfx::testtools::Plotter, don't change!" << ::std::endl
                           << "#" << ::std::endl
                           << "set parametric" << ::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 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

                // 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(a,b,t) = a*(1-t) + b*t" << ::std::endl << ::std::endl
                           << "# end of setup" << ::std::endl << ::std::endl

                // Start the actual plot line
                           << "plot [t=0:1] ";
        }

        namespace
        {
            class PointWriter
            {
            public:
                PointWriter( ::std::ostream& rOutputStream ) :
                    mrOutputStream( rOutputStream )
                { 
                }

                void operator()( const B2DPoint& rPoint ) const
                {
                    mrOutputStream << rPoint.getX() << "\t" << rPoint.getY() << ::std::endl;
                    mrOutputStream << "e" << ::std::endl;
                }

            private:
                ::std::ostream& 	mrOutputStream;
            };
        }

        Plotter::~Plotter()
        {
            // End the plot line
            mrOutputStream << ::std::endl;
                        
            // write stored data points. Cannot write before, since
            // this is an inline dataset, which must be after the plot <...>
            // line
            ::std::for_each( maPoints.begin(), maPoints.end(), PointWriter(mrOutputStream) );
        }

        void Plotter::plot( const B2DPolygon& rPoly )
        {
            const sal_uInt32 pointCount( rPoly.count() );

            if( pointCount < 1 )
                return;
            
            if( pointCount == 1 )
            {
                plot( rPoly.getB2DPoint(0) );
                return;
            }

            sal_uInt32 i;
            for( i=0; i<pointCount-1; ++i )
            {
                if(rPoly.isNextControlPointUsed(i) || rPoly.isPrevControlPointUsed(i + 1))
                {
					const B2DCubicBezier aBezierPlot(
						rPoly.getB2DPoint(i), rPoly.getNextControlPoint(i), 
						rPoly.getPrevControlPoint(i + 1), rPoly.getB2DPoint(i + 1));
                    
					plot(aBezierPlot);
                }
                else
                {
                    plot( rPoly.getB2DPoint(i), rPoly.getB2DPoint(i+1) );
                }
            }
        }

        void Plotter::plot( const B2DPolyPolygon& rPolyPoly )
        {
            const sal_uInt32 nPolyCount( rPolyPoly.count() );

            sal_uInt32 i;
            for( i=0; i<nPolyCount; ++i )
            {
                plot( rPolyPoly.getB2DPolygon(i) );
            }
        }

        void Plotter::plot( const B2DPoint& rPoint )
        {
            maPoints.push_back( rPoint );
            writeSeparator();
            mrOutputStream << "'-' using ($1):($2) title \"Point " << maPoints.size() << "\" with points";
        }

        void Plotter::plot( const B2DRange& rRect )
        {
            // TODO: do that also as a data file plot. maPoints must
            // then become polymorph, but WTF.

            // decompose into four lines
            plot( B2DPoint(rRect.getMinX(),
                           rRect.getMinY()), 
                  B2DPoint(rRect.getMaxX(),
                           rRect.getMinY()) );
            plot( B2DPoint(rRect.getMaxX(),
                           rRect.getMinY()), 
                  B2DPoint(rRect.getMaxX(),
                           rRect.getMaxY()) );
            plot( B2DPoint(rRect.getMaxX(),
                           rRect.getMaxY()), 
                  B2DPoint(rRect.getMinX(),
                           rRect.getMaxY()) );
            plot( B2DPoint(rRect.getMinX(),
                           rRect.getMaxY()), 
                  B2DPoint(rRect.getMinX(),
                           rRect.getMinY()) );
        }

        void Plotter::plot( const B2DPoint& rStartPoint, const B2DPoint& rEndPoint )
        {
            writeSeparator();
            mrOutputStream << "line(" << rStartPoint.getX()
                           << "," << rEndPoint.getX() 
                           << ",t), "
                           << "line(" << rStartPoint.getY()
                           << "," << rEndPoint.getY() 
                           << ",t)";
        }

        void Plotter::plot( const B2DCubicBezier& rCurve )
        {
            writeSeparator();
            mrOutputStream << "cubicBezier(" << rCurve.getStartPoint().getX()
                           << "," << rCurve.getControlPointA().getX() 
                           << "," << rCurve.getControlPointB().getX() 
                           << "," << rCurve.getEndPoint().getX()
                           << ",t), "
                           << "cubicBezier(" << rCurve.getStartPoint().getY()
                           << "," << rCurve.getControlPointA().getY() 
                           << "," << rCurve.getControlPointB().getY() 
                           << "," << rCurve.getEndPoint().getY()
                           << ",t)";
        }

        void Plotter::writeSeparator()
        {
            if( mbFirstElement )
            {
                mbFirstElement = false;
            }
            else
            {
                mrOutputStream << ", ";
            }
        }

    }
}
