1/* This file is part of Gradio.
2 *
3 * Gradio is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * Gradio is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with Gradio.  If not, see <http://www.gnu.org/licenses/>.
15 */
16
17using Gtk;
18
19namespace Gradio{
20
21	[GtkTemplate (ui = "/de/haecker-felix/gradio/ui/page/search-page.ui")]
22	public class SearchPage : Gtk.Box, Page{
23		[GtkChild] private Box ResultsBox;
24		[GtkChild] private Label ResultsLabel;
25		[GtkChild] private Box SearchBox;
26		[GtkChild] private Stack SearchStack;
27		[GtkChild] private Stack SectionStack;
28		private SearchBar searchbar;
29
30		private StationModel search_station_model;
31		private StationProvider search_station_provider;
32
33		[GtkChild] private Frame MostVotesFrame;
34		[GtkChild] private Frame RecentlyClickedFrame;
35		[GtkChild] private Frame MostClicksFrame;
36
37		private MainBox search_mainbox;
38		private MainBox most_votes_mainbox;
39		private MainBox recently_clicked_mainbox;
40		private MainBox most_clicks_mainbox;
41
42		public SearchPage(){
43			search_station_model =  new StationModel();
44			search_station_provider = new StationProvider(ref search_station_model);
45
46			search_station_provider.ready.connect(() => {
47				if(search_station_model.get_n_items() == 0){
48					SearchStack.set_visible_child_name("no-results");
49				}else{
50					SearchStack.set_visible_child_name("results");
51				}
52				ResultsLabel.set_text(search_station_model.get_n_items().to_string());
53			});
54
55			searchbar = new Gradio.SearchBar(ref search_station_provider);
56			searchbar.timeout_reset.connect(() => {SearchStack.set_visible_child_name("loading");});
57			searchbar.show_search_results.connect(show_search);
58			searchbar.BackButton.clicked.connect(show_discover);
59			SearchBox.add(searchbar);
60
61			setup_discover_section();
62			setup_search_section();
63		}
64
65		private void setup_discover_section(){
66			HashTable<string, string> filter_table = new HashTable<string, string> (str_hash, str_equal);
67
68			most_votes_mainbox = new MainBox();
69			recently_clicked_mainbox = new MainBox();
70			most_clicks_mainbox = new MainBox();
71
72			StationModel most_votes_model = new StationModel();
73			StationModel recently_clicked_model = new StationModel();
74			StationModel most_clicks_model = new StationModel();
75
76			StationProvider most_votes_provider = new StationProvider(ref most_votes_model);
77			StationProvider recently_clicked_provider = new StationProvider(ref recently_clicked_model);
78			StationProvider most_clicks_provider = new StationProvider(ref most_clicks_model);
79
80			most_votes_provider.get_stations.begin(RadioBrowser.most_votes(14), filter_table);
81			recently_clicked_provider.get_stations.begin(RadioBrowser.recently_clicked(14), filter_table);
82			most_clicks_provider.get_stations.begin(RadioBrowser.most_clicks(14), filter_table);
83
84			most_votes_mainbox.set_model(most_votes_model);
85			recently_clicked_mainbox.set_model(recently_clicked_model);
86			most_clicks_mainbox.set_model(most_clicks_model);
87
88			most_votes_mainbox.set_show_secondary_text(false);
89			recently_clicked_mainbox.set_show_secondary_text(false);
90			most_clicks_mainbox.set_show_secondary_text(false);
91
92			MostVotesFrame.add(most_votes_mainbox);
93			RecentlyClickedFrame.add(recently_clicked_mainbox);
94			MostClicksFrame.add(most_clicks_mainbox);
95
96			most_votes_mainbox.selection_changed.connect(() => {selection_changed();});
97			recently_clicked_mainbox.selection_changed.connect(() => {selection_changed();});
98			most_clicks_mainbox.selection_changed.connect(() => {selection_changed();});
99
100			most_votes_mainbox.selection_mode_request.connect(() => {selection_mode_enabled();});
101			recently_clicked_mainbox.selection_mode_request.connect(() => {selection_mode_enabled();});
102			most_clicks_mainbox.selection_mode_request.connect(() => {selection_mode_enabled();});
103		}
104
105		private void setup_search_section(){
106			search_mainbox = new MainBox();
107			search_mainbox.set_model(search_station_model);
108			search_mainbox.selection_changed.connect(() => {selection_changed();});
109			search_mainbox.selection_mode_request.connect(() => {selection_mode_enabled();});
110			ResultsBox.add(search_mainbox);
111		}
112
113		private void show_search(){
114			SectionStack.set_visible_child_name("search");
115			searchbar.BackButton.set_visible(true);
116		}
117
118		private void show_discover(){
119			SectionStack.set_visible_child_name("discover");
120			searchbar.BackButton.set_visible(false);
121		}
122
123		public void set_search(string term){
124			searchbar.set_search(term);
125		}
126
127		public void set_selection_mode(bool b){
128			search_mainbox.set_selection_mode(b);
129			most_clicks_mainbox.set_selection_mode(b);
130			recently_clicked_mainbox.set_selection_mode(b);
131			most_votes_mainbox.set_selection_mode(b);
132			SearchBox.set_visible(!b);
133		}
134
135		public void select_all(){
136			if(SectionStack.get_visible_child_name() == "discover"){
137				most_clicks_mainbox.select_all();
138				recently_clicked_mainbox.select_all();
139				most_votes_mainbox.select_all();
140			}
141
142			if(SectionStack.get_visible_child_name() == "search"){
143				search_mainbox.select_all();
144			}
145		}
146
147		public void select_none(){
148			search_mainbox.unselect_all();
149			most_clicks_mainbox.unselect_all();
150			recently_clicked_mainbox.unselect_all();
151			most_votes_mainbox.unselect_all();
152		}
153
154		public StationModel get_selection(){
155			StationModel model = new StationModel();
156
157			List<Gd.MainBoxItem> selection = search_mainbox.get_selection();
158			List<Gd.MainBoxItem> most_clicks_selection = most_clicks_mainbox.get_selection();
159			List<Gd.MainBoxItem> recently_clicked_selection = recently_clicked_mainbox.get_selection();
160			List<Gd.MainBoxItem> most_votes_selection = most_votes_mainbox.get_selection();
161
162			foreach(Gd.MainBoxItem item in most_clicks_selection) model.add_item(item);
163			foreach(Gd.MainBoxItem item in recently_clicked_selection) model.add_item(item);
164			foreach(Gd.MainBoxItem item in most_votes_selection) model.add_item(item);
165			foreach(Gd.MainBoxItem item in selection) model.add_item(item);
166
167			return model;
168		}
169
170		public string get_title(){
171			return _("Search");
172		}
173
174		[GtkCallback]
175		private void MostVotesButton_clicked(){
176			searchbar.reset_filters();
177			searchbar.set_sort("votes", "descending");
178			show_search();
179		}
180
181		[GtkCallback]
182		private void RecentlyClickedButton_clicked(){
183			searchbar.reset_filters();
184			searchbar.set_sort("clicktimestamp", "descending");
185			show_search();
186		}
187
188		[GtkCallback]
189		private void MostClicksButton_clicked(){
190			searchbar.reset_filters();
191			searchbar.set_sort("clicks", "descending");
192			show_search();
193		}
194	}
195}
196
197
198