package com.kuxhausen.huemore.state;
import com.google.gson.Gson;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
public class Mood implements Cloneable {
public final static long NUMBER_OF_MILLISECONDS_IN_DAY = 86400000;
private Event[] mEvents;
private int mNumChannels;
private boolean mUsesTiming;
/**
* in units of 1/10 of a second
*/
private int mLoopIterationTimeLength;
private TimingPolicy mTimingPolicy;
public enum TimingPolicy {
BASIC, // play the mood relative to start time, no looping
LOOPING, // play the mood relative to start time, looping
DAILY, // play the mood relative to start of day, looping
}
private Mood() {
// for Gson
}
private Mood(Event[] events, int loopIterationTimeLength, int numChannels,
TimingPolicy timingPolicy, boolean usesTiming) {
this.mEvents = events;
this.mLoopIterationTimeLength = loopIterationTimeLength;
this.mNumChannels = numChannels;
this.mTimingPolicy = timingPolicy;
this.mUsesTiming = usesTiming;
}
public int getNumChannels() {
return Math.max(mNumChannels, 1);
}
@Override
public Mood clone() {
Gson gson = new Gson();
return gson.fromJson(gson.toJson(this), Mood.class);
}
public int getNumTimeslots() {
int result = 0;
if (mEvents == null) {
return result;
}
HashSet<Integer> times = new HashSet<Integer>();
for (Event e : mEvents) {
if (e != null && times.add(e.getLegacyTime())) {
result++;
}
}
return result;
}
public Event[] getEvents() {
return mEvents;
}
public BulbState[][] getEventStatesAsSparseMatrix() {
int maxCol = getNumChannels();
int maxRow = getNumTimeslots();
HashMap<Integer, Integer> timeslotMapping = new HashMap<Integer, Integer>();
BulbState[][] colorGrid = new BulbState[maxRow][maxCol];
int curRow = -1;
for (Event e : mEvents) {
if (!timeslotMapping.containsKey(e.getLegacyTime())) {
timeslotMapping.put(e.getLegacyTime(), ++curRow);
}
colorGrid[timeslotMapping.get(e.getLegacyTime())][e.getChannel()] = e.getBulbState();
}
return colorGrid;
}
public boolean isSimple() {
if (mEvents == null) {
return true;
}
for (Event e : mEvents) {
if (e != null && e.getLegacyTime() != 0) {
return false;
}
}
return true;
}
public long getLoopMilliTime() {
if (mTimingPolicy == TimingPolicy.DAILY) {
return NUMBER_OF_MILLISECONDS_IN_DAY;
} else {
return mLoopIterationTimeLength * 100l;
}
}
public TimingPolicy getTimingPolicy() {
return mTimingPolicy;
}
public boolean getUsesTiming() {
return mUsesTiming;
}
@Override
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof Mood)) {
throw new IllegalArgumentException();
}
return (Arrays.equals(this.getEvents(), ((Mood) obj).getEvents())
&& this.getNumChannels() == ((Mood) obj).getNumChannels()
&& this.getTimingPolicy() == ((Mood) obj).getTimingPolicy()
&& this.getUsesTiming() == ((Mood) obj).getUsesTiming()
&& this.getLoopMilliTime() == ((Mood) obj).getLoopMilliTime());
}
public static class Builder {
private Event[] mEvents;
private int mLoopIterationTimeLength;
private Integer mNumChannels;
private TimingPolicy mTimingPolicy;
private boolean mUsesTiming;
public Builder() {
}
public Builder(BulbState bulbState) {
mNumChannels = 1;
mEvents = new Event[]{new Event(bulbState, 0, 0l)};
}
public Builder setEvents(Event[] events) {
if (events == null || events.length < 1 || events[0] == null) {
throw new IllegalArgumentException();
}
mEvents = events;
return this;
}
public Builder setNumChannels(int num) {
mNumChannels = num;
return this;
}
public Builder setLoopMilliTime(long milliseconds) {
mLoopIterationTimeLength = (int) (milliseconds / 100l);
return this;
}
public Builder setTimingPolicy(TimingPolicy timingPolicy) {
mTimingPolicy = timingPolicy;
return this;
}
public Builder setUsesTiming(boolean usesTiming) {
mUsesTiming = usesTiming;
return this;
}
public Mood build() {
// Lazy init default parameters
if (mEvents == null) {
throw new IllegalStateException();
}
if (mTimingPolicy == null) {
mTimingPolicy = TimingPolicy.BASIC;
}
if (mNumChannels == null) {
mNumChannels = 0;
for (Event e : mEvents) {
if (e.getChannel() >= mNumChannels) {
mNumChannels = e.getChannel() + 1; // channels are zero-indexed
}
}
}
return new Mood(mEvents, mLoopIterationTimeLength, mNumChannels, mTimingPolicy, mUsesTiming);
}
}
}