package timer;
import java.io.Serializable;
import java.text.NumberFormat;
import utility.RunnableOfT;
import com.google.common.base.Preconditions;
public abstract class ChessTimer implements Serializable
{
public interface ChessTimerListener extends Serializable
{
public void onDisplayUpdated(String displayText);
public void onTimerStart();
public void onTimerStop();
public void setInitialDelay(int initialDelay);
public void onTimerRestart();
}
public void init(RunnableOfT<Boolean> timeElapsedCallback)
{
mNumberFormat = NumberFormat.getNumberInstance();
mNumberFormat.setMinimumIntegerDigits(2);
mTimeElapsedCallback = timeElapsedCallback;
mIsStopped = false;
}
public void setChessTimerListener(ChessTimerListener listener)
{
mListener = listener;
}
// FIXME: this is a terrible method...
public static boolean isNoTimer(ChessTimer timer)
{
return timer instanceof NoTimer;
}
// FIXME: this is a terrible method...
public static boolean isWordTimer(ChessTimer timer)
{
return timer instanceof WordTimer;
}
public static ChessTimer createTimer(TimerTypes timerType, RunnableOfT<Boolean> timeElapsedCallback, long incrementAmount,
long startTime, boolean isBlackTeamTimer)
{
switch (timerType)
{
case NO_TIMER:
return new NoTimer();
case BRONSTEIN_DELAY:
return new BronsteinDelayTimer(timeElapsedCallback, incrementAmount, startTime, isBlackTeamTimer);
case FISCHER:
return new FischerTimer(timeElapsedCallback, incrementAmount, startTime, false, isBlackTeamTimer);
case FISCHER_AFTER:
return new FischerTimer(timeElapsedCallback, incrementAmount, startTime, true, isBlackTeamTimer);
case HOUR_GLASS:
// time is halved since it is actually the time the player may not
// exceed
return new HourGlassTimer(timeElapsedCallback, startTime / 2, isBlackTeamTimer);
case SIMPLE_DELAY:
return new SimpleDelayTimer(timeElapsedCallback, incrementAmount, startTime, isBlackTeamTimer);
case WORD:
return new WordTimer(startTime);
default:
Preconditions.checkArgument(false);
return null;
}
}
public static void stopTimers()
{
mIsStopped = true;
}
public int getClockDirection()
{
return mClockDirection;
}
public long getStartTime()
{
return mInitialStartTime;
}
public long getRawTime()
{
return mCurrentTime;
}
/**
* Reset the timer to the original settings
*/
public void reset()
{
mClockLastUpdatedTime = System.currentTimeMillis();
mCurrentTime = mInitialStartTime;
updateDisplay();
}
/**
* Restart the timer after resuming a saved game.
*/
public void restart()
{
if (mListener != null)
mListener.onTimerRestart();
mClockLastUpdatedTime = System.currentTimeMillis();
}
public void setClockDirection(int newDirection)
{
mClockDirection = newDirection;
}
public void setClockTime(long newTime)
{
mCurrentTime = newTime == -1 ? mInitialStartTime : newTime;
mTimeWasRecentlyReset = true;
}
public abstract void startTimer();
public abstract void stopTimer();
public void timeElapsed()
{
mTimeElapsedCallback.run(mIsBlackTeamTimer);
if (mListener != null)
mListener.onTimerStop();
}
public void updateDisplay()
{
if (mIsStopped)
{
if (mListener != null)
mListener.onTimerStop();
return;
}
long now = System.currentTimeMillis();
long elapsed = now - mClockLastUpdatedTime;
if (!mIsDelayedTimer)
mCurrentTime -= elapsed * mClockDirection;
else
mIsDelayedTimer = false;
mClockLastUpdatedTime = now;
int minutes = (int) (mCurrentTime / 60000);
int seconds = (int) ((mCurrentTime % 60000) / 1000);
if (mListener != null)
mListener.onDisplayUpdated(mNumberFormat.format(minutes) + ":" + mNumberFormat.format(seconds)); //$NON-NLS-1$
if (mCurrentTime <= 0)
{
mCurrentTime = Math.abs(mCurrentTime);
timeElapsed();
}
}
private static final long serialVersionUID = -1195203886987180343L;
protected long mCurrentTime;
protected long mClockLastUpdatedTime;
protected NumberFormat mNumberFormat;
protected boolean mIsDelayedTimer;
protected boolean mIsBlackTeamTimer;
protected boolean mTimeWasRecentlyReset;
protected long mInitialStartTime;
// should be 1 or -1 to account for timer counting up instead. -1 to count
// up since it gets subtracted
protected int mClockDirection = 1;
protected static boolean mIsStopped;
protected RunnableOfT<Boolean> mTimeElapsedCallback;
protected ChessTimerListener mListener;
}