[NUI] Change GetDefaultWindow() to static func (#900)
[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 }