1816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko/*
2816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Copyright (C) 2015 The Android Open Source Project
3816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko *
4816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Licensed under the Apache License, Version 2.0 (the "License");
5816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * you may not use this file except in compliance with the License.
6816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * You may obtain a copy of the License at
7816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko *
8816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko *      http://www.apache.org/licenses/LICENSE-2.0
9816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko *
10816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Unless required by applicable law or agreed to in writing, software
11816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * distributed under the License is distributed on an "AS IS" BASIS,
12816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * See the License for the specific language governing permissions and
14816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * limitations under the License.
15816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */
16816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
17816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkopackage com.android.tv.ui.sidepanel;
18816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
196ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport android.content.Context;
206ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport android.content.SharedPreferences;
21816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.media.tv.TvContract.Channels;
22816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.os.Bundle;
23816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.support.v17.leanback.widget.VerticalGridView;
24816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.view.KeyEvent;
25816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.view.LayoutInflater;
26816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.view.View;
27816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.view.ViewGroup;
28816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.widget.TextView;
29816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
30816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.MainActivity;
31816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.R;
326ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport com.android.tv.common.SharedPreferencesUtils;
33816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.data.Channel;
34816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.data.ChannelNumber;
3507b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalkoimport com.android.tv.ui.OnRepeatedKeyInterceptListener;
36816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.util.TvInputManagerHelper;
37816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.util.Utils;
38816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
39816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport java.util.ArrayList;
40816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport java.util.Collections;
41816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport java.util.Comparator;
422e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalkoimport java.util.Iterator;
436ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport java.util.List;
44816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
45816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkopublic class CustomizeChannelListFragment extends SideFragment {
46816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private static final int GROUP_BY_SOURCE = 0;
47816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private static final int GROUP_BY_HD_SD = 1;
48816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private static final String TRACKER_LABEL = "customize channel list";
49816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
506ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    private static final String PREF_KEY_GROUP_SETTINGS = "pref_key_group_settigns";
51816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
526ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    private final List<Channel> mChannels = new ArrayList<>();
536ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    private long mInitialChannelId = Channel.INVALID_ID;
54816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private long mLastFocusedChannelId = Channel.INVALID_ID;
55816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
566ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    private static Integer sGroupingType;
57816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private TvInputManagerHelper mInputManager;
58816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private Channel.DefaultComparator mChannelComparator;
59816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private boolean mGroupByFragmentRunning;
60816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
61816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final List<Item> mItems = new ArrayList<>();
62816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
63816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    @Override
64816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public void onCreate(Bundle savedInstanceState) {
65816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        super.onCreate(savedInstanceState);
66816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mInputManager = getMainActivity().getTvInputManagerHelper();
676ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        mInitialChannelId = getMainActivity().getCurrentChannelId();
68816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelComparator = new Channel.DefaultComparator(getActivity(), mInputManager);
696ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        if (sGroupingType == null) {
706ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            SharedPreferences sharedPreferences = getContext().getSharedPreferences(
716ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    SharedPreferencesUtils.SHARED_PREF_UI_SETTINGS, Context.MODE_PRIVATE);
726ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            sGroupingType = sharedPreferences.getInt(PREF_KEY_GROUP_SETTINGS, GROUP_BY_SOURCE);
736ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
74816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
75816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
76816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    @Override
77816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public View onCreateView(LayoutInflater inflater, ViewGroup container,
78816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            Bundle savedInstanceState) {
79816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        View view = super.onCreateView(inflater, container, savedInstanceState);
80816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        VerticalGridView listView = (VerticalGridView) view.findViewById(R.id.side_panel_list);
8107b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        listView.setOnKeyInterceptListener(new OnRepeatedKeyInterceptListener(listView) {
8207b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko            @Override
8307b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko            public boolean onInterceptKeyEvent(KeyEvent event) {
8407b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                // In order to send tune operation once for continuous channel up/down events,
8507b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                // we only call the moveToChannel method on ACTION_UP event of channel switch keys.
8607b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                if (event.getAction() == KeyEvent.ACTION_UP) {
8707b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                    switch (event.getKeyCode()) {
8807b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                        case KeyEvent.KEYCODE_DPAD_UP:
8907b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                        case KeyEvent.KEYCODE_DPAD_DOWN:
9007b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                            if (mLastFocusedChannelId != Channel.INVALID_ID) {
9107b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                                getMainActivity().tuneToChannel(
9207b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                                        getChannelDataManager().getChannel(mLastFocusedChannelId));
9307b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                            }
9407b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                            break;
9507b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                    }
9607b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                }
9707b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                return super.onInterceptKeyEvent(event);
9807b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko            }
9907b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        });
100816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
101816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (!mGroupByFragmentRunning) {
102816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            getMainActivity().startShrunkenTvView(false, true);
103816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
104816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            int initialChannelPosition = INVALID_POSITION;
105816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            int i = 0;
106816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            for (Item item : mItems) {
107816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                if (item instanceof ChannelItem
108816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                        && ((ChannelItem) item).getChannel().getId() == mInitialChannelId) {
109816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    initialChannelPosition = i;
110816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    break;
111816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                }
112816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                ++i;
113816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
114816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            if (initialChannelPosition != INVALID_POSITION) {
115816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                setSelectedPosition(initialChannelPosition);
116816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            } else {
117816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                setSelectedPosition(0);
118816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
119816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mLastFocusedChannelId = mInitialChannelId;
120816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            MainActivity tvActivity = getMainActivity();
121816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            if (mLastFocusedChannelId != Channel.INVALID_ID &&
122816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    mLastFocusedChannelId != tvActivity.getCurrentChannelId()) {
123816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                tvActivity.tuneToChannel(getChannelDataManager().getChannel(mLastFocusedChannelId));
124816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
125816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
126816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mGroupByFragmentRunning = false;
127816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        return view;
128816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
129816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
130816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    @Override
131816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public void onDestroyView() {
132816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        getChannelDataManager().applyUpdatedValuesToDb();
133816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        super.onDestroyView();
134816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
135816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
136816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    @Override
1376ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    public void onDestroy() {
1386ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        super.onDestroy();
1396ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        getMainActivity().endShrunkenTvView();
1406ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    }
1416ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko
1426ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    @Override
143816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    protected String getTitle() {
144816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        return getString(R.string.side_panel_title_edit_channels_for_an_input);
145816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
146816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
147816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    @Override
148816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public String getTrackerLabel() {
149816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        return TRACKER_LABEL;
150816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
151816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
152816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    @Override
153816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    protected List<Item> getItemList() {
154816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mItems.clear();
155816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannels.clear();
156816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannels.addAll(getChannelDataManager().getChannelList());
1576ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        if (sGroupingType == GROUP_BY_SOURCE) {
158816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            addItemForGroupBySource(mItems);
159816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        } else {
160816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            // GROUP_BY_HD_SD
161816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            addItemForGroupByHdSd(mItems);
162816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
163816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        return mItems;
164816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
165816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
1662e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    private void cleanUpOneChannelGroupItem(List<Item> items) {
1672e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        Iterator<Item> iter = items.iterator();
1682e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        while (iter.hasNext()) {
1692e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            Item item = iter.next();
1702e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            if (item instanceof SelectGroupItem) {
1712e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko                SelectGroupItem selectGroupItem = (SelectGroupItem) item;
1722e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko                if (selectGroupItem.mChannelItemsInGroup.size() == 1) {
17365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko                    selectGroupItem.mChannelItemsInGroup.get(0).mSelectGroupItem = null;
1742e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko                    iter.remove();
1752e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko                }
1762e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            }
1772e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        }
1782e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    }
1792e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko
180816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private void addItemForGroupBySource(List<Item> items) {
181816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        items.add(new GroupBySubMenu(getString(R.string.edit_channels_group_by_sources)));
182816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        SelectGroupItem selectGroupItem = null;
183816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        ArrayList<Channel> channels = new ArrayList<>(mChannels);
184816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        Collections.sort(channels, mChannelComparator);
185816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
186816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        String inputId = null;
187816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        for (Channel channel: channels) {
188816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            if (!channel.getInputId().equals(inputId)) {
189816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                inputId = channel.getInputId();
190816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                String inputLabel = Utils.loadLabel(getActivity(),
191816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                        mInputManager.getTvInputInfo(inputId));
192816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                items.add(new DividerItem(inputLabel));
193816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                selectGroupItem = new SelectGroupItem();
194816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                items.add(selectGroupItem);
195816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
196816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            ChannelItem channelItem = new ChannelItem(channel, selectGroupItem);
197816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            items.add(channelItem);
198816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            selectGroupItem.addChannelItem(channelItem);
199816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
2002e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        cleanUpOneChannelGroupItem(items);
201816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
202816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
203816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private void addItemForGroupByHdSd(List<Item> items) {
204816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        items.add(new GroupBySubMenu(getString(R.string.edit_channels_group_by_hd_sd)));
205816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        SelectGroupItem selectGroupItem = null;
206816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        ArrayList<Channel> channels = new ArrayList<>(mChannels);
207816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        Collections.sort(channels, new Comparator<Channel>() {
208816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            @Override
209816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            public int compare(Channel lhs, Channel rhs) {
210816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                boolean lhsHd = isHdChannel(lhs);
211816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                boolean rhsHd = isHdChannel(rhs);
212816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                if (lhsHd == rhsHd) {
213816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    return ChannelNumber.compare(lhs.getDisplayNumber(), rhs.getDisplayNumber());
214816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                } else {
215816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    return lhsHd ? -1 : 1;
216816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                }
217816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
218816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        });
219816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
220816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        Boolean isHdGroup = null;
221816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        for (Channel channel: channels) {
222816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            boolean isHd = isHdChannel(channel);
223816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            if (isHdGroup == null || isHd != isHdGroup) {
224816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                isHdGroup = isHd;
225816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                items.add(new DividerItem(isHd
226816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                        ? getString(R.string.edit_channels_group_divider_for_hd)
227816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                        : getString(R.string.edit_channels_group_divider_for_sd)));
228816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                selectGroupItem = new SelectGroupItem();
229816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                items.add(selectGroupItem);
230816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
231816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            ChannelItem channelItem = new ChannelItem(channel, selectGroupItem);
232816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            items.add(channelItem);
233816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            selectGroupItem.addChannelItem(channelItem);
234816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
2352e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        cleanUpOneChannelGroupItem(items);
236816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
237816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
238816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private static boolean isHdChannel(Channel channel) {
239816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        String videoFormat = channel.getVideoFormat();
240816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        return videoFormat != null &&
241816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                (Channels.VIDEO_FORMAT_720P.equals(videoFormat)
242816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                        || Channels.VIDEO_FORMAT_1080I.equals(videoFormat)
243816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                        || Channels.VIDEO_FORMAT_1080P.equals(videoFormat)
244816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                        || Channels.VIDEO_FORMAT_2160P.equals(videoFormat)
245816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                        || Channels.VIDEO_FORMAT_4320P.equals(videoFormat));
246816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
247816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
248816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private class SelectGroupItem extends ActionItem {
249816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        private final List<ChannelItem> mChannelItemsInGroup = new ArrayList<>();
250816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        private TextView mTextView;
251816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        private boolean mAllChecked;
252816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
253816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public SelectGroupItem() {
254816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            super(null);
255816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
256816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
257816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        private void addChannelItem(ChannelItem channelItem) {
258816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mChannelItemsInGroup.add(channelItem);
259816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
260816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
261816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
262816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        protected void onBind(View view) {
263816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            super.onBind(view);
264816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mTextView = (TextView) view.findViewById(R.id.title);
265816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
266816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
267816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
268816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        protected void onUpdate() {
269816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            super.onUpdate();
270816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mAllChecked = true;
271816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            for (ChannelItem channelItem : mChannelItemsInGroup) {
272816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                if (!channelItem.getChannel().isBrowsable()) {
273816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    mAllChecked = false;
274816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    break;
275816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                }
276816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
277816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mTextView.setText(getString(mAllChecked
278816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    ? R.string.edit_channels_item_deselect_group
279816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    : R.string.edit_channels_item_select_group));
280816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
281816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
282816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
283816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        protected void onSelected() {
284816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            for (ChannelItem channelItem : mChannelItemsInGroup) {
285816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                Channel channel = channelItem.getChannel();
286816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                if (channel.isBrowsable() == mAllChecked) {
287816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    getChannelDataManager().updateBrowsable(channel.getId(), !mAllChecked, true);
288816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    channelItem.notifyUpdated();
289816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                }
290816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
291816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            getChannelDataManager().notifyChannelBrowsableChanged();
292816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mAllChecked = !mAllChecked;
293816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mTextView.setText(getString(mAllChecked
294816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    ? R.string.edit_channels_item_deselect_group
295816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    : R.string.edit_channels_item_select_group));
296816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
297816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
298816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
299816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private class ChannelItem extends ChannelCheckItem {
3002e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        private SelectGroupItem mSelectGroupItem;
301816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
302816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public ChannelItem(Channel channel, SelectGroupItem selectGroupItem) {
303816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            super(channel, getChannelDataManager(), getProgramDataManager());
304816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mSelectGroupItem = selectGroupItem;
305816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
306816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
307816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
308816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        protected void onUpdate() {
309816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            super.onUpdate();
310816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            setChecked(getChannel().isBrowsable());
311816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
312816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
313816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
314816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        protected void onSelected() {
315816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            super.onSelected();
316816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            getChannelDataManager().updateBrowsable(getChannel().getId(), isChecked());
3172e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            if (mSelectGroupItem != null) {
3182e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko                mSelectGroupItem.notifyUpdated();
3192e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            }
320816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
321816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
322816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
323816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        protected void onFocused() {
324816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            super.onFocused();
325816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mLastFocusedChannelId = getChannel().getId();
326816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
327816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
328816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
3296ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    public static class GroupByFragment extends SideFragment {
3306ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        @Override
3316ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        protected String getTitle() {
3326ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            return getString(R.string.side_panel_title_group_by);
3336ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
3346ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        @Override
3356ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        public String getTrackerLabel() {
3366ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            return GroupBySubMenu.TRACKER_LABEL;
3376ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
3386ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko
3396ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        @Override
3406ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        protected List<Item> getItemList() {
3416ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            List<Item> items = new ArrayList<>();
3426ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            items.add(new RadioButtonItem(
3436ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    getString(R.string.edit_channels_group_by_sources)) {
3446ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                @Override
3456ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                protected void onSelected() {
3466ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    super.onSelected();
3476ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    setGroupingType(GROUP_BY_SOURCE);
3486ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    closeFragment();
3496ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                }
3506ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            });
3516ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            items.add(new RadioButtonItem(
3526ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    getString(R.string.edit_channels_group_by_hd_sd)) {
3536ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                @Override
3546ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                protected void onSelected() {
3556ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    super.onSelected();
3566ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    setGroupingType(GROUP_BY_HD_SD);
3576ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    closeFragment();
3586ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                }
3596ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            });
3606ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            ((RadioButtonItem) items.get(sGroupingType)).setChecked(true);
3616ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            return items;
3626ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
3636ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko
3646ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        private void setGroupingType(int groupingType) {
3656ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            sGroupingType = groupingType;
3666ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            SharedPreferences sharedPreferences = getContext().getSharedPreferences(
3676ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    SharedPreferencesUtils.SHARED_PREF_UI_SETTINGS, Context.MODE_PRIVATE);
3686ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            sharedPreferences.edit().putInt(PREF_KEY_GROUP_SETTINGS, groupingType).apply();
3696ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
3706ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    }
3716ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko
372816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private class GroupBySubMenu extends SubMenuItem {
373816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        private static final String TRACKER_LABEL = "Group by";
374816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public GroupBySubMenu(String description) {
375816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            super(getString(R.string.edit_channels_item_group_by), description,
376816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    getMainActivity().getOverlayManager().getSideFragmentManager());
377816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
378816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
379816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
380816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        protected SideFragment getFragment() {
3816ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            return new GroupByFragment();
382816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
383816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
384816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
385816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        protected void onSelected() {
386816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mGroupByFragmentRunning = true;
387816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            super.onSelected();
388816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
389816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
390816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko}
391