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

// must be first
#include <canvas/debug.hxx>
#include <tools/diagnose_ex.h>

#include <rtl/math.hxx>

#include <smilfunctionparser.hxx>
#include <expressionnodefactory.hxx>

#include <rtl/ustring.hxx>
#include <canvas/verbosetrace.hxx>

#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/point/b2dpoint.hxx>

// Makes parser a static resource, 
// we're synchronized externally.
// But watch out, the parser might have
// state not visible to this code!
#define BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE
#if defined(VERBOSE) && defined(DBG_UTIL)
#include <typeinfo>
#define BOOST_SPIRIT_DEBUG
#endif
#include <boost/spirit/include/classic_core.hpp>

#if OSL_DEBUG_LEVEL > 0
#include <iostream>
#endif
#include <functional>
#include <algorithm>
#include <stack>



/* Implementation of SmilFunctionParser class */

namespace slideshow
{
    namespace internal
    {
        namespace
        {
            typedef const sal_Char*					  StringIteratorT;

            struct ParserContext
            {
                typedef ::std::stack< ExpressionNodeSharedPtr > OperandStack;

                // stores a stack of not-yet-evaluated operands. This is used
                // by the operators (i.e. '+', '*', 'sin' etc.) to pop their
                // arguments from. If all arguments to an operator are constant,
                // the operator pushes a precalculated result on the stack, and
                // a composite ExpressionNode otherwise.
                OperandStack				maOperandStack;

                // bounds of the shape this expression is associated with
                ::basegfx::B2DRectangle		maShapeBounds;

                // when true, enable usage of time-dependent variable '$' 
                // in expressions
                bool						mbParseAnimationFunction;
            };

            typedef ::boost::shared_ptr< ParserContext > ParserContextSharedPtr;


            template< typename Generator > class ShapeBoundsFunctor
            {
            public:
                ShapeBoundsFunctor( Generator 						aGenerator,
                                    const ParserContextSharedPtr& 	rContext ) :
                    maGenerator( aGenerator ),
                    mpContext( rContext )
                {
                    ENSURE_OR_THROW( mpContext,
                                      "ShapeBoundsFunctor::ShapeBoundsFunctor(): Invalid context" );
                }

                void operator()( StringIteratorT, StringIteratorT ) const
                {
                    mpContext->maOperandStack.push( 
                        ExpressionNodeFactory::createConstantValueExpression( 
                            maGenerator( mpContext->maShapeBounds ) ) );
                }

            private:
                Generator				maGenerator;
                ParserContextSharedPtr	mpContext;
            };

            template< typename Generator > ShapeBoundsFunctor< Generator > 
	            makeShapeBoundsFunctor( const Generator& 				rGenerator,
                                        const ParserContextSharedPtr&	rContext )
            {
                return ShapeBoundsFunctor<Generator>(rGenerator, rContext);
            }

            /** Generate apriori constant value
             */
            class ConstantFunctor
            {
            public:
                ConstantFunctor( double 						rValue,
                                 const ParserContextSharedPtr&	rContext ) :
                    mnValue( rValue ),
                    mpContext( rContext )
                {
                    ENSURE_OR_THROW( mpContext,
                                      "ConstantFunctor::ConstantFunctor(): Invalid context" );
                }

                void operator()( StringIteratorT, StringIteratorT ) const
                {
                    mpContext->maOperandStack.push( 
                        ExpressionNodeFactory::createConstantValueExpression( mnValue ) );
                }

            private:
                const double			mnValue;
                ParserContextSharedPtr	mpContext;
            };

            /** Generate parse-dependent-but-then-constant value
             */
            class DoubleConstantFunctor
            {
            public:
                DoubleConstantFunctor( const ParserContextSharedPtr& rContext ) :
                    mpContext( rContext )
                {
                    ENSURE_OR_THROW( mpContext,
                                      "DoubleConstantFunctor::DoubleConstantFunctor(): Invalid context" );
                }

