package net.mvla.mvhs.schedulecalendar; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.annotation.SuppressLint; import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.content.ContextCompat; import android.support.v4.view.animation.FastOutSlowInInterpolator; import android.support.v7.widget.CardView; import android.text.format.DateUtils; import android.text.method.LinkMovementMethod; import android.text.style.ForegroundColorSpan; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView; import com.prolificinteractive.materialcalendarview.CalendarDay; import com.prolificinteractive.materialcalendarview.DayViewDecorator; import com.prolificinteractive.materialcalendarview.DayViewFacade; import com.prolificinteractive.materialcalendarview.MaterialCalendarView; import net.mvla.mvhs.MvpPresenterHolder; import net.mvla.mvhs.PrefUtils; import net.mvla.mvhs.R; import net.mvla.mvhs.Utils; import net.mvla.mvhs.schedulecalendar.bellschedule.BellSchedule; import net.mvla.mvhs.schedulecalendar.bellschedule.BellSchedulePeriod; import net.mvla.mvhs.schedulecalendar.bellschedule.UserPeriodInfo; import net.mvla.mvhs.ui.DrawerActivity; import java.util.Calendar; import java.util.Date; import java.util.List; import butterknife.BindView; import butterknife.ButterKnife; public class ScheduleCalendarActivity extends DrawerActivity implements ScheduleCalendarView { @BindView(R.id.activity_schedule_calendar) MaterialCalendarView mCalendarView; @BindView(R.id.activity_schedule_appbar) LinearLayout mAppBar; @BindView(R.id.activity_schedule_title_linear) LinearLayout mTitleTextBar; @BindView(R.id.activity_schedule_title_text) TextView mTitle; @BindView(R.id.activity_schedule_calendar_dropdown_image) ImageView mCalendarDropdownImage; @BindView(R.id.fragment_schedule_events_title) TextView mEventsTitle; @BindView(R.id.list_item_schedule_title) TextView mBellScheduleTitle; @BindView(R.id.list_item_schedule_table) TableLayout mTableLayout; @BindView(R.id.schedule_events_linear) LinearLayout mEventsLayout; @BindView(R.id.calendar_events_progress) ProgressBar mCalendarProgressBar; @BindView(R.id.bell_schedule_progress) ProgressBar mBellScheduleProgressBar; @BindView(R.id.fragment_schedule_bell_schedule) CardView mBellScheduleCard; @BindView(R.id.schedule_events) CardView mEventsCard; @BindView(R.id.schedule_disclaimer) TextView mDisclaimer; private ScheduleCalendarPresenter mPresenter; @Override public void showCalendarError(String error) { mCalendarProgressBar.setVisibility(View.GONE); mEventsTitle.setText(error); } @Override public void showBellScheduleError(String error) { mBellScheduleProgressBar.setVisibility(View.GONE); mBellScheduleTitle.setText(error); } @Override public void onDestroy() { super.onDestroy(); mPresenter.detachView(); } public void setLoading() { mCalendarProgressBar.setVisibility(View.VISIBLE); mBellScheduleProgressBar.setVisibility(View.VISIBLE); mEventsTitle.setText(R.string.loading); mBellScheduleTitle.setText(R.string.loading); while (mEventsLayout.getChildCount() > 1) { mEventsLayout.removeViewAt(1); } mTableLayout.removeAllViews(); } @Override public void setBellSchedule(@NonNull BellSchedule bellSchedule, Calendar selectedCalDate) { LayoutInflater layoutInflater = getLayoutInflater(); mTableLayout.removeAllViews(); if (bellSchedule.bellSchedulePeriods != null && !bellSchedule.bellSchedulePeriods.isEmpty()) { inflateBellSchedule(bellSchedule, layoutInflater, selectedCalDate); } else { mBellScheduleTitle.setText(R.string.bell_schedule_no_school); } } @Override public void hideBellScheduleProgress() { mBellScheduleProgressBar.setVisibility(View.GONE); } @Override public void setSelectedDate(Calendar date) { mCalendarView.setDateSelected(date, true); mTitle.setText(DateUtils.formatDateTime( this, date.getTimeInMillis(), DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_MONTH)); } @Override public void setEvents(@NonNull List<ScheduleCalendarRepository.Event> events) { LayoutInflater layoutInflater = getLayoutInflater(); while (mEventsLayout.getChildCount() > 1) { mEventsLayout.removeViewAt(1); } if (!events.isEmpty()) { mEventsTitle.setText(R.string.school_events); //CALENDAR EVENTS for (ScheduleCalendarRepository.Event event : events) { View tableRowSeparator = layoutInflater.inflate(R.layout.table_row_divider, mEventsLayout, false); mEventsLayout.addView(tableRowSeparator); View eventLayout = layoutInflater.inflate(R.layout.list_item_calendar_event, mEventsLayout, false); TextView name = (TextView) eventLayout.findViewById(R.id.list_item_calendar_event_name); TextView subtitle = (TextView) eventLayout.findViewById(R.id.list_item_calendar_event_subtitle); name.setText(event.name); String range = DateUtils.formatDateRange(this, event.startTime, event.endTime, DateUtils.FORMAT_SHOW_TIME); subtitle.setText(range); mEventsLayout.addView(eventLayout); } } else { mEventsTitle.setText(R.string.no_school_events); } } @Override public void hideCalendarProgress() { mCalendarProgressBar.setVisibility(View.GONE); } private void inflateBellSchedule(@NonNull BellSchedule bellSchedule, LayoutInflater layoutInflater, Calendar selectedCalDate) { mBellScheduleTitle.setText(bellSchedule.name.replace("Sched.", "Bell Schedule")); //BELL SCHEDULE TABLE View divider = layoutInflater.inflate(R.layout.table_row_divider, mTableLayout, false); mTableLayout.addView(divider); View heading = layoutInflater.inflate(R.layout.table_row_heading_schedule, mTableLayout, false); mTableLayout.addView(heading); SharedPreferences preferences = android.preference.PreferenceManager.getDefaultSharedPreferences(this); for (BellSchedulePeriod period : bellSchedule.bellSchedulePeriods) { inflatePeriod(layoutInflater, preferences, period, selectedCalDate); } } @SuppressLint("SetTextI18n") private void inflatePeriod(LayoutInflater layoutInflater, SharedPreferences preferences, BellSchedulePeriod period, Calendar selectedCalDate) { View tableRowSeparator = layoutInflater.inflate(R.layout.table_row_divider, mTableLayout, false); mTableLayout.addView(tableRowSeparator); TableRow tableRow = (TableRow) layoutInflater.inflate(R.layout.table_row_schedule, mTableLayout, false); Calendar start = Calendar.getInstance(); Date selectedDate = selectedCalDate.getTime(); start.setTime(selectedDate); start.set(Calendar.HOUR_OF_DAY, period.startHour); start.set(Calendar.MINUTE, period.startMinute); Calendar end = Calendar.getInstance(); end.setTime(selectedDate); end.set(Calendar.HOUR_OF_DAY, period.endHour); end.set(Calendar.MINUTE, period.endMinute); Calendar now = Calendar.getInstance(); if (now.getTime().after(start.getTime()) && now.getTime().before(end.getTime())) { //In this period right now tableRow.setBackgroundColor(ContextCompat.getColor(this, R.color.primary)); } TextView periodText = (TextView) tableRow.findViewById(R.id.table_row_schedule_period_name_text); TextView timeText = (TextView) tableRow.findViewById(R.id.table_row_schedule_period_time_text); TextView room = (TextView) tableRow.findViewById(R.id.table_row_schedule_room_text); TextView subject = (TextView) tableRow.findViewById(R.id.table_row_schedule_subject_text); if (period.name.substring(0, 1).matches("^-?\\d+$")) { //is integer (is a number period) int firstChar = Integer.parseInt(period.name.substring(0, 1)); UserPeriodInfo info = new UserPeriodInfo(); info.room = preferences.getString(PrefUtils.PREF_SCHEDULE_PREFIX + firstChar + PrefUtils.PREF_SCHEDULE_ROOM, ""); info.subject = preferences.getString(PrefUtils.PREF_SCHEDULE_PREFIX + firstChar + PrefUtils.PREF_SCHEDULE_SBJCT, ""); boolean secondCharA = period.name.length() > 1 && period.name.substring(1, 2).equals("A"); boolean secondCharB = period.name.length() > 1 && period.name.substring(1, 2).equals("B"); boolean rallyB = preferences.getBoolean(PrefUtils.PREF_SCHEDULE_RALLY_B, false); if (firstChar == 2 && (secondCharA || secondCharB) && ((rallyB && secondCharB) || (!rallyB && secondCharA))) { //Rally schedule and this period is their rally room.setText(R.string.gym); subject.setText(String.format(getString(R.string.rally_blank), rallyB ? "B" : "A")); } else { room.setText(!info.room.isEmpty() ? info.room : ""); subject.setText(!info.subject.isEmpty() ? info.subject : ""); } } periodText.setText(period.name); timeText.setText(Utils.formatTime(start.getTime()) + " - " + Utils.formatTime(end.getTime())); mTableLayout.addView(tableRow); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); MvpPresenterHolder.getInstance().putPresenter(ScheduleCalendarPresenter.class, mPresenter); } @Override protected void onCreate(Bundle savedInstanceState) { setTheme(R.style.Theme_MVHSApp_Light_WithNavDrawer); super.onCreate(savedInstanceState); setContentView(R.layout.activity_schedule_calendar); ButterKnife.bind(this); mDisclaimer.setMovementMethod(LinkMovementMethod.getInstance()); mTitleTextBar.setOnClickListener(v -> { animateToggleCalendar(); }); mCalendarView.addDecorators(new DayViewDecorator() { @Override public boolean shouldDecorate(CalendarDay day) { return true; } @Override public void decorate(DayViewFacade view) { view.setSelectionDrawable(ContextCompat .getDrawable(ScheduleCalendarActivity.this, R.drawable.calendar_selector)); } }, new DayViewDecorator() { @Override public boolean shouldDecorate(CalendarDay day) { Calendar cal = Calendar.getInstance(); day.copyTo(cal); return Utils.sameDay(Calendar.getInstance(), cal); } @Override public void decorate(DayViewFacade view) { ForegroundColorSpan span = new ForegroundColorSpan(ContextCompat .getColor(ScheduleCalendarActivity.this, R.color.primary_text_default_material_dark)); view.addSpan(span); view.setBackgroundDrawable(ContextCompat .getDrawable(ScheduleCalendarActivity.this, R.drawable.calendar_today_selected)); } }); mCalendarView.setOnDateChangedListener((widget, date, selected) -> { mPresenter.onDateChanged(date.getCalendar()); ScheduleCalendarActivity.this.animateToggleCalendar(); }); mPresenter = MvpPresenterHolder.getInstance().getPresenter(ScheduleCalendarPresenter.class); if (mPresenter == null) { mPresenter = new ScheduleCalendarPresenter(); } mPresenter.attachView(this); mPresenter.onCreate(); } public void openCalendarView() { ViewGroup.LayoutParams layoutParams = mAppBar.getLayoutParams(); layoutParams.height = Utils.convertDpToPx(this, 48 * 8) + getResources().getDimensionPixelSize(R.dimen.abc_action_bar_default_height_material); mAppBar.setLayoutParams(layoutParams); mCalendarDropdownImage.setRotation(180); mCalendarView.setVisibility(View.VISIBLE); } private void animateToggleCalendar() { AnimatorSet set = new AnimatorSet(); ValueAnimator animator; boolean needExpand = mAppBar.getHeight() == mTitleTextBar.getHeight(); if (needExpand) { animator = ValueAnimator.ofInt(mTitleTextBar.getHeight(), Utils.convertDpToPx(this, 48 * 8) + mTitleTextBar.getHeight()); mCalendarView.setVisibility(View.VISIBLE); } else { animator = ValueAnimator.ofInt(mAppBar.getHeight(), mTitleTextBar.getHeight()); animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mCalendarView.setVisibility(View.GONE); } }); } animator.addUpdateListener(animation -> { RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mAppBar.getLayoutParams(); params.height = ((int) animation.getAnimatedValue()); mAppBar.setLayoutParams(params); }); animator.setInterpolator(new FastOutSlowInInterpolator()); ObjectAnimator animatorSpin; if (needExpand) { animatorSpin = ObjectAnimator.ofFloat(mCalendarDropdownImage, ImageView.ROTATION, 180); } else { animatorSpin = ObjectAnimator.ofFloat(mCalendarDropdownImage, ImageView.ROTATION, 0f); } animatorSpin.setInterpolator(new FastOutSlowInInterpolator()); set.setDuration(300); set.play(animator).with(animatorSpin); set.start(); } @Override public Context getContext() { return this; } @Override protected int getSelfNavDrawerItem() { return R.id.nav_sched; } @Override protected String getToolbarTitle(String navDrawerString) { return ""; } }