/**************************************************************
 *
 * 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"

#include <canvas/debug.hxx>
#include <canvas/verbosetrace.hxx>

#include "delayevent.hxx"
#include "eventqueue.hxx"
#include "usereventqueue.hxx"
#include "sequentialtimecontainer.hxx"
#include "tools.hxx"

#include <boost/bind.hpp>
#include <algorithm>

namespace slideshow {
namespace internal {

void SequentialTimeContainer::activate_st()
{
    // resolve first possible child, ignore
    for ( ; mnFinishedChildren < maChildren.size(); ++mnFinishedChildren ) {
        if (resolveChild( maChildren[mnFinishedChildren] ))
            break;
        else {
            // node still UNRESOLVED, no need to deactivate or end...
            OSL_ENSURE( false, "### resolving child failed!" );
        }
    }

    if (isDurationIndefinite() &&
        (maChildren.empty() || mnFinishedChildren >= maChildren.size()))
    {
        // deactivate ASAP:
        scheduleDeactivationEvent(
            makeEvent(
                 boost::bind< void >( boost::mem_fn( &AnimationNode::deactivate ), getSelf() ),
                 "SequentialTimeContainer::deactivate") );
    }
    else // use default
        scheduleDeactivationEvent();
}

void SequentialTimeContainer::dispose()
{
    BaseContainerNode::dispose();
    if (mpCurrentSkipEvent) {
        mpCurrentSkipEvent->dispose();
        mpCurrentSkipEvent.reset();
    }
    if (mpCurrentRewindEvent) {
        mpCurrentRewindEvent->dispose();
        mpCurrentRewindEvent.reset();
    }
}

void SequentialTimeContainer::skipEffect(
    AnimationNodeSharedPtr const& pChildNode )
{
    if (isChildNode(pChildNode)) {
        // empty all events ignoring timings => until next effect
        getContext().mrEventQueue.forceEmpty();
        getContext().mrEventQueue.addEvent(
            makeEvent(
                boost::bind<void>( boost::mem_fn( &AnimationNode::deactivate ), pChildNode ),
                "SequentialTimeContainer::deactivate, skipEffect with delay") );
    }
    else
        OSL_ENSURE( false, "unknown notifier!" );
}

void SequentialTimeContainer::rewindEffect(
    AnimationNodeSharedPtr const& /*pChildNode*/ )
{
    // xxx todo: ...
}

bool SequentialTimeContainer::resolveChild(
    AnimationNodeSharedPtr const& pChildNode )
{
    bool const bResolved = pChildNode->resolve();
    if (bResolved && isMainSequenceRootNode()) {
        // discharge events:
        if (mpCurrentSkipEvent)
            mpCurrentSkipEvent->dispose();
        if (mpCurrentRewindEvent)
            mpCurrentRewindEvent->dispose();

        // event that will deactivate the resolved/running child:
        mpCurrentSkipEvent = makeEvent(
            boost::bind( &SequentialTimeContainer::skipEffect,
                         boost::dynamic_pointer_cast<SequentialTimeContainer>( getSelf() ),
                         pChildNode ),
            "SequentialTimeContainer::skipEffect, resolveChild");
        // event that will reresolve the resolved/activated child:
        mpCurrentRewindEvent = makeEvent(
            boost::bind( &SequentialTimeContainer::rewindEffect,
                         boost::dynamic_pointer_cast<SequentialTimeContainer>( getSelf() ),
                         pChildNode ),
            "SequentialTimeContainer::rewindEffect, resolveChild");

        // deactivate child node when skip event occurs:
        getContext().mrUserEventQueue.registerSkipEffectEvent(
            mpCurrentSkipEvent,
            mnFinishedChildren+1<maChildren.size());
        // rewind to previous child:
        getContext().mrUserEventQueue.registerRewindEffectEvent(
            mpCurrentRewindEvent );
    }
    return bResolved;
}

void SequentialTimeContainer::notifyDeactivating(
    AnimationNodeSharedPtr const& rNotifier )
{
    if (notifyDeactivatedChild( rNotifier ))
        return;

    OSL_ASSERT( mnFinishedChildren < maChildren.size() );
    AnimationNodeSharedPtr const& pNextChild = maChildren[mnFinishedChildren];
    OSL_ASSERT( pNextChild->getState() == UNRESOLVED );

    if (! resolveChild( pNextChild )) {
        // could not resolve child - since we risk to
        // stall the chain of events here, play it safe
        // and deactivate this node (only if we have
        // indefinite duration - otherwise, we'll get a
        // deactivation event, anyways).
        deactivate();
    }
}

} // namespace internal
} // namespace slideshow
