f79b72c28e2b9e61567938b0dbd7d641558860c4
[profile/tv/apps/dotnet/home.git] / TVHome / TVHome / ViewModels / MainPageViewModel.cs
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using System.Collections.Generic;
19 using System.ComponentModel;
20 using System.Linq;
21 using LibTVRefCommonPortable.DataModels;
22 using LibTVRefCommonPortable.Utils;
23 using Xamarin.Forms;
24
25 namespace TVHome.ViewModels
26 {
27     /// <summary>
28     /// A HomeStatus type enumeration
29     /// </summary>
30     public enum HomeStatus
31     {
32         Default = 0,
33         MainPanelFocused,
34         SubPanelFocused,
35         UnPin,
36         Move,
37     };
38
39     /// <summary>
40     /// A HomeMenuItem type enumeration
41     /// </summary>
42     public enum HomeMenuItem
43     {
44         Recent = 0,
45         Apps,
46         Settings,
47         NotSelected,
48     };
49
50     /// <summary>
51     /// A class for ViewModel of TV Home
52     /// </summary>
53     public class MainPageViewModel : INotifyPropertyChanged, IHomeViewModel
54     {
55         /// <summary>
56         /// Gets or set MainList for MainPanel
57         /// </summary>
58         public IEnumerable<ShortcutInfo> MainList { get; set; }
59         /// <summary>
60         /// Gets or set RecentList for Recent SubPanel
61         /// </summary>
62         public IEnumerable<ShortcutInfo> RecentList { get; set; }
63         /// <summary>
64         /// Gets or set AppList for Apps SubPanel
65         /// </summary>
66         public IEnumerable<ShortcutInfo> AppList { get; set; }
67         /// <summary>
68         /// Gets or set SettingsList for Settings SubPanel
69         /// </summary>
70         public IEnumerable<ShortcutInfo> SettingsList { get; set; }
71
72         /// <summary>
73         /// A command for executing when MainPanel is focused.
74         /// </summary>
75         public Command MainPanelFocusedCommand { get; set; }
76         /// <summary>
77         /// A command for executing when SubPanel is focused.
78         /// </summary>
79         public Command SubPanelFocusedCommand { get; set; }
80         /// <summary>
81         /// A command for changing the status to Move status
82         /// </summary>
83         public Command SetMoveStatusCommand { get; set; }
84         /// <summary>
85         /// A command for changing the status to Unpin status
86         /// </summary>
87         public Command SetUnpinStatusCommand { get; set; }
88
89         public Command OnMoveCommand { get; set; }
90         public Command OnUnpinCommand { get; set; }
91         public Command OnClearCommand { get; set; }
92         public Command OnClearAllCommand { get; set; }
93
94         /// <summary>
95         /// Gets or set CurrentStatus of HomeStatus
96         /// </summary>
97         public HomeStatus CurrentStatus { get; private set; }
98         /// <summary>
99         /// Gets or set SelectedMenuName of HomeMenuItem
100         /// </summary>
101         public HomeMenuItem SelectedMenuName { get; private set; }
102
103         /// <summary>
104         /// A flag indicates whether "No recent info" in Recent SubPanel to be displayed or not
105         /// </summary>
106         public bool IsShowNoRecentContents { get; set; }
107
108         /// <summary>
109         /// A event that is occurred when property of MainPageViewModel is changed
110         /// </summary>
111         public event PropertyChangedEventHandler PropertyChanged;
112
113         /// <summary>
114         /// Main panel icon's width
115         /// </summary>
116         public int MainPanelIconWidth
117         {
118             get
119             {
120                 return SizeUtils.GetWidthSize(236);
121             }
122         }
123
124         /// <summary>
125         /// Sub panel's padding size
126         /// </summary>
127         public Thickness SubPanelPadding
128         {
129             get
130             {
131                 int lr = SizeUtils.GetWidthSize(74);
132                 return new Thickness(lr, 0, lr, SizeUtils.GetWidthSize(26));
133             }
134         }
135
136         /// <summary>
137         /// Sub panel's spacing size
138         /// </summary>
139         public int SubPanelSpacing
140         {
141             get
142             {
143                 // TODO : set proper size
144                 return SizeUtils.GetWidthSize(34);
145             }
146         }
147
148         /// <summary>
149         /// Information text font size.
150         /// </summary>
151         public int NoContentInformationFontSize
152         {
153             get
154             {
155                 return SizeUtils.GetFontSize(28);
156             }
157         }
158
159         /// <summary>
160         /// Sub thumbnail panel's padding size
161         /// </summary>
162         public Thickness SubThumbNailPanelPadding
163         {
164             get
165             {
166                 return new Thickness(SizeUtils.GetHeightSize(223), SizeUtils.GetWidthSize(32));
167             }
168         }
169
170         /// <summary>
171         /// Constructor
172         /// Initialize MainPanel, SubPanel, Command and EventListeners
173         /// </summary>
174         public MainPageViewModel()
175         {
176             // Init sequence
177             // MainPage ( MainPageViewModel -> MainPanel -> SubPanel )
178             MakeMainMenuItems();
179             InitStatus();
180             InitCommands();
181             SetDefaultAppList();
182             MakeSettingsButtons();
183
184             UpdateAppList(null, null);
185
186             TVHomeImpl.GetInstance.AppShortcutControllerInstance.AddFileSystemChangedListener(UpdateAppList);
187
188             App.SetAppPinnedNotificationListener((s, e) =>
189             {
190                 // TODO : Make this for Move a pinned app/Show pinned apps(scroll to last)
191                 ChangeCurrentStatus(HomeStatus.SubPanelFocused);
192                 ChangeSelectedPanelName(HomeMenuItem.Apps);
193                 if (e.arg.Length > 0)
194                 {
195                     DebuggingUtils.Dbg("Move, AppID : " + e.arg);
196                 }
197                 else
198                 {
199                     DebuggingUtils.Dbg("Show, Pinned Apps");
200                 }
201             });
202
203             MessagingCenter.Subscribe<App, TVHomeStatus>(this, App.AppStatus, (sender, arg) =>
204             {
205                 switch (arg)
206                 {
207                     case TVHomeStatus.OnResume:
208                         MakeRecentButtons();
209                         break;
210                     case TVHomeStatus.OnSleep:
211                         ChangeCurrentStatus(HomeStatus.Default, true);
212                         break;
213                 }
214             });
215         }
216
217         /// <summary>
218         /// A method for initializing HomeStatus to Default
219         /// </summary>
220         private void InitStatus()
221         {
222             ChangeCurrentStatus(HomeStatus.Default, true);
223         }
224
225         /// <summary>
226         /// A method for initializing commands
227         /// </summary>
228         private void InitCommands()
229         {
230             MainPanelFocusedCommand = new Command<HomeMenuItem>((key) =>
231             {
232                 DebuggingUtils.Dbg(key.ToString());
233                 ChangeCurrentStatus(HomeStatus.MainPanelFocused);
234                 ChangeSelectedPanelName(key);
235             });
236
237             SubPanelFocusedCommand = new Command(() =>
238             {
239                 ChangeCurrentStatus(HomeStatus.SubPanelFocused);
240             });
241
242             SetMoveStatusCommand = new Command(() =>
243             {
244                 ChangeCurrentStatus(HomeStatus.Move);
245             });
246
247             SetUnpinStatusCommand = new Command(() =>
248             {
249                 ChangeCurrentStatus(HomeStatus.UnPin);
250             });
251
252             OnMoveCommand = new Command<List<View>>((moveList) =>
253             {
254                 MoveAppShortcutInfo(moveList);
255             });
256
257             OnUnpinCommand = new Command<string>((appId) =>
258             {
259                 UnpinAppShortcutInfo(appId);
260             });
261
262             OnClearCommand = new Command<string>((appId) =>
263             {
264                 RemoveRecentApplication(appId);
265             });
266
267             OnClearAllCommand = new Command(() =>
268             {
269                 ClearAllRecentApplications();
270             });
271         }
272
273         /// <summary>
274         /// A method for makeing MainMenu items and display in MainPanel
275         /// </summary>
276         private void MakeMainMenuItems()
277         {
278             string[] AppName = { "Recent", "Apps", "Settings" };
279             // TODO : Revert this before release
280             //string[] AppControlID = { "org.tizen.settings", "org.tizen.apps", "org.tizen.settings" };
281             string[] AppControlID = { "org.tizen.xaapps", "org.tizen.xaapps", "org.tizen.settings" };
282             string[] AppIconPath =
283                 {
284                 "ic_tizen_home_menu_{0}_normal.png",
285                 "ic_tizen_home_menu_{0}_focused.png",
286                 "ic_tizen_home_menu_{0}_selected.png",
287                 "ic_tizen_home_menu_{0}_unselect.png"
288             };
289
290             List<ShortcutInfo> TempList = new List<ShortcutInfo>();
291             for (int i = 0; i < AppName.Length; i++)
292             {
293                 AppControlAction appControlAction = new AppControlAction()
294                 {
295                     AppID = AppControlID[i]
296                 };
297
298                 ShortcutInfo shortcutInfo = new HomeMenuAppShortcutInfo()
299                 {
300                     StateDescriptions =
301                     {
302                         {
303                             "default",
304                             new StateDescription
305                             {
306                                 Label = AppName[i],
307                                 IconPath = String.Format(AppIconPath[0], AppName[i].ToLower()),
308                                 Action = appControlAction,
309                             }
310                         },
311                         {
312                             "focused",
313                             new StateDescription
314                             {
315                                 Label = AppName[i],
316                                 IconPath = String.Format(AppIconPath[1], AppName[i].ToLower()),
317                                 Action = appControlAction,
318                             }
319                         },
320                         {
321                             "selected",
322                             new StateDescription
323                             {
324                                 Label = AppName[i],
325                                 IconPath = String.Format(AppIconPath[2], AppName[i].ToLower()),
326                                 Action = appControlAction,
327                             }
328                         },
329                         {
330                             "unselect",
331                             new StateDescription
332                             {
333                                 Label = AppName[i],
334                                 IconPath = String.Format(AppIconPath[3], AppName[i].ToLower()),
335                                 Action = appControlAction,
336                             }
337                         },
338                     },
339                 };
340                 shortcutInfo.UpdateState();
341                 TempList.Add(shortcutInfo);
342             }
343
344             MainList = TempList;
345             OnPropertyChanged("MainList");
346         }
347
348         /// <summary>
349         /// Gets default AppList for displaying items and updates the list to Apps SubPanel
350         /// </summary>
351         private void SetDefaultAppList()
352         {
353             AppList = TVHomeImpl.GetInstance.AppShortcutControllerInstance.GetDefaultShortcuts();
354             OnPropertyChanged("AppList");
355         }
356
357         /// <summary>
358         /// Gets the AppList for displaying items and updates the list to Apps SubPanel
359         /// </summary>
360         /// <param name="sender">The source of event</param>
361         /// <param name="e">The event that is occurred pinned app file is changed</param>
362         private async void UpdateAppList(object sender, EventArgs e)
363         {
364             AppList = await TVHomeImpl.GetInstance.AppShortcutControllerInstance.GetPinnedAppsWithDefaultShortcuts();
365             OnPropertyChanged("AppList");
366         }
367
368         /// <summary>
369         /// Gets the SettingsList for displaying items and updates the list to Settings SubPanel
370         /// </summary>
371         private void MakeSettingsButtons()
372         {
373             string[] ShortCutLabel = { "Brightness", "Contrast", "Color", "Tint" };
374             string[] shortCutActionID = { "org.tizen.settings", "org.tizen.settings", "org.tizen.settings", "org.tizen.settings" };
375
376             List<ShortcutInfo> TempList = new List<ShortcutInfo>();
377
378             ShortcutInfo Settings = new SettingShortcutInfo()
379             {
380                 StateDescriptions =
381                 {
382                     {
383                         "default",
384                         new StateDescription
385                         {
386                             Label = "All Settings",
387                             IconPath = "ic_home_settings_all_138.png",
388                             Action = new AppControlAction()
389                             {
390                                 AppID = "org.tizen.settings"
391                             }
392                         }
393                     },
394                     {
395                         "focused",
396                         new StateDescription
397                         {
398                             Label = "All Settings",
399                             IconPath = "ic_home_settings_all_182.png",
400                             Action = new AppControlAction()
401                             {
402                                 AppID = "org.tizen.settings"
403                             }
404                         }
405                     },
406                 }
407             };
408             Settings.UpdateState();
409             TempList.Add(Settings);
410
411             for (int i = 0; i < ShortCutLabel.Length; i++)
412             {
413                 AppControlAction appControlAction = new AppControlAction()
414                 {
415                     AppID = shortCutActionID[i]
416                 };
417
418                 ShortcutInfo shortcutInfo = new SettingShortcutInfo()
419                 {
420                     StateDescriptions =
421                     {
422                         {
423                             "default",
424                             new StateDescription
425                             {
426                                 Label = ShortCutLabel[i],
427                                 IconPath = "ic_home_settings_" + ShortCutLabel[i].ToLower() + "_138.png",
428                                 Action = appControlAction,
429                             }
430                         },
431                         {
432                             "focused",
433                             new StateDescription
434                             {
435                                 Label = ShortCutLabel[i],
436                                 IconPath = "ic_home_settings_" + ShortCutLabel[i].ToLower() + "_182.png",
437                                 Action = appControlAction,
438                             }
439                         },
440                     },
441                 };
442                 shortcutInfo.UpdateState();
443                 TempList.Add(shortcutInfo);
444             }
445
446             SettingsList = TempList;
447             OnPropertyChanged("SettingsList");
448         }
449
450         /// <summary>
451         /// Gets the RecentList for displaying items and updates the list to Recent SubPanel
452         /// </summary>
453         private void MakeRecentButtons()
454         {
455             RecentList = TVHomeImpl.GetInstance.RecentShortcutControllerInstance.GetList();
456             if (RecentList.Count<ShortcutInfo>() > 0)
457             {
458                 IsShowNoRecentContents = false;
459                 OnPropertyChanged("RecentList");
460             }
461             else
462             {
463                 IsShowNoRecentContents = true;
464             }
465
466             OnPropertyChanged("IsShowNoRecentContents");
467         }
468
469         /// <summary>
470         /// Clears all recent applications and updates the list to Recent SubPanel
471         /// </summary>
472         private void ClearAllRecentApplications()
473         {
474             TVHomeImpl.GetInstance.RecentShortcutControllerInstance.RemoveAll();
475             MakeRecentButtons();
476         }
477
478         /// <summary>
479         /// Removes specified recent application and updates the list to Recent SubPanel
480         /// </summary>
481         /// <param name="appId">A application ID</param>
482         private void RemoveRecentApplication(string appId)
483         {
484             TVHomeImpl.GetInstance.RecentShortcutControllerInstance.Remove(appId);
485             MakeRecentButtons();
486         }
487
488         /// <summary>
489         /// A method for invoking PropertyChanged event
490         /// </summary>
491         /// <param name="name">The name of property</param>
492         public void OnPropertyChanged(string name)
493         {
494             PropertyChangedEventHandler handler = PropertyChanged;
495             if (handler != null)
496             {
497                 handler(this, new PropertyChangedEventArgs(name));
498             }
499         }
500
501         /// <summary>
502         /// A method for changing CurrentStatus according to parameter
503         /// </summary>
504         /// <param name="newStatus">The next status name</param>
505         /// <param name="isForceUpdate">A flag indicates whether CurrentStatus to be changed or not</param>
506         public void ChangeCurrentStatus(HomeStatus newStatus, bool isForceUpdate = false)
507         {
508             if (isForceUpdate ||
509                 CurrentStatus.CompareTo(newStatus) != 0)
510             {
511                 CurrentStatus = newStatus;
512                 if (CurrentStatus.CompareTo(HomeStatus.Default) == 0)
513                 {
514                     foreach (HomeMenuAppShortcutInfo item in MainList)
515                     {
516                         if (item.CurrentStateDescription.Label.CompareTo("Apps") == 0)
517                         {
518                             DebuggingUtils.Dbg(item.CurrentStateDescription.Label + " To Focused");
519                             item.ChangeStatus("focused");
520                         }
521                         else
522                         {
523                             DebuggingUtils.Dbg(item.CurrentStateDescription.Label + " To Default");
524                             item.ChangeStatus("default");
525                         }
526                     }
527
528                     ChangeSelectedPanelName(HomeMenuItem.Apps, isForceUpdate);
529                 }
530                 else if (CurrentStatus.CompareTo(HomeStatus.MainPanelFocused) == 0)
531                 {
532                     HomeMenuItem index = HomeMenuItem.Recent;
533                     foreach (HomeMenuAppShortcutInfo item in MainList)
534                     {
535                         if (index == SelectedMenuName)
536                         {
537                             DebuggingUtils.Dbg(index.ToString() + " To Focused");
538                             item.ChangeStatus("focused");
539                         }
540                         else
541                         {
542                             DebuggingUtils.Dbg(index.ToString() + " To Default");
543                             item.ChangeStatus("default");
544                         }
545
546                         index++;
547                     }
548                 }
549                 else if (CurrentStatus.CompareTo(HomeStatus.SubPanelFocused) == 0)
550                 {
551                     HomeMenuItem index = HomeMenuItem.Recent;
552                     foreach (HomeMenuAppShortcutInfo item in MainList)
553                     {
554                         if (index == SelectedMenuName)
555                         {
556                             DebuggingUtils.Dbg(index.ToString() + " To be selected");
557                             item.ChangeStatus("selected");
558                         }
559                         else
560                         {
561                             DebuggingUtils.Dbg(index.ToString() + " To be unselect");
562                             item.ChangeStatus("unselect");
563                         }
564
565                         index++;
566                     }
567                 }
568
569                 OnPropertyChanged("CurrentStatus");
570             }
571         }
572
573         /// <summary>
574         /// A method for changing selected HomeMenuItem according to parameter
575         /// </summary>
576         /// <param name="panelName">Selected menu name in MainPanel</param>
577         /// <param name="isForceUpdate">A flag indicates whether selected menu name to be changed or not</param>
578         public void ChangeSelectedPanelName(HomeMenuItem panelName, bool isForceUpdate = false)
579         {
580             if (isForceUpdate ||
581                 SelectedMenuName.CompareTo(panelName) != 0)
582             {
583                 SelectedMenuName = panelName;
584                 HomeMenuItem index = HomeMenuItem.Recent;
585                 foreach (HomeMenuAppShortcutInfo item in MainList)
586                 {
587                     if (index == panelName)
588                     {
589                         DebuggingUtils.Dbg(index.ToString() + " To Focused");
590                         item.ChangeStatus("focused");
591                     }
592                     else
593                     {
594                         DebuggingUtils.Dbg(index.ToString() + " To Default");
595                         item.ChangeStatus("default");
596                     }
597
598                     index++;
599                 }
600
601                 OnPropertyChanged("SelectedMenuName");
602             }
603         }
604
605         private void UnpinAppShortcutInfo(string appId)
606         {
607             RemovePinnedApp(appId);
608         }
609
610         private void UpdatePinnedApps(Dictionary<string, string> pinnedApps)
611         {
612             List<AppShortcutInfo> pinnedAppList = new List<AppShortcutInfo>();
613             foreach (var item in pinnedApps)
614             {
615                 pinnedAppList.Add(new AppShortcutInfo()
616                 {
617                     AppID = item.Key,
618                 });
619             }
620
621             TVHomeImpl.GetInstance.AppShortcutControllerInstance.UpdatePinnedApps(pinnedAppList);
622         }
623
624         private async void RemovePinnedApp(string appID)
625         {
626             Dictionary<string, string> PinnedApps = await TVHomeImpl.GetInstance.AppShortcutControllerInstance.GetPinnedAppsAppIDs();
627             if (PinnedApps.ContainsKey(appID))
628             {
629                 PinnedApps.Remove(appID);
630                 UpdatePinnedApps(PinnedApps);
631                 return;
632             }
633         }
634
635         private void MoveAppShortcutInfo(List<View> moveList)
636         {
637             List<AppShortcutInfo> pinnedAppList = new List<AppShortcutInfo>();
638             AppShortcutInfo appShortcut;
639
640             foreach (var item in moveList)
641             {
642                 appShortcut = (AppShortcutInfo)item.BindingContext;
643                 if (appShortcut.AppID != null && appShortcut.AppID.Length > 0)
644                 {
645                     pinnedAppList.Add(new AppShortcutInfo()
646                     {
647                         AppID = appShortcut.AppID,
648                     });
649                 }
650             }
651
652             TVHomeImpl.GetInstance.AppShortcutControllerInstance.UpdatePinnedApps(pinnedAppList);
653         }
654     }
655 }