/*****************************************************
*
* Copyright 2009 Adobe Systems Incorporated. All Rights Reserved.
*
*****************************************************
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
*
* The Initial Developer of the Original Code is Adobe Systems Incorporated.
* Portions created by Adobe Systems Incorporated are Copyright (C) 2009 Adobe Systems
* Incorporated. All Rights Reserved.
*
*****************************************************/
package org.osmf.elements.compositeClasses
{
import flash.errors.IllegalOperationError;
import org.osmf.events.MediaElementEvent;
import org.osmf.events.SeekEvent;
import org.osmf.media.MediaElement;
import org.osmf.traits.MediaTraitBase;
import org.osmf.traits.MediaTraitType;
import org.osmf.traits.SeekTrait;
import org.osmf.traits.TimeTrait;
import org.osmf.utils.OSMFStrings;
/**
* Implementation of SeekTrait which can be a composite media trait.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion OSMF 1.0
*/
internal class CompositeSeekTrait extends SeekTrait implements IReusable
{
public function CompositeSeekTrait(traitAggregator:TraitAggregator, mode:String, owner:MediaElement)
{
super(owner.getTrait(MediaTraitType.TIME) as TimeTrait);
// Add listener for traitAdd/remove, in case TimeTrait changes (or
// doesn't exist yet).
owner.addEventListener(MediaElementEvent.TRAIT_ADD, onTraitAdd);
owner.addEventListener(MediaElementEvent.TRAIT_REMOVE, onTraitRemove);
_traitAggregator = traitAggregator;
this.mode = mode;
traitAggregationHelper = new TraitAggregationHelper
( traitType
, traitAggregator
, processAggregatedChild
, processUnaggregatedChild
);
}
/**
* @private
*/
public function attach():void
{
traitAggregationHelper.attach();
}
/**
* @private
*/
public function detach():void
{
traitAggregationHelper.detach();
}
/**
* @private
*/
override protected function seekingChangeEnd(time:Number):void
{
super.seekingChangeEnd(time);
if (seeking)
{
// Calls prepareSeekOperationInfo methods of the derived classes, ParallelSeekTrait
// and SerialSeekTrait. The prepareSeekOperationInfo returns whether the composite
// trait can seek to the position. If yes, it also returns a "description" of how
// to carry out the seek operation for the composite, depending on the concrete type
// of the composite seek trait.
var seekOp:CompositeSeekOperationInfo = prepareSeekOperationInfo(time);
if (seekOp.canSeekTo)
{
doSeek(seekOp);
}
}
}
/**
* @private
*/
override public function canSeekTo(time:Number):Boolean
{
// Similar to the seek function, here we call the prepareSeekOperation of the derived
// composite seek trait. Only this time the returned operation is only used to
// determine whether a seek is possible.
return super.canSeekTo(time) && prepareSeekOperationInfo(time).canSeekTo;
}
// Internals
//
private function onTraitAdd(event:MediaElementEvent):void
{
if (event.traitType == MediaTraitType.TIME)
{
super.timeTrait = MediaElement(event.target).getTrait(MediaTraitType.TIME) as TimeTrait;
}
}
private function onTraitRemove(event:MediaElementEvent):void
{
if (event.traitType == MediaTraitType.TIME)
{
super.timeTrait = null;
}
}
private function processAggregatedChild(child:MediaTraitBase):void
{
child.addEventListener(SeekEvent.SEEKING_CHANGE, onSeekingChanged, false, 0, true);
}
private function processUnaggregatedChild(child:MediaTraitBase):void
{
child.removeEventListener(SeekEvent.SEEKING_CHANGE, onSeekingChanged);
}
/**
* This is event handler for SeekEvent, typically dispatched from the SeekTrait
* of a child/children. This must be overridden by derived classes.
*
* @param event The SeekEvent.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion OSMF 1.0
*/
protected function onSeekingChanged(event:SeekEvent):void
{
throw new IllegalOperationError(OSMFStrings.getString(OSMFStrings.FUNCTION_MUST_BE_OVERRIDDEN));
}
/**
* This function carries out the actual seeking operation. Derived classes must override this
* function.
*
* @param seekOp The object that contains the complete information of how to carry out this
* particular seek operation.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion OSMF 1.0
*/
protected function doSeek(seekOp:CompositeSeekOperationInfo):void
{
throw new IllegalOperationError(OSMFStrings.getString(OSMFStrings.FUNCTION_MUST_BE_OVERRIDDEN));
}
/**
* This function carries out the operation to check whether a seek operation is feasible
* as well as coming up with a complete plan of how to do the actual seek. The derived
* classes must override this function.
*
* @param time The time the seek operation will seek to.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion OSMF 1.0
*/
protected function prepareSeekOperationInfo(time:Number):CompositeSeekOperationInfo
{
throw new IllegalOperationError(OSMFStrings.getString(OSMFStrings.FUNCTION_MUST_BE_OVERRIDDEN));
}
/**
* This function checks whether the composite seek trait is currently seeking. The derived
* classes must override this function.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion OSMF 1.0
*/
protected function checkSeeking():Boolean
{
throw new IllegalOperationError(OSMFStrings.getString(OSMFStrings.FUNCTION_MUST_BE_OVERRIDDEN));
}
protected final function get traitAggregator():TraitAggregator
{
return _traitAggregator;
}
// Internals
//
private var mode:String;
private var _traitAggregator:TraitAggregator;
private var traitAggregationHelper:TraitAggregationHelper;
}
}