app/src/main/java/ch/epfl/sweng/zuluzulu/fragments/CalendarFragment.java
package ch.epfl.sweng.zuluzulu.fragments;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.util.Log;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import com.google.firebase.Timestamp;
import com.imanoweb.calendarview.CalendarListener;
import com.imanoweb.calendarview.CustomCalendarView;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import ch.epfl.sweng.zuluzulu.adapters.EventArrayAdapter;
import ch.epfl.sweng.zuluzulu.firebase.DatabaseFactory;
import ch.epfl.sweng.zuluzulu.R;
import ch.epfl.sweng.zuluzulu.fragments.superFragments.FragmentWithUser;
import ch.epfl.sweng.zuluzulu.structure.Event;
import ch.epfl.sweng.zuluzulu.structure.user.AuthenticatedUser;
public class CalendarFragment extends FragmentWithUser<AuthenticatedUser> {
private Date today;
private Date tomorrow;
private List<Event> followedEvents;
private List<Event> selectedDayEvents;
private EventArrayAdapter eventAdapter;
private ListView list;
private CustomCalendarView calendarView;
private Calendar calendar;
public CalendarFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @return A new instance of fragment CalendarFragment.
*/
public static CalendarFragment newInstance(AuthenticatedUser user) {
if(user == null)
throw new IllegalArgumentException("user can't be null");
CalendarFragment fragment = new CalendarFragment();
Bundle args = new Bundle();
args.putSerializable(ARG_USER, user);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
followedEvents = new ArrayList<>();
selectedDayEvents = new ArrayList<>();
eventAdapter = new EventArrayAdapter(getContext(), selectedDayEvents, mListener, user);
Pair<Date, Date> pair = getStartAndEndOfTheDay(Timestamp.now().toDate());
today = pair.first;
tomorrow = pair.second;
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_calendar, container, false);
list = view.findViewById(R.id.calendar_list);
list.setAdapter(eventAdapter);
//Initialize CustomCalendarView from layout
calendarView = view.findViewById(R.id.calendar_view);
//Initialize calendarView with date
calendar = Calendar.getInstance(Locale.getDefault());
//Show Monday as first date of week
calendarView.setFirstDayOfWeek(Calendar.MONDAY);
//Show/hide overflow days of a month
calendarView.setShowOverflowDate(true);
//call refreshCalendar to update calendarView the view
calendarView.refreshCalendar(calendar);
//Handling custom calendarView events
calendarView.setCalendarListener(new CalendarListener() {
@Override
public void onDateSelected(Date date) {
Pair<Date, Date> pair = getStartAndEndOfTheDay(date);
selectedDayEvents.clear();
for (Event event : followedEvents) {
if (isCurrentlyGoing(event, pair.first, pair.second))
selectedDayEvents.add(event);
}
eventAdapter.notifyDataSetChanged();
calendar.setTime(date);
calendarView.refreshCalendar(calendar);
calendarView.markDayAsSelectedDay(date);
}
//Required method, but not used here
@Override
public void onMonthChanged(Date date) {
}
});
//Set the day decorator
calendarView.setDecorators(Collections.singletonList(dayView -> {
Pair<Date, Date> pair = getStartAndEndOfTheDay(dayView.getDate());
for (Event event : followedEvents) {
if (isCurrentlyGoing(event, pair.first, pair.second))
dayView.setBackgroundColor(getResources().getColor(R.color.colorPrimaryLight));
}
}));
//Fill the followed events list from user's preferences
fillFollowedEventsList();
return view;
}
/**
* Fill the event list from the database
*/
private void fillFollowedEventsList() {
DatabaseFactory.getDependency().getEventsFromIds(user.getFollowedEvents(), result -> {
for (Event event : result) {
followedEvents.add(event);
if (isCurrentlyGoing(event, today, tomorrow))
selectedDayEvents.add(event);
}
eventAdapter.notifyDataSetChanged();
if (getContext() != null)
calendarView.refreshCalendar(calendar);
calendarView.markDayAsSelectedDay(today);
});
}
/**
* Return if an event is going on between two dates
*
* @param event event to check
* @param start lower_bound date
* @param end upper_bound date
* @return true if an event is going on between the two dates
*/
private boolean isCurrentlyGoing(Event event, Date start, Date end) {
assert (start.before(end));
return (event.getStartDate().after(start) && event.getStartDate().before(end)) ||
(event.getEndDate().after(start) && event.getStartDate().before(end)) ||
(event.getStartDate().before(start) && event.getEndDate().after(end));
}
/**
* Return the start and end of a day of a date
*
* @param date date
* @return the beginning and ending of the day in a pair
*/
private Pair<Date, Date> getStartAndEndOfTheDay(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 1);
Date start = calendar.getTime();
calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
Date end = calendar.getTime();
Log.d("TODAY and TOMORROW", start.toString() + " " + end.toString());
return new Pair<>(start, end);
}
}