/***********************************************************************************
* The MIT License (MIT)
* Copyright (c) 2014 Robin Chutaux
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
***********************************************************************************/
package com.marshalchen.common.uimodule.calendarlistview;
import android.content.Context;
import android.content.res.TypedArray;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import com.marshalchen.common.uimodule.widgets.R;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
public class SimpleMonthAdapter extends BaseAdapter implements SimpleMonthView.OnDayClickListener {
protected static final int MONTHS_IN_YEAR = 12;
private final TypedArray typedArray;
private final Context mContext;
private final DatePickerController mController;
private final Calendar calendar;
private final SelectedDays<CalendarDay> selectedDays;
private final Boolean startCurrentMonth;
public SimpleMonthAdapter(Context context, DatePickerController datePickerController, TypedArray typedArray) {
this.typedArray = typedArray;
startCurrentMonth = typedArray.getBoolean(R.styleable.DayPickerView_dpv_startCurrentMonth, false);
selectedDays = new SelectedDays<CalendarDay>();
mContext = context;
mController = datePickerController;
calendar = Calendar.getInstance();
init();
}
public int getCount() {
return ((mController.getMaxYear() - calendar.get(Calendar.YEAR)) + 1) * MONTHS_IN_YEAR;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
int month;
int year;
SimpleMonthView v;
HashMap<String, Integer> drawingParams = null;
if (convertView != null) {
v = (SimpleMonthView) convertView;
drawingParams = (HashMap<String, Integer>) v.getTag();
} else {
v = new SimpleMonthView(mContext, typedArray);
v.setLayoutParams(new AbsListView.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
v.setClickable(true);
v.setOnDayClickListener(this);
}
if (drawingParams == null) {
drawingParams = new HashMap<String, Integer>();
}
drawingParams.clear();
if (startCurrentMonth)
{
month = (calendar.get(Calendar.MONTH) + (position % MONTHS_IN_YEAR)) % MONTHS_IN_YEAR;
year = position / MONTHS_IN_YEAR + calendar.get(Calendar.YEAR) + ((calendar.get(Calendar.MONTH) + (position % MONTHS_IN_YEAR)) / MONTHS_IN_YEAR);
}
else
{
month = position % MONTHS_IN_YEAR;
year = position / MONTHS_IN_YEAR + calendar.get(Calendar.YEAR);
}
int selectedFirstDay = -1;
int selectedLastDay = -1;
int selectedFirstMonth = -1;
int selectedLastMonth = -1;
int selectedFirstYear = -1;
int selectedLastYear = -1;
if (selectedDays.getFirst() != null)
{
selectedFirstDay = selectedDays.getFirst().day;
selectedFirstMonth = selectedDays.getFirst().month;
selectedFirstYear = selectedDays.getFirst().year;
}
if (selectedDays.getLast() != null)
{
selectedLastDay = selectedDays.getLast().day;
selectedLastMonth = selectedDays.getLast().month;
selectedLastYear = selectedDays.getLast().year;
}
v.reuse();
drawingParams.put(SimpleMonthView.VIEW_PARAMS_SELECTED_BEGIN_YEAR, selectedFirstYear);
drawingParams.put(SimpleMonthView.VIEW_PARAMS_SELECTED_LAST_YEAR, selectedLastYear);
drawingParams.put(SimpleMonthView.VIEW_PARAMS_SELECTED_BEGIN_MONTH, selectedFirstMonth);
drawingParams.put(SimpleMonthView.VIEW_PARAMS_SELECTED_LAST_MONTH, selectedLastMonth);
drawingParams.put(SimpleMonthView.VIEW_PARAMS_SELECTED_BEGIN_DAY, selectedFirstDay);
drawingParams.put(SimpleMonthView.VIEW_PARAMS_SELECTED_LAST_DAY, selectedLastDay);
drawingParams.put(SimpleMonthView.VIEW_PARAMS_YEAR, year);
drawingParams.put(SimpleMonthView.VIEW_PARAMS_MONTH, month);
drawingParams.put(SimpleMonthView.VIEW_PARAMS_WEEK_START, calendar.getFirstDayOfWeek());
v.setMonthParams(drawingParams);
v.invalidate();
return v;
}
protected void init() {
if (typedArray.getBoolean(R.styleable.DayPickerView_dpv_currentDaySelected, false))
onDayTapped(new CalendarDay(System.currentTimeMillis()));
}
public void onDayClick(SimpleMonthView simpleMonthView, CalendarDay calendarDay) {
if (calendarDay != null) {
onDayTapped(calendarDay);
}
}
protected void onDayTapped(CalendarDay calendarDay) {
mController.onDayOfMonthSelected(calendarDay.year, calendarDay.month, calendarDay.day);
setSelectedDay(calendarDay);
}
public void setSelectedDay(CalendarDay calendarDay) {
if (selectedDays.getFirst() != null && selectedDays.getLast() == null)
{
selectedDays.setLast(calendarDay);
if (selectedDays.getFirst().month < calendarDay.month)
{
for (int i = 0; i < selectedDays.getFirst().month - calendarDay.month - 1; ++i)
mController.onDayOfMonthSelected(selectedDays.getFirst().year, selectedDays.getFirst().month + i, selectedDays.getFirst().day);
}
}
else if (selectedDays.getLast() != null)
{
selectedDays.setFirst(calendarDay);
selectedDays.setLast(null);
}
else
selectedDays.setFirst(calendarDay);
notifyDataSetChanged();
}
public static class CalendarDay implements Serializable
{
private static final long serialVersionUID = -5456695978688356202L;
private Calendar calendar;
int day;
int month;
int year;
public CalendarDay() {
setTime(System.currentTimeMillis());
}
public CalendarDay(int year, int month, int day) {
setDay(year, month, day);
}
public CalendarDay(long timeInMillis) {
setTime(timeInMillis);
}
public CalendarDay(Calendar calendar) {
year = calendar.get(Calendar.YEAR);
month = calendar.get(Calendar.MONTH);
day = calendar.get(Calendar.DAY_OF_MONTH);
}
private void setTime(long timeInMillis) {
if (calendar == null) {
calendar = Calendar.getInstance();
}
calendar.setTimeInMillis(timeInMillis);
month = this.calendar.get(Calendar.MONTH);
year = this.calendar.get(Calendar.YEAR);
day = this.calendar.get(Calendar.DAY_OF_MONTH);
}
public void set(CalendarDay calendarDay) {
year = calendarDay.year;
month = calendarDay.month;
day = calendarDay.day;
}
public void setDay(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public Date getDate()
{
if (calendar == null) {
calendar = Calendar.getInstance();
}
calendar.set(year, month, day);
return calendar.getTime();
}
}
public SelectedDays<CalendarDay> getSelectedDays()
{
return selectedDays;
}
public static class SelectedDays<K> implements Serializable
{
private static final long serialVersionUID = 3942549765282708376L;
private K first;
private K last;
public K getFirst()
{
return first;
}
public void setFirst(K first)
{
this.first = first;
}
public K getLast()
{
return last;
}
public void setLast(K last)
{
this.last = last;
}
}
}