/*
* Copyright (C) 2006, 2007 Clam <clamisgood@gmail.com>
* Copyright (C) 2008, 2009 Quadduc <quadduc@gmail.com>
*
* This file is part of LateralGM.
* LateralGM is free software and comes with ABSOLUTELY NO WARRANTY.
* See LICENSE for details.
*/
package org.lateralgm.resources;
import java.util.ArrayList;
import java.util.Collections;
import org.lateralgm.resources.sub.Moment;
import org.lateralgm.util.PropertyMap;
public class Timeline extends InstantiableResource<Timeline,Timeline.PTimeline>
{
public ArrayList<Moment> moments = new ArrayList<Moment>();
public enum PTimeline
{ //Unused
}
public Timeline()
{
this(null);
}
public Timeline(ResourceReference<Timeline> r)
{
super(r);
}
public Timeline makeInstance(ResourceReference<Timeline> r)
{
return new Timeline(r);
}
public Moment addMoment()
{
Moment m = new Moment();
moments.add(m);
return m;
}
@Override
protected void postCopy(Timeline dest)
{
super.postCopy(dest);
for (Moment mom : moments)
{
Moment mom2 = mom.copy();
dest.moments.add(mom2);
}
}
/**
* Shifts the Step Numbers of all moments in range (start,end) by given amount.
* In the event that start > end or amt == 0, no shift is performed.
* @param start - The smallest step number to shift
* @param end - The largest step number to shift
* @param amt - The amount to shift by
* @return Original array index of first moment, or -1 if no shift was performed.
*/
public int shiftMoments(int start, int end, int amt)
{
if (start > end || amt == 0) return -1;
int left = Collections.binarySearch(moments,start);
if (left < 0)
left = -left - 1;
else
while (left > 0 && moments.get(left).stepNo == start)
left--; //handle duplicates
for (int i = left; i < moments.size(); i++)
{
if (moments.get(i).stepNo > end) break;
//This is not efficient, because it brings the list out of order.
//Could have been dynamically sorted as stepNo was incremented.
//Efficiency shouldn't matter much here, though, as this is infrequently called.
moments.get(i).stepNo += amt;
}
Collections.sort(moments); //See efficiency comment above
return left;
}
/**
* Merges all moments within the given range (start,end) into the first found moment
* by appending all actions in the order that they are found.
* @param start - The smallest step number to merge
* @param end - The largest step number to merge
* @return Array index of first moment, to which the other moments merged into,
* or -1 if no merge was performed.
*/
public int mergeMoments(int start, int end)
{
if (start > end) return -1;
int left = Collections.binarySearch(moments,start);
if (left < 0)
left = -left - 1;
else
while (left > 0 && moments.get(left).stepNo == start)
left--; //handle duplicates
for (int i = left; i < moments.size(); i++)
{
if (moments.get(i).stepNo > end) return left;
moments.get(left).actions.addAll(moments.remove(i).actions);
}
return left;
}
@Override
protected PropertyMap<PTimeline> makePropertyMap()
{
return new PropertyMap<PTimeline>(PTimeline.class,this,null);
}
}