package org.mtransit.android.ui.fragment;
import java.util.Calendar;
import org.mtransit.android.R;
import org.mtransit.android.commons.BundleUtils;
import org.mtransit.android.commons.MTLog;
import org.mtransit.android.commons.TimeUtils;
import org.mtransit.android.commons.data.RouteTripStop;
import org.mtransit.android.commons.provider.POIProviderContract;
import org.mtransit.android.commons.task.MTAsyncTask;
import org.mtransit.android.commons.TaskUtils;
import org.mtransit.android.data.DataSourceManager;
import org.mtransit.android.data.POIManager;
import org.mtransit.android.task.ServiceUpdateLoader;
import org.mtransit.android.task.StatusLoader;
import org.mtransit.android.ui.MainActivity;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
public class ScheduleFragment extends ABFragment implements ViewPager.OnPageChangeListener {
private static final String TAG = ScheduleFragment.class.getSimpleName();
@Override
public String getLogTag() {
return TAG;
}
private static final String TRACKING_SCREEN_NAME = "Schedule";
@Override
public String getScreenName() {
return TRACKING_SCREEN_NAME;
}
private static final String EXTRA_AUTHORITY = "extra_agency_authority";
private static final String EXTRA_POI_UUID = "extra_poi_uuid";
private static final String EXTRA_COLOR_INT = "extra_color_int";
public static ScheduleFragment newInstance(String uuid, String authority, RouteTripStop optRts, Integer optColorInt) {
ScheduleFragment f = new ScheduleFragment();
Bundle args = new Bundle();
args.putString(EXTRA_AUTHORITY, authority);
f.authority = authority;
args.putString(EXTRA_POI_UUID, uuid);
f.uuid = uuid;
f.rts = optRts;
if (optColorInt != null) {
args.putInt(EXTRA_COLOR_INT, optColorInt);
f.colorInt = optColorInt;
}
f.setArguments(args);
return f;
}
private DayPagerAdapter adapter;
private int lastPageSelected = -1;
private String uuid;
private RouteTripStop rts;
private Integer colorInt;
private boolean hasRts() {
if (this.rts == null) {
initRtsAsync();
return false;
}
return true;
}
private void initRtsAsync() {
if (this.loadRtsTask != null && this.loadRtsTask.getStatus() == MTAsyncTask.Status.RUNNING) {
return;
}
if (TextUtils.isEmpty(this.uuid) || TextUtils.isEmpty(this.authority)) {
return;
}
this.loadRtsTask = new LoadRtsTask();
TaskUtils.execute(this.loadRtsTask);
}
private LoadRtsTask loadRtsTask = null;
private class LoadRtsTask extends MTAsyncTask<Void, Void, Boolean> {
@Override
public String getLogTag() {
return ScheduleFragment.this.getLogTag() + ">" + LoadRtsTask.class.getSimpleName();
}
@Override
protected Boolean doInBackgroundMT(Void... params) {
return initRtsSync();
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if (result) {
applyNewRts();
}
}
}
private void resetRts() {
this.rts = null;
}
private RouteTripStop getRtsOrNull() {
if (!hasRts()) {
return null;
}
return this.rts;
}
private boolean initRtsSync() {
if (this.rts != null) {
return false;
}
if (!TextUtils.isEmpty(this.uuid) && !TextUtils.isEmpty(this.authority)) {
POIManager poim = DataSourceManager.findPOI(getActivity(), this.authority, POIProviderContract.Filter.getNewUUIDFilter(this.uuid));
if (poim != null && poim.poi instanceof RouteTripStop) {
this.rts = (RouteTripStop) poim.poi;
}
}
return this.rts != null;
}
private void applyNewRts() {
if (this.rts == null) {
return;
}
getAbController().setABBgColor(this, getABBgColor(getActivity()), false);
getAbController().setABSubtitle(this, getABSubtitle(getActivity()), false);
getAbController().setABReady(this, isABReady(), true);
if (this.adapter != null) {
this.adapter.setOptRts(this.rts);
}
}
private String authority;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
initAdapters(activity);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
restoreInstanceState(savedInstanceState, getArguments());
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.fragment_schedule, container, false);
setupView(view);
switchView(view);
return view;
}
@Override
public void onSaveInstanceState(Bundle outState) {
if (!TextUtils.isEmpty(this.authority)) {
outState.putString(EXTRA_AUTHORITY, this.authority);
}
if (!TextUtils.isEmpty(this.uuid)) {
outState.putString(EXTRA_POI_UUID, this.uuid);
}
if (this.colorInt != null) {
outState.putInt(EXTRA_COLOR_INT, this.colorInt);
}
super.onSaveInstanceState(outState);
}
private void restoreInstanceState(Bundle... bundles) {
String newAuthority = BundleUtils.getString(EXTRA_AUTHORITY, bundles);
if (!TextUtils.isEmpty(newAuthority) && !newAuthority.equals(this.authority)) {
this.authority = newAuthority;
resetRts();
}
String newUuid = BundleUtils.getString(EXTRA_POI_UUID, bundles);
if (!TextUtils.isEmpty(newUuid) && !newUuid.equals(this.uuid)) {
this.uuid = newUuid;
resetRts();
}
Integer newColorInt = BundleUtils.getInt(EXTRA_COLOR_INT, bundles);
if (newColorInt != null) {
this.colorInt = newColorInt;
}
this.adapter.setUuid(this.uuid);
this.adapter.setAuthority(this.authority);
}
private void initAdapters(Activity activity) {
if (activity == null) {
return;
}
this.adapter = new DayPagerAdapter(this, TimeUtils.getBeginningOfTodayInMs(), null, null, null);
}
@SuppressWarnings("deprecation")
private void setupView(View view) {
if (view == null) {
return;
}
ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewpager);
viewPager.setOffscreenPageLimit(2);
viewPager.setOnPageChangeListener(this); // TODO upgrade to #ViewPager#addOnPageChangeListener()
setupAdapter(view);
}
private void setupAdapter(View view) {
if (view == null) {
return;
}
ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewpager);
viewPager.setAdapter(this.adapter);
if (this.lastPageSelected < 0) {
this.lastPageSelected = DayPagerAdapter.STARTING_POSITION;
}
viewPager.setCurrentItem(this.lastPageSelected);
switchView(view);
onPageSelected(this.lastPageSelected); // tell current page it's selected
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageScrollStateChanged(int state) {
switch (state) {
case ViewPager.SCROLL_STATE_IDLE:
setFragmentVisibleAtPosition(this.lastPageSelected); // resume
break;
case ViewPager.SCROLL_STATE_DRAGGING:
setFragmentVisibleAtPosition(-1); // pause
break;
}
}
@Override
public void onPageSelected(int position) {
StatusLoader.get().clearAllTasks();
ServiceUpdateLoader.get().clearAllTasks();
setFragmentVisibleAtPosition(position);
this.lastPageSelected = position;
if (this.adapter != null) {
this.adapter.setLastVisibleFragmentPosition(this.lastPageSelected);
}
}
private void setFragmentVisibleAtPosition(int position) {
java.util.List<Fragment> fragments = getChildFragmentManager().getFragments();
if (fragments != null) {
for (Fragment fragment : fragments) {
if (fragment instanceof VisibilityAwareFragment) {
VisibilityAwareFragment visibilityAwareFragment = (VisibilityAwareFragment) fragment;
visibilityAwareFragment.setFragmentVisibleAtPosition(position);
}
}
}
}
@Override
public void onResume() {
super.onResume();
View view = getView();
if (this.modulesUpdated) {
if (view != null) {
view.post(new Runnable() {
@Override
public void run() {
if (ScheduleFragment.this.modulesUpdated) {
onModulesUpdated();
}
}
});
}
}
}
private boolean modulesUpdated = false;
@Override
public void onModulesUpdated() {
this.modulesUpdated = true;
if (!isResumed()) {
return;
}
if (!TextUtils.isEmpty(this.uuid) && !TextUtils.isEmpty(this.authority)) {
FragmentActivity activity = getActivity();
if (activity == null) {
return;
}
POIProviderContract.Filter poiFilter = POIProviderContract.Filter.getNewUUIDFilter(this.uuid);
POIManager newPoim = DataSourceManager.findPOI(activity, this.authority, poiFilter);
if (newPoim == null || !(newPoim.poi instanceof RouteTripStop)) {
((MainActivity) activity).popFragmentFromStack(this); // close this fragment
this.modulesUpdated = false; // processed
return;
}
resetRts();
setupView(getView());
this.modulesUpdated = false; // processed
} else {
this.modulesUpdated = false; // processed
}
}
private void switchView(View view) {
if (view == null) {
return;
}
if (this.adapter == null || !this.adapter.isInitialized()) {
showLoading(view);
} else if (this.adapter.getCount() > 0) {
showTabsAndViewPager(view);
} else {
showEmpty(view);
}
}
private void showTabsAndViewPager(View view) {
if (view.findViewById(R.id.loading) != null) { // IF inflated/present DO
view.findViewById(R.id.loading).setVisibility(View.GONE); // hide
}
if (view.findViewById(R.id.empty) != null) { // IF inflated/present DO
view.findViewById(R.id.empty).setVisibility(View.GONE); // hide
}
view.findViewById(R.id.viewpager).setVisibility(View.VISIBLE); // show
}
private void showLoading(View view) {
if (view.findViewById(R.id.tabs) != null) { // IF inflated/present DO
view.findViewById(R.id.tabs).setVisibility(View.GONE); // hide
}
if (view.findViewById(R.id.viewpager) != null) { // IF inflated/present DO
view.findViewById(R.id.viewpager).setVisibility(View.GONE); // hide
}
if (view.findViewById(R.id.empty) != null) { // IF inflated/present DO
view.findViewById(R.id.empty).setVisibility(View.GONE); // hide
}
view.findViewById(R.id.loading).setVisibility(View.VISIBLE); // show
}
private void showEmpty(View view) {
if (view.findViewById(R.id.tabs) != null) { // IF inflated/present DO
view.findViewById(R.id.tabs).setVisibility(View.GONE); // hide
}
if (view.findViewById(R.id.viewpager) != null) { // IF inflated/present DO
view.findViewById(R.id.viewpager).setVisibility(View.GONE); // hide
}
if (view.findViewById(R.id.loading) != null) { // IF inflated/present DO
view.findViewById(R.id.loading).setVisibility(View.GONE); // hide
}
if (view.findViewById(R.id.empty) == null) { // IF NOT present/inflated DO
((ViewStub) view.findViewById(R.id.empty_stub)).inflate(); // inflate
}
view.findViewById(R.id.empty).setVisibility(View.VISIBLE); // show
}
@Override
public boolean isABReady() {
return hasRts();
}
@Override
public CharSequence getABTitle(Context context) {
return context.getString(R.string.full_schedule);
}
@Override
public CharSequence getABSubtitle(Context context) {
RouteTripStop rts = getRtsOrNull();
return POIManager.getOneLineDescription(getActivity(), rts);
}
@Override
public Integer getABBgColor(Context context) {
if (this.colorInt != null) {
return this.colorInt;
}
return super.getABBgColor(context);
}
@Override
public void onDestroy() {
super.onDestroy();
TaskUtils.cancelQuietly(this.loadRtsTask, true);
}
private static class DayPagerAdapter extends FragmentStatePagerAdapter implements MTLog.Loggable {
private static final String TAG = ScheduleFragment.class.getSimpleName() + ">" + DayPagerAdapter.class.getSimpleName();
@Override
public String getLogTag() {
return TAG;
}
private static int BEFORE_TODAY = 100;
private static int COUNT = BEFORE_TODAY + 365; // should be enough
private static final int STARTING_POSITION = BEFORE_TODAY > 0 ? BEFORE_TODAY : COUNT / 2;
private int todayPosition = STARTING_POSITION;
private long todayStartsAtInMs;
private Calendar todayStartsAtCal;
private int lastVisibleFragmentPosition = -1;
private String uuid;
private String authority;
private RouteTripStop optRts;
public DayPagerAdapter(ScheduleFragment scheduleFragment, long todayStartsAtInMs, String uuid, String authority, RouteTripStop optRts) {
super(scheduleFragment.getChildFragmentManager());
this.uuid = uuid;
this.authority = authority;
this.optRts = optRts;
this.todayStartsAtInMs = todayStartsAtInMs;
this.todayStartsAtCal = TimeUtils.getNewCalendarInstance(this.todayStartsAtInMs);
}
public boolean isInitialized() {
return !TextUtils.isEmpty(this.uuid) && !TextUtils.isEmpty(this.authority);
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public void setAuthority(String authority) {
this.authority = authority;
}
public void setOptRts(RouteTripStop optRts) {
this.optRts = optRts;
}
public void setLastVisibleFragmentPosition(int lastVisibleFragmentPosition) {
this.lastVisibleFragmentPosition = lastVisibleFragmentPosition;
}
private Calendar getPageDayCal(int position) {
Calendar pageDay = (Calendar) this.todayStartsAtCal.clone();
pageDay.add(Calendar.DATE, (position - this.todayPosition));
return pageDay;
}
@Override
public Fragment getItem(int position) {
return ScheduleDayFragment.newInstance(this.uuid, this.authority, getPageDayCal(position).getTimeInMillis(), position,
this.lastVisibleFragmentPosition, this.optRts);
}
@Override
public int getItemPosition(Object object) {
if (object != null && object instanceof ScheduleDayFragment) {
ScheduleDayFragment f = (ScheduleDayFragment) object;
return f.getFragmentPosition();
}
return POSITION_NONE;
}
@Override
public int getCount() {
return COUNT;
}
}
}