/*
* Copyright (C) 2011 - 2013 Niall 'Rivernile' Scott
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors or contributors be held liable for
* any damages arising from the use of this software.
*
* The aforementioned copyright holder(s) hereby grant you a
* non-transferrable right to use this software for any purpose (including
* commercial applications), and to modify it and redistribute it, subject to
* the following conditions:
*
* 1. This notice may not be removed or altered from any file it appears in.
*
* 2. Any modifications made to this software, except those defined in
* clause 3 of this agreement, must be released under this license, and
* the source code of any modifications must be made available on a
* publically accessible (and locateable) website, or sent to the
* original author of this software.
*
* 3. Software modifications that do not alter the functionality of the
* software but are simply adaptations to a specific environment are
* exempt from clause 2.
*/
package uk.org.rivernile.edinburghbustracker.android.fragments.general;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;
import uk.org.rivernile.edinburghbustracker.android.BusStopDatabase;
import uk.org.rivernile.edinburghbustracker.android.R;
import uk.org.rivernile.edinburghbustracker.android.alerts.AlertManager;
import uk.org.rivernile.edinburghbustracker.android.fragments.dialogs
.ServicesChooserDialogFragment;
/**
* This fragment allows the user to add a new time alert. This alerts the user
* when a service that they have selected is within a certain time of a chosen
* bus stop.
*
* @author Niall Scott
*/
public class AddTimeAlertFragment extends Fragment
implements ServicesChooserDialogFragment.Callbacks {
/** The argument for the stopCode. */
public static final String ARG_STOPCODE = "stopCode";
/** The argument for the default services. */
public static final String ARG_DEFAULT_SERVICES = "defaultServices";
/** The argument used in saving the instance state.*/
private static final String ARG_SELECTED_SERVICES = "selectedServices";
private Callbacks callbacks;
private BusStopDatabase bsd;
private AlertManager alertMan;
private String stopCode;
private String[] services;
private String[] selectedServices;
private int timeTrigger = 0;
private Button btnOkay;
private TextView txtServices, txtTimeDialogStop;
/**
* Create a new instance of the AddTimeAlertFragment.
*
* @param stopCode The stopCode this alert setting should be for.
* @return A new instance of this Fragment.
*/
public static AddTimeAlertFragment newInstance(final String stopCode) {
final AddTimeAlertFragment f = new AddTimeAlertFragment();
final Bundle b = new Bundle();
b.putString(ARG_STOPCODE, stopCode);
f.setArguments(b);
return f;
}
/**
* Create a new instance of the AddTimeAlertFragment.
*
* @param stopCode The stopCode this alert setting should be for.
* @param defaultServices The default services to show.
* @return A new instance of this Fragment.
*/
public static AddTimeAlertFragment newInstance(final String stopCode,
final String[] defaultServices) {
final AddTimeAlertFragment f = new AddTimeAlertFragment();
final Bundle b = new Bundle();
b.putString(ARG_STOPCODE, stopCode);
b.putStringArray(ARG_DEFAULT_SERVICES, defaultServices);
f.setArguments(b);
return f;
}
/**
* {@inheritDoc}
*/
@Override
public void onAttach(final Activity activity) {
super.onAttach(activity);
try {
callbacks = (Callbacks) activity;
} catch (ClassCastException e) {
throw new IllegalStateException(activity.getClass().getName() +
" does not implement " + Callbacks.class.getName());
}
}
/**
* {@inheritDoc}
*/
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get the various resources.
final Context context = getActivity().getApplicationContext();
bsd = BusStopDatabase.getInstance(context);
alertMan = AlertManager.getInstance(context);
final Bundle args = getArguments();
// Get the stop code from the arguments.
stopCode = args.getString(ARG_STOPCODE);
// Make sure a stopcode exists.
if(stopCode == null || stopCode.length() == 0)
throw new IllegalArgumentException("A stop code must be " +
"supplied.");
services = bsd.getBusServicesForStop(stopCode);
if (savedInstanceState != null) {
selectedServices = savedInstanceState
.getStringArray(ARG_SELECTED_SERVICES);
} else {
selectedServices = args.getStringArray(ARG_DEFAULT_SERVICES);
}
}
/**
* {@inheritDoc}
*/
@Override
public View onCreateView(final LayoutInflater inflater,
final ViewGroup container, final Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.addtimealert, container,
false);
btnOkay = (Button)v.findViewById(R.id.btnOkay);
txtServices = (TextView)v.findViewById(R.id.txtTimeAlertServices);
txtTimeDialogStop = (TextView)v.findViewById(R.id.txtTimeDialogStop);
btnOkay.setOnClickListener(new OnClickListener() {
@Override
public void onClick(final View v) {
// Add the alert.
alertMan.addTimeAlert(stopCode, selectedServices, timeTrigger);
// Tell the underlying Activity that a new alert has been added.
callbacks.onTimeAlertAdded();
}
});
// Set up the spinner.
final Spinner spinner = (Spinner)v.findViewById(R.id.time_time_select);
final ArrayAdapter<CharSequence> adapter = ArrayAdapter
.createFromResource(getActivity(),
R.array.addtimealert_array,
android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(final AdapterView<?> parent,
final View view, final int pos, final long id) {
switch(pos) {
case 0:
timeTrigger = 1;
break;
case 1:
timeTrigger = 2;
break;
case 2:
timeTrigger = 5;
break;
case 3:
timeTrigger = 10;
break;
case 4:
timeTrigger = 15;
break;
case 5:
timeTrigger = 20;
break;
case 6:
timeTrigger = 25;
break;
case 7:
timeTrigger = 30;
break;
default:
timeTrigger = 0;
break;
}
}
@Override
public void onNothingSelected(final AdapterView parent) {
timeTrigger = 0;
}
});
Button btn = (Button)v.findViewById(R.id.btnCancel);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(final View v) {
// Tell the underlying Activity that the user has cancelled.
callbacks.onCancelAddTimeAlert();
}
});
btn = (Button)v.findViewById(R.id.btnAlertTimeServices);
if (services != null && services.length > 0) {
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(final View v) {
callbacks.onShowServicesChooser(services, selectedServices,
getString(R.string.addtimealert_services_title));
}
});
} else {
btn.setEnabled(false);
}
btn = (Button)v.findViewById(R.id.btnLimitations);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(final View v) {
callbacks.onShowTimeAlertLimitations();
}
});
// Set a piece of informative text with the stopCode, stopName and
// locality (if available).
final String locality = bsd.getLocalityForStopCode(stopCode);
final String name;
if(locality != null) {
name = getString(R.string.busstop_locality_coloured,
bsd.getNameForBusStop(stopCode), locality, stopCode);
} else {
name = getString(R.string.busstop_coloured,
bsd.getNameForBusStop(stopCode), stopCode);
}
txtTimeDialogStop.setText(Html.fromHtml(
getString(R.string.addtimealert_busstop, name)));
// Force a refresh of the TextView that shows the services that have
// been chosen.
onServicesChosen(selectedServices);
return v;
}
/**
* {@inheritDoc}
*/
@Override
public void onSaveInstanceState(final Bundle outState) {
super.onSaveInstanceState(outState);
outState.putStringArray(ARG_SELECTED_SERVICES, selectedServices);
}
/**
* {@inheritDoc}
*/
@Override
public void onServicesChosen(final String[] chosenServices) {
selectedServices = chosenServices;
if (chosenServices != null && chosenServices.length > 0) {
// If the services list is not empty, put the services list in the
// view and enable the okay button.
txtServices.setText(
BusStopDatabase.getColouredServiceListString(
ServicesChooserDialogFragment
.getChosenServicesAsString(
chosenServices)));
btnOkay.setEnabled(true);
} else {
// If the services list is empty, put the default text in the view
// and disable the okay button.
txtServices.setText(R.string.addtimealert_noservices);
btnOkay.setEnabled(false);
}
}
/**
* Any Activities which host this Fragment must implement this interface to
* handle navigation events.
*/
public static interface Callbacks {
/**
* This is called when the user wants to read the text about the time
* alert limitations.
*/
public void onShowTimeAlertLimitations();
/**
* This is called when the user wishes to select services, for example,
* for filtering.
*
* @param services The services to choose from.
* @param selectedServices Any services that should be selected by
* default.
* @param title A title to show on the chooser.
*/
public void onShowServicesChooser(String[] services,
String[] selectedServices, String title);
/**
* This is called when the user has added a new time alert.
*/
public void onTimeAlertAdded();
/**
* This is called when the user wants to cancel adding a new time alert.
*/
public void onCancelAddTimeAlert();
}
}