/* * Copyright 2015. Appsi Mobile * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.appsimobile.appsii.module.appsiagenda; import android.text.format.Time; import android.util.SparseIntArray; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.appsimobile.appsii.R; import com.appsimobile.util.TimeUtils; import java.util.ArrayList; import java.util.List; /** * Created by nick on 07/01/15. */ public class ColoredAgendaAdapter extends AgendaAdapter<ColoredAgendaViewHolder> { final ArrayList<AgendaEvent> mEvents = new ArrayList<>(120); final Time mRecycleTime = new Time(Time.TIMEZONE_UTC); /** * Maps encoded week-year numbers to their position in the list */ final SparseIntArray mStartPositionsForWeeks = new SparseIntArray(); /** * Maps a position to an encoded week-year number */ final SparseIntArray mReversedStartPositionsForWeeks = new SparseIntArray(); private ItemAgendaViewHolder.OnItemClickListener mOnAgendaItemClickListener; @Override public void setOnAgendaItemClickListener( ItemAgendaViewHolder.OnItemClickListener onItemClickListener) { mOnAgendaItemClickListener = onItemClickListener; } @Override public float getHeaderScrollPercentage() { // we don't have a scrolling header, always return 0 for now. return 0; } @Override public boolean getTimeAtPosition(Time time, int position) { if (position >= mEvents.size()) return false; AgendaEvent event = mEvents.get(position); time.setJulianDay(event.startDay); return true; } @Override public int positionOfDate(int year, int month, int day) { mRecycleTime.set(day, month, year); int julianDay = Time.getJulianDay(mRecycleTime.toMillis(false), 0); return positionOfJulianDay(julianDay); } public int positionOfJulianDay(int julianDay) { for (int i = 0; i < mEvents.size(); i++) { AgendaEvent event = mEvents.get(i); if (event.startDay >= julianDay) { return i; } } return -1; } @Override public int setAgendaEvents(List<AgendaEvent> data) { mStartPositionsForWeeks.clear(); mReversedStartPositionsForWeeks.clear(); mEvents.clear(); if (data == null) { notifyDataSetChanged(); return -1; } int todayPosition = -1; int today = TimeUtils.getJulianDay(); for (AgendaEvent event : data) { if (todayPosition == -1 && event.startDay >= today) { todayPosition = mEvents.size(); } // now determine the week-number. // The week-number is encoded with the year to create a unique id mRecycleTime.setJulianDay(event.startDay); int weekNumber = mRecycleTime.getWeekNumber(); int yearWeek = encodeYearWeekNumber(mRecycleTime.year, weekNumber); // when we already have a position for the given week/year, do nothing // otherwise register it in the index. int existingPosition = mStartPositionsForWeeks.get(yearWeek, -1); if (existingPosition == -1) { mStartPositionsForWeeks.put(yearWeek, mEvents.size()); mReversedStartPositionsForWeeks.put(mEvents.size(), yearWeek); } mEvents.add(event); } notifyDataSetChanged(); return todayPosition; } @Override public boolean hasWeekNumberAtPosition(int position) { int weekYear = mReversedStartPositionsForWeeks.get(position, 0xFFFFFFFF); return weekYear != 0xFFFFFFFF; } @Override int getJulianDayAtPosition(int position) { if (position >= mEvents.size()) return -1; return mEvents.get(position).startDay; } @Override public void focusPosition(int agendaPosition) { // We don't need to do anything special here. } @Override public void clear() { int count = mEvents.size(); mEvents.clear(); notifyItemRangeRemoved(0, count); } int encodeYearWeekNumber(int year, int weekNumber) { return ((year & 0x0000FFFF) << 16) | (weekNumber & 0x0000FFFF); } int decodeYear(int yearWeekNumber) { return (yearWeekNumber >> 16); } int decodeWeekNumber(int yearWeekNumber) { return (yearWeekNumber & 0xFFFF); } @Override public ColoredAgendaViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); View result = inflater.inflate(R.layout.list_item_agenda_colored, parent, false); return new ColoredAgendaViewHolder(result, mOnAgendaItemClickListener); } @Override public void onBindViewHolder(ColoredAgendaViewHolder holder, int position) { holder.bind(mEvents.get(position)); } @Override public int getItemCount() { return mEvents.size(); } }