package com.code44.finance.utils; import android.content.Context; import com.code44.finance.R; import com.code44.finance.common.utils.Preconditions; import net.danlew.android.joda.DateUtils; import org.joda.time.DateTime; import org.joda.time.Interval; import org.joda.time.Period; import org.joda.time.format.DateTimeFormat; public abstract class BaseInterval { protected final Context context; protected final EventBus eventBus; protected Type type; protected int length; protected Interval interval; protected BaseInterval(Context context, EventBus eventBus, Type type, int length) { this.context = Preconditions.notNull(context, "Context cannot be null."); this.eventBus = Preconditions.notNull(eventBus, "EventBus cannot be null."); this.type = Preconditions.notNull(type, "Type cannot be null."); this.length = Preconditions.more(length, 0, "Length must be > 0."); reset(); } public static Period getPeriod(Type type, int length) { final Period period; switch (type) { case DAY: period = Period.days(length); break; case WEEK: period = Period.weeks(length); break; case MONTH: period = Period.months(length); break; case YEAR: period = Period.years(length); break; default: throw new IllegalArgumentException("Type " + type + " is not supported."); } return period; } public static Interval getInterval(long millis, Period period, Type type) { final DateTime currentTime = new DateTime(millis); final DateTime intervalStart; switch (type) { case DAY: intervalStart = currentTime.withTimeAtStartOfDay(); break; case WEEK: intervalStart = currentTime.weekOfWeekyear().roundFloorCopy(); break; case MONTH: intervalStart = currentTime.dayOfMonth().withMinimumValue().withTimeAtStartOfDay(); break; case YEAR: intervalStart = currentTime.withMonthOfYear(1).withDayOfMonth(1).withTimeAtStartOfDay(); break; default: throw new IllegalArgumentException("Type " + type + " is not supported."); } return new Interval(intervalStart, period); } public static String getTitle(Context context, Interval interval, Type type) { switch (type) { case DAY: return DateTimeFormat.mediumDate().print(interval.getStart()); case WEEK: return DateUtils.formatDateTime(context, interval.getStart(), DateUtils.FORMAT_ABBREV_ALL) + " - " + DateUtils.formatDateTime(context, interval.getEnd().minusMillis(1), DateUtils.FORMAT_ABBREV_ALL); case MONTH: return DateUtils.formatDateTime(context, interval.getStart(), DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_MONTH_DAY); case YEAR: return interval.getStart().year().getAsText(); default: throw new IllegalArgumentException("Type " + type + " is not supported."); } } public Type getType() { return type; } public int getLength() { return length; } public void setTypeAndLength(Type type, int length) { Preconditions.notNull(type, "Type cannot be null."); Preconditions.more(length, 0, "Length must be > 0."); final boolean changed = this.type != type || this.length != length; this.type = type; this.length = length; if (changed) { reset(); } } public Interval getInterval() { return interval; } public String getTitle() { return getTitle(context, interval, type); } public String getTypeTitle() { switch (type) { case DAY: return context.getString(R.string.day); case WEEK: return context.getString(R.string.week); case MONTH: return context.getString(R.string.month); case YEAR: return context.getString(R.string.year); default: throw new IllegalArgumentException("Type " + type + " is not supported."); } } public void reset() { interval = getInterval(System.currentTimeMillis(), getPeriodForType(), type); notifyChanged(); } protected Period getPeriodForType() { return getPeriod(type, length); } protected void notifyChanged() { eventBus.post(this); } public static enum Type { DAY, WEEK, MONTH, YEAR } }