                void operator()( double n ) const
                {
                    // push constant value expression to the stack
                    mpContext->maOperandStack.push( 
                        ExpressionNodeFactory::createConstantValueExpression( n ) );
                }

            private:
                ParserContextSharedPtr	mpContext;
            };

            /** Generate special t value expression node
             */
            class ValueTFunctor
            {
            public:
                ValueTFunctor( const ParserContextSharedPtr& rContext ) :
                    mpContext( rContext )
                {
                    ENSURE_OR_THROW( mpContext,
                                      "ValueTFunctor::ValueTFunctor(): Invalid context" );
                }

                void operator()( StringIteratorT, StringIteratorT ) const
                {
                    if( !mpContext->mbParseAnimationFunction )
                    {
                        OSL_ENSURE( false,
                                    "ValueTFunctor::operator(): variable encountered, but we're not parsing a function here" );
                        throw ParseError();
                    }

                    // push special t value expression to the stack
                    mpContext->maOperandStack.push( 
                        ExpressionNodeFactory::createValueTExpression() );
                }

            private:
                ParserContextSharedPtr	mpContext;
            };

            template< typename Functor > class UnaryFunctionFunctor
            {
            private:
                /** ExpressionNode implementation for unary
                    function over one ExpressionNode
                 */
                class UnaryFunctionExpression : public ExpressionNode
                {
                public:
                    UnaryFunctionExpression( const Functor&					rFunctor,
                                             const ExpressionNodeSharedPtr&	rArg ) :
                        maFunctor( rFunctor ),
                        mpArg( rArg )
                    {
                    }

                    virtual double operator()( double t ) const
                    {
                        return maFunctor( (*mpArg)(t) );
                    }
                    
                    virtual bool isConstant() const
                    {
                        return mpArg->isConstant();
                    }

                private:
                    Functor					maFunctor;
                    ExpressionNodeSharedPtr	mpArg;
                };

            public:
                UnaryFunctionFunctor( const Functor& 				rFunctor,
                                      const ParserContextSharedPtr&	rContext ) :
                    maFunctor( rFunctor ),
                    mpContext( rContext )
                {
                    ENSURE_OR_THROW( mpContext,
                                      "UnaryFunctionFunctor::UnaryFunctionFunctor(): Invalid context" );
                }

                void operator()( StringIteratorT, StringIteratorT ) const
                {
                    ParserContext::OperandStack& rNodeStack( mpContext->maOperandStack );

                    if( rNodeStack.size() < 1 )
                        throw ParseError( "Not enough arguments for unary operator" );

                    // retrieve arguments
                    ExpressionNodeSharedPtr pArg( rNodeStack.top() );
                    rNodeStack.pop();

                    // check for constness
                    if( pArg->isConstant() )
                    {
                        rNodeStack.push( 
                            ExpressionNodeFactory::createConstantValueExpression(
                                maFunctor( (*pArg)(0.0) ) ) );
                    }
                    else
                    {
                        // push complex node, that calcs the value on demand
                        rNodeStack.push( 
                            ExpressionNodeSharedPtr(
                                new UnaryFunctionExpression( 
                                    maFunctor,
                                    pArg ) ) );
                    }
                }

            private:
                Functor					maFunctor;
                ParserContextSharedPtr	mpContext;
            };

            // TODO(Q2): Refactor makeUnaryFunctionFunctor,
            // makeBinaryFunctionFunctor and the whole
            // ExpressionNodeFactory, to use a generic
            // makeFunctionFunctor template, which is overloaded for
            // unary, binary, ternary, etc. function pointers.
            template< typename Functor > UnaryFunctionFunctor<Functor> 
	            makeUnaryFunctionFunctor( const Functor& 				rFunctor,
                                          const ParserContextSharedPtr&	rContext )
            {
                return UnaryFunctionFunctor<Functor>( rFunctor, rContext );
            }

