/*
* Copyright (C) 2007-2008 Esmertec AG.
* Copyright (C) 2007-2008 The Android Open Source Project
*
* Licensed 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.
*/
package com.android.mms.dom.smil;
import java.util.ArrayList;
import org.w3c.dom.DOMException;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.smil.ElementParallelTimeContainer;
import org.w3c.dom.smil.ElementTime;
import org.w3c.dom.smil.SMILElement;
import org.w3c.dom.smil.Time;
import org.w3c.dom.smil.TimeList;
import com.android.mms.dom.NodeListImpl;
public abstract class ElementParallelTimeContainerImpl extends ElementTimeContainerImpl
implements ElementParallelTimeContainer {
private final static String ENDSYNC_ATTRIBUTE_NAME = "endsync";
private final static String ENDSYNC_FIRST = "first";
private final static String ENDSYNC_LAST = "last";
private final static String ENDSYNC_ALL = "all";
private final static String ENDSYNC_MEDIA = "media";
/*
* Internal Interface
*/
ElementParallelTimeContainerImpl(SMILElement element) {
super(element);
}
public String getEndSync() {
String endsync = mSmilElement.getAttribute(ENDSYNC_ATTRIBUTE_NAME);
if ((endsync == null) || (endsync.length() == 0)) {
setEndSync(ENDSYNC_LAST);
return ENDSYNC_LAST;
}
if (ENDSYNC_FIRST.equals(endsync) || ENDSYNC_LAST.equals(endsync) ||
ENDSYNC_ALL.equals(endsync) || ENDSYNC_MEDIA.equals(endsync)) {
return endsync;
}
// FIXME add the checking for ID-Value and smil1.0-Id-value.
setEndSync(ENDSYNC_LAST);
return ENDSYNC_LAST;
}
public void setEndSync(String endSync) throws DOMException {
if (ENDSYNC_FIRST.equals(endSync) || ENDSYNC_LAST.equals(endSync) ||
ENDSYNC_ALL.equals(endSync) || ENDSYNC_MEDIA.equals(endSync)) {
mSmilElement.setAttribute(ENDSYNC_ATTRIBUTE_NAME, endSync);
} else { // FIXME add the support for ID-Value and smil1.0-Id-value.
throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
"Unsupported endsync value" + endSync);
}
}
@Override
public float getDur() {
float dur = super.getDur();
if (dur == 0) {
dur = getImplicitDuration();
}
return dur;
}
public float getImplicitDuration() {
float dur = -1.0F;
if (ENDSYNC_LAST.equals(getEndSync())) {
NodeList children = getTimeChildren();
for (int i = 0; i < children.getLength(); ++i) {
ElementTime child = (ElementTime) children.item(i);
TimeList endTimeList = child.getEnd();
for (int j = 0; j < endTimeList.getLength(); ++j) {
Time endTime = endTimeList.item(j);
if (endTime.getTimeType() == Time.SMIL_TIME_INDEFINITE) {
// Return "indefinite" here.
return -1.0F;
}
if (endTime.getResolved()) {
float end = (float)endTime.getResolvedOffset();
dur = (end > dur) ? end : dur;
}
}
}
} // Other endsync types are not supported now.
return dur;
}
public NodeList getActiveChildrenAt(float instant) {
/*
* Find the closest Time of ElementTime before instant.
* Add ElementTime to list of active elements if the Time belongs to the begin-list,
* do not add it otherwise.
*/
ArrayList<Node> activeChildren = new ArrayList<Node>();
NodeList children = getTimeChildren();
int childrenLen = children.getLength();
for (int i = 0; i < childrenLen; ++i) {
double maxOffset = 0.0;
boolean active = false;
ElementTime child = (ElementTime) children.item(i);
TimeList beginList = child.getBegin();
int len = beginList.getLength();
for (int j = 0; j < len; ++j) {
Time begin = beginList.item(j);
if (begin.getResolved()) {
double resolvedOffset = begin.getResolvedOffset() * 1000.0;
if ((resolvedOffset <= instant) && (resolvedOffset >= maxOffset)) {
maxOffset = resolvedOffset;
active = true;
}
}
}
TimeList endList = child.getEnd();
len = endList.getLength();
for (int j = 0; j < len; ++j) {
Time end = endList.item(j);
if (end.getResolved()) {
double resolvedOffset = end.getResolvedOffset() * 1000.0;
if ((resolvedOffset <= instant) && (resolvedOffset >= maxOffset)) {
maxOffset = resolvedOffset;
active = false;
}
}
}
if (active) {
activeChildren.add((Node) child);
}
}
return new NodeListImpl(activeChildren);
}
}