package com.mehmetakiftutuncu.eshotroid.activity;
import java.util.ArrayList;
import java.util.Calendar;
import android.annotation.TargetApi;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import com.mehmetakiftutuncu.eshotroid.BuildConfig;
import com.mehmetakiftutuncu.eshotroid.R;
import com.mehmetakiftutuncu.eshotroid.adapter.BusTimesFragmentPagerAdapter;
import com.mehmetakiftutuncu.eshotroid.database.BusDatabase;
import com.mehmetakiftutuncu.eshotroid.fragment.BusTimesFragment;
import com.mehmetakiftutuncu.eshotroid.model.Bus;
import com.mehmetakiftutuncu.eshotroid.model.BusTime;
import com.mehmetakiftutuncu.eshotroid.model.BusTimeTypes;
import com.mehmetakiftutuncu.eshotroid.task.GetBusTimesPageTask;
import com.mehmetakiftutuncu.eshotroid.utility.Constants;
import com.mehmetakiftutuncu.eshotroid.utility.Messages;
/** Times activity of the application which shows the times of a selected bus
* and contains a {@link ViewPager} for switching between three main types of
* the time table; week days, saturday and sunday
*
* @author mehmetakiftutuncu */
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class Times extends ActionBarActivity implements BusTimesFragment.BusTimesListener
{
/** A {@link BusTimesFragmentPagerAdapter} for switching between types */
private BusTimesFragmentPagerAdapter pagerAdapter;
/** A {@link ViewPager} containing the pages to switch */
private ViewPager viewPager;
/** Reference to the refresh item in the action bar menu */
private MenuItem refreshMenuItem;
/** {@link Bus} object whose times will be displayed */
private Bus bus;
/** Number of the bus to load from database into {@link Times#bus} */
private int busNumber;
/** Tag for debugging */
private static final String LOG_TAG = "Eshotroid_Times";
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_times);
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Creating times activity...");
// Get bus number that was passed
Bundle bundle = getIntent().getExtras();
if(bundle != null)
{
busNumber = bundle.getInt(Constants.BUS_NUMBER_EXTRA);
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Bus number is read from bundle as " + busNumber + ".");
// Set the title in ActionBar with the bus number
getSupportActionBar().setTitle(getString(R.string.times_title, busNumber));
}
// Create and initialize pages
initializePages();
/* Show home button in the action bar which will go back to main
* activity */
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public void onBusTimesLoaded()
{
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Loading bus times...");
// Get bus from the database
BusDatabase db = BusDatabase.getDatabase(this);
bus = db.get(busNumber);
db.closeDatabase();
// Check current page to decide the type of times
BusTimeTypes type = null;
switch(viewPager.getCurrentItem())
{
case Constants.PAGE_ID_BUS_TIMES_H:
type = BusTimeTypes.WEEK_DAY;
break;
case Constants.PAGE_ID_BUS_TIMES_C:
type = BusTimeTypes.SATURDAY;
break;
case Constants.PAGE_ID_BUS_TIMES_P:
type = BusTimeTypes.SUNDAY;
break;
}
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Type of bus times is " + type + ".");
// If bus is found on the database
if(bus != null)
{
BusTimesFragment busTimesFragment = null;
ArrayList<BusTime> busTimes = null;
boolean busTimesExist = true;
/* Check the type to decide what fragment and times data set to use
*
* By getting fragments here it is guaranteed that the fragments
* will be created because corresponding get methods ensure it. */
switch(type)
{
case WEEK_DAY:
busTimesFragment = pagerAdapter.getHBusTimesFragment();
busTimes = bus.getTimesH();
busTimesExist = bus.timesHExists();
break;
case SATURDAY:
busTimesFragment = pagerAdapter.getCBusTimesFragment();
busTimes = bus.getTimesC();
busTimesExist = bus.timesCExists();
break;
case SUNDAY:
busTimesFragment = pagerAdapter.getPBusTimesFragment();
busTimes = bus.getTimesP();
busTimesExist = bus.timesPExists();
break;
}
if(busTimes == null)
{
if(!busTimesExist)
{
// There is no bus that day
Messages.getInstance().showNeutral(this,
getString(R.string.info_busTimes_noTimes,
bus.getNumber(), getString(type.getNameResourceId())));
}
else
{
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Times for " + busNumber + type.getCode() + " are not in the database! Downloading...");
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
new GetBusTimesPageTask(this, busTimesFragment, bus, type).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
else
new GetBusTimesPageTask(this, busTimesFragment, bus, type).execute();
}
}
else
{
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Times for " + busNumber + type.getCode() + " are loaded from the database!");
// Set bus times of the fragment so the times will be shown
busTimesFragment.setBusTimes(busTimes);
busTimesFragment.setRefreshing(false);
}
}
else
{
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Times for " + busNumber + " are not in the database! Downloading...");
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
new GetBusTimesPageTask(this, pagerAdapter.getHBusTimesFragment(), bus, BusTimeTypes.WEEK_DAY).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
else
new GetBusTimesPageTask(this, pagerAdapter.getHBusTimesFragment(), bus, BusTimeTypes.WEEK_DAY).execute();
}
}
/** This method is called when menu (ActionBar items) is being created */
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the refresh menu and add it
getMenuInflater().inflate(R.menu.refresh, menu);
// Get refresh menu item
refreshMenuItem = menu.findItem(R.id.item_refresh);
// Get fragment of current page
BusTimesFragment fragment = null;
switch(viewPager.getCurrentItem())
{
case Constants.PAGE_ID_BUS_TIMES_H:
fragment = pagerAdapter.getHBusTimesFragment();
break;
case Constants.PAGE_ID_BUS_TIMES_C:
fragment = pagerAdapter.getCBusTimesFragment();
break;
case Constants.PAGE_ID_BUS_TIMES_P:
fragment = pagerAdapter.getPBusTimesFragment();
break;
}
// Show progress if necessary
if(fragment.isRefreshing())
{
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Setting refresh button as progress...");
MenuItemCompat.setActionView(refreshMenuItem, R.layout.item_progress);
}
return super.onCreateOptionsMenu(menu);
}
/** This method is called when a menu item is clicked */
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
// Check which menu item is selected
switch(item.getItemId())
{
case android.R.id.home:
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Home button is selected for going up.");
// Up button to go to the list of busses so finish activity
finish();
break;
case R.id.item_refresh:
// Check current page to decide what to refresh
switch(viewPager.getCurrentItem())
{
case Constants.PAGE_ID_BUS_TIMES_H:
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Refreshing bus times for H...");
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
new GetBusTimesPageTask(this, pagerAdapter.getHBusTimesFragment(), bus, BusTimeTypes.WEEK_DAY).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
else
new GetBusTimesPageTask(this, pagerAdapter.getHBusTimesFragment(), bus, BusTimeTypes.WEEK_DAY).execute();
break;
case Constants.PAGE_ID_BUS_TIMES_C:
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Refreshing bus times for C...");
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
new GetBusTimesPageTask(this, pagerAdapter.getCBusTimesFragment(), bus, BusTimeTypes.SATURDAY).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
else
new GetBusTimesPageTask(this, pagerAdapter.getCBusTimesFragment(), bus, BusTimeTypes.SATURDAY).execute();
break;
case Constants.PAGE_ID_BUS_TIMES_P:
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Refreshing bus times for P...");
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
new GetBusTimesPageTask(this, pagerAdapter.getPBusTimesFragment(), bus, BusTimeTypes.SUNDAY).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
else
new GetBusTimesPageTask(this, pagerAdapter.getPBusTimesFragment(), bus, BusTimeTypes.SUNDAY).execute();
break;
}
break;
}
return super.onOptionsItemSelected(item);
}
/** Toggles the UI mode to either ready or waiting (hides other content and
* shows a progress bar)
*
* @param isWaiting If true, mode will change to waiting, else it will
* change to ready mode
* @param pageId Id of the page whose contents are being refreshed */
public void toggleMode(boolean isRefreshing, int pageId)
{
if(refreshMenuItem != null)
{
/* Check the current page to decide for what page refreshing state
* should change */
switch(viewPager.getCurrentItem())
{
case Constants.PAGE_ID_BUS_TIMES_H:
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Setting refreshing state for H times page as " + isRefreshing + "...");
pagerAdapter.getHBusTimesFragment().setRefreshing(isRefreshing);
break;
case Constants.PAGE_ID_BUS_TIMES_C:
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Setting refreshing state for C times page as " + isRefreshing + "...");
pagerAdapter.getCBusTimesFragment().setRefreshing(isRefreshing);
break;
case Constants.PAGE_ID_BUS_TIMES_P:
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Setting refreshing state for P times page as " + isRefreshing + "...");
pagerAdapter.getPBusTimesFragment().setRefreshing(isRefreshing);
break;
}
// Cause action bar menu to be created again
supportInvalidateOptionsMenu();
}
}
/** Creates and initializes pages */
private void initializePages()
{
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Initializing pages...");
// Get view pager
viewPager = (ViewPager) findViewById(R.id.viewPager_times);
/* Set off screen page limit to 2 indicating that there may be 2
* non-visible pages in memory */
viewPager.setOffscreenPageLimit(2);
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Setting bus times fragment pager adapter...");
/* Create the adapter that will return a fragment for each of the three
* main types of time tables */
pagerAdapter = new BusTimesFragmentPagerAdapter(this, getSupportFragmentManager());
// Set up the ViewPager with the pages adapter.
viewPager.setAdapter(pagerAdapter);
/* Set page change listener to load correct times each time the page is
* changed */
viewPager.setOnPageChangeListener(new OnPageChangeListener()
{
@Override
public void onPageSelected(int position)
{
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Page " + position + " is selected.");
// Load bus times for the selected page
onBusTimesLoaded();
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2)
{
}
@Override
public void onPageScrollStateChanged(int arg0)
{
}
});
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Selecting default page...");
// Going to select the default page on startup according to current day
switch(Calendar.getInstance().get(Calendar.DAY_OF_WEEK))
{
case Calendar.MONDAY:
case Calendar.TUESDAY:
case Calendar.WEDNESDAY:
case Calendar.THURSDAY:
case Calendar.FRIDAY:
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Selecting H times page as default...");
viewPager.setCurrentItem(Constants.PAGE_ID_BUS_TIMES_H);
break;
case Calendar.SATURDAY:
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Selecting C times page as default...");
viewPager.setCurrentItem(Constants.PAGE_ID_BUS_TIMES_C);
break;
case Calendar.SUNDAY:
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Selecting P times page as default...");
viewPager.setCurrentItem(Constants.PAGE_ID_BUS_TIMES_P);
break;
}
}
/** @return {@link Times#bus} */
public Bus getBus()
{
return bus;
}
}