            // MSVC has problems instantiating above template function with plain function 
            // pointers (doesn't like the const reference there). Thus, provide it with
            // a dedicated overload here.
            UnaryFunctionFunctor< double (*)(double) > 
	            makeUnaryFunctionFunctor( double (*pFunc)(double),
                                          const ParserContextSharedPtr&	rContext )
            {
                return UnaryFunctionFunctor< double (*)(double) >( pFunc, rContext );
            }

            /** Implements a binary function over two ExpressionNodes

                @tpl Generator
                Generator functor, to generate an ExpressionNode of
                appropriate type
                
             */
            template< class Generator > class BinaryFunctionFunctor
            {
            public:
                BinaryFunctionFunctor( const Generator& 				rGenerator,
                                       const ParserContextSharedPtr&	rContext ) :
                    maGenerator( rGenerator ),
                    mpContext( rContext )
                {
                    ENSURE_OR_THROW( mpContext,
                                      "BinaryFunctionFunctor::BinaryFunctionFunctor(): Invalid context" );
                }

                void operator()( StringIteratorT, StringIteratorT ) const
                {
                    ParserContext::OperandStack& rNodeStack( mpContext->maOperandStack );

                    if( rNodeStack.size() < 2 )
                        throw ParseError( "Not enough arguments for binary operator" );

                    // retrieve arguments
                    ExpressionNodeSharedPtr pSecondArg( rNodeStack.top() );
                    rNodeStack.pop();
                    ExpressionNodeSharedPtr pFirstArg( rNodeStack.top() );
                    rNodeStack.pop();

                    // create combined ExpressionNode
                    ExpressionNodeSharedPtr pNode( maGenerator( pFirstArg,
                                                                pSecondArg ) );
                    // check for constness
                    if( pFirstArg->isConstant() &&
                        pSecondArg->isConstant() )
                    {
                        // call the operator() at pNode, store result
                        // in constant value ExpressionNode.
                        rNodeStack.push( 
                            ExpressionNodeFactory::createConstantValueExpression(
                                (*pNode)( 0.0 ) ) );
                    }
                    else
                    {
                        // push complex node, that calcs the value on demand
                        rNodeStack.push( pNode );
                    }
                }

            private:
                Generator				maGenerator;
                ParserContextSharedPtr	mpContext;
            };

            template< typename Generator > BinaryFunctionFunctor<Generator> 
            	makeBinaryFunctionFunctor( const Generator&					rGenerator,
                                           const ParserContextSharedPtr&	rContext )
            {
                return BinaryFunctionFunctor<Generator>( rGenerator, rContext );
            }


            // Workaround for MSVC compiler anomaly (stack trashing)
            //
            // The default ureal_parser_policies implementation of parse_exp 
            // triggers a really weird error in MSVC7 (Version 13.00.9466), in 
            // that the real_parser_impl::parse_main() call of parse_exp() 
            // overwrites the frame pointer _on the stack_ (EBP of the calling
            // function gets overwritten while lying on the stack). 
            //
            // For the time being, our parser thus can only read the 1.0E10 
            // notation, not the 1.0e10 one.
            //
            // TODO(F1): Also handle the 1.0e10 case here.
            template< typename T > struct custom_real_parser_policies : public ::boost::spirit::ureal_parser_policies<T>
            {
                template< typename ScannerT >
	                static typename ::boost::spirit::parser_result< ::boost::spirit::chlit<>, ScannerT >::type
                parse_exp(ScannerT& scan)
                { 
                    // as_lower_d somehow breaks MSVC7
                    return ::boost::spirit::ch_p('E').parse(scan); 
                }
            };

