package semtex.archery; import java.text.DateFormat; import java.text.MessageFormat; import java.text.SimpleDateFormat; import java.util.*; import semtex.archery.business.SharingDispatcher; import semtex.archery.business.interfaces.CallbackAdapter; import semtex.archery.data.DatabaseHelper; import semtex.archery.data.ReportGenerator; import semtex.archery.data.entities.UserVisit; import semtex.archery.data.entities.Visit; import semtex.archery.data.reports.ParcourReportData; import semtex.archery.util.BackupRestoreHelper; import semtex.archery.util.ProcessUtils; import android.annotation.SuppressLint; import android.app.AlertDialog; import android.app.SearchManager; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.ParcelUuid; import android.util.Log; import android.view.*; import android.view.ContextMenu.ContextMenuInfo; import android.widget.*; import android.widget.AdapterView.OnItemClickListener; import com.j256.ormlite.android.apptools.OrmLiteBaseListActivity; public class History extends OrmLiteBaseListActivity<DatabaseHelper> { private static final int REQ_CODE_RET_FROM_SCORING = 0; private static final int CTX_REMOVE_ITEM_ID = 1; private static final int CTX_SHARE = 2; private static final int CTX_SHARE_WEB = 3; private static final int CTX_REOPEN = 4; private static final String TAG = History.class.getName(); public Map<Visit, ParcourReportData> reportCache = new HashMap<Visit, ParcourReportData>(); public List<Visit> visitCache = new LinkedList<Visit>(); private final DateFormat dateFormatter = DateFormat.getDateInstance(); private ListView lv; private TextView txtCurrentStatus; private ProgressBar progressBarSearch; private ArrayAdapter<Visit> adapter; private ReportGenerator generator; private SharingDispatcher dispatcher; @Override public void onCreateContextMenu(final ContextMenu menu, final View v, final ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); // if (v.getId() == R.id.lvVisitHistory) { menu.add(Menu.NONE, CTX_REOPEN, Menu.NONE, "Reopen"); menu.add(Menu.NONE, CTX_REMOVE_ITEM_ID, Menu.NONE, "Remove"); menu.add(Menu.NONE, CTX_SHARE, Menu.NONE, "Share"); menu.add(Menu.NONE, CTX_SHARE_WEB, Menu.NONE, "Share with Web"); // } } @Override public boolean onContextItemSelected(final MenuItem item) { final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo(); final Visit visit = adapter.getItem(info.position); if (item.getItemId() == CTX_REMOVE_ITEM_ID) { final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this); alertDialog.setTitle("Remove Visit"); alertDialog.setMessage("Are you sure?"); alertDialog.setPositiveButton("Remove", new DialogInterface.OnClickListener() { public void onClick(final DialogInterface dialog, final int which) { for (final UserVisit uv : visit.getUserVisit()) { getHelper().getTargetHitDao().deleteTargetHitsFromUserVisit(uv); getHelper().getUserVisitDao().delete(uv); } getHelper().getVisitDao().delete(visit); refreshVisitList(); Toast.makeText(getApplicationContext(), "Disposed " + visit.getId(), Toast.LENGTH_SHORT).show(); } // onClick }); // setPositiveButton alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { public void onClick(final DialogInterface dialog, final int which) { } // onClick }); // setNegativeButton alertDialog.show(); } else if (item.getItemId() == CTX_SHARE) { dispatcher = new SharingDispatcher(getHelper(), visit); final Intent sharingIntent = dispatcher.shareMail(); startActivity(Intent.createChooser(sharingIntent, "Share using")); } else if (item.getItemId() == CTX_SHARE_WEB) { // else if dispatcher = new SharingDispatcher(getHelper(), visit); dispatcher.shareServer(new CallbackAdapter<Void>() { @Override public void onSuccess(final Void data) { Toast.makeText(getApplicationContext(), "Data uploaded successfully!", Toast.LENGTH_LONG).show(); } @Override public void onFailure(final Throwable tr) { Toast.makeText(getApplicationContext(), "Could not upload data to server!", Toast.LENGTH_LONG).show(); Log.e(TAG, "Could not upload to server!", tr); } }); } else if (item.getItemId() == CTX_REOPEN) { // else if if (getHelper().getVisitDao().findLastOpenVisit() != null) { Toast.makeText(getApplicationContext(), "close the current open visit first!", Toast.LENGTH_LONG).show(); } else { visit.setEndTime(null); getHelper().getVisitDao().update(visit); final Intent intent = new Intent(getBaseContext(), StartParcour.class); startActivityForResult(intent, REQ_CODE_RET_FROM_SCORING); } // else } // else if return true; } @Override protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) { if (requestCode == REQ_CODE_RET_FROM_SCORING) { refreshVisitList(); } // if } // onActivityResult @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.history_visit); generator = new ReportGenerator(History.this.getHelper()); txtCurrentStatus = (TextView)findViewById(R.id.txtCurrentStatus); progressBarSearch = (ProgressBar)findViewById(R.id.progressBarSearch); lv = getListView(); lv.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE); lv.setItemsCanFocus(true); lv.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(final AdapterView<?> parentView, final View childView, final int position, final long id) { final Visit v = (Visit)lv.getItemAtPosition(position); final Intent i = new Intent(getApplicationContext(), Scoreboard.class); i.putExtra("visit_id", new ParcelUuid(v.getId())); startActivity(i); } // open parcour }); // setOnItemClickListener registerForContextMenu(lv); refreshVisitList(); } // onCreate @Override protected void onNewIntent(final Intent intent) { if (Intent.ACTION_SEARCH.equals(intent.getAction())) { final String query = intent.getStringExtra(SearchManager.QUERY); if (visitCache == null) { visitCache = getHelper().getVisitDao().findAllVisits(false, 0L); } // if final List<Visit> filteredVisits = performFiltering(visitCache, query); adapter = new VisitHistoryAdapter(History.this, R.layout.history_visit_row, filteredVisits); setListAdapter(adapter); } // if } // onNewIntent protected List<Visit> performFiltering(final Collection<Visit> originalCollection, final CharSequence constraint) { final String comp = constraint.toString().toLowerCase(); final ArrayList<Visit> filtered = new ArrayList<Visit>(); for (final Visit v : originalCollection) { if (v.getVersion().getParcour().getName().toLowerCase().contains(comp)) { filtered.add(v); continue; } // for - parcour name for (final UserVisit uv : v.getUserVisit()) { if (uv.getUser().getUserName().toLowerCase().contains(comp)) { filtered.add(v); break; } // if } // for - each userVisit } // for each visit return filtered; } // performFiltering @SuppressLint("NewApi") @Override public boolean onCreateOptionsMenu(final Menu menu) { final MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.options_menu, menu); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { final SearchManager searchManager = (SearchManager)getSystemService(Context.SEARCH_SERVICE); final SearchView searchView = (SearchView)menu.findItem(R.id.search).getActionView(); searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); searchView.setIconifiedByDefault(false); } // if return true; } // onCreateOptionsMenu @Override public boolean onOptionsItemSelected(final MenuItem item) { switch (item.getItemId()) { case R.id.search: onSearchRequested(); return true; case R.id.importdb: importDBfromSD(); return true; case R.id.exportdb: exportDbToSDCard(); return true; default: return false; } } private void exportDbToSDCard() { if (!BackupRestoreHelper.backupDB()) { Toast.makeText(getApplicationContext(), "Backup to SD Card failed!", Toast.LENGTH_LONG).show(); } else { // if Toast.makeText(getApplicationContext(), "Backup successfull", Toast.LENGTH_LONG).show(); } } // exportDbToSDScard private void importDBfromSD() { if (!BackupRestoreHelper.restoreDB()) { Toast.makeText(getApplicationContext(), "Restored to internal storage failed!", Toast.LENGTH_LONG).show(); } else { // if Toast.makeText(getApplicationContext(), "Restore successfull, application will restart instantly", Toast.LENGTH_LONG).show(); ProcessUtils.getInstance().killTasWithTimeout(3, getApplicationContext()); } } // importDBFromSDCard private void refreshVisitList() { final AsyncTask<Void, Void, List<Visit>> task = new AsyncTask<Void, Void, List<Visit>>() { @Override protected void onPreExecute() { txtCurrentStatus.setVisibility(View.VISIBLE); txtCurrentStatus.setText("Loading Results..."); progressBarSearch.setVisibility(View.VISIBLE); lv.setVisibility(View.GONE); } @Override protected List<Visit> doInBackground(final Void... params) { return getHelper().getVisitDao().findAllVisits(false, 0L); } @Override protected void onPostExecute(final List<Visit> result) { if (result == null || result.size() == 0) { visitCache = new LinkedList<Visit>(); txtCurrentStatus.setText("No results found!"); progressBarSearch.setVisibility(View.GONE); } else { visitCache = result; txtCurrentStatus.setVisibility(View.GONE); progressBarSearch.setVisibility(View.GONE); lv.setVisibility(View.VISIBLE); adapter = new VisitHistoryAdapter(History.this, R.layout.history_visit_row, result); lv.setAdapter(adapter); } } }; task.execute((Void)null); } // refreshVisitList public class VisitHistoryAdapter extends ArrayAdapter<Visit> { private static final String USER_TEXTVIEW = "scoring line"; public final String TAG = VisitHistoryAdapter.class.getName(); private final DateFormat dateFormatter = DateFormat.getDateInstance(); private final DateFormat dateTimeFormatter = new SimpleDateFormat(); final List<Visit> objects; public VisitHistoryAdapter(final Context context, final int textViewResourceId, final List<Visit> objects) { super(context, textViewResourceId, objects); this.objects = objects; } @Override public View getView(final int position, final View convertView, final ViewGroup parent) { View v = convertView; final Visit visit = getItem(position); if (v == null) { final LayoutInflater li = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE); v = li.inflate(R.layout.history_visit_row, null); } // if ParcourReportData reportData = reportCache.get(visit); if (reportData == null) { reportData = generator.generateReportForVisit(visit); reportCache.put(visit, reportData); } // reportData final String beginTime = visit.getBeginTime() != null ? dateTimeFormatter.format(visit.getBeginTime()) : ""; final String endTime = visit.getEndTime() != null ? dateTimeFormatter.format(visit.getEndTime()) : ""; final String revision = reportData.getParcourRevisionDate() != null ? dateFormatter.format(reportData.getParcourRevisionDate()) : ""; final TextView txtParcourName = (TextView)v.findViewById(R.id.lblParcourName); txtParcourName.setText(reportData.getParcourName()); final TextView txtParcourVersion = (TextView)v.findViewById(R.id.lblVersionDate); txtParcourVersion.setText(beginTime + " - " + endTime); final TextView txtRevisionNumber = (TextView)v.findViewById(R.id.lblRevision); txtRevisionNumber.setText(revision); final LinearLayout ll = (LinearLayout)v.findViewById(R.id.llUserScores); ll.removeAllViews(); final Map<String, Double> avgPointsMap = reportData.getAvgPoints(); final Map<String, Integer> totalPointsMap = reportData.getTotalPoints(); for (final Map.Entry<String, Double> entries : avgPointsMap.entrySet()) { final LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(android.view.ViewGroup.LayoutParams.FILL_PARENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT); lp.setMargins(30, 0, 0, 0); final Integer totalPoints = totalPointsMap.get(entries.getKey()); final TextView tv = new TextView(v.getContext()); tv.setId(View.NO_ID); tv.setTag(USER_TEXTVIEW); tv.setText(entries.getKey() + " - " + (totalPoints != null ? MessageFormat.format("{0,number,#}", totalPoints) : "-") + " - avg " + (entries.getValue() != null ? MessageFormat.format("{0,number,#.##}", entries.getValue()) : "-")); ll.addView(tv, lp); } // for return v; } // getView } // VisitHistoryAdapter }