package com.mechinn.android.ouralliance.fragment; import android.app.Activity; import android.bluetooth.BluetoothAdapter; import com.activeandroid.query.From; import com.activeandroid.query.Select; import com.mechinn.android.ouralliance.Prefs; import com.mechinn.android.ouralliance.R; import com.mechinn.android.ouralliance.adapter.MatchAdapter; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.support.v4.app.DialogFragment; import android.support.v4.app.ListFragment; import android.support.v7.app.ActionBarActivity; import android.util.Log; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; import android.widget.AdapterView.AdapterContextMenuInfo; import com.mechinn.android.ouralliance.csv.frc2015.ExportCsvMatchScouting2015; import com.mechinn.android.ouralliance.data.EventTeam; import com.mechinn.android.ouralliance.event.BluetoothEvent; import com.mechinn.android.ouralliance.data.Match; import com.mechinn.android.ouralliance.event.SelectMatchEvent; import com.mechinn.android.ouralliance.gson.OurAllianceGson; import com.mechinn.android.ouralliance.gson.frc2015.ExportJsonEventMatchScouting2015; import com.mechinn.android.ouralliance.gson.frc2015.ExportJsonEventTeamScouting2015; import com.mechinn.android.ouralliance.gson.frc2015.ImportJsonEventMatchScouting2015; import com.mechinn.android.ouralliance.gson.frc2015.ImportJsonEventTeamScouting2015; import com.mechinn.android.ouralliance.rest.thebluealliance.GetMatches; import java.util.Collections; import java.util.List; import app.akexorcist.bluetotohspp.library.BluetoothSPP; import app.akexorcist.bluetotohspp.library.BluetoothState; import app.akexorcist.bluetotohspp.library.DeviceList; import de.greenrobot.event.EventBus; import de.greenrobot.event.util.AsyncExecutor; import timber.log.Timber; public class MatchListFragment extends ListFragment { public static final String TAG = "MatchListFragment"; private static final String STATE_ACTIVATED_POSITION = "activated_position"; public static final int OPEN_DOCUMENT_REQUEST_CODE = 4002; public static final int CREATE_DOCUMENT_CSV_REQUEST_CODE = 4003; public static final int CREATE_DOCUMENT_JSON_REQUEST_CODE = 4004; private Prefs prefs; private MatchAdapter adapter; private GetMatches downloadMatches; private boolean enoughTeams; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); prefs = new Prefs(this.getActivity()); downloadMatches = new GetMatches(this.getActivity()); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); setHasOptionsMenu(true); setRetainInstance(true); registerForContextMenu(getListView()); getListView().setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { selectItem(position); } }); if (savedInstanceState != null && savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) { int position = savedInstanceState.getInt(STATE_ACTIVATED_POSITION); if (position == ListView.INVALID_POSITION) { getListView().setItemChecked(this.getSelectedItemPosition(), false); } else { getListView().setItemChecked(position, true); this.setSelection(position); } } adapter = new MatchAdapter(getActivity(), null); setListAdapter(adapter); } @Override public void onStart() { super.onStart(); EventBus.getDefault().register(this); // this.getActivity().registerForContextMenu(this.getListView()); // When in two-pane layout, set the listview to highlight the selected list item // (We do this during onStart because at the point the listview is available.) if (getFragmentManager().findFragmentById(R.id.list_fragment) != null) { getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); } } public void onEventMainThread(BluetoothEvent event) { getActivity().invalidateOptionsMenu(); } public void onStop() { EventBus.getDefault().unregister(this); super.onStop(); } @Override public void onResume() { super.onResume(); if(!prefs.isMatchesDownloaded()) { AsyncExecutor.create().execute(downloadMatches); } loadMatches(); loadEventTeams(); } private void selectItem(int position) { // Notify the parent activity of selected item EventBus.getDefault().post(new SelectMatchEvent(((Match)adapter.getItem(position)).getId())); ((ActionBarActivity)this.getActivity()).getSupportActionBar().setTitle(((Match)adapter.getItem(position)).toString()); // Set the item as checked to be highlighted when in two-pane layout getListView().setItemChecked(position, true); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); try { if (this.getSelectedItemPosition() != ListView.INVALID_POSITION) { // Serialize and persist the activated item position. outState.putInt(STATE_ACTIVATED_POSITION, this.getSelectedItemPosition()); } } catch (IllegalStateException e) { Timber.d(e,e.getMessage()); } } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); inflater.inflate(R.menu.match_list, menu); } @Override public void onPrepareOptionsMenu(Menu menu) { menu.findItem(R.id.practice).setChecked(prefs.isPractice()); menu.findItem(R.id.insert).setVisible(prefs.getComp() > 0 && enoughTeams); menu.findItem(R.id.sendMatchScoutingCsv).setVisible(prefs.getComp()>0); menu.findItem(R.id.restoreMatchListScouting).setVisible(prefs.getComp() > 0); menu.findItem(R.id.backupMatchListScouting).setVisible(null!=adapter && adapter.getCount()>0); BluetoothEvent bluetoothState = EventBus.getDefault().getStickyEvent(BluetoothEvent.class); menu.findItem(R.id.bluetoothMatchScoutingList).setVisible(null!=adapter && adapter.getCount()>0 && !bluetoothState.isDisabled()); if(bluetoothState.isOn()) { menu.findItem(R.id.bluetoothMatchScoutingList).setIcon(R.drawable.ic_action_bluetooth_searching); } else { menu.findItem(R.id.bluetoothMatchScoutingList).setIcon(R.drawable.ic_action_bluetooth); } } @Override public boolean onOptionsItemSelected(MenuItem item) { Intent intent; switch (item.getItemId()) { case R.id.practice: if (item.isChecked()) { item.setChecked(false); } else { item.setChecked(true); } prefs.setPractice(item.isChecked()); return true; case R.id.insert: new InsertMatchDialogFragment().show(this.getFragmentManager(), "Add Match"); return true; case R.id.refreshMatches: AsyncExecutor.create().execute(downloadMatches); return true; case R.id.sendMatchScoutingCsv: switch(prefs.getYear()) { case 2015: AsyncExecutor.create().execute(new ExportCsvMatchScouting2015(this.getActivity())); break; } return true; case R.id.bluetoothMatchScoutingList: intent = new Intent(this.getActivity().getApplicationContext(), DeviceList.class); startActivityForResult(intent, BluetoothState.REQUEST_CONNECT_DEVICE); return true; case R.id.backupMatchListScouting: switch(prefs.getYear()) { case 2015: intent = new Intent(Intent.ACTION_CREATE_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType(OurAllianceGson.TYPE); intent.putExtra(Intent.EXTRA_TITLE, "matchList.json"); startActivityForResult(intent, CREATE_DOCUMENT_JSON_REQUEST_CODE); break; } return true; case R.id.restoreMatchListScouting: switch(prefs.getYear()) { case 2015: intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType(OurAllianceGson.TYPE); startActivityForResult(intent, OPEN_DOCUMENT_REQUEST_CODE); break; } return true; default: return super.onOptionsItemSelected(item); } } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if(OPEN_DOCUMENT_REQUEST_CODE == requestCode && Activity.RESULT_OK == resultCode && null!=data) { final Uri uri = data.getData(); Timber.d("Uri: " + uri.toString()); AsyncExecutor.create().execute(new ImportJsonEventMatchScouting2015(this.getActivity(), uri)); } else if(CREATE_DOCUMENT_JSON_REQUEST_CODE == requestCode && Activity.RESULT_OK == resultCode && null!=data) { final Uri uri = data.getData(); Timber.d("Uri: " + uri.toString()); AsyncExecutor.create().execute(new ExportJsonEventMatchScouting2015(this.getActivity(), uri)); } else if(requestCode == BluetoothState.REQUEST_CONNECT_DEVICE && resultCode == Activity.RESULT_OK) { BluetoothSPP bt = EventBus.getDefault().getStickyEvent(BluetoothSPP.class); bt.connect(data); AsyncExecutor.create().execute(new ExportJsonEventMatchScouting2015(this.getActivity(), bt)); } else if(requestCode == BluetoothState.REQUEST_ENABLE_BT && resultCode == Activity.RESULT_OK) { Intent intent = new Intent(this.getActivity().getApplicationContext(), DeviceList.class); startActivityForResult(intent, BluetoothState.REQUEST_CONNECT_DEVICE); } super.onActivityResult(requestCode, resultCode, data); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); MenuInflater inflater = this.getActivity().getMenuInflater(); inflater.inflate(R.menu.team_context, menu); } @Override public boolean onContextItemSelected(MenuItem item) { int position = ((AdapterContextMenuInfo) item.getMenuInfo()).position; DialogFragment dialog; switch (item.getItemId()) { case R.id.open: selectItem(position); return true; // case R.id.edit: // dialog = new InsertTeamDialogFragment(); // Bundle updateArgs = new Bundle(); // updateArgs.putSerializable(InsertTeamDialogFragment.TEAM_ARG, adapter.get(position).getTeam()); // dialog.setArguments(updateArgs); // dialog.show(this.getFragmentManager(), "Edit Team"); // return true; case R.id.delete: dialog = new DeleteMatchDialogFragment(); Bundle deleteArgs = new Bundle(); deleteArgs.putSerializable(DeleteMatchDialogFragment.MATCH_ARG, (Match)adapter.getItem(position)); dialog.setArguments(deleteArgs); dialog.show(this.getFragmentManager(), "Delete Team"); return true; default: return super.onContextItemSelected(item); } } public void loadEventTeams() { AsyncExecutor.create().execute(new AsyncExecutor.RunnableEx() { @Override public void run() throws Exception { int count = new Select().from(EventTeam.class).where(EventTeam.EVENT+"=?",prefs.getComp()).count(); Timber.d("event teams =" + count); EventBus.getDefault().post(new LoadEventTeams(count)); } }); } public void onEventMainThread(EventTeam eventTeamsChanged) { loadEventTeams(); } public void onEventMainThread(LoadEventTeams teams) { enoughTeams = teams.enoughTeams(); Timber.d("enough teams ="+enoughTeams); getActivity().invalidateOptionsMenu(); } private class LoadEventTeams { int count; public LoadEventTeams(int count) { this.count = count; } public boolean enoughTeams() { return count>5; } } public void loadMatches() { AsyncExecutor.create().execute(new AsyncExecutor.RunnableEx() { @Override public void run() throws Exception { From matchBuilder = new Select().from(Match.class).where(Match.EVENT+"=?",prefs.getComp()); if(prefs.isPractice()) { matchBuilder = matchBuilder.and(Match.COMPETITION_LEVEL+"=?",Match.PRACTICE); } else { matchBuilder = matchBuilder.and(Match.COMPETITION_LEVEL+"<>?",Match.PRACTICE); } List<Match> matches = matchBuilder.execute(); EventBus.getDefault().post(new LoadMatches(matches)); } }); } public void onEventMainThread(Match scoutingChanged) { loadMatches(); } public void onEventMainThread(LoadMatches matches) { List<Match> result = matches.getMatches(); Timber.d( "Count: " + result.size()); Collections.sort(result); adapter.swapList(result); getActivity().invalidateOptionsMenu(); } private class LoadMatches { List<Match> matches; public LoadMatches(List<Match> matches) { this.matches = matches; } public List<Match> getMatches() { return matches; } } }