            /* This class implements the following grammar (more or
               less literally written down below, only slightly
               obfuscated by the parser actions):

               identifier = '$'|'pi'|'e'|'X'|'Y'|'Width'|'Height'                                                   
                                                                                                                    
               function = 'abs'|'sqrt'|'sin'|'cos'|'tan'|'atan'|'acos'|'asin'|'exp'|'log'

               basic_expression =                                                                                   
               				 number |                                                                            
               				 identifier |                                                                        
               				 function '(' additive_expression ')' |                                              
               				 '(' additive_expression ')'                                                         
                                                                                                                    
               unary_expression = 
               					'-' basic_expression |
                                basic_expression
                                                                                                                    
               multiplicative_expression =                                                                          
               				    unary_expression ( ( '*' unary_expression )* |                           
                                				   ( '/' unary_expression )* )
                                                                                                                    
               additive_expression =                                                                                
               					multiplicative_expression ( ( '+' multiplicative_expression )* |                              
               											    ( '-' multiplicative_expression )* ) 

             */
            class ExpressionGrammar : public ::boost::spirit::grammar< ExpressionGrammar >
            {
            public:
                /** Create an arithmetic expression grammar

                	@param rParserContext
                    Contains context info for the parser
                 */
                ExpressionGrammar( const ParserContextSharedPtr& rParserContext ) :
                    mpParserContext( rParserContext )
                {
                }

