package com.kaichunlin.transition;
import android.support.annotation.NonNull;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Manages a collection of {@link Transition}.
*/
public class DefaultTransitionManager implements TransitionManager {
private ArrayList<TransitionManagerListener> mListenerList = new ArrayList<>();
private ArrayList<Transition> mTransitionList = new ArrayList<>();
private Set<Transition> mBackupTransitionList = new HashSet<>();
@Override
public void addTransition(@NonNull AbstractTransitionBuilder transitionBuilder) {
addTransition(transitionBuilder.build());
}
@Override
public void addTransition(@NonNull Transition transition) {
processAnimation(transition);
}
@Override
public void addAllTransitions(@NonNull List<Transition> transitionsList) {
for (int i = 0, size = transitionsList.size(); i < size; i++) {
addTransition(transitionsList.get(i));
}
}
private void processAnimation(Transition transition) {
//attempt to merge an animation
boolean merged = false;
//no optimization is taken if the TransitionOption is not an AbstractTransition subclass
if (transition instanceof AbstractTransition) {
TransitionOperation to;
for (int i = 0, size = mTransitionList.size(); i < size; i++) {
to = mTransitionList.get(i);
if (to instanceof AbstractTransition) {
AbstractTransition atTo = (AbstractTransition) to;
AbstractTransition atTransition = (AbstractTransition) transition;
if (atTo.isCompatible(atTransition)) {
//the Transition has already merged another Transition previously
if (atTo.hasMultipleSetup()) {
atTo.merge(atTransition);
} else { //the Transition has not merged another Transition
mTransitionList.remove(atTo);
atTo = atTo.clone();
atTo.merge(atTransition);
mTransitionList.add(atTo);
}
break;
}
}
}
}
if (!merged) {
mTransitionList.add(transition);
}
mBackupTransitionList.add(transition);
}
@Override
public boolean removeTransition(@NonNull Transition transition) {
//rebuilding mTransitionList
if (mBackupTransitionList.remove(transition)) {
List<Transition> temp = new ArrayList<>(mBackupTransitionList.size());
temp.addAll(mBackupTransitionList);
mTransitionList.clear();
mBackupTransitionList.clear();
for (int i = 0, size = temp.size(); i < size; i++) {
processAnimation(temp.get(i));
}
return true;
}
return false;
}
@Override
public void removeAllTransitions() {
mTransitionList.clear();
}
@Override
public List<Transition> getTransitions() {
return mTransitionList;
}
@Override
public boolean startTransition() {
//call listeners so they can perform their actions first, like modifying this adapter's transitions
notifyTransitionStart();
boolean start = false;
final int size = mTransitionList.size();
for (int i = 0; i < size; i++) {
start |= mTransitionList.get(i).startTransition();
}
return start;
}
@Override
public boolean startTransition(float progress) {
//call listeners so they can perform their actions first, like modifying this adapter's transitions
notifyTransitionStart();
boolean start = false;
final int size = mTransitionList.size();
for (int i = 0; i < size; i++) {
start |= mTransitionList.get(i).startTransition(progress);
}
return start;
}
/**
* Updates the transition progress
*
* @param value
*/
@Override
public void updateProgress(float value) {
final int size = mTransitionList.size();
for (int i = 0; i < size; i++) {
mTransitionList.get(i).updateProgress(value);
}
}
/**
* Stops all transitions.
*/
@Override
public void stopTransition() {
//call listeners so they can perform their actions first, like modifying this adapter's transitions
for (int i = 0, size = mListenerList.size(); i < size; i++) {
mListenerList.get(i).onTransitionEnd(this);
}
for (int i = 0, size = mTransitionList.size(); i < size; i++) {
mTransitionList.get(i).stopTransition();
}
}
@Override
public void addTransitionListener(TransitionManagerListener listener) {
if (!mListenerList.contains(listener)) {
mListenerList.add(listener);
}
}
@Override
public void removeTransitionListener(TransitionManagerListener listener) {
mListenerList.remove(listener);
}
@Override
public void notifyTransitionStart() {
for (int i = 0, size = mListenerList.size(); i < size; i++) {
mListenerList.get(i).onTransitionStart(this);
}
}
@Override
public void notifyTransitionEnd() {
for (int i = 0, size = mListenerList.size(); i < size; i++) {
mListenerList.get(i).onTransitionEnd(this);
}
}
}