1113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzsteinpackage com.android.deskclock.stopwatch;
263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
3526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzsteinimport android.app.Activity;
463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelsonimport android.content.Context;
563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelsonimport android.content.Intent;
67c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelsonimport android.content.SharedPreferences;
76b9508b70d9bb11590f96ef4ff6d5dfc703ac868Isaac Katzenelsonimport android.content.SharedPreferences.OnSharedPreferenceChangeListener;
8526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzsteinimport android.content.pm.PackageManager;
9526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzsteinimport android.content.pm.ResolveInfo;
10526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzsteinimport android.graphics.drawable.Drawable;
1163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelsonimport android.os.Bundle;
127c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelsonimport android.preference.PreferenceManager;
1363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelsonimport android.view.LayoutInflater;
1463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelsonimport android.view.View;
1563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelsonimport android.view.ViewGroup;
16526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzsteinimport android.widget.AdapterView;
17526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzsteinimport android.widget.AdapterView.OnItemClickListener;
18526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzsteinimport android.widget.ArrayAdapter;
1963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelsonimport android.widget.BaseAdapter;
2063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelsonimport android.widget.Button;
216b9508b70d9bb11590f96ef4ff6d5dfc703ac868Isaac Katzenelsonimport android.widget.ImageButton;
22526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzsteinimport android.widget.ImageView;
23526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzsteinimport android.widget.ListPopupWindow;
2463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelsonimport android.widget.ListView;
25526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzsteinimport android.widget.PopupWindow.OnDismissListener;
2663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelsonimport android.widget.TextView;
2763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
28386d8b05069c95899149c4b18542fc18c3761314Sam Blitzsteinimport com.android.deskclock.CircleButtonsLinearLayout;
29113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzsteinimport com.android.deskclock.CircleTimerView;
30357497c341662c56945e22e458852f52a977efdfSam Blitzsteinimport com.android.deskclock.DeskClock;
31357497c341662c56945e22e458852f52a977efdfSam Blitzsteinimport com.android.deskclock.DeskClock.OnTapListener;
32113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzsteinimport com.android.deskclock.DeskClockFragment;
33113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzsteinimport com.android.deskclock.Log;
34113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzsteinimport com.android.deskclock.R;
35113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzsteinimport com.android.deskclock.Utils;
366b9508b70d9bb11590f96ef4ff6d5dfc703ac868Isaac Katzenelsonimport com.android.deskclock.timer.CountingTimerView;
3763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
3863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelsonimport java.util.ArrayList;
39526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzsteinimport java.util.List;
4063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
4163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson/**
4263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson * TODO: Insert description here. (generated by isaackatz)
4363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson */
44113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzsteinpublic class StopwatchFragment extends DeskClockFragment implements OnSharedPreferenceChangeListener{
45113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein    int mState = Stopwatches.STOPWATCH_RESET;
4663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
4763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    // Stopwatch views that are accessed by the activity
48386d8b05069c95899149c4b18542fc18c3761314Sam Blitzstein    private ImageButton mLeftButton;
49386d8b05069c95899149c4b18542fc18c3761314Sam Blitzstein    private TextView mCenterButton;
50526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein    private CircleTimerView mTime;
514243fb005ecf4810eb2a1adc28df73abf431f178Isaac Katzenelson    private CountingTimerView mTimeText;
52526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein    private ListView mLapsList;
536b9508b70d9bb11590f96ef4ff6d5dfc703ac868Isaac Katzenelson    private ImageButton mShareButton;
54526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein    private ListPopupWindow mSharePopup;
5563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
5663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    // Used for calculating the time from the start taking into account the pause times
5763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    long mStartTime = 0;
5863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    long mAccumulatedTime = 0;
5963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
6063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    // Lap information
6163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    class Lap {
6263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        Lap () {
6363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            mLapTime = 0;
6463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            mTotalTime = 0;
6563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        }
6663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
6763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        Lap (long time, long total) {
6863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            mLapTime = time;
6963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            mTotalTime = total;
7063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        }
7163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        public long mLapTime;
7263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        public long mTotalTime;
7363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    }
7463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
7563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    // Adapter for the ListView that shows the lap times.
7663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    class LapsListAdapter extends BaseAdapter {
7763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
7863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        ArrayList<Lap> mLaps = new ArrayList<Lap>();
7963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        private final LayoutInflater mInflater;
80f67abfd4e9d546732d67d0b3afe57921e34b7dcdIsaac Katzenelson        private final int mBackgroundColor;
8163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
8263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        public LapsListAdapter(Context context) {
83e35b85f33550504005cd57000bee94c9c477aa4bIsaac Katzenelson            mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
84357497c341662c56945e22e458852f52a977efdfSam Blitzstein            mBackgroundColor = getResources().getColor(R.color.blackish);
8563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        }
8663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
8763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        @Override
8863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        public long getItemId(int position) {
8963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            return position;
9063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        }
9163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
9263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        @Override
9363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        public View getView(int position, View convertView, ViewGroup parent) {
9463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            if (mLaps.size() == 0 || position >= mLaps.size()) {
9563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                return null;
9663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            }
9763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            View lapInfo;
9863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            if (convertView != null) {
9963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                lapInfo = convertView;
10063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            } else {
10163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                lapInfo =  mInflater.inflate(R.layout.lap_view, parent, false);
10263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            }
10363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            TextView count = (TextView)lapInfo.findViewById(R.id.lap_number);
10463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            TextView lapTime = (TextView)lapInfo.findViewById(R.id.lap_time);
10563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            TextView toalTime = (TextView)lapInfo.findViewById(R.id.lap_total);
106113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            lapTime.setText(Stopwatches.getTimeText(mLaps.get(position).mLapTime));
107113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            toalTime.setText(Stopwatches.getTimeText(mLaps.get(position).mTotalTime));
108fccd1dcdf6d83edc800e64d0494872a1c688acaeIsaac Katzenelson            count.setText(getString(R.string.sw_notification_lap_number, mLaps.size() - position)
109fccd1dcdf6d83edc800e64d0494872a1c688acaeIsaac Katzenelson                    .toUpperCase());
11063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
111357497c341662c56945e22e458852f52a977efdfSam Blitzstein            lapInfo.setBackgroundColor(mBackgroundColor);
112357497c341662c56945e22e458852f52a977efdfSam Blitzstein            return lapInfo;
11363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        }
11463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
11563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        @Override
11663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        public int getCount() {
11763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            return mLaps.size();
11863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        }
11963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
12063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        @Override
12163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        public Object getItem(int position) {
12263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            if (mLaps.size() == 0 || position >= mLaps.size()) {
12363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                return null;
12463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            }
12563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            return mLaps.get(position);
12663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        }
12763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
12863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        public void addLap(Lap l) {
12963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            mLaps.add(0, l);
13063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            notifyDataSetChanged();
13163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        }
13263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
13363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        public void clearLaps() {
13463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            mLaps.clear();
13563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            notifyDataSetChanged();
13663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        }
13763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
13863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        // Helper function used to get the lap data to be stored in the activitys's bundle
13963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        public long [] getLapTimes() {
14063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            int size = mLaps.size();
14163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            if (size == 0) {
14263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                return null;
14363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            }
14463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            long [] laps = new long[size];
14563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            for (int i = 0; i < size; i ++) {
146113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                laps[i] = mLaps.get(i).mTotalTime;
14763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            }
14863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            return laps;
14963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        }
15063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
15163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        // Helper function to restore adapter's data from the activity's bundle
15263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        public void setLapTimes(long [] laps) {
15363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            if (laps == null || laps.length == 0) {
15463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                return;
15563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            }
15663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
15763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            int size = laps.length;
15863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            mLaps.clear();
15963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            for (int i = 0; i < size; i ++) {
16063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                mLaps.add(new Lap (laps[i], 0));
16163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            }
16263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            long totalTime = 0;
16363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            for (int i = size -1; i >= 0; i --) {
16463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                totalTime += laps[i];
16563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                mLaps.get(i).mTotalTime = totalTime;
16663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            }
16763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            notifyDataSetChanged();
16863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        }
16963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    }
17063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
17163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    // Keys for data stored in the activity's bundle
17263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    private static final String START_TIME_KEY = "start_time";
17363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    private static final String ACCUM_TIME_KEY = "accum_time";
17463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    private static final String STATE_KEY = "state";
17563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    private static final String LAPS_KEY = "laps";
17663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
17763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    LapsListAdapter mLapsAdapter;
17863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
17963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    public StopwatchFragment() {
18063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    }
18163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
182e40b31200dee36341e5697b2774799555ca79c9bSara Ting    private void rightButtonAction() {
183e40b31200dee36341e5697b2774799555ca79c9bSara Ting        long time = Utils.getTimeNow();
184e40b31200dee36341e5697b2774799555ca79c9bSara Ting        Context context = getActivity().getApplicationContext();
185e40b31200dee36341e5697b2774799555ca79c9bSara Ting        Intent intent = new Intent(context, StopwatchService.class);
186e40b31200dee36341e5697b2774799555ca79c9bSara Ting        intent.putExtra(Stopwatches.MESSAGE_TIME, time);
187e40b31200dee36341e5697b2774799555ca79c9bSara Ting        intent.putExtra(Stopwatches.SHOW_NOTIF, false);
188e40b31200dee36341e5697b2774799555ca79c9bSara Ting        buttonClicked(true);
189e40b31200dee36341e5697b2774799555ca79c9bSara Ting        switch (mState) {
190e40b31200dee36341e5697b2774799555ca79c9bSara Ting            case Stopwatches.STOPWATCH_RUNNING:
191e40b31200dee36341e5697b2774799555ca79c9bSara Ting                // do stop
192e40b31200dee36341e5697b2774799555ca79c9bSara Ting                long curTime = Utils.getTimeNow();
193e40b31200dee36341e5697b2774799555ca79c9bSara Ting                mAccumulatedTime += (curTime - mStartTime);
194e40b31200dee36341e5697b2774799555ca79c9bSara Ting                doStop();
195e40b31200dee36341e5697b2774799555ca79c9bSara Ting                intent.setAction(Stopwatches.STOP_STOPWATCH);
196e40b31200dee36341e5697b2774799555ca79c9bSara Ting                context.startService(intent);
197e40b31200dee36341e5697b2774799555ca79c9bSara Ting                break;
198e40b31200dee36341e5697b2774799555ca79c9bSara Ting            case Stopwatches.STOPWATCH_RESET:
199e40b31200dee36341e5697b2774799555ca79c9bSara Ting            case Stopwatches.STOPWATCH_STOPPED:
200e40b31200dee36341e5697b2774799555ca79c9bSara Ting                // do start
201e40b31200dee36341e5697b2774799555ca79c9bSara Ting                doStart(time);
202e40b31200dee36341e5697b2774799555ca79c9bSara Ting                intent.setAction(Stopwatches.START_STOPWATCH);
203e40b31200dee36341e5697b2774799555ca79c9bSara Ting                context.startService(intent);
204e40b31200dee36341e5697b2774799555ca79c9bSara Ting                break;
205e40b31200dee36341e5697b2774799555ca79c9bSara Ting            default:
206e40b31200dee36341e5697b2774799555ca79c9bSara Ting                Log.wtf("Illegal state " + mState
207e40b31200dee36341e5697b2774799555ca79c9bSara Ting                        + " while pressing the right stopwatch button");
208e40b31200dee36341e5697b2774799555ca79c9bSara Ting                break;
209e40b31200dee36341e5697b2774799555ca79c9bSara Ting        }
210e40b31200dee36341e5697b2774799555ca79c9bSara Ting    }
211e40b31200dee36341e5697b2774799555ca79c9bSara Ting
21263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    @Override
21363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    public View onCreateView(LayoutInflater inflater, ViewGroup container,
21463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                             Bundle savedInstanceState) {
21563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        // Inflate the layout for this fragment
21663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        View v = inflater.inflate(R.layout.stopwatch_fragment, container, false);
217113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein
2186b9508b70d9bb11590f96ef4ff6d5dfc703ac868Isaac Katzenelson        mLeftButton = (ImageButton)v.findViewById(R.id.stopwatch_left_button);
21963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        mLeftButton.setOnClickListener(new View.OnClickListener() {
22063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            @Override
22163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            public void onClick(View v) {
222113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                long time = Utils.getTimeNow();
223113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                Context context = getActivity().getApplicationContext();
224113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                Intent intent = new Intent(context, StopwatchService.class);
225113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                intent.putExtra(Stopwatches.MESSAGE_TIME, time);
226113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                intent.putExtra(Stopwatches.SHOW_NOTIF, false);
22763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                buttonClicked(true);
22863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                switch (mState) {
229113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                    case Stopwatches.STOPWATCH_RUNNING:
23063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                        // Save lap time
231113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                        addLapTime(time);
232113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                        doLap();
233113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                        intent.setAction(Stopwatches.LAP_STOPWATCH);
234113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                        context.startService(intent);
23563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                        break;
236113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                    case Stopwatches.STOPWATCH_STOPPED:
23763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                        // do reset
238113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                        doReset();
239113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                        intent.setAction(Stopwatches.RESET_STOPWATCH);
240113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                        context.startService(intent);
24163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                        break;
24263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                    default:
24363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                        Log.wtf("Illegal state " + mState
24463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                                + " while pressing the left stopwatch button");
24563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                        break;
24663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                }
24763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            }
24863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        });
24963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
25063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
251386d8b05069c95899149c4b18542fc18c3761314Sam Blitzstein        mCenterButton = (TextView)v.findViewById(R.id.stopwatch_stop);
2526b9508b70d9bb11590f96ef4ff6d5dfc703ac868Isaac Katzenelson        mShareButton = (ImageButton)v.findViewById(R.id.stopwatch_share_button);
25363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
25463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        mShareButton.setOnClickListener(new View.OnClickListener() {
25563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            @Override
25663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            public void onClick(View v) {
257526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                showSharePopup();
25863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            }
25963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        });
26063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
261e40b31200dee36341e5697b2774799555ca79c9bSara Ting        // Timer text serves as a virtual start/stop button.
262e40b31200dee36341e5697b2774799555ca79c9bSara Ting        final CountingTimerView countingTimerView = (CountingTimerView)
263e40b31200dee36341e5697b2774799555ca79c9bSara Ting                v.findViewById(R.id.stopwatch_time_text);
264e40b31200dee36341e5697b2774799555ca79c9bSara Ting        countingTimerView.registerVirtualButtonAction(new Runnable() {
265e40b31200dee36341e5697b2774799555ca79c9bSara Ting            @Override
266e40b31200dee36341e5697b2774799555ca79c9bSara Ting            public void run() {
267e40b31200dee36341e5697b2774799555ca79c9bSara Ting                rightButtonAction();
268e40b31200dee36341e5697b2774799555ca79c9bSara Ting            }
269e40b31200dee36341e5697b2774799555ca79c9bSara Ting        });
270386d8b05069c95899149c4b18542fc18c3761314Sam Blitzstein        countingTimerView.registerStopTextView(mCenterButton);
271e40b31200dee36341e5697b2774799555ca79c9bSara Ting        countingTimerView.setVirtualButtonEnabled(true);
272e40b31200dee36341e5697b2774799555ca79c9bSara Ting
27363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        mTime = (CircleTimerView)v.findViewById(R.id.stopwatch_time);
2744243fb005ecf4810eb2a1adc28df73abf431f178Isaac Katzenelson        mTimeText = (CountingTimerView)v.findViewById(R.id.stopwatch_time_text);
27563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        mLapsList = (ListView)v.findViewById(R.id.laps_list);
27663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        mLapsList.setDividerHeight(0);
27763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        mLapsAdapter = new LapsListAdapter(getActivity());
27863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        if (mLapsList != null) {
27963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            mLapsList.setAdapter(mLapsAdapter);
28063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        }
28163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
282386d8b05069c95899149c4b18542fc18c3761314Sam Blitzstein        CircleButtonsLinearLayout circleLayout =
283386d8b05069c95899149c4b18542fc18c3761314Sam Blitzstein                (CircleButtonsLinearLayout)v.findViewById(R.id.stopwatch_circle);
284386d8b05069c95899149c4b18542fc18c3761314Sam Blitzstein        circleLayout.setCircleTimerViewIds(R.id.stopwatch_time, R.id.stopwatch_left_button,
285386d8b05069c95899149c4b18542fc18c3761314Sam Blitzstein                R.id.stopwatch_share_button, R.id.stopwatch_stop,
2860f6e3350fed144e3909ba4e45f3006f042c0187cSam Blitzstein                R.dimen.plusone_reset_button_padding, R.dimen.share_button_padding,
2870f6e3350fed144e3909ba4e45f3006f042c0187cSam Blitzstein                0, 0); /** No label for a stopwatch**/
288386d8b05069c95899149c4b18542fc18c3761314Sam Blitzstein
28963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        return v;
29063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    }
29163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
29263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    @Override
29363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    public void onResume() {
294e35b85f33550504005cd57000bee94c9c477aa4bIsaac Katzenelson        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
295113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        prefs.registerOnSharedPreferenceChangeListener(this);
2967c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson        readFromSharedPref(prefs);
2977c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson        mTime.readFromSharedPref(prefs, "sw");
298113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        mTime.postInvalidate();
299113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein
30063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        setButtons(mState);
301644a5d887d7033e669ac362a8ed6e79197d13c72Itzhak Katzenelson        mTimeText.setTime(mAccumulatedTime, true, true);
302113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        if (mState == Stopwatches.STOPWATCH_RUNNING) {
30363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            startUpdateThread();
304113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        } else if (mState == Stopwatches.STOPWATCH_STOPPED && mAccumulatedTime != 0) {
3057c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson            mTimeText.blinkTimeStr(true);
30663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        }
30763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        showLaps();
308113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein
30963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        super.onResume();
31063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    }
31163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
31263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    @Override
31363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    public void onPause() {
314113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        if (mState == Stopwatches.STOPWATCH_RUNNING) {
31563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            stopUpdateThread();
31663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        }
3177c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson        // The stopwatch must keep running even if the user closes the app so save stopwatch state
3187c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson        // in shared prefs
319e35b85f33550504005cd57000bee94c9c477aa4bIsaac Katzenelson        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
320113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        prefs.unregisterOnSharedPreferenceChangeListener(this);
3217c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson        writeToSharedPref(prefs);
3227c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson        mTime.writeToSharedPref(prefs, "sw");
323a80f15ded8c0be8bf2268bc4cf7b0ce125b07d1bIsaac Katzenelson        mTimeText.blinkTimeStr(false);
324526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        if (mSharePopup != null) {
325526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            mSharePopup.dismiss();
326526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            mSharePopup = null;
327526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        }
328526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein
32963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        super.onPause();
33063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    }
33163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
332113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein    private void doStop() {
333113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        stopUpdateThread();
334113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        mTime.pauseIntervalAnimation();
335644a5d887d7033e669ac362a8ed6e79197d13c72Itzhak Katzenelson        mTimeText.setTime(mAccumulatedTime, true, true);
336113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        mTimeText.blinkTimeStr(true);
337113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        updateCurrentLap(mAccumulatedTime);
338113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        setButtons(Stopwatches.STOPWATCH_STOPPED);
339113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        mState = Stopwatches.STOPWATCH_STOPPED;
340113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein    }
341113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein
342113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein    private void doStart(long time) {
343113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        mStartTime = time;
344113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        startUpdateThread();
345113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        mTimeText.blinkTimeStr(false);
346113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        if (mTime.isAnimating()) {
347113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            mTime.startIntervalAnimation();
348113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        }
349113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        setButtons(Stopwatches.STOPWATCH_RUNNING);
350113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        mState = Stopwatches.STOPWATCH_RUNNING;
351113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein    }
352113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein
353113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein    private void doLap() {
354113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        showLaps();
355113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        setButtons(Stopwatches.STOPWATCH_RUNNING);
356113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein    }
357113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein
358113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein    private void doReset() {
359113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        SharedPreferences prefs =
360113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                PreferenceManager.getDefaultSharedPreferences(getActivity());
361f67abfd4e9d546732d67d0b3afe57921e34b7dcdIsaac Katzenelson        Utils.clearSwSharedPref(prefs);
362113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        mTime.clearSharedPref(prefs, "sw");
363113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        mAccumulatedTime = 0;
364113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        mLapsAdapter.clearLaps();
365113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        showLaps();
366113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        mTime.stopIntervalAnimation();
367113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        mTime.reset();
368644a5d887d7033e669ac362a8ed6e79197d13c72Itzhak Katzenelson        mTimeText.setTime(mAccumulatedTime, true, true);
369113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        mTimeText.blinkTimeStr(false);
370113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        setButtons(Stopwatches.STOPWATCH_RESET);
371113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        mState = Stopwatches.STOPWATCH_RESET;
372113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein    }
373113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein
37463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    private void showShareButton(boolean show) {
37563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        if (mShareButton != null) {
3766b9508b70d9bb11590f96ef4ff6d5dfc703ac868Isaac Katzenelson            mShareButton.setVisibility(show ? View.VISIBLE : View.INVISIBLE);
37763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            mShareButton.setEnabled(show);
37863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        }
37963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    }
38063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
381526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein    private void showSharePopup() {
382113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        Intent intent = getShareIntent();
383526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein
384526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        Activity parent = getActivity();
385526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        PackageManager packageManager = parent.getPackageManager();
386526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein
387526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        // Get a list of sharable options.
388526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        List<ResolveInfo> shareOptions = packageManager
389526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                .queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
390526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein
391526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        if (shareOptions.size() == 0) {
392526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            return;
393526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        }
394526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        ArrayList<CharSequence> shareOptionTitles = new ArrayList<CharSequence>();
395526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        ArrayList<Drawable> shareOptionIcons = new ArrayList<Drawable>();
396526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        ArrayList<CharSequence> shareOptionThreeTitles = new ArrayList<CharSequence>();
397526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        ArrayList<Drawable> shareOptionThreeIcons = new ArrayList<Drawable>();
398526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        ArrayList<String> shareOptionPackageNames = new ArrayList<String>();
399526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        ArrayList<String> shareOptionClassNames = new ArrayList<String>();
400526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein
401526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        for (int option_i = 0; option_i < shareOptions.size(); option_i++) {
402526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            ResolveInfo option = shareOptions.get(option_i);
403526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            CharSequence label = option.loadLabel(packageManager);
404526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            Drawable icon = option.loadIcon(packageManager);
405526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            shareOptionTitles.add(label);
406526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            shareOptionIcons.add(icon);
407526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            if (shareOptions.size() > 4 && option_i < 3) {
408526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                shareOptionThreeTitles.add(label);
409526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                shareOptionThreeIcons.add(icon);
410526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            }
411526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            shareOptionPackageNames.add(option.activityInfo.packageName);
412526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            shareOptionClassNames.add(option.activityInfo.name);
413526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        }
414526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        if (shareOptionTitles.size() > 4) {
415526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            shareOptionThreeTitles.add(getResources().getString(R.string.see_all));
416526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            shareOptionThreeIcons.add(getResources().getDrawable(android.R.color.transparent));
417526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        }
418526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein
419526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        if (mSharePopup != null) {
420526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            mSharePopup.dismiss();
421526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            mSharePopup = null;
422526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        }
423526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        mSharePopup = new ListPopupWindow(parent);
424526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        mSharePopup.setAnchorView(mShareButton);
425526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        mSharePopup.setModal(true);
426526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        // This adapter to show the rest will be used to quickly repopulate if "See all..." is hit.
427526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        ImageLabelAdapter showAllAdapter = new ImageLabelAdapter(parent,
428526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                R.layout.popup_window_item, shareOptionTitles, shareOptionIcons,
429526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                shareOptionPackageNames, shareOptionClassNames);
430526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        if (shareOptionTitles.size() > 4) {
431526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            mSharePopup.setAdapter(new ImageLabelAdapter(parent, R.layout.popup_window_item,
432526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                    shareOptionThreeTitles, shareOptionThreeIcons, shareOptionPackageNames,
433526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                    shareOptionClassNames, showAllAdapter));
434526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        } else {
435526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            mSharePopup.setAdapter(showAllAdapter);
436526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        }
437526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein
438526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        mSharePopup.setOnItemClickListener(new OnItemClickListener() {
439526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            @Override
440526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
441526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                CharSequence label = ((TextView) view.findViewById(R.id.title)).getText();
442526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                if (label.equals(getResources().getString(R.string.see_all))) {
443526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                    mSharePopup.setAdapter(
444526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                            ((ImageLabelAdapter) parent.getAdapter()).getShowAllAdapter());
445526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                    mSharePopup.show();
446526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                    return;
447526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                }
448526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein
449113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                Intent intent = getShareIntent();
450526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                ImageLabelAdapter adapter = (ImageLabelAdapter) parent.getAdapter();
451526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                String packageName = adapter.getPackageName(position);
452526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                String className = adapter.getClassName(position);
453526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                intent.setClassName(packageName, className);
454526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                startActivity(intent);
455526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            }
456526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        });
457526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        mSharePopup.setOnDismissListener(new OnDismissListener() {
458526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            @Override
459526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            public void onDismiss() {
460526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                mSharePopup = null;
461526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            }
462526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        });
463526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        mSharePopup.setWidth((int) getResources().getDimension(R.dimen.popup_window_width));
464526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        mSharePopup.show();
465526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein    }
466526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein
467113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein    private Intent getShareIntent() {
468113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        Intent intent = new Intent(android.content.Intent.ACTION_SEND);
469113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        intent.setType("text/plain");
470113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
471113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        intent.putExtra(Intent.EXTRA_SUBJECT,
472113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                Stopwatches.getShareTitle(getActivity().getApplicationContext()));
473113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        intent.putExtra(Intent.EXTRA_TEXT, Stopwatches.buildShareResults(
474113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                getActivity().getApplicationContext(), mTimeText.getTimeString(),
475113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                getLapShareTimes(mLapsAdapter.getLapTimes())));
476113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        return intent;
477113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein    }
478113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein
479113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein    /** Turn laps as they would be saved in prefs into format for sharing. **/
480113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein    private long[] getLapShareTimes(long[] input) {
481113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        if (input == null) {
482113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            return null;
483113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        }
484113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein
485113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        int numLaps = input.length;
486113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        long[] output = new long[numLaps];
487113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        long prevLapElapsedTime = 0;
488113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        for (int lap_i = numLaps - 1; lap_i >= 0; lap_i--) {
489113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            long lap = input[lap_i];
490113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            Log.v("lap "+lap_i+": "+lap);
491113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            output[lap_i] = lap - prevLapElapsedTime;
492113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            prevLapElapsedTime = lap;
493113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        }
494113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        return output;
495113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein    }
496113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein
49763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    /***
49863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson     * Update the buttons on the stopwatch according to the watch's state
49963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson     */
50063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    private void setButtons(int state) {
50163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        switch (state) {
502113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            case Stopwatches.STOPWATCH_RESET:
503646258f02bdeb2f9436b8d844514fa8feca383ddPeter Ng                setButton(mLeftButton, R.string.sw_lap_button, R.drawable.ic_lap, false,
5046b9508b70d9bb11590f96ef4ff6d5dfc703ac868Isaac Katzenelson                        View.INVISIBLE);
505386d8b05069c95899149c4b18542fc18c3761314Sam Blitzstein                setStartStopText(mCenterButton, R.string.sw_start_button);
50663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                showShareButton(false);
50763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                break;
508113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            case Stopwatches.STOPWATCH_RUNNING:
509646258f02bdeb2f9436b8d844514fa8feca383ddPeter Ng                setButton(mLeftButton, R.string.sw_lap_button, R.drawable.ic_lap,
5106b9508b70d9bb11590f96ef4ff6d5dfc703ac868Isaac Katzenelson                        !reachedMaxLaps(), View.VISIBLE);
511386d8b05069c95899149c4b18542fc18c3761314Sam Blitzstein                setStartStopText(mCenterButton, R.string.sw_stop_button);
51263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                showShareButton(false);
51363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                break;
514113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            case Stopwatches.STOPWATCH_STOPPED:
515646258f02bdeb2f9436b8d844514fa8feca383ddPeter Ng                setButton(mLeftButton, R.string.sw_reset_button, R.drawable.ic_reset, true,
5166b9508b70d9bb11590f96ef4ff6d5dfc703ac868Isaac Katzenelson                        View.VISIBLE);
517386d8b05069c95899149c4b18542fc18c3761314Sam Blitzstein                setStartStopText(mCenterButton, R.string.sw_start_button);
51863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                showShareButton(true);
51963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                break;
52063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            default:
52163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson                break;
52263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        }
52363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    }
52463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    private boolean reachedMaxLaps() {
525113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        return mLapsAdapter.getCount() >= Stopwatches.MAX_LAPS;
52663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    }
52763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
52863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    /***
52963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson     * Set a single button with the string and states provided.
53063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson     * @param b - Button view to update
53163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson     * @param text - Text in button
53263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson     * @param enabled - enable/disables the button
53363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson     * @param visibility - Show/hide the button
53463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson     */
5356b9508b70d9bb11590f96ef4ff6d5dfc703ac868Isaac Katzenelson    private void setButton(
5366b9508b70d9bb11590f96ef4ff6d5dfc703ac868Isaac Katzenelson            ImageButton b, int text, int drawableId, boolean enabled, int visibility) {
5376b9508b70d9bb11590f96ef4ff6d5dfc703ac868Isaac Katzenelson        b.setContentDescription(getActivity().getResources().getString(text));
5386b9508b70d9bb11590f96ef4ff6d5dfc703ac868Isaac Katzenelson        b.setImageResource(drawableId);
53963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        b.setVisibility(visibility);
54063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        b.setEnabled(enabled);
54163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    }
54263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
543386d8b05069c95899149c4b18542fc18c3761314Sam Blitzstein    private void setStartStopText(TextView v, int text) {
544386d8b05069c95899149c4b18542fc18c3761314Sam Blitzstein        String textStr = getActivity().getResources().getString(text);
545386d8b05069c95899149c4b18542fc18c3761314Sam Blitzstein        v.setText(textStr);
546932e0129e244e2874dfa3c6be58b2fe9a20cc89dSara Ting        v.setContentDescription(textStr);
547386d8b05069c95899149c4b18542fc18c3761314Sam Blitzstein    }
548386d8b05069c95899149c4b18542fc18c3761314Sam Blitzstein
54963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    /***
55063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson     *
55163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson     * @param time - in hundredths of a second
55263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson     */
55363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    private void addLapTime(long time) {
55463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        int size = mLapsAdapter.getCount();
55563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        long curTime = time - mStartTime + mAccumulatedTime;
55663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        if (size == 0) {
55763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            // Always show the ending lap and a new one
55863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            mLapsAdapter.addLap(new Lap(curTime, curTime));
55963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            mLapsAdapter.addLap(new Lap(0, curTime));
560113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            mTime.setIntervalTime(curTime);
56163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        } else {
56263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            long lapTime = curTime - ((Lap) mLapsAdapter.getItem(1)).mTotalTime;
56363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            ((Lap)mLapsAdapter.getItem(0)).mLapTime = lapTime;
56463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            ((Lap)mLapsAdapter.getItem(0)).mTotalTime = curTime;
56563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            mLapsAdapter.addLap(new Lap(0, 0));
566113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            mTime.setMarkerTime(lapTime);
56763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        //    mTime.setIntervalTime(lapTime * 10);
56863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        }
56963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        mLapsAdapter.notifyDataSetChanged();
57063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        // Start lap animation starting from the second lap
57163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson         mTime.stopIntervalAnimation();
57263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson         if (!reachedMaxLaps()) {
57363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson             mTime.startIntervalAnimation();
57463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson         }
57563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    }
57663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
577113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein    private void updateCurrentLap(long totalTime) {
57863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        if (mLapsAdapter.getCount() > 0) {
57963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            Lap curLap = (Lap)mLapsAdapter.getItem(0);
58063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            curLap.mLapTime = totalTime - ((Lap)mLapsAdapter.getItem(1)).mTotalTime;
58163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            curLap.mTotalTime = totalTime;
58263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            mLapsAdapter.notifyDataSetChanged();
58363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        }
58463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    }
58563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
58663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    private void showLaps() {
58763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        if (mLapsAdapter.getCount() > 0) {
58863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            mLapsList.setVisibility(View.VISIBLE);
58963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        } else {
59063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            mLapsList.setVisibility(View.INVISIBLE);
59163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        }
59263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    }
59363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
59463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    private void startUpdateThread() {
59563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        mTime.post(mTimeUpdateThread);
59663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    }
59763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
59863211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    private void stopUpdateThread() {
59963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        mTime.removeCallbacks(mTimeUpdateThread);
60063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    }
60163211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
60263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    Runnable mTimeUpdateThread = new Runnable() {
60363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        @Override
60463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        public void run() {
605113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            long curTime = Utils.getTimeNow();
60663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            long totalTime = mAccumulatedTime + (curTime - mStartTime);
60763211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            if (mTime != null) {
608644a5d887d7033e669ac362a8ed6e79197d13c72Itzhak Katzenelson                mTimeText.setTime(totalTime, true, true);
60963211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            }
61063211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            if (mLapsAdapter.getCount() > 0) {
611113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                updateCurrentLap(totalTime);
61263211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            }
61363211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson            mTime.postDelayed(mTimeUpdateThread, 10);
61463211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson        }
61563211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson    };
61663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson
6177c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson    private void writeToSharedPref(SharedPreferences prefs) {
6187c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson        SharedPreferences.Editor editor = prefs.edit();
619113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        editor.putLong (Stopwatches.PREF_START_TIME, mStartTime);
620113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        editor.putLong (Stopwatches.PREF_ACCUM_TIME, mAccumulatedTime);
621113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        editor.putInt (Stopwatches.PREF_STATE, mState);
6227c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson        if (mLapsAdapter != null) {
6237c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson            long [] laps = mLapsAdapter.getLapTimes();
6247c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson            if (laps != null) {
625113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                editor.putInt (Stopwatches.PREF_LAP_NUM, laps.length);
6267c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson                for (int i = 0; i < laps.length; i++) {
627113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                    String key = Stopwatches.PREF_LAP_TIME + Integer.toString(laps.length - i);
6287c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson                    editor.putLong (key, laps[i]);
6297c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson                }
6307c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson            }
6317c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson        }
632113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        if (mState == Stopwatches.STOPWATCH_RUNNING) {
633113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            editor.putLong(Stopwatches.NOTIF_CLOCK_BASE, mStartTime-mAccumulatedTime);
634113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            editor.putLong(Stopwatches.NOTIF_CLOCK_ELAPSED, -1);
635113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            editor.putBoolean(Stopwatches.NOTIF_CLOCK_RUNNING, true);
636113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        } else if (mState == Stopwatches.STOPWATCH_STOPPED) {
637113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            editor.putLong(Stopwatches.NOTIF_CLOCK_ELAPSED, mAccumulatedTime);
638113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            editor.putLong(Stopwatches.NOTIF_CLOCK_BASE, -1);
639113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            editor.putBoolean(Stopwatches.NOTIF_CLOCK_RUNNING, false);
640113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        } else if (mState == Stopwatches.STOPWATCH_RESET) {
641113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            editor.remove(Stopwatches.NOTIF_CLOCK_BASE);
642113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            editor.remove(Stopwatches.NOTIF_CLOCK_RUNNING);
643113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            editor.remove(Stopwatches.NOTIF_CLOCK_ELAPSED);
644113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        }
645113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        editor.putBoolean(Stopwatches.PREF_UPDATE_CIRCLE, false);
6467c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson        editor.apply();
6477c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson    }
6487c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson
6497c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson    private void readFromSharedPref(SharedPreferences prefs) {
650113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        mStartTime = prefs.getLong(Stopwatches.PREF_START_TIME, 0);
651113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        mAccumulatedTime = prefs.getLong(Stopwatches.PREF_ACCUM_TIME, 0);
652113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        mState = prefs.getInt(Stopwatches.PREF_STATE, Stopwatches.STOPWATCH_RESET);
653113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        int numLaps = prefs.getInt(Stopwatches.PREF_LAP_NUM, Stopwatches.STOPWATCH_RESET);
6547c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson        if (mLapsAdapter != null) {
655113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            long[] oldLaps = mLapsAdapter.getLapTimes();
656113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            if (oldLaps == null || oldLaps.length < numLaps) {
657113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                long[] laps = new long[numLaps];
658113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                long prevLapElapsedTime = 0;
659113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                for (int lap_i = 0; lap_i < numLaps; lap_i++) {
660113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                    String key = Stopwatches.PREF_LAP_TIME + Integer.toString(lap_i + 1);
661113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                    long lap = prefs.getLong(key, 0);
662113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                    laps[numLaps - lap_i - 1] = lap - prevLapElapsedTime;
663113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                    prevLapElapsedTime = lap;
664113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                }
665113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                mLapsAdapter.setLapTimes(laps);
666113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            }
667113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        }
668113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        if (prefs.getBoolean(Stopwatches.PREF_UPDATE_CIRCLE, true)) {
669113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            if (mState == Stopwatches.STOPWATCH_STOPPED) {
670113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                doStop();
671113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            } else if (mState == Stopwatches.STOPWATCH_RUNNING) {
672113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                doStart(mStartTime);
673113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            } else if (mState == Stopwatches.STOPWATCH_RESET) {
674113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                doReset();
6757c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson            }
6767c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson        }
6777c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson    }
6787c71fbab5ecd558e60edff636a149ff3bf73ec57Isaac Katzenelson
679526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein    public class ImageLabelAdapter extends ArrayAdapter<CharSequence> {
680526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        private final ArrayList<CharSequence> mStrings;
681526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        private final ArrayList<Drawable> mDrawables;
682526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        private final ArrayList<String> mPackageNames;
683526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        private final ArrayList<String> mClassNames;
684526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        private ImageLabelAdapter mShowAllAdapter;
685526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein
686526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        public ImageLabelAdapter(Context context, int textViewResourceId,
687526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                ArrayList<CharSequence> strings, ArrayList<Drawable> drawables,
688526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                ArrayList<String> packageNames, ArrayList<String> classNames) {
689526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            super(context, textViewResourceId, strings);
690526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            mStrings = strings;
691526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            mDrawables = drawables;
692526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            mPackageNames = packageNames;
693526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            mClassNames = classNames;
694526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        }
695526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein
696526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        // Use this constructor if showing a "see all" option, to pass in the adapter
697526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        // that will be needed to quickly show all the remaining options.
698526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        public ImageLabelAdapter(Context context, int textViewResourceId,
699526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                ArrayList<CharSequence> strings, ArrayList<Drawable> drawables,
700526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                ArrayList<String> packageNames, ArrayList<String> classNames,
701526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                ImageLabelAdapter showAllAdapter) {
702526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            super(context, textViewResourceId, strings);
703526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            mStrings = strings;
704526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            mDrawables = drawables;
705526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            mPackageNames = packageNames;
706526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            mClassNames = classNames;
707526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            mShowAllAdapter = showAllAdapter;
708526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        }
709526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein
710526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        @Override
711526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        public View getView(int position, View convertView, ViewGroup parent) {
712526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            LayoutInflater li = getActivity().getLayoutInflater();
713526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            View row = li.inflate(R.layout.popup_window_item, parent, false);
714526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            ((TextView) row.findViewById(R.id.title)).setText(
715526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                    mStrings.get(position));
716526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            ((ImageView) row.findViewById(R.id.icon)).setBackground(
717526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein                    mDrawables.get(position));
718526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            return row;
719526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        }
720526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein
721526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        public String getPackageName(int position) {
722526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            return mPackageNames.get(position);
723526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        }
724526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein
725526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        public String getClassName(int position) {
726526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            return mClassNames.get(position);
727526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        }
728526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein
729526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        public ImageLabelAdapter getShowAllAdapter() {
730526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein            return mShowAllAdapter;
731526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein        }
732526cf41d8a473a005d7649ec5becf00f57ae8febSam Blitzstein    }
733113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein
734113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein    @Override
735113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein    public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
736113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        if (prefs.equals(PreferenceManager.getDefaultSharedPreferences(getActivity()))) {
737113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            if (! (key.equals(Stopwatches.PREF_LAP_NUM) ||
738113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                    key.startsWith(Stopwatches.PREF_LAP_TIME))) {
739113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                readFromSharedPref(prefs);
740113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                if (prefs.getBoolean(Stopwatches.PREF_UPDATE_CIRCLE, true)) {
741113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                    mTime.readFromSharedPref(prefs, "sw");
742113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein                }
743113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein            }
744113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein        }
745113e1daddd8cb0e890084aa4b6ea3194d8ad4826Sam Blitzstein    }
74663211efa1565b5dc171938740ba183302d0e46f3Isaac Katzenelson}
747