package tim.prune.function.autoplay;
/**
* Class to hold a list of points and hold a running position
*/
public class PointList
{
/** Array of milliseconds for each point */
private long[] _millis = null;
/** Array of indexes of corresponding points */
private int[] _indexes = null;
/** Array index of current position */
private int _currentItem = 0;
/** Max array index */
private int _maxItem = 0;
/**
* Constructor
* @param inNumPoints number of points
*/
public PointList(int inNumPoints)
{
_millis = new long[inNumPoints];
_indexes = new int[inNumPoints];
_currentItem = 0;
_maxItem = inNumPoints - 1;
}
/**
* Add a point to the array
* @param inMillis milliseconds since start
* @param inIndex point index
*/
public void setPoint(long inMillis, int inIndex)
{
_millis[_currentItem] = inMillis;
_indexes[_currentItem] = inIndex;
_currentItem++;
}
/**
* Set the position using the current milliseconds
* @param inMillis milliseconds since start
*/
public void set(long inMillis)
{
if (isFinished() || inMillis < _millis[_currentItem])
{
// must be reset
_currentItem = 0;
}
while (_currentItem < _maxItem && _millis[_currentItem + 1] < inMillis)
{
_currentItem++;
}
}
/**
* Normalize the list to cover the requested number of seconds duration
* @param inSeconds length of autoplay sequence in seconds
*/
public void normalize(int inSeconds)
{
if (_maxItem <= 0)
{
return; // nothing to normalize
}
long currentDuration = _millis[_maxItem] - _millis[0];
if (currentDuration > 0L)
{
double multFactor = inSeconds * 1000.0 / currentDuration;
for (int i=0; i<=_maxItem; i++)
{
_millis[i] = (long) (_millis[i] * multFactor);
}
}
}
/** @return the milliseconds of the current point */
public long getCurrentMilliseconds()
{
if (isAtStart() || isFinished()) {
return 0L;
}
return _millis[_currentItem];
}
/** @return the index of the current point */
public int getCurrentPointIndex()
{
return _indexes[_currentItem];
}
/** @return true if we're on the first point */
public boolean isAtStart() {
return _currentItem == 0;
}
/** @return true if we're on the last point */
public boolean isFinished() {
return _currentItem >= _maxItem;
}
/**
* @param inCurrentMillis current time in milliseconds since start
* @return number of milliseconds to wait until next point is due
*/
public long getMillisUntilNextPoint(long inCurrentMillis)
{
if (isFinished() || _millis[_currentItem+1] < _millis[_currentItem]) {
return 0; // no next point
}
return _millis[_currentItem+1] - inCurrentMillis;
}
}