package com.wigwamlabs.veckify;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import static com.wigwamlabs.veckify.AlarmUtils.DAYS_NONE;
public class DayPicker extends View {
private final Paint mTextPaint = new Paint();
private final Paint mPressedPaint = new Paint();
private final Paint mIndicatorPaint = new Paint();
private final String[] mDayNames;
private int mDays = DAYS_NONE;
private int mPressedDay = DAYS_NONE;
private OnDaysChangedListener mListener;
private int mIndicatorHeight;
private boolean mPressEnables;
public DayPicker(Context context) {
this(context, null, 0);
}
public DayPicker(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DayPicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
final Resources res = context.getResources();
mDayNames = res.getStringArray(R.array.repeatdays_shortday);
for (int i = 0; i < mDayNames.length; i++) {
mDayNames[i] = mDayNames[i].toUpperCase();
}
mTextPaint.setTextSize(res.getDimensionPixelSize(R.dimen.daypicker_textsize));
mTextPaint.setColor(res.getColor(android.R.color.white));
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setTypeface(Typeface.create("sans-serif-condensed", Typeface.ITALIC));
mIndicatorPaint.setColor(res.getColor(R.color.accent_primary));
mIndicatorPaint.setStyle(Paint.Style.FILL);
mIndicatorHeight = res.getDimensionPixelSize(R.dimen.daypicker_indicatorheight);
mPressedPaint.setColor(res.getColor(R.color.accent_secondary));
mPressedPaint.setStyle(Paint.Style.FILL);
}
@Override
public boolean onTouchEvent(@NonNull MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
final int day = mapEventToDay(event);
mPressedDay = day;
mPressEnables = !isDaySet(day);
setDay(day, mPressEnables, true);
return true;
}
case MotionEvent.ACTION_MOVE: {
final int day = mapEventToDay(event);
if (day != mPressedDay) {
mPressedDay = day;
setDay(day, mPressEnables, true);
invalidate();
}
return true;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP: {
mPressedDay = DAYS_NONE;
invalidate();
return true;
}
}
return false;
}
private int mapEventToDay(MotionEvent event) {
final float x = event.getX();
final float y = event.getY();
final int width = getWidth();
final int height = getHeight();
if (x < 0 || x > width ||
y < 0 || y > height) {
return DAYS_NONE;
}
final float dayWidth = (float) width / mDayNames.length;
int index = (int) (x / dayWidth);
if (index >= mDayNames.length) {
index = mDayNames.length - 1;
}
return (1 << index);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
final float dayWidth = (float) getWidth() / mDayNames.length;
final int height = getHeight();
//TODO ensure days follow locale's first weekday: Calendar.getFirstDayOfWeek()
for (int i = 0; i < mDayNames.length; i++) {
final int day = (1 << i);
float backgroundHeight = height;
final float left = i * dayWidth;
final float right = (i + 1) * dayWidth;
if ((mDays & day) != 0) {
canvas.drawRect(left, height - mIndicatorHeight, right, height, mIndicatorPaint);
backgroundHeight -= mIndicatorHeight;
}
if ((mPressedDay & day) != 0) {
canvas.drawRect(left, 0, right, backgroundHeight, mPressedPaint);
}
}
final float textY = height / 2 + mTextPaint.getTextSize() / 2;
for (int i = 0; i < mDayNames.length; i++) {
canvas.drawText(mDayNames[i], (i + 0.5f) * dayWidth, textY, mTextPaint);
}
}
private void setDay(int day, boolean checked, boolean fromUser) {
final int days;
if (checked) {
days = mDays | day;
} else {
days = mDays & ~day;
}
setDays(days, fromUser);
}
private boolean isDaySet(int day) {
return (mDays & day) != 0;
}
private void setDays(int days, boolean fromUser) {
if (days != mDays) {
mDays = days;
invalidate();
if (mListener != null) {
mListener.onDaysChanged(this, mDays, fromUser);
}
}
}
public int getDays() {
return mDays;
}
public void setDays(int days) {
setDays(days, false);
}
public void setDaysChangedListener(OnDaysChangedListener daysChangedListener) {
mListener = daysChangedListener;
}
public interface OnDaysChangedListener {
public void onDaysChanged(DayPicker dayPicker, int days, boolean fromUser);
}
}