                template< typename ScannerT > class definition
                {
                public:
                    // grammar definition
                    definition( const ExpressionGrammar& self )
                    {
                        using ::boost::spirit::str_p;
                        using ::boost::spirit::real_parser;

                        identifier =
	                            	str_p( "$" 	 	)[ ValueTFunctor(															   self.getContext()) ]
                              |		str_p( "pi"     )[ ConstantFunctor(M_PI, 					  	  	  						   self.getContext()) ]
                              |		str_p( "e"      )[ ConstantFunctor(M_E, 					  	  	  						   self.getContext()) ]
                              |		str_p( "x"      )[ makeShapeBoundsFunctor(::std::mem_fun_ref(&::basegfx::B2DRange::getCenterX),self.getContext()) ]
                              |		str_p( "y"      )[ makeShapeBoundsFunctor(::std::mem_fun_ref(&::basegfx::B2DRange::getCenterY),self.getContext()) ]
                              |   	str_p( "width"  )[ makeShapeBoundsFunctor(::std::mem_fun_ref(&::basegfx::B2DRange::getWidth),  self.getContext()) ]
                              |		str_p( "height" )[ makeShapeBoundsFunctor(::std::mem_fun_ref(&::basegfx::B2DRange::getHeight), self.getContext()) ]
                              ;
                        
                        unaryFunction = 
                            	(str_p( "abs"  ) >> '(' >> additiveExpression >> ')' )[ makeUnaryFunctionFunctor(&fabs, self.getContext()) ]
                            |	(str_p( "sqrt" ) >> '(' >> additiveExpression >> ')' )[ makeUnaryFunctionFunctor(&sqrt, self.getContext()) ]
                            |	(str_p( "sin"  ) >> '(' >> additiveExpression >> ')' )[ makeUnaryFunctionFunctor(&sin,  self.getContext()) ]
                            |	(str_p( "cos"  ) >> '(' >> additiveExpression >> ')' )[ makeUnaryFunctionFunctor(&cos,  self.getContext()) ]
                            |	(str_p( "tan"  ) >> '(' >> additiveExpression >> ')' )[ makeUnaryFunctionFunctor(&tan,  self.getContext()) ]
                            |	(str_p( "atan" ) >> '(' >> additiveExpression >> ')' )[ makeUnaryFunctionFunctor(&atan, self.getContext()) ]
                            |	(str_p( "acos" ) >> '(' >> additiveExpression >> ')' )[ makeUnaryFunctionFunctor(&acos, self.getContext()) ]
                            |	(str_p( "asin" ) >> '(' >> additiveExpression >> ')' )[ makeUnaryFunctionFunctor(&asin, self.getContext()) ]
                            |	(str_p( "exp"  ) >> '(' >> additiveExpression >> ')' )[ makeUnaryFunctionFunctor(&exp,  self.getContext()) ]
                            |	(str_p( "log"  ) >> '(' >> additiveExpression >> ')' )[ makeUnaryFunctionFunctor(&log,  self.getContext()) ]
                            ;

                        binaryFunction = 
	                            (str_p( "min"  ) >> '(' >> additiveExpression >> ',' >> additiveExpression >> ')' )[ makeBinaryFunctionFunctor(&ExpressionNodeFactory::createMinExpression, self.getContext()) ]
                            |	(str_p( "max"  ) >> '(' >> additiveExpression >> ',' >> additiveExpression >> ')' )[ makeBinaryFunctionFunctor(&ExpressionNodeFactory::createMaxExpression, self.getContext()) ]
                            ;

                        basicExpression = 
                            	real_parser<double, custom_real_parser_policies<double> >()[ DoubleConstantFunctor(self.getContext()) ]
                            |	identifier
                            |	unaryFunction
                            |	binaryFunction
                            |	'(' >> additiveExpression >> ')'
                            ;
                            
                        unaryExpression = 
                            	('-' >> basicExpression)[ makeUnaryFunctionFunctor(::std::negate<double>(), self.getContext()) ]
                            |	basicExpression
                            ;

                        multiplicativeExpression = 
                            	unaryExpression
                            >> *( ('*' >> unaryExpression)[ makeBinaryFunctionFunctor(&ExpressionNodeFactory::createMultipliesExpression, self.getContext()) ]
                                | ('/' >> unaryExpression)[ makeBinaryFunctionFunctor(&ExpressionNodeFactory::createDividesExpression,    self.getContext()) ]
                                )
                            ;

                        additiveExpression = 
                                multiplicativeExpression
                            >> *( ('+' >> multiplicativeExpression)[ makeBinaryFunctionFunctor(&ExpressionNodeFactory::createPlusExpression,  self.getContext()) ]
                                | ('-' >> multiplicativeExpression)[ makeBinaryFunctionFunctor(&ExpressionNodeFactory::createMinusExpression, self.getContext()) ]
                                )
                            ;

                        BOOST_SPIRIT_DEBUG_RULE(additiveExpression);
                        BOOST_SPIRIT_DEBUG_RULE(multiplicativeExpression);
                        BOOST_SPIRIT_DEBUG_RULE(unaryExpression);
                        BOOST_SPIRIT_DEBUG_RULE(basicExpression);
                        BOOST_SPIRIT_DEBUG_RULE(unaryFunction);
                        BOOST_SPIRIT_DEBUG_RULE(binaryFunction);
                        BOOST_SPIRIT_DEBUG_RULE(identifier);
                    }

                    const ::boost::spirit::rule< ScannerT >& start() const
                    {
                        return additiveExpression;
                    }
                    
                private:
                    // the constituents of the Spirit arithmetic expression grammar. 
                    // For the sake of readability, without 'ma' prefix.
                    ::boost::spirit::rule< ScannerT >	additiveExpression;
                    ::boost::spirit::rule< ScannerT >	multiplicativeExpression;
                    ::boost::spirit::rule< ScannerT >	unaryExpression;
                    ::boost::spirit::rule< ScannerT >	basicExpression;
                    ::boost::spirit::rule< ScannerT >	unaryFunction;
                    ::boost::spirit::rule< ScannerT >	binaryFunction;
                    ::boost::spirit::rule< ScannerT >	identifier;
                };                

                const ParserContextSharedPtr& getContext() const
                {
                    return mpParserContext;
                }

            private:
                ParserContextSharedPtr	mpParserContext; // might get modified during parsing
            };
            
#ifdef BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE
            const ParserContextSharedPtr& getParserContext()
            {
                static ParserContextSharedPtr lcl_parserContext( new ParserContext() );

                // clear node stack (since we reuse the static object, that's 
                // the whole point here)
                while( !lcl_parserContext->maOperandStack.empty() )
                    lcl_parserContext->maOperandStack.pop();

                return lcl_parserContext;
            }
#endif
        }

