package com.mehmetakiftutuncu.eshotroid;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.ScrollView;
import android.widget.TableLayout;
import android.widget.TextView;
import com.actionbarsherlock.app.SherlockActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.devspark.appmsg.AppMsg;
import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
import com.handmark.pulltorefresh.library.PullToRefreshBase.OnPullEventListener;
import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener;
import com.handmark.pulltorefresh.library.PullToRefreshBase.State;
import com.handmark.pulltorefresh.library.PullToRefreshScrollView;
import com.mehmetakiftutuncu.eshotroid.database.MyDatabase;
import com.mehmetakiftutuncu.eshotroid.model.Bus;
import com.mehmetakiftutuncu.eshotroid.model.BusTime;
import com.mehmetakiftutuncu.eshotroid.tasks.GetTimesPageTask;
import com.mehmetakiftutuncu.eshotroid.utilities.Dialogs;
import com.mehmetakiftutuncu.eshotroid.utilities.MenuHandler;
/**
* Times activity of the application
*
* @author Mehmet Akif Tütüncü
*/
public class Times extends SherlockActivity
{
private PullToRefreshScrollView ptrScrollView;
private RadioGroup rgTypes;
private RadioButton rbWeekDays;
private RadioButton rbSaturday;
private RadioButton rbSunday;
private TextView tvRoute;
private TableLayout tlTable;
private TextView tvSource;
private TextView tvDestination;
private ProgressBar progressBar;
private String type;
private int number;
private Bus bus;
private boolean isClosestTime;
private Menu moreMenu;
/**
* Tag for debugging
*/
public static final String LOG_TAG = "Eshotroid_Times";
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.times);
Bundle bundle = getIntent().getExtras();
if(bundle != null)
{
number = bundle.getInt(Constants.BUS_NUMBER_EXTRA);
}
initialize();
loadBusTimes();
Dialogs.showTimesHelpDialog(this, false);
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
moreMenu = menu;
menu.add("item_closesttime")
.setIcon(R.drawable.ic_closesttime)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
MenuInflater inflater = getSherlock().getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
/*
@Override
public boolean onMenuItemSelected(int featureId, android.view.MenuItem item)
{
if(item.getTitle().equals("item_closesttime"))
{
if(isClosestTime)
{
isClosestTime = false;
}
else
{
isClosestTime = true;
}
updateInformation(bus);
ptrScrollView.getRefreshableView().scrollTo(0, 0);
}
else if(item.getItemId() == android.R.id.home)
{
finish();
}
else
{
MenuHandler.handle(this, item);
}
return true;
}
*/
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
if(item.getTitle().equals("item_closesttime"))
{
if(isClosestTime)
{
isClosestTime = false;
}
else
{
isClosestTime = true;
}
updateInformation(bus);
ptrScrollView.getRefreshableView().scrollTo(0, 0);
}
else if(item.getItemId() == android.R.id.home)
{
finish();
}
else
{
MenuHandler.handle(this, item);
}
return true;
}
// Using onKeyUp instead of onKeyDown is working, otherwise the menu would just close itself after opening
@Override
public boolean onKeyUp(int keyCode, KeyEvent event)
{
if(keyCode == KeyEvent.KEYCODE_MENU)
{
if (event.getAction() == KeyEvent.ACTION_UP && moreMenu != null)
{
moreMenu.performIdentifierAction(R.id.item_more, 0);
return true;
}
}
return super.onKeyUp(keyCode, event);
}
/** Initializes components */
private void initialize()
{
isClosestTime = true;
rgTypes = (RadioGroup) findViewById(R.id.radioGroup_times_types);
rbWeekDays = (RadioButton) findViewById(R.id.radioButton_times_weekDays);
rbSaturday = (RadioButton) findViewById(R.id.radioButton_times_saturday);
rbSunday = (RadioButton) findViewById(R.id.radioButton_times_sunday);
tvRoute = (TextView) findViewById(R.id.textView_times_route);
tlTable = (TableLayout) findViewById(R.id.tableLayout_times);
tvSource = (TextView) findViewById(R.id.textView_times_source);
tvDestination = (TextView) findViewById(R.id.textView_times_destination);
updateSelectedType();
ptrScrollView = (PullToRefreshScrollView) findViewById(R.id.pullToRefreshScrollView_times);
ptrScrollView.getLoadingLayoutProxy().setPullLabel(getString(R.string.pullToRefresh_pull));
ptrScrollView.getLoadingLayoutProxy().setReleaseLabel(getString(R.string.pullToRefresh_release));
ptrScrollView.setOnPullEventListener(new OnPullEventListener<ScrollView>()
{
@Override
public void onPullEvent(PullToRefreshBase<ScrollView> refreshView, State state, Mode direction)
{
ptrScrollView.getLoadingLayoutProxy().setRefreshingLabel(getString(R.string.pullToRefresh_refresh));
}
});
ptrScrollView.setOnRefreshListener(new OnRefreshListener<ScrollView>()
{
@Override
public void onRefresh(PullToRefreshBase<ScrollView> refreshView)
{
downloadBusTimes();
}
});
ptrScrollView.setScrollingWhileRefreshingEnabled(false);
progressBar = (ProgressBar) findViewById(R.id.progressBar_times);
rgTypes.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(RadioGroup group, int checkedId)
{
loadBusTimes();
}
});
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
/** Tries to download bus times */
private void downloadBusTimes()
{
GetTimesPageTask task = new GetTimesPageTask(this, ptrScrollView, bus, type);
task.execute();
}
/** Loads bus times from the database if possible, if not tries to download them. */
private void loadBusTimes()
{
type = getSelectedType();
toggleProgressBar(true);
MyDatabase db = new MyDatabase(this);
db.openDB();
bus = db.get(number);
db.closeDB();
if(bus != null && ((type.equals("H") && bus.getTimesH() != null) || (type.equals("C") && bus.getTimesC() != null) || (type.equals("P") && bus.getTimesP() != null)))
{
toggleProgressBar(false);
updateInformation(bus);
}
else
{
Log.d(LOG_TAG, "Bus times for " + number + type + " could not be found on the database!");
downloadBusTimes();
}
}
/** Updates the table with bus route and times */
public void updateInformation(Bus bus)
{
this.bus = bus;
tlTable.removeAllViews();
setTitle("" + bus.getNumber());
tvRoute.setText(bus.getRoute());
tvSource.setText(bus.getSource());
tvDestination.setText(bus.getDestination());
LayoutInflater inflater = getLayoutInflater();
ArrayList<BusTime> times = null;
if(type.equals("H"))
{
times = bus.getTimesH();
}
else if(type.equals("C"))
{
times = bus.getTimesC();
}
else if(type.equals("P"))
{
times = bus.getTimesP();
}
if(times != null)
{
boolean isEmpty = true;
for(BusTime i : times)
{
View row = inflater.inflate(R.layout.times_row, null);
Button source = (Button) row.findViewById(R.id.button_times_row_source);
Button destination = (Button) row.findViewById(R.id.button_times_row_destination);
source.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
showRemainingTime(((Button) v).getText().toString());
}
});
destination.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
showRemainingTime(((Button) v).getText().toString());
}
});
if(isClosestTime)
{
String tempSource = i.getTimeFromSource();
String tempDestination = i.getTimeFromDestination();
if(!isTimePassed(tempSource))
{
source.setText(tempSource);
}
else
{
source.setText("");
}
if(!isTimePassed(tempDestination))
{
destination.setText(tempDestination);
}
else
{
destination.setText("");
}
if(!source.getText().toString().equals("") || !destination.getText().toString().equals(""))
{
tlTable.addView(row);
isEmpty = false;
}
}
else
{
source.setText(i.getTimeFromSource());
destination.setText(i.getTimeFromDestination());
tlTable.addView(row);
}
}
if(isClosestTime && isEmpty)
{
isClosestTime = false;
AppMsg.makeText(this, getString(R.string.info_noClosestTime), AppMsg.STYLE_CONFIRM).show();
updateInformation(bus);
}
}
}
/**
* Shows the remaining time to the given time if the given time has not passed yet
*
* @param time Time as a string with format HH:MM
*/
@SuppressLint("SimpleDateFormat")
private void showRemainingTime(String time)
{
boolean isTimePassed = false;
try
{
SimpleDateFormat format = new SimpleDateFormat("HH:mm");
String currentTime = format.format(new Date(System.currentTimeMillis()));
String[] currentTokens = currentTime.split(":");
String givenTime = format.format(format.parse(time));
String[] givenTokens = givenTime.split(":");
int currentHours = Integer.parseInt(currentTokens[0]);
int currentMinutes = Integer.parseInt(currentTokens[1]);
int givenHours = Integer.parseInt(givenTokens[0]);
int givenMinutes = Integer.parseInt(givenTokens[1]);
if(givenHours < currentHours)
{
isTimePassed = true;
}
else if(givenHours == currentHours)
{
if(givenMinutes < currentMinutes)
{
isTimePassed = true;
}
}
if(!isTimePassed)
{
int remainingHours = givenHours - currentHours;
int remainingMinutes = givenMinutes - currentMinutes;
if(remainingMinutes < 0)
{
remainingHours--;
remainingMinutes += 60;
}
AppMsg.makeText(this, getString(R.string.info_remainingTime, time, remainingHours, remainingMinutes), AppMsg.STYLE_INFO).show();
}
else
{
AppMsg.makeText(this, getString(R.string.info_selectedTimePassed), AppMsg.STYLE_CONFIRM).show();
}
}
catch(Exception e)
{
}
}
/**
* Checks if the given time is passed
*
* @param time Time as a string with format HH:MM
*
* @return true if the time is passed, false otherwise or an error occures
*/
@SuppressLint("SimpleDateFormat")
private boolean isTimePassed(String time)
{
boolean result = false;
try
{
SimpleDateFormat format = new SimpleDateFormat("HH:mm");
String currentTime = format.format(new Date(System.currentTimeMillis()));
String[] currentTokens = currentTime.split(":");
String givenTime = format.format(format.parse(time));
String[] givenTokens = givenTime.split(":");
int currentHours = Integer.parseInt(currentTokens[0]);
int currentMinutes = Integer.parseInt(currentTokens[1]);
int givenHours = Integer.parseInt(givenTokens[0]);
int givenMinutes = Integer.parseInt(givenTokens[1]);
if(givenHours < currentHours)
{
return true;
}
else if(givenHours == currentHours)
{
if(givenMinutes < currentMinutes)
{
return true;
}
}
}
catch(Exception e)
{
}
return result;
}
/** Updates the selected type radio buttons according to the current day */
private void updateSelectedType()
{
switch(Calendar.getInstance().get(Calendar.DAY_OF_WEEK))
{
case Calendar.MONDAY:
case Calendar.TUESDAY:
case Calendar.WEDNESDAY:
case Calendar.THURSDAY:
case Calendar.FRIDAY:
rbWeekDays.setChecked(true);
break;
case Calendar.SATURDAY:
rbSaturday.setChecked(true);
break;
case Calendar.SUNDAY:
rbSunday.setChecked(true);
break;
}
}
/**
* Gets the appropriate type parameter according to the selected radio button
*
* @return The appropriate type parameter
*/
private String getSelectedType()
{
if(rbSaturday.isChecked())
{
return "C";
}
else if(rbSunday.isChecked())
{
return "P";
}
else
{
return "H";
}
}
/**
* Toggles the progress bar
*
* @param turnOn Should be true to turn progress bar on
*/
public void toggleProgressBar(boolean turnOn)
{
if(turnOn)
{
progressBar.setVisibility(View.VISIBLE);
tlTable.setVisibility(View.GONE);
tvDestination.setVisibility(View.GONE);
tvSource.setVisibility(View.GONE);
}
else
{
progressBar.setVisibility(View.GONE);
tlTable.setVisibility(View.VISIBLE);
tvDestination.setVisibility(View.VISIBLE);
tvSource.setVisibility(View.VISIBLE);
}
}
}