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

