package de.onyxbits.bureauengine.util;
import com.badlogic.gdx.Preferences;
/**
* Utility class for giving the user time to test something for a reasonable
* number of times before having to make a decission. This class is designed
* for reminding the user. It is not fit for licensing.
* <p>
* The idea of the <code>TrialPeriod</code> is that a counter get's increased
* everytime the app is started (call <code>trialed()</code> from the boot
* code of the game). After a reasonable amount of time and launches,
* <code>isOver()</code> will return <code>true</code>, signalling that
* further actions can be taken.<br>
* Additionally, the result of the <code>TrialPeriod</code> can be persisted
* in a state variable. The state, however, is not evaluated internally.
* <p>
* Sometimes it is desirable to extend a trial period. The easiest way to do
* this is to call the <code>reset()</code> method which will simply wipe
* all data from the persistent storage, allowing for a completely fresh start.
* The more sophisticated approach is to use two trial objects (with two different
* key sets) and leave the first one in state <code>ENDED</code>.
*/
public class TrialPeriod {
/**
* Unknown state
*/
public static final int UNKNOWN = 0;
/**
* Positive state
*/
public static final int POSITIVE = 1;
/**
* Negative state
*/
public static final int NEGATIVE = 2;
/**
* Currently on trial
*/
public static final int INPROGRESS = 4;
/**
* Trial period ended with undetermined result
*/
public static final int ENDED = 8;
/**
* Trial ended with positive user feed back
*/
public static final int ENDEDPOSITIVELY = ENDED | POSITIVE;
/**
* Trial ended with negative user feedback
*/
public static final int ENDEDNEGATIVELY = ENDED | NEGATIVE;
private Preferences prefs;
private String keyLaunchCount;
private String keyFirstLaunch;
private String keyState;
private long minLaunches = 10;
private long minTime = 3 * 24 * 60 * 60 * 1000; // Three days
/**
* Configure the persistant storage.
* @param prefs persistent storage
* @param directFlush whether or not to call <code>Preferences.flush()</code>.
* @param keyLaunchCount name of the key with which to count how often the game was started
* @param keyFirstLaunch name of the key with which to record the date of the first launch
* @param keyActive name of the key with which to store the state.
*/
public TrialPeriod(Preferences prefs, String keyLaunchCount, String keyFirstLaunch, String keyState) {
if (prefs==null || keyLaunchCount==null || keyFirstLaunch == null || keyState==null) {
throw new NullPointerException(); // Crash early
}
this.prefs=prefs;
this.keyLaunchCount=keyLaunchCount;
this.keyFirstLaunch=keyFirstLaunch;
this.keyState=keyState;
}
/**
* Configure the minimum amount of time that has to pass since the first launch before
* <code>isOver()</code> will return true;
* @param minTime time in milliseconds
* @return the object for method chaining.
*/
public TrialPeriod withMinTime(long minTime) {
this.minTime=minTime;
return this;
}
/**
* Configure the minimum amount of launches that have to occur before <code>isOver()</code>
* returns true
* @param minLauncher number of times the game has to be started in addition to minimum time.
* @return the object for method chaining.
*/
public TrialPeriod withMinLaunches(long minLaunches) {
this.minLaunches=minLaunches;
return this;
}
/**
* Check if the trialperiod is over
* @return true if the time is over and the minimum number of launches have occured
*/
public boolean isOver() {
long fl = prefs.getLong(keyFirstLaunch,-1);
long lc = prefs.getLong(keyLaunchCount,-1);
if (lc >= minLaunches && fl+minTime <= System.currentTimeMillis()) {
return true;
}
else {
return false;
}
}
/**
* Should be called once everytime the application is started
* @return the object for method chaining.
*/
public TrialPeriod trialed() {
long tmp = prefs.getLong(keyFirstLaunch,0);
if (tmp==0) {
prefs.putLong(keyFirstLaunch,System.currentTimeMillis());
}
tmp = prefs.getLong(keyLaunchCount,0);
prefs.putLong(keyLaunchCount,tmp+1);
prefs.flush();
return this;
}
/**
* Restart the trialcounter by removing all the keys from the storage.
*/
public void reset() {
prefs.remove(keyLaunchCount);
prefs.remove(keyFirstLaunch);
prefs.remove(keyState);
prefs.flush();
}
/**
* Query the state of the <code>TrialPeriod</code>
* @return integer encoded state. If no state has been set yet, this
* will be UNKNOWN.
*/
public int getState() {
return prefs.getInteger(keyState,UNKNOWN);
}
/**
* Set the state of the trial. Note: The state is not evaluated internally.
* It is recommended to use the predefined states, but not nescessary.
* @param int encoded state.
*/
public void setState(int state) {
prefs.putInteger(keyState,state);
prefs.flush();
}
}