package com.pluscubed.plustimer.model;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.IntDef;
import com.couchbase.lite.CouchbaseLiteException;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.pluscubed.plustimer.utils.Utils;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import rx.Completable;
/**
* Solve data object
*/
@JsonAutoDetect(creatorVisibility = JsonAutoDetect.Visibility.NONE,
fieldVisibility = JsonAutoDetect.Visibility.NONE,
getterVisibility = JsonAutoDetect.Visibility.NONE,
isGetterVisibility = JsonAutoDetect.Visibility.NONE,
setterVisibility = JsonAutoDetect.Visibility.NONE
)
public class Solve extends CbObject implements Parcelable {
public static final String TYPE_SOLVE = "solve";
public static final int PENALTY_DNF = 2;
public static final int PENALTY_PLUSTWO = 1;
public static final int PENALTY_NONE = 0;
public static final Parcelable.Creator<Solve> CREATOR = new Parcelable.Creator<Solve>() {
public Solve createFromParcel(Parcel source) {
return new Solve(source);
}
public Solve[] newArray(int size) {
return new Solve[size];
}
};
@JsonProperty("scramble")
private String mScramble;
@JsonProperty("penalty")
private int mPenalty;
@JsonProperty("time")
private long mTime;
/**
* Timestamp in milliseconds
*/
@JsonProperty("timestamp")
private long mTimestamp;
public Solve(Solve s) {
copy(s);
}
protected Solve(Context context) throws CouchbaseLiteException, IOException {
super(context);
init();
updateCb(context);
}
/**
* Creates new disconnected solve
*/
public Solve() {
init();
}
protected Solve(Parcel in) {
this.mId = in.readString();
this.mScramble = in.readString();
this.mPenalty = in.readInt();
this.mTime = in.readLong();
this.mTimestamp = in.readLong();
}
private void init() {
this.mScramble = "";
this.mTime = 0L;
this.mPenalty = PENALTY_NONE;
this.mTimestamp = System.currentTimeMillis();
}
public String getId() {
return mId;
}
protected void setId(String id) {
mId = id;
}
/**
* Doesn't copy ID
*/
public void copy(Solve s) {
mScramble = s.getScramble();
mTime = s.getRawTime();
mPenalty = s.getPenalty();
mTimestamp = s.getTimestamp();
}
public String getScramble() {
return mScramble;
}
public void setScramble(Context context, String scramble) throws CouchbaseLiteException, IOException {
this.mScramble = scramble;
updateCb(context);
}
public long getTimestamp() {
return mTimestamp;
}
public long getTimeTwo() {
return mTime + (mPenalty == PENALTY_PLUSTWO ? 2000000000L : 0);
}
public String getTimeString(boolean milliseconds) {
switch (mPenalty) {
case PENALTY_DNF:
return "DNF";
case PENALTY_PLUSTWO:
return Utils.timeStringFromNs(mTime + 2000000000L,
milliseconds) + "+";
case PENALTY_NONE:
default:
return Utils.timeStringFromNs(mTime, milliseconds);
}
}
public String[] getTimeStringArray(boolean milliseconds) {
switch (mPenalty) {
case PENALTY_DNF:
return new String[]{"DNF", ""};
case PENALTY_PLUSTWO:
long nanoseconds = mTime + 2000000000L;
String[] timeStringsSplitByDecimal = Utils
.timeStringsFromNsSplitByDecimal(nanoseconds,
milliseconds);
timeStringsSplitByDecimal[1] = timeStringsSplitByDecimal[1] +
"+";
return timeStringsSplitByDecimal;
case PENALTY_NONE:
default:
return Utils.timeStringsFromNsSplitByDecimal(mTime,
milliseconds);
}
}
public String getDescriptiveTimeString(boolean milliseconds) {
switch (mPenalty) {
case PENALTY_DNF:
if (mTime != 0) {
return "DNF (" + Utils.timeStringFromNs(mTime,
milliseconds) + ")";
}
default:
return getTimeString(milliseconds);
}
}
@Penalty
public int getPenalty() {
return mPenalty;
}
public void setPenalty(Context context, @Penalty int penalty) throws CouchbaseLiteException, IOException {
this.mPenalty = penalty;
updateCb(context);
}
public Completable setPenaltyDeferred(Context context, @Penalty int penalty) {
return Completable.fromCallable(() -> {
setPenalty(context, penalty);
return null;
});
}
public long getRawTime() {
return mTime;
}
//TODO: Update database
public void setRawTime(Context context, long time) throws CouchbaseLiteException, IOException {
if (this.mTime != time) {
this.mTime = time;
updateCb(context);
}
}
@Override
public void updateCb(Context context) {
super.updateCb(context);
}
@Override
public boolean equals(Object o) {
return o instanceof Solve &&
mId.equals(((Solve) o).getId()) &&
mTime == ((Solve) o).getRawTime() &&
mTimestamp == ((Solve) o).getTimestamp() &&
mScramble.equals(((Solve) o).getScramble()) &&
mPenalty == ((Solve) o).getPenalty();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.mId);
dest.writeString(this.mScramble);
dest.writeInt(this.mPenalty);
dest.writeLong(this.mTime);
dest.writeLong(this.mTimestamp);
}
@Override
protected String getType() {
return TYPE_SOLVE;
}
@Override
public String toString() {
return "Solve{" +
"time=" + mTime +
", scramble='" + mScramble + '\'' +
", penalty=" + mPenalty +
", timestamp=" + mTimestamp +
'}';
}
@IntDef({PENALTY_DNF, PENALTY_PLUSTWO, PENALTY_NONE})
@Retention(RetentionPolicy.SOURCE)
public @interface Penalty {
}
protected static class Builder {
protected Context context;
protected Solve solve;
protected Builder(Context context) {
solve = new Solve();
this.context = context;
}
protected Builder setRawTime(long time) {
solve.mTime = time;
return this;
}
protected Builder setTimestamp(long timestamp) {
solve.mTime = timestamp;
return this;
}
protected Builder setPenalty(@Penalty int penalty) {
solve.mPenalty = penalty;
return this;
}
protected Builder setScramble(String scramble) {
solve.mScramble = scramble;
return this;
}
protected Solve build() throws CouchbaseLiteException, IOException {
solve.connectCb(context);
return solve;
}
}
}