1 /*
2  * Entity - Entity is an object-relational mapping tool for the D programming language. Referring to the design idea of JPA.
3  *
4  * Copyright (C) 2015-2018  Shanghai Putao Technology Co., Ltd
5  *
6  * Developer: HuntLabs.cn
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module hunt.entity.domain.Page;
13 
14 import hunt.entity.domain.Pageable;
15 import hunt.entity.domain.Sort;
16 
17 class Page(T)
18 {
19 	T[] 		_content;
20 	Pageable	_pageable;
21 	long		_total;
22 
23 	struct PageModel
24 	{
25 		int previous;
26 		int current;
27 		int next;
28 		int[] pages;
29 		int size;
30 		long totalElements;
31 		int totalPages;
32 	}
33 
34 	this(T []content ,
35 	Pageable pageable ,
36 	long total)
37 	{
38 		_content = content;
39 		_pageable = pageable;
40 		_total = total;
41 	}
42 
43 	int getNumber()
44 	{
45 		return _pageable.getPageNumber();
46 	}
47 
48 	int getSize()
49 	{
50 		return _pageable.getPageSize();
51 	}
52 
53 	int getTotalPages()
54 	{
55 		return cast(int)(_total / getSize() + (_total % getSize() == 0 ? 0 : 1));
56 	}
57 
58 	int getNumberOfElements()
59 	{
60 		return cast(int)_content.length;
61 	}
62 
63 	long getTotalElements()
64 	{
65 		return _total;
66 	}
67 
68 	bool hasPreviousPage()
69 	{
70 		return getNumber() > 0;
71 	}
72 
73 	bool isFirstPage()
74 	{
75 		return getNumber() == 0;
76 	}
77 
78 	bool hasNextPage()
79 	{
80 		return getNumber() < getTotalPages() - 1;
81 	}
82 
83 	bool isLastPage()
84 	{
85 		return getNumber() == getTotalPages() - 1;
86 	}
87 
88 	T[] getContent()
89 	{
90 		return _content;
91 	}
92 
93 	bool hasContent()
94 	{
95 		return _content.length > 0 ;
96 	}
97 
98 	Sort getSort()
99 	{
100 		return _pageable.getSort();
101 	}
102 
103 	PageModel getModel(int num = 5)
104 	{
105 		if(num < 2)
106 		{
107 			num = 3;
108 		}
109 		if(num%2 == 0)
110 		{
111 			num++;
112 		}
113 		PageModel pm;
114 
115 		pm.current = this.getNumber() + 1;
116 		if (this.hasNextPage())
117 		{
118 			pm.next = pm.current + 1;
119 		}
120 
121 		if (this.hasPreviousPage())
122 		{
123 			pm.previous = pm.current - 1;
124 		}
125 
126 		pm.size = this.getSize();
127 		pm.totalPages = this.getTotalPages();
128 		if(pm.totalPages < pm.current)
129 		{
130 			pm.current = pm.totalPages;
131 		}
132 		pm.totalElements = this.getTotalElements();
133 
134 		if(pm.totalPages <= (num*2+1))
135 		{
136 			for(int i = 1; i <= pm.totalPages; i++)
137 			{
138 				pm.pages ~= i;
139 			}
140 		}else{
141 			int half = cast(int)(num/2);
142 			int[] pages;
143 			int[] firsts;
144 			int[] lefts;
145 			int[] rights;
146 			int[] lasts;
147 			if(pm.current - num >= half)
148 			{
149 				for(int i = 1; i <= half; i++)
150 				{
151 					firsts ~= i;
152 				}
153 				if(firsts.length > 0)
154 				{
155 					firsts ~= 0;
156 				}
157 			}
158 
159 			for(int i = pm.current - (num - cast(int)firsts.length); i < pm.current; i++)
160 			{
161 				if(i > 0)
162 				{
163 					lefts ~= i;
164 				}
165 			}
166 
167 			if(pm.current + num < pm.totalPages)
168 			{
169 				lasts ~= 0;
170 				for(int i = (pm.totalPages - half) + 1; i <= pm.totalPages; i++)
171 				{
172 					lasts ~= i;
173 				}
174 			}
175 
176 			for(int i = pm.current + 1; i <= pm.current + (num - cast(int)lasts.length); i++)
177 			{
178 				if(i <= pm.totalPages)
179 				{
180 					rights ~= i;
181 				}
182 			}
183 			if(pm.current <= half)
184 			{
185 				rights = [];
186 				for(int i = pm.current + 1; i <= num; i++)
187 				{
188 					rights ~= i;
189 				}
190 			}
191 			if(pm.totalPages - pm.current <= half)
192 			{
193 				lefts = [];
194 				for(int i = pm.totalPages - num + 1; i < pm.current; i++)
195 				{
196 					lefts ~= i;
197 				}
198 			}
199 			pm.pages ~= firsts;
200 			pm.pages ~= lefts;
201 			pm.pages ~= pm.current;
202 			pm.pages ~= rights;
203 			pm.pages ~= lasts;
204 		}
205 		return pm;
206 	}
207 }