        ExpressionNodeSharedPtr SmilFunctionParser::parseSmilValue( const ::rtl::OUString& 			rSmilValue,
                                                                    const ::basegfx::B2DRectangle&	rRelativeShapeBounds )
        {
            // TODO(Q1): Check if a combination of the RTL_UNICODETOTEXT_FLAGS_* 
            // gives better conversion robustness here (we might want to map space 
            // etc. to ASCII space here)
            const ::rtl::OString& rAsciiSmilValue( 
                rtl::OUStringToOString( rSmilValue, RTL_TEXTENCODING_ASCII_US ) );

            StringIteratorT aStart( rAsciiSmilValue.getStr() );
            StringIteratorT aEnd( rAsciiSmilValue.getStr()+rAsciiSmilValue.getLength() );

            ParserContextSharedPtr pContext;

#ifdef BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE
            // static parser context, because the actual
            // Spirit parser is also a static object
            pContext = getParserContext();
#else
            pContext.reset( new ParserContext() );
#endif

            pContext->maShapeBounds = rRelativeShapeBounds;
            pContext->mbParseAnimationFunction = false; // parse with '$' disabled


            ExpressionGrammar aExpressionGrammer( pContext );
            const ::boost::spirit::parse_info<StringIteratorT> aParseInfo( 
                  ::boost::spirit::parse( aStart,
                                          aEnd,
                                          aExpressionGrammer,
                                          ::boost::spirit::space_p ) );
            OSL_DEBUG_ONLY(::std::cout.flush()); // needed to keep stdout and cout in sync

            // input fully congested by the parser?
            if( !aParseInfo.full )
                throw ParseError( "SmilFunctionParser::parseSmilValue(): string not fully parseable" );

            // parser's state stack now must contain exactly _one_ ExpressionNode, 
            // which represents our formula.
            if( pContext->maOperandStack.size() != 1 )
                throw ParseError( "SmilFunctionParser::parseSmilValue(): incomplete or empty expression" );

            return pContext->maOperandStack.top();
        }

        ExpressionNodeSharedPtr SmilFunctionParser::parseSmilFunction( const ::rtl::OUString& 			rSmilFunction,
                                                                       const ::basegfx::B2DRectangle&	rRelativeShapeBounds )
        {
            // TODO(Q1): Check if a combination of the RTL_UNICODETOTEXT_FLAGS_* 
            // gives better conversion robustness here (we might want to map space 
            // etc. to ASCII space here)
            const ::rtl::OString& rAsciiSmilFunction( 
                rtl::OUStringToOString( rSmilFunction, RTL_TEXTENCODING_ASCII_US ) );

            StringIteratorT aStart( rAsciiSmilFunction.getStr() );
            StringIteratorT aEnd( rAsciiSmilFunction.getStr()+rAsciiSmilFunction.getLength() );

            ParserContextSharedPtr pContext;

#ifdef BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE
            // static parser context, because the actual
            // Spirit parser is also a static object
            pContext = getParserContext();
#else
            pContext.reset( new ParserContext() );
#endif

            pContext->maShapeBounds = rRelativeShapeBounds;
            pContext->mbParseAnimationFunction = true; // parse with '$' enabled


            ExpressionGrammar aExpressionGrammer( pContext );
            const ::boost::spirit::parse_info<StringIteratorT> aParseInfo( 
                  ::boost::spirit::parse( aStart,
                                          aEnd,
                                          aExpressionGrammer >> ::boost::spirit::end_p,
                                          ::boost::spirit::space_p ) );
            OSL_DEBUG_ONLY(::std::cout.flush()); // needed to keep stdout and cout in sync

            // input fully congested by the parser?
            if( !aParseInfo.full )
                throw ParseError( "SmilFunctionParser::parseSmilFunction(): string not fully parseable" );

            // parser's state stack now must contain exactly _one_ ExpressionNode, 
            // which represents our formula.
            if( pContext->maOperandStack.size() != 1 )
                throw ParseError( "SmilFunctionParser::parseSmilFunction(): incomplete or empty expression" );

            return pContext->maOperandStack.top();
        }
    }
}
