/* * Copyright 2015 Daniel Dittmar * * 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 dan.dit.whatsthat.testsubject.intro; import android.support.annotation.NonNull; import android.text.TextUtils; import java.util.LinkedList; import java.util.List; import dan.dit.whatsthat.util.compaction.Compactable; import dan.dit.whatsthat.util.compaction.CompactedDataCorruptException; import dan.dit.whatsthat.util.compaction.Compacter; /** * Created by daniel on 08.08.15. */ public class Episode implements Compactable { private final String[] mMessages; protected int mCurrMessageIndex; protected final Intro mIntro; private final String mEpisodeKey; private int mIcon; private int mNextChildIndex; private List<Episode> mChildren = new LinkedList<>(); public Episode(@NonNull String episodeKey, Intro intro, String[] messages) { mEpisodeKey = episodeKey; mIntro = intro; if (intro == null) { throw new IllegalArgumentException("No intro given."); } if (mEpisodeKey == null) { throw new IllegalArgumentException("No episode key given."); } mMessages = messages; } public Episode(@NonNull String episodeKey, Intro intro, String message) { this(episodeKey, intro, new String[] {message}); } public Episode setIcon(int icon) { mIcon = icon; return this; } protected boolean isDone() { return true; } protected boolean isMandatory() { return false; } protected void init(String data) throws CompactedDataCorruptException { unloadData(TextUtils.isEmpty(data) ? null : new Compacter(data)); } protected void start() { if (mMessages != null && mCurrMessageIndex < mMessages.length) { mIntro.applyMessage(mMessages[mCurrMessageIndex]); } else { mIntro.applyMessage(0); } mIntro.applyIcon(mIcon); } public @NonNull String getEpisodeKey() { return mEpisodeKey; } public static String extractEpisodeKey(@NonNull String data) { return new Compacter(data).getData(0); } @Override public int hashCode() { return getEpisodeKey().hashCode(); } @Override public boolean equals(Object other) { if (other instanceof Episode) { return getEpisodeKey().equals(((Episode) other).getEpisodeKey()); } return super.equals(other); } public Episode getChild(int index) { return mChildren.get(index); } public int getChildrenCount() { return mChildren.size(); } public void addChild(Episode child) { mChildren.add(child); } public boolean hasNextMessage() { return mCurrMessageIndex < mMessages.length - 1; } public Episode next(int childIndex) { if (hasNextMessage()) { mCurrMessageIndex++; return this; } if (mNextChildIndex >= mChildren.size()) { return null; } mCurrMessageIndex = 0; // reset current episode in case it returns in later cycle if (childIndex >= 0 && childIndex < mChildren.size()) { return mChildren.get(childIndex); } Episode next = mChildren.get(mNextChildIndex); mNextChildIndex++; mNextChildIndex %= mChildren.size(); // cycle return next; } @Override public String compact() { Compacter cmp = new Compacter(5); cmp.appendData(getEpisodeKey()); cmp.appendData(mCurrMessageIndex); cmp.appendData(mNextChildIndex); return cmp.compact(); } @Override public void unloadData(Compacter compactedData) throws CompactedDataCorruptException { if (compactedData == null || compactedData.getSize() < 1) { return; } if (!compactedData.getData(0).equals(getEpisodeKey())) { throw new CompactedDataCorruptException("Wrong episode for compacted data!" + getEpisodeKey()).setCorruptData(compactedData); } if (compactedData.getSize() > 1) { mCurrMessageIndex = compactedData.getInt(1); if (mMessages != null && mMessages.length > 0) { mCurrMessageIndex %= mMessages.length; } } else { mCurrMessageIndex = 0; } if (compactedData.getSize() > 2) { mNextChildIndex = compactedData.getInt(2); if (mChildren != null && mChildren.size() > 0) { mNextChildIndex %= mChildren.size(); } } else { mNextChildIndex = 0; } } }