cat.mvmike.minimalcalendarwidget.service.DayService.java Source code

Java tutorial

Introduction

Here is the source code for cat.mvmike.minimalcalendarwidget.service.DayService.java

Source

// Copyright (c) 2016, Miquel Mart <miquelmarti111@gmail.com>
// See LICENSE for licensing information

package cat.mvmike.minimalcalendarwidget.service;

import android.content.Context;
import android.graphics.Typeface;
import android.support.v4.content.ContextCompat;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ForegroundColorSpan;
import android.text.style.RelativeSizeSpan;
import android.text.style.StyleSpan;
import android.widget.RemoteViews;

import java.util.Calendar;
import java.util.HashSet;
import java.util.Set;
import java.util.TimeZone;

import cat.mvmike.minimalcalendarwidget.R;
import cat.mvmike.minimalcalendarwidget.activity.PermissionsActivity;
import cat.mvmike.minimalcalendarwidget.resolver.CalendarResolver;
import cat.mvmike.minimalcalendarwidget.resolver.dto.InstanceDto;
import cat.mvmike.minimalcalendarwidget.service.configuration.ConfigurationService;
import cat.mvmike.minimalcalendarwidget.service.enums.Symbol;
import cat.mvmike.minimalcalendarwidget.service.enums.Theme;
import cat.mvmike.minimalcalendarwidget.status.CalendarStatus;
import cat.mvmike.minimalcalendarwidget.status.DayStatus;

public final class DayService {

    private static final int NUM_WEEKS = 6;

    private static final String PADDING = " ";

    private static final String DOUBLE_PADDING = PADDING + PADDING;

    public static void setDays(final Context context, final Calendar cal, final SpannableString ss,
            final RemoteViews remoteViews) {

        int firstDayOfWeek = ConfigurationService.getStartWeekDay(context);
        Theme theme = ConfigurationService.getTheme(context);
        CalendarStatus cs = new CalendarStatus(context, cal, firstDayOfWeek);

        Set<InstanceDto> instanceSet = PermissionsActivity.isPermitted(context)
                ? CalendarResolver.readAllInstances(context.getContentResolver(), cal)
                : new HashSet<>();

        RemoteViews rowRv;
        for (int week = 0; week < NUM_WEEKS; week++) {

            rowRv = new RemoteViews(context.getPackageName(), R.layout.row_week);

            DayStatus ds;
            for (int day = 0; day < Calendar.DAY_OF_WEEK; day++) {

                ds = new DayStatus(cal, cs.getTodayYear(), cs.getThisMonth(), cs.getToday());
                RemoteViews cellRv = new RemoteViews(context.getPackageName(), getDayLayout(theme, ds));

                int numberOfInstances = getNumberOfInstances(instanceSet, ds);
                setInstanceNumber(context, cellRv, Integer.toString(ds.getDayOfMonth()), ds.isToday(),
                        numberOfInstances);
                checkMonthBeginningStyleChange(cs.getCalendar(), cellRv, ss);

                cs.getCalendar().add(Calendar.DAY_OF_MONTH, 1);

                rowRv.addView(R.id.row_container, cellRv);
            }

            remoteViews.addView(R.id.calendar_widget, rowRv);
        }
    }

    private static void setInstanceNumber(final Context context, final RemoteViews cellRv, final String dayOfMonth,
            final boolean isToday, final int found) {

        Symbol symbols = ConfigurationService.getInstancesSymbols(context);
        Character[] symbolArray = symbols.getArray();

        int max = symbolArray.length - 1;
        String symbol = String.valueOf(found > max ? symbolArray[max] : symbolArray[found]);
        String dayOfMonthSpSt = PADDING + (dayOfMonth.length() == 1 ? dayOfMonth + DOUBLE_PADDING : dayOfMonth)
                + PADDING + symbol;
        SpannableString daySpSt = new SpannableString(dayOfMonthSpSt);
        daySpSt.setSpan(new StyleSpan(Typeface.BOLD), dayOfMonthSpSt.length() - 1, dayOfMonthSpSt.length(),
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        int color;
        if (isToday) {
            color = ContextCompat.getColor(context, R.color.instances_today);
            daySpSt.setSpan(new StyleSpan(Typeface.BOLD), 0, dayOfMonthSpSt.length() - 1,
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        } else {
            color = ContextCompat.getColor(context,
                    ConfigurationService.getInstancesSymbolsColours(context).getHexValue());
        }

        daySpSt.setSpan(new ForegroundColorSpan(color), dayOfMonthSpSt.length() - 1, dayOfMonthSpSt.length(),
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        daySpSt.setSpan(new RelativeSizeSpan(symbols.getRelativeSize()), dayOfMonthSpSt.length() - 1,
                dayOfMonthSpSt.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        cellRv.setTextViewText(android.R.id.text1, daySpSt);
    }

    private static int getDayLayout(final Theme theme, final DayStatus ds) {

        int cellLayoutResId = theme.getCellDay();

        if (ds.isInMonth()) {
            cellLayoutResId = theme.getCellDayThisMonth();
        }

        if (ds.isToday()) {
            if (ds.isSaturday()) {
                cellLayoutResId = theme.getCellDaySaturdayToday();
            } else if (ds.isSunday()) {
                cellLayoutResId = theme.getCellDaySundayToday();
            } else {
                cellLayoutResId = theme.getCellDayToday();
            }

        } else if (ds.isInMonth()) {
            if (ds.isSaturday()) {
                cellLayoutResId = theme.getCellDaySaturday();
            } else if (ds.isSunday()) {
                cellLayoutResId = theme.getCellDaySunday();
            }
        }

        return cellLayoutResId;
    }

    private static void checkMonthBeginningStyleChange(final Calendar cal, final RemoteViews cellRv,
            final SpannableString ss) {

        if (CalendarStatus.isMonthFirstDay(cal)) {
            cellRv.setTextViewText(R.id.month_year_label, ss);
        }
    }

    private static int getNumberOfInstances(final Set<InstanceDto> instanceSet, final DayStatus ds) {

        int found = 0;
        if (instanceSet == null || instanceSet.isEmpty()) {
            return found;
        }

        for (InstanceDto instance : instanceSet) {

            Calendar startCalendar = Calendar.getInstance(TimeZone.getDefault());
            startCalendar.setTime(instance.getDateStart());

            Calendar endCalendar = Calendar.getInstance(TimeZone.getDefault());
            endCalendar.setTime(instance.getDateEnd());

            // take out 5 milliseconds to avoid erratic behaviour with full day events (or those that end at 00:00)
            endCalendar.add(Calendar.MILLISECOND, -5);

            if (ds.isInDay(startCalendar, endCalendar)) {
                found++;
            }
        }

        return found;
    }
}