/**************************************************************
 *
 * 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 <canvas/verbosetrace.hxx>
#include <canvas/canvastools.hxx>

#include <activitybase.hxx>


namespace slideshow
{
    namespace internal
    {
        // TODO(P1): Elide some virtual function calls, by templifying this
        // static hierarchy

        ActivityBase::ActivityBase( const ActivityParameters& rParms ) :
            mpEndEvent( rParms.mrEndEvent ),
            mrEventQueue( rParms.mrEventQueue ),
            mpShape(),
            mpAttributeLayer(),
            maRepeats( rParms.mrRepeats ),
            mnAccelerationFraction( rParms.mnAccelerationFraction ),
            mnDecelerationFraction( rParms.mnDecelerationFraction ),
            mbAutoReverse( rParms.mbAutoReverse ),
            mbFirstPerformCall( true ),
            mbIsActive( true ) {}

        void ActivityBase::dispose()
        {
            // deactivate
            mbIsActive = false;

            // dispose event
            if( mpEndEvent )
                mpEndEvent->dispose();

            // release references
            mpEndEvent.reset();
            mpShape.reset();
            mpAttributeLayer.reset();
        }

        double ActivityBase::calcTimeLag() const
        {
            // TODO(Q1): implement different init process!
            if (isActive() && mbFirstPerformCall)
            {
                mbFirstPerformCall = false;

                // notify derived classes that we're
                // starting now
                const_cast<ActivityBase *>(this)->startAnimation();
            }
            return 0.0;
        }

        bool ActivityBase::perform()
        {
            // still active?
            if( !isActive() )
                return false; // no, early exit.

            OSL_ASSERT( ! mbFirstPerformCall );

            return true;
        }

        bool ActivityBase::isActive() const
        {
            return mbIsActive;
        }

        void ActivityBase::setTargets( const AnimatableShapeSharedPtr& 		rShape,
                                       const ShapeAttributeLayerSharedPtr& 	rAttrLayer )
        {
            ENSURE_OR_THROW( rShape,
                              "ActivityBase::setTargets(): Invalid shape" );
            ENSURE_OR_THROW( rAttrLayer,
                              "ActivityBase::setTargets(): Invalid attribute layer" );

            mpShape = rShape;
            mpAttributeLayer = rAttrLayer;
        }

        void ActivityBase::endActivity()
        {
            // this is a regular activity end
            mbIsActive = false;

            // Activity is ending, queue event, then
            if( mpEndEvent )
                mrEventQueue.addEvent( mpEndEvent );

            // release references
            mpEndEvent.reset();
        }

        void ActivityBase::dequeued()
        {
            // xxx todo:
//             // ignored here, if we're still active. Discrete
//             // activities are dequeued after every perform() call,
//             // thus, the call is only significant when isActive() ==
//             // false.
            if( !isActive() )
                endAnimation();
        }

        void ActivityBase::end()
        {
            if (!isActive() || isDisposed())
                return;
            // assure animation is started:
            if (mbFirstPerformCall) {
                mbFirstPerformCall = false;
                // notify derived classes that we're starting now
                this->startAnimation();
            }

            performEnd(); // calling private virtual
            endAnimation();
            endActivity();
        }

        double ActivityBase::calcAcceleratedTime( double nT ) const
        {
            // Handle acceleration/deceleration
            // ================================

            // clamp nT to permissible [0,1] range
            nT = ::basegfx::clamp( nT, 0.0, 1.0 );

            // take acceleration/deceleration into account. if the sum
            // of mnAccelerationFraction and mnDecelerationFraction
            // exceeds 1.0, ignore both (that's according to SMIL spec)
            if( (mnAccelerationFraction > 0.0 ||
                 mnDecelerationFraction > 0.0) &&
                mnAccelerationFraction + mnDecelerationFraction <= 1.0 )
            {
                /*
                // calc accelerated/decelerated time.
                //
                // We have three intervals:
                // 1 [0,a]
                // 2 [a,d]
                // 3 [d,1] (with a and d being acceleration/deceleration
                // fraction, resp.)
                //
                // The change rate during interval 1 is constantly
                // increasing, reaching 1 at a. It then stays at 1,
                // starting a linear decrease at d, ending with 0 at
                // time 1. The integral of this function is the
                // required new time nT'.
                //
                // As we arbitrarily assumed 1 as the upper value of
                // the change rate, the integral must be normalized to
                // reach nT'=1 at the end of the interval. This
                // normalization constant is:
                //
                // c = 1 - 0.5a - 0.5d
                //
                // The integral itself then amounts to:
                //
                // 0.5 nT^2 / a + (nT-a) + (nT - 0.5 nT^2 / d)
                //
                // (where each of the three summands correspond to the
                // three intervals above, and are applied only if nT
                // has reached the corresponding interval)
                //
                // The graph of the change rate is a trapezoid:
                //
                //   |
                //  1|      /--------------\
                //   |     /                \
                //   |    /                  \
                //   |   /                    \
                //   -----------------------------
                //      0   a              d  1
                //
                //*/
                const double nC( 1.0 - 0.5*mnAccelerationFraction - 0.5*mnDecelerationFraction );

                // this variable accumulates the new time value
                double nTPrime(0.0);

                if( nT < mnAccelerationFraction )
                {
                    nTPrime += 0.5*nT*nT/mnAccelerationFraction; // partial first interval
                }
                else
                {
                    nTPrime += 0.5*mnAccelerationFraction; // full first interval

                    if( nT <= 1.0-mnDecelerationFraction )
                    {
                        nTPrime += nT-mnAccelerationFraction; // partial second interval
                    }
                    else
                    {
                        nTPrime += 1.0 - mnAccelerationFraction - mnDecelerationFraction; // full second interval

                        const double nTRelative( nT - 1.0 + mnDecelerationFraction );

                        nTPrime += nTRelative - 0.5*nTRelative*nTRelative / mnDecelerationFraction;
                    }
                }

                // normalize, and assign to work variable
                nT = nTPrime / nC;
            }

            return nT;
        }
    }
}
