added iOS source code
[wl-app.git] / iOS / WolneLektury / Screens / Search / SearchFiltersManager.swift
1 //
2 //  SearchViewFiltersManager.swift
3 //  WolneLektury
4 //
5 //  Created by Pawel Dabrowski on 16/06/2018.
6 //  Copyright © 2018 Fundacja Nowoczesna Polska. All rights reserved.
7 //
8
9 import UIKit
10
11 protocol SearchFiltersManagerDelegate: class {
12     func searchFiltersManagerFiltersChanged(reloadData: Bool)
13 }
14
15 class SearchFiltersManager: NSObject{
16     
17     init(delegate: SearchFiltersManagerDelegate) {
18         self.delegate = delegate
19     }
20     
21     weak var delegate: SearchFiltersManagerDelegate?
22     
23     enum FilterType{
24         case onlyLectures
25         case hasAudiobook
26         case epochs
27         case kinds
28         case genres
29     }
30     
31     lazy var onlyLecturesCategory : CategoryModel = {
32         var mdl = CategoryModel()
33         mdl.name = "only_lecture".localized
34         mdl.slug = "only_lectures_slug"
35         mdl.checked = false
36         return mdl
37     }()
38
39     lazy var hasAudiobookCategory : CategoryModel = {
40         var mdl = CategoryModel()
41         mdl.name = "has_audiobook".localized
42         mdl.slug = "has_audiobook_slug"
43         mdl.checked = false
44         return mdl
45     }()
46
47     var selectedKindsArray = [CategoryModel]()
48     var selectedEpochsArray = [CategoryModel]()
49     var selectedGenresArray = [CategoryModel]()
50     
51     func numberOfFilters() -> Int{
52         return (onlyLecturesCategory.checked ? 1 : 0) + (hasAudiobookCategory.checked ? 1 : 0) + selectedKindsArray.count + selectedGenresArray.count + selectedEpochsArray.count
53     }
54     
55     func removeFilter(atIndex: Int) {
56         
57         if let obj = getFilterTypeAndIndex(forIndex: atIndex){
58                 
59             print("removeFilter getFilterType \(obj.0) AndIndex \(obj.1)")
60             switch obj.0{
61             case .onlyLectures:
62                 onlyLecturesCategory.checked = false
63             case .hasAudiobook:
64                 hasAudiobookCategory.checked = false
65             case .kinds:
66                 print("remove selectedKindsArray.count: \(selectedKindsArray.count), index: \(obj.1)")
67                 selectedKindsArray.remove(at: obj.1)
68             case .epochs:
69                 print("remove selectedEpochsArray.count: \(selectedEpochsArray.count), index: \(obj.1)")
70                 selectedEpochsArray.remove(at: obj.1)
71             case .genres:
72                 print("remove selectedGenresArray.count: \(selectedGenresArray.count), index: \(obj.1)")
73                 selectedGenresArray.remove(at: obj.1)
74             }
75         }
76     }
77     
78     func getFilterArrayAndIndex(forIndex: Int) -> ([CategoryModel], Int)? {
79         if let obj = getFilterTypeAndIndex(forIndex: forIndex){
80             print("FilterArrayAndIndex getFilterType \(obj.0) AndIndex \(obj.1)")
81
82             switch obj.0{
83             case .onlyLectures:
84                 return ([onlyLecturesCategory], 0)
85             case .hasAudiobook:
86                 return ([hasAudiobookCategory], 0)
87             case .kinds:
88                 print("selectedKindsArray.count: \(selectedKindsArray.count), index: \(obj.1)")
89                 return (selectedKindsArray, obj.1)
90             case .epochs:
91                 print("selectedEpochsArray.count: \(selectedEpochsArray.count), index: \(obj.1)")
92                 return (selectedEpochsArray, obj.1)
93             case .genres:
94                 print("selectedGenresArray.count: \(selectedGenresArray.count), index: \(obj.1)")
95                 return (selectedGenresArray, obj.1)
96             }
97         }
98         return nil
99     }
100     
101     func getFilterTypeAndIndex(forIndex: Int) -> (FilterType, Int)? {
102         
103         var index = forIndex
104         if onlyLecturesCategory.checked{
105             if forIndex == 0{
106                 return (.onlyLectures, 0)
107             }
108             else{
109                 index -= 1
110             }
111         }
112         
113         if hasAudiobookCategory.checked {
114             if forIndex == 0 || (forIndex == 1 && onlyLecturesCategory.checked){
115                 return (.hasAudiobook, 0)
116             }
117             else {
118                 index -= 1
119             }
120         }
121         
122         if index < selectedEpochsArray.count{
123             return (.epochs, index)
124         }
125         else if index < (selectedEpochsArray.count + selectedKindsArray.count){
126             return (.kinds, index - selectedEpochsArray.count)
127         }
128         else if index < (selectedEpochsArray.count + selectedKindsArray.count + selectedGenresArray.count){
129             return (.genres, index - selectedEpochsArray.count - selectedKindsArray.count )
130         }
131
132         return nil
133     }
134     
135     func getFilter(forIndex: Int) -> CategoryModel? {
136         
137         if let obj = getFilterArrayAndIndex(forIndex: forIndex){
138             return obj.0[obj.1]
139         }
140         return nil
141     }
142     
143     func getFilterForApi(filterType: FilterType) -> String? {
144         
145         var value: String = ""
146         switch filterType {
147         case .onlyLectures:
148             return onlyLecturesCategory.slug
149         case .hasAudiobook:
150             return hasAudiobookCategory.slug
151         case .epochs:
152             value = selectedEpochsArray.map({$0.slug}).joined(separator: ",")
153         case .genres:
154             value = selectedGenresArray.map({$0.slug}).joined(separator: ",")
155         case .kinds:
156             value = selectedKindsArray.map({$0.slug}).joined(separator: ",")
157         }
158         
159         return value.count > 0 ? value : nil
160     }
161     
162     func getParametersForApi() -> FilterBooksParameters {
163         let params = FilterBooksParameters()
164         params.epochs = getFilterForApi(filterType: .epochs)
165         params.genres = getFilterForApi(filterType: .genres)
166         params.kinds = getFilterForApi(filterType: .kinds)
167         params.onlyLectures = onlyLecturesCategory.checked
168         params.hasAudiobook = hasAudiobookCategory.checked
169
170         return params
171     }
172     
173     func clearFilters() {
174         selectedKindsArray = [CategoryModel]()
175         selectedEpochsArray = [CategoryModel]()
176         selectedGenresArray = [CategoryModel]()
177         onlyLecturesCategory.checked = false
178         hasAudiobookCategory.checked = false
179         delegate?.searchFiltersManagerFiltersChanged(reloadData: true)
180     }
181 }
182
183 extension SearchFiltersManager: UICollectionViewDataSource{
184     
185     func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int{
186         let numerOfFilters = numberOfFilters()
187         print("numerOfFilters += \(numerOfFilters)")
188         return numerOfFilters
189     }
190     
191     func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell{
192         
193         let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SearchFilterCollectionViewCell", for: indexPath) as! SearchFilterCollectionViewCell
194         print("beforeGetFilter")
195         if let filter = getFilter(forIndex: indexPath.row){
196             cell.setup(categoryModel: filter)
197         }
198         print("afterGetFilter")
199         return cell
200     }
201 }
202
203 extension SearchFiltersManager: UICollectionViewDelegate{
204     
205     func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
206         print("didSelectItems.row += \(indexPath.row)")
207         
208         removeFilter(atIndex: indexPath.row)
209         collectionView.deleteItems(at: [indexPath])
210         
211         delegate?.searchFiltersManagerFiltersChanged(reloadData: numberOfFilters() == 0)
212     }
213 }
214
215 extension SearchFiltersManager: UICollectionViewDelegateFlowLayout {
216     func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
217         var size = CGSize(width: 200, height: 44)
218         if let filter = getFilter(forIndex: indexPath.row){
219             
220             size.width = filter.name.sizeOf(UIFont.systemFont(ofSize: 10, weight: .medium)).width + 14 + 35
221         }
222         return size
223     }
224 }