dbb6d3fa74eb733d138960fb5552dad644d27b15
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / internal / XamlBinding / NavigationModel.cs
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Linq;
5
6 namespace Tizen.NUI.Binding
7 {
8         [EditorBrowsable(EditorBrowsableState.Never)]
9         internal class NavigationModel
10         {
11                 readonly List<Page> _modalStack = new List<Page>();
12                 readonly List<List<Page>> _navTree = new List<List<Page>>();
13
14                 public Page CurrentPage
15                 {
16                         get
17                         {
18                                 if (_navTree.Any())
19                                         return _navTree.Last().Last();
20                                 return null;
21                         }
22                 }
23
24                 public IEnumerable<Page> Modals
25                 {
26                         get { return _modalStack; }
27                 }
28
29                 public IEnumerable<Page> Roots
30                 {
31                         get
32                         {
33                                 foreach (List<Page> list in _navTree)
34                                 {
35                                         yield return list[0];
36                                 }
37                         }
38                 }
39
40                 public IReadOnlyList<IReadOnlyList<Page>> Tree
41                 {
42                         get { return _navTree; }
43                 }
44
45                 public void Clear()
46                 {
47                         _navTree.Clear();
48                         _modalStack.Clear();
49                 }
50
51                 public void InsertPageBefore(Page page, Page before)
52                 {
53                         List<Page> currentStack = _navTree.Last();
54                         int index = currentStack.IndexOf(before);
55
56                         if (index == -1)
57                                 throw new ArgumentException("before must be in the current navigation context");
58
59                         currentStack.Insert(index, page);
60                 }
61
62                 public Page Pop(Page ancestralNav)
63                 {
64                         ancestralNav = AncestorToRoot(ancestralNav);
65                         foreach (List<Page> stack in _navTree)
66                         {
67                                 if (stack.Contains(ancestralNav))
68                                 {
69                                         if (stack.Count <= 1)
70                                                 throw new InvalidNavigationException("Can not pop final item in stack");
71                                         Page result = stack.Last();
72                                         stack.Remove(result);
73                                         return result;
74                                 }
75                         }
76
77                         throw new InvalidNavigationException("Popped from unpushed item?");
78                 }
79
80                 public Page PopModal()
81                 {
82                         if (_navTree.Count <= 1)
83                                 throw new InvalidNavigationException("Can't pop modal without any modals pushed");
84                         Page modal = _navTree.Last().First();
85                         _modalStack.Remove(modal);
86                         _navTree.Remove(_navTree.Last());
87                         return modal;
88                 }
89
90                 public Page PopTopPage()
91                 {
92                         Page itemToRemove;
93                         if (_navTree.Count == 1)
94                         {
95                                 if (_navTree[0].Count > 1)
96                                 {
97                                         itemToRemove = _navTree[0].Last();
98                                         _navTree[0].Remove(itemToRemove);
99                                         return itemToRemove;
100                                 }
101                                 return null;
102                         }
103                         itemToRemove = _navTree.Last().Last();
104                         _navTree.Last().Remove(itemToRemove);
105                         if (!_navTree.Last().Any())
106                         {
107                                 _navTree.RemoveAt(_navTree.Count - 1);
108                         }
109                         return itemToRemove;
110                 }
111
112                 public void PopToRoot(Page ancestralNav)
113                 {
114                         ancestralNav = AncestorToRoot(ancestralNav);
115                         foreach (List<Page> stack in _navTree)
116                         {
117                                 if (stack.Contains(ancestralNav))
118                                 {
119                                         if (stack.Count <= 1)
120                                                 throw new InvalidNavigationException("Can not pop final item in stack");
121                                         stack.RemoveRange(1, stack.Count - 1);
122                                         return;
123                                 }
124                         }
125
126                         throw new InvalidNavigationException("Popped from unpushed item?");
127                 }
128
129                 public void Push(Page page, Page ancestralNav)
130                 {
131                         if (ancestralNav == null)
132                         {
133                                 if (_navTree.Any())
134                                         throw new InvalidNavigationException("Ancestor must be provided for all pushes except first");
135                                 _navTree.Add(new List<Page> { page });
136                                 return;
137                         }
138
139                         ancestralNav = AncestorToRoot(ancestralNav);
140
141                         foreach (List<Page> stack in _navTree)
142                         {
143                                 if (stack.Contains(ancestralNav))
144                                 {
145                                         stack.Add(page);
146                                         return;
147                                 }
148                         }
149
150                         throw new InvalidNavigationException("Invalid ancestor passed");
151                 }
152
153                 public void PushModal(Page page)
154                 {
155                         _navTree.Add(new List<Page> { page });
156                         _modalStack.Add(page);
157                 }
158
159                 public bool RemovePage(Page page)
160                 {
161                         bool found;
162                         List<Page> currentStack = _navTree.Last();
163                         var i = 0;
164                         while (!(found = currentStack.Remove(page)) && i < _navTree.Count - 1)
165                         {
166                                 currentStack = _navTree[i++];
167                         }
168
169                         return found;
170                 }
171
172                 Page AncestorToRoot(Page ancestor)
173                 {
174                         Page result = ancestor;
175                         // while (!Application.IsApplicationOrNull(result.RealParent))
176                                 result = (Page)result.RealParent;
177                         return result;
178                 }
179         }
180 }