Remove unnecessaray parameter of TizenDeviceInfo
[platform/upstream/xamarin-forms.git] / Xamarin.Forms.Pages / DataSourceList.cs
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Collections.Specialized;
5
6 namespace Xamarin.Forms.Pages
7 {
8         internal class DataSourceList : IList<IDataItem>, IReadOnlyList<IDataItem>, INotifyCollectionChanged
9         {
10                 readonly List<int> _maskedIndexes = new List<int>(); // Indices  
11                 readonly HashSet<string> _maskedKeys = new HashSet<string>();
12                 IList<IDataItem> _mainList;
13
14                 public IList<IDataItem> MainList
15                 {
16                         get { return _mainList; }
17                         set
18                         {
19                                 var observable = _mainList as INotifyCollectionChanged;
20                                 if (observable != null)
21                                         observable.CollectionChanged -= OnMainCollectionChanged;
22                                 _mainList = value;
23                                 observable = _mainList as INotifyCollectionChanged;
24                                 if (observable != null)
25                                         observable.CollectionChanged += OnMainCollectionChanged;
26                                 _maskedIndexes.Clear();
27                                 for (var i = 0; i < _mainList.Count; i++)
28                                 {
29                                         IDataItem data = _mainList[i];
30                                         if (_maskedKeys.Contains(data.Name))
31                                                 _maskedIndexes.Add(i);
32                                 }
33                                 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
34                         }
35                 }
36
37                 public IEnumerable<string> MaskedKeys => _maskedKeys;
38
39                 public void Add(IDataItem item)
40                 {
41                         throw new NotSupportedException();
42                 }
43
44                 public void Clear()
45                 {
46                         throw new NotSupportedException();
47                 }
48
49                 public bool Contains(IDataItem item)
50                 {
51                         return MainList != null && !_maskedKeys.Contains(item.Name) && MainList.Contains(item);
52                 }
53
54                 public void CopyTo(IDataItem[] array, int arrayIndex)
55                 {
56                         throw new NotSupportedException();
57                 }
58
59                 public int Count
60                 {
61                         get
62                         {
63                                 if (MainList == null)
64                                         return 0;
65                                 var result = 0;
66                                 result += MainList.Count;
67                                 result -= _maskedIndexes.Count;
68                                 return result;
69                         }
70                 }
71
72                 public bool IsReadOnly => true;
73
74                 public bool Remove(IDataItem item)
75                 {
76                         throw new NotSupportedException();
77                 }
78
79                 IEnumerator IEnumerable.GetEnumerator()
80                 {
81                         return GetEnumerator();
82                 }
83
84                 public IEnumerator<IDataItem> GetEnumerator()
85                 {
86                         var index = 0;
87                         if (MainList == null)
88                                 yield break;
89                         foreach (IDataItem item in MainList)
90                         {
91                                 if (!_maskedIndexes.Contains(index))
92                                         yield return item;
93                                 index++;
94                         }
95                 }
96
97                 public int IndexOf(IDataItem item)
98                 {
99                         if (_maskedKeys.Contains(item.Name))
100                                 return -1;
101
102                         if (MainList != null)
103                         {
104                                 int result = MainList.IndexOf(item);
105                                 if (result >= 0)
106                                         return PublicIndexFromMainIndex(result);
107                         }
108                         return -1;
109                 }
110
111                 public void Insert(int index, IDataItem item)
112                 {
113                         throw new NotSupportedException();
114                 }
115
116                 public IDataItem this[int index]
117                 {
118                         get
119                         {
120                                 foreach (int i in _maskedIndexes)
121                                 {
122                                         if (i <= index)
123                                                 index++;
124                                 }
125                                 if (_mainList == null)
126                                         throw new IndexOutOfRangeException();
127                                 return _mainList[index];
128                         }
129                         set { throw new NotSupportedException(); }
130                 }
131
132                 public void RemoveAt(int index)
133                 {
134                         throw new NotSupportedException();
135                 }
136
137                 public event NotifyCollectionChangedEventHandler CollectionChanged;
138
139                 public void MaskKey(string key)
140                 {
141                         if (_maskedKeys.Contains(key) || _mainList == null)
142                                 return;
143                         _maskedKeys.Add(key);
144                         var index = 0;
145                         foreach (IDataItem item in _mainList)
146                         {
147                                 if (item.Name == key)
148                                 {
149                                         // We need to keep our indexes list sorted, so we insert everything pre-sorted
150                                         var added = false;
151                                         for (var i = 0; i < _maskedIndexes.Count; i++)
152                                         {
153                                                 if (_maskedIndexes[i] > index)
154                                                 {
155                                                         _maskedIndexes.Insert(i, index);
156                                                         added = true;
157                                                         break;
158                                                 }
159                                         }
160                                         if (!added)
161                                                 _maskedIndexes.Add(index);
162                                         OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, PublicIndexFromMainIndex(index)));
163                                         break;
164                                 }
165                                 index++;
166                         }
167                 }
168
169                 public void UnmaskKey(string key)
170                 {
171                         _maskedKeys.Remove(key);
172                         if (_mainList == null)
173                                 return;
174                         var index = 0;
175                         foreach (IDataItem item in _mainList)
176                         {
177                                 if (item.Name == key)
178                                 {
179                                         bool removed = _maskedIndexes.Remove(index);
180                                         if (removed)
181                                         {
182                                                 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, PublicIndexFromMainIndex(index)));
183                                         }
184                                         break;
185                                 }
186                                 index++;
187                         }
188                 }
189
190                 protected void OnCollectionChanged(NotifyCollectionChangedEventArgs args)
191                 {
192                         CollectionChanged?.Invoke(this, args);
193                 }
194
195                 void OnMainCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
196                 {
197                         // much complexity to be had here
198                         switch (args.Action)
199                         {
200                                 case NotifyCollectionChangedAction.Add:
201                                         OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, args.NewItems, PublicIndexFromMainIndex(args.NewStartingIndex)));
202                                         break;
203                                 case NotifyCollectionChangedAction.Move:
204                                         OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, args.OldItems, PublicIndexFromMainIndex(args.NewStartingIndex),
205                                                 PublicIndexFromMainIndex(args.OldStartingIndex)));
206                                         break;
207                                 case NotifyCollectionChangedAction.Remove:
208                                         OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, args.OldItems, PublicIndexFromMainIndex(args.OldStartingIndex)));
209                                         break;
210                                 case NotifyCollectionChangedAction.Replace:
211                                         OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, args.NewItems, args.OldItems, PublicIndexFromMainIndex(args.OldStartingIndex)));
212                                         break;
213                                 case NotifyCollectionChangedAction.Reset:
214                                         OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
215                                         break;
216                                 default:
217                                         throw new ArgumentOutOfRangeException();
218                         }
219                 }
220
221                 int PublicIndexFromMainIndex(int index)
222                 {
223                         var count = 0;
224                         for (var x = 0; x < _maskedIndexes.Count; x++)
225                         {
226                                 int i = _maskedIndexes[x];
227                                 if (i < index)
228                                         count++;
229                         }
230                         return index - count;
231                 }
232         }
233 }