package co.smartreceipts.android.trips.editor;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
import android.text.format.DateFormat;
import android.text.method.TextKeyListener;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;
import java.sql.Date;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import co.smartreceipts.android.R;
import co.smartreceipts.android.activities.NavigationHandler;
import co.smartreceipts.android.date.DateEditText;
import co.smartreceipts.android.date.DateManager;
import co.smartreceipts.android.fragments.WBFragment;
import co.smartreceipts.android.model.Trip;
import co.smartreceipts.android.persistence.DatabaseHelper;
import co.smartreceipts.android.utils.SoftKeyboardManager;
import co.smartreceipts.android.utils.cache.FragmentStateCache;
import dagger.android.support.AndroidSupportInjection;
import wb.android.autocomplete.AutoCompleteAdapter;
import wb.android.flex.Flex;
public class TripCreateEditFragment extends WBFragment implements View.OnFocusChangeListener {
@Inject
Flex flex;
@Inject
DateManager dateManager;
@Inject
NavigationHandler navigationHandler;
@Inject
FragmentStateCache fragmentStateCache;
@Inject
TripCreateEditFragmentPresenter presenter;
private AutoCompleteTextView nameBox;
private DateEditText startDateBox;
private DateEditText endDateBox;
private Spinner currencySpinner;
private EditText commentBox;
private AutoCompleteTextView costCenterBox;
private View focusedView;
private AutoCompleteAdapter nameAutoCompleteAdapter, costCenterAutoCompleteAdapter;
private ArrayAdapter<CharSequence> currencies;
public static TripCreateEditFragment newInstance() {
return new TripCreateEditFragment();
}
@Override
public void onAttach(Context context) {
AndroidSupportInjection.inject(this);
super.onAttach(context);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Nullable
public Trip getTrip() {
return getArguments() != null ? getArguments().getParcelable(Trip.PARCEL_KEY) : null;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.update_trip, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initViews(view);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
fillFields();
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_save, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
navigationHandler.navigateToHomeTripsFragment();
return true;
}
if (item.getItemId() == R.id.action_save) {
saveTripChanges();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onResume() {
super.onResume();
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setHomeButtonEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(R.drawable.ic_action_cancel);
actionBar.setTitle((getTrip() == null) ? getFlexString(R.string.DIALOG_TRIPMENU_TITLE_NEW) : getFlexString(R.string.DIALOG_TRIPMENU_TITLE_EDIT));
actionBar.setSubtitle("");
}
if (focusedView != null) {
focusedView.requestFocus(); // Make sure we're focused on the right view
}
}
@Override
public void onPause() {
if (nameAutoCompleteAdapter != null) {
nameAutoCompleteAdapter.onPause();
}
if (costCenterAutoCompleteAdapter != null) {
costCenterAutoCompleteAdapter.onPause();
}
// Dismiss the soft keyboard
SoftKeyboardManager.hideKeyboard(focusedView);
super.onPause();
}
@Override
public void onDestroy() {
fragmentStateCache.onDestroy(this);
super.onDestroy();
}
private void initViews(View rootView) {
nameBox = (AutoCompleteTextView) flex.getSubView(getActivity(), rootView, R.id.dialog_tripmenu_name);
startDateBox = (DateEditText) flex.getSubView(getActivity(), rootView, R.id.dialog_tripmenu_start);
endDateBox = (DateEditText) flex.getSubView(getActivity(), rootView, R.id.dialog_tripmenu_end);
currencySpinner = (Spinner) flex.getSubView(getActivity(), rootView, R.id.dialog_tripmenu_currency);
commentBox = (EditText) flex.getSubView(getActivity(), rootView, R.id.dialog_tripmenu_comment);
costCenterBox = (AutoCompleteTextView) rootView.findViewById(R.id.dialog_tripmenu_cost_center);
View costCenterBoxLayout = rootView.findViewById(R.id.dialog_tripmenu_cost_center_layout);
costCenterBoxLayout.setVisibility(presenter.isIncludeCostCenter() ? View.VISIBLE : View.GONE);
Toolbar toolbar = (Toolbar) rootView.findViewById(R.id.toolbar);
if (navigationHandler.isDualPane()) {
toolbar.setVisibility(View.GONE);
} else {
setSupportActionBar(toolbar);
}
currencies = new ArrayAdapter<>(getActivity(), android.R.layout.simple_spinner_item, presenter.getCurrenciesList());
currencies.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
currencySpinner.setAdapter(currencies);
// Show default dictionary with auto-complete
TextKeyListener input = TextKeyListener.getInstance(true, TextKeyListener.Capitalize.SENTENCES);
nameBox.setKeyListener(input);
setKeyboardRelatedListeners();
}
private void fillFields() {
int currencySpinnerPosition;
if (getTrip() == null) { // new trip
if (presenter.isEnableAutoCompleteSuggestions()) {
DatabaseHelper db = presenter.getDatabaseHelper();
nameAutoCompleteAdapter = AutoCompleteAdapter.getInstance(getActivity(), DatabaseHelper.TAG_TRIPS_NAME, db);
costCenterAutoCompleteAdapter = AutoCompleteAdapter.getInstance(getActivity(), DatabaseHelper.TAG_TRIPS_COST_CENTER, db);
nameBox.setAdapter(nameAutoCompleteAdapter);
costCenterBox.setAdapter(costCenterAutoCompleteAdapter);
}
startDateBox.setOnClickListener(dateManager.getDurationDateEditTextListener(endDateBox));
//prefill the dates
startDateBox.date = new Date(Calendar.getInstance().getTimeInMillis());
startDateBox.setText(DateFormat.getDateFormat(getActivity()).format(startDateBox.date));
endDateBox.date = new Date(startDateBox.date.getTime() + TimeUnit.DAYS.toMillis(presenter.getDefaultTripDuration()));
endDateBox.setText(DateFormat.getDateFormat(getActivity()).format(endDateBox.date));
currencySpinnerPosition = currencies.getPosition(presenter.getDefaultCurrency());
} else { // edit trip
nameBox.setText(getTrip().getName());
startDateBox.setText(getTrip().getFormattedStartDate(getActivity(), presenter.getDateSeparator()));
startDateBox.date = getTrip().getStartDate();
endDateBox.setText(getTrip().getFormattedEndDate(getActivity(), presenter.getDateSeparator()));
endDateBox.date = getTrip().getEndDate();
commentBox.setText(getTrip().getComment());
currencySpinnerPosition = currencies.getPosition(getTrip().getDefaultCurrencyCode());
startDateBox.setOnClickListener(dateManager.getDateEditTextListener());
costCenterBox.setText(getTrip().getCostCenter());
currencySpinner.setOnItemSelectedListener(new CurrencySpinnerSelectionListener());
}
// Focused View
if (focusedView == null) {
focusedView = nameBox;
}
// set currency
if (currencySpinnerPosition > 0) {
currencySpinner.setSelection(currencySpinnerPosition);
}
startDateBox.setFocusableInTouchMode(false);
endDateBox.setFocusableInTouchMode(false);
endDateBox.setOnClickListener(dateManager.getDateEditTextListener());
nameBox.setSelection(nameBox.getText().length()); // Put the cursor at the end
}
private void setKeyboardRelatedListeners() {
// Set each focus listener, so we can track the focus view across resume -> pauses
nameBox.setOnFocusChangeListener(this);
startDateBox.setOnFocusChangeListener(this);
endDateBox.setOnFocusChangeListener(this);
currencySpinner.setOnFocusChangeListener(this);
commentBox.setOnFocusChangeListener(this);
costCenterBox.setOnFocusChangeListener(this);
// Set click listeners
View.OnTouchListener hideSoftKeyboardOnTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
SoftKeyboardManager.hideKeyboard(view);
}
return false;
}
};
startDateBox.setOnTouchListener(hideSoftKeyboardOnTouchListener);
endDateBox.setOnTouchListener(hideSoftKeyboardOnTouchListener);
currencySpinner.setOnTouchListener(hideSoftKeyboardOnTouchListener);
}
private void saveTripChanges() {
String name = nameBox.getText().toString().trim();
final String startDateText = startDateBox.getText().toString();
final String endDateText = endDateBox.getText().toString();
final String currencyCode = currencySpinner.getSelectedItem().toString();
final String comment = commentBox.getText().toString();
final String costCenter = costCenterBox.getText().toString();
if (presenter.checkTrip(name, startDateText, startDateBox.date, endDateText, endDateBox.date)) {
Trip updatedTrip = presenter.saveTrip(name, startDateBox.date, endDateBox.date,
currencyCode, comment, costCenter);
// open created/edited trip info
navigationHandler.navigateToReportInfoFragmentWithoutBackStack(updatedTrip);
}
}
public void showError(TripEditorErrors error) {
switch (error) {
case MISSING_FIELD:
Toast.makeText(getActivity(), getFlexString(R.string.DIALOG_TRIPMENU_TOAST_MISSING_FIELD), Toast.LENGTH_LONG).show();
break;
case CALENDAR_ERROR:
Toast.makeText(getActivity(), getFlexString(R.string.CALENDAR_TAB_ERROR), Toast.LENGTH_LONG).show();
break;
case DURATION_ERROR:
Toast.makeText(getActivity(), getFlexString(R.string.DURATION_ERROR), Toast.LENGTH_LONG).show();
break;
case SPACE_ERROR:
Toast.makeText(getActivity(), getFlexString(R.string.SPACE_ERROR), Toast.LENGTH_LONG).show();
break;
case ILLEGAL_CHAR_ERROR:
Toast.makeText(getActivity(), getFlexString(R.string.ILLEGAL_CHAR_ERROR), Toast.LENGTH_LONG).show();
break;
}
}
@Override
public void onFocusChange(View view, boolean hasFocus) {
focusedView = hasFocus ? view : null;
if (getTrip() == null && hasFocus) {
SoftKeyboardManager.showKeyboard(view);
}
}
private class CurrencySpinnerSelectionListener implements AdapterView.OnItemSelectedListener {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
final String newCurrencyCode = currencies.getItem(position).toString();
if (!getTrip().getDefaultCurrencyCode().equals(newCurrencyCode)) {
Toast.makeText(view.getContext(), R.string.toast_warning_reset_exchange_rate, Toast.LENGTH_LONG).show();
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// Intentional no-op
}
}
private String getFlexString(int id) {
return getFlexString(flex, id);
}
}