/*
* Copyright (C) 2010-2016 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.ReadOnlyTagList;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter;
import com.jpexs.decompiler.flash.tags.DefineButtonSoundTag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.timeline.Timeline;
import com.jpexs.decompiler.flash.timeline.Timelined;
import com.jpexs.decompiler.flash.types.BUTTONRECORD;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.helpers.ByteArrayRange;
import com.jpexs.helpers.SerializableImage;
import java.awt.Shape;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
*
* @author JPEXS
*/
public abstract class ButtonTag extends DrawableTag implements Timelined {
public static int FRAME_UP = 0;
public static int FRAME_OVER = 1;
public static int FRAME_DOWN = 2;
public static int FRAME_HITTEST = 3;
private Timeline timeline;
private boolean isSingleFrameInitialized;
private boolean isSingleFrame;
public ButtonTag(SWF swf, int id, String name, ByteArrayRange data) {
super(swf, id, name, data);
}
public abstract List<BUTTONRECORD> getRecords();
public abstract boolean trackAsMenu();
@Override
public void getNeededCharacters(Set<Integer> needed) {
for (BUTTONRECORD r : getRecords()) {
needed.add(r.characterId);
}
DefineButtonSoundTag sounds = getSounds();
if (sounds != null) {
sounds.getNeededCharacters(needed);
}
}
@Override
public RECT getRect() {
return getRect(new HashSet<>());
}
@Override
public int getUsedParameters() {
return PARAMETER_FRAME | PARAMETER_TIME | PARAMETER_RATIO; // inner tags can contain morphshapes, too
}
@Override
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, boolean stroked) {
return getTimeline().getOutline(frame, time, renderContext, transformation, stroked);
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, ColorTransform colorTransform) {
getTimeline().toImage(frame, time, renderContext, image, isClip, transformation, strokeTransformation, absoluteTransformation, colorTransform);
}
@Override
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException {
getTimeline().toSVG(0, 0, null, 0, exporter, colorTransform, level + 1);
}
public DefineButtonSoundTag getSounds() {
return (DefineButtonSoundTag) swf.getCharacterIdTag(getCharacterId(), DefineButtonSoundTag.ID);
}
@Override
public void toHtmlCanvas(StringBuilder result, double unitDivisor) {
getTimeline().toHtmlCanvas(result, unitDivisor, Arrays.asList(0)); //TODO: handle states?
}
@Override
public boolean isSingleFrame() {
if (!isSingleFrameInitialized) {
initialiteIsSingleFrame();
}
return isSingleFrame;
}
private synchronized void initialiteIsSingleFrame() {
if (!isSingleFrameInitialized) {
isSingleFrame = getTimeline().isSingleFrame();
isSingleFrameInitialized = true;
}
}
@Override
public Timeline getTimeline() {
if (timeline != null) {
return timeline;
}
timeline = new Timeline(swf, this, getCharacterId(), getRect());
initTimeline(timeline);
return timeline;
}
@Override
public void resetTimeline() {
if (timeline != null) {
timeline.reset(swf, this, getCharacterId(), getRect());
initTimeline(timeline);
}
}
protected abstract void initTimeline(Timeline timeline);
@Override
public ReadOnlyTagList getTags() {
return ReadOnlyTagList.EMPTY;
}
@Override
public void removeTag(int index) {
}
@Override
public void removeTag(Tag tag) {
}
@Override
public void addTag(Tag tag) {
}
@Override
public void addTag(int index, Tag tag) {
}
@Override
public void replaceTag(int index, Tag newTag) {
removeTag(index);
addTag(index, newTag);
}
}