1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 * in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the License
10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 * or implied. See the License for the specific language governing permissions and limitations under
12 * the License.
13 */
14package android.support.v17.leanback.widget;
15
16import java.util.ArrayList;
17import java.util.Collection;
18import java.util.Collections;
19import java.util.List;
20
21/**
22 * An {@link ObjectAdapter} implemented with an {@link ArrayList}.
23 */
24public class ArrayObjectAdapter extends ObjectAdapter {
25
26    private ArrayList<Object> mItems = new ArrayList<Object>();
27
28    /**
29     * Constructs an adapter with the given {@link PresenterSelector}.
30     */
31    public ArrayObjectAdapter(PresenterSelector presenterSelector) {
32        super(presenterSelector);
33    }
34
35    /**
36     * Constructs an adapter that uses the given {@link Presenter} for all items.
37     */
38    public ArrayObjectAdapter(Presenter presenter) {
39        super(presenter);
40    }
41
42    /**
43     * Constructs an adapter.
44     */
45    public ArrayObjectAdapter() {
46        super();
47    }
48
49    @Override
50    public int size() {
51        return mItems.size();
52    }
53
54    @Override
55    public Object get(int index) {
56        return mItems.get(index);
57    }
58
59    /**
60     * Returns the index for the first occurrence of item in the adapter, or -1 if
61     * not found.
62     *
63     * @param item  The item to find in the list.
64     * @return Index of the first occurrence of the item in the adapter, or -1
65     *         if not found.
66     */
67    public int indexOf(Object item) {
68        return mItems.indexOf(item);
69    }
70
71    /**
72     * Notify that the content of a range of items changed. Note that this is
73     * not same as items being added or removed.
74     *
75     * @param positionStart The position of first item that has changed.
76     * @param itemCount The count of how many items have changed.
77     */
78    public void notifyArrayItemRangeChanged(int positionStart, int itemCount) {
79        notifyItemRangeChanged(positionStart, itemCount);
80    }
81
82    /**
83     * Adds an item to the end of the adapter.
84     *
85     * @param item The item to add to the end of the adapter.
86     */
87    public void add(Object item) {
88        add(mItems.size(), item);
89    }
90
91    /**
92     * Inserts an item into this adapter at the specified index.
93     * If the index is >= {@link #size} an exception will be thrown.
94     *
95     * @param index The index at which the item should be inserted.
96     * @param item The item to insert into the adapter.
97     */
98    public void add(int index, Object item) {
99        mItems.add(index, item);
100        notifyItemRangeInserted(index, 1);
101    }
102
103    /**
104     * Adds the objects in the given collection to the adapter, starting at the
105     * given index.  If the index is >= {@link #size} an exception will be thrown.
106     *
107     * @param index The index at which the items should be inserted.
108     * @param items A {@link Collection} of items to insert.
109     */
110    public void addAll(int index, Collection items) {
111        int itemsCount = items.size();
112        if (itemsCount == 0) {
113            return;
114        }
115        mItems.addAll(index, items);
116        notifyItemRangeInserted(index, itemsCount);
117    }
118
119    /**
120     * Removes the first occurrence of the given item from the adapter.
121     *
122     * @param item The item to remove from the adapter.
123     * @return True if the item was found and thus removed from the adapter.
124     */
125    public boolean remove(Object item) {
126        int index = mItems.indexOf(item);
127        if (index >= 0) {
128            mItems.remove(index);
129            notifyItemRangeRemoved(index, 1);
130        }
131        return index >= 0;
132    }
133
134    /**
135     * Replaces item at position with a new item and calls notifyItemRangeChanged()
136     * at the given position.  Note that this method does not compare new item to
137     * existing item.
138     * @param position  The index of item to replace.
139     * @param item      The new item to be placed at given position.
140     */
141    public void replace(int position, Object item) {
142        mItems.set(position, item);
143        notifyItemRangeChanged(position, 1);
144    }
145
146    /**
147     * Removes a range of items from the adapter. The range is specified by giving
148     * the starting position and the number of elements to remove.
149     *
150     * @param position The index of the first item to remove.
151     * @param count The number of items to remove.
152     * @return The number of items removed.
153     */
154    public int removeItems(int position, int count) {
155        int itemsToRemove = Math.min(count, mItems.size() - position);
156        if (itemsToRemove <= 0) {
157            return 0;
158        }
159
160        for (int i = 0; i < itemsToRemove; i++) {
161            mItems.remove(position);
162        }
163        notifyItemRangeRemoved(position, itemsToRemove);
164        return itemsToRemove;
165    }
166
167    /**
168     * Removes all items from this adapter, leaving it empty.
169     */
170    public void clear() {
171        int itemCount = mItems.size();
172        if (itemCount == 0) {
173            return;
174        }
175        mItems.clear();
176        notifyItemRangeRemoved(0, itemCount);
177    }
178
179    /**
180     * Gets a read-only view of the list of object of this ArrayObjectAdapter.
181     */
182    public <E> List<E> unmodifiableList() {
183        return Collections.unmodifiableList((List<E>) mItems);
184    }
185}
186