/*
 * Copyright 2013 gitblit.com.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.gitblit.wicket.pages;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import org.apache.wicket.Component;
import org.apache.wicket.PageParameters;
import org.apache.wicket.behavior.SimpleAttributeModifier;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.markup.repeater.data.ListDataProvider;

import com.gitblit.Constants.AccessPermission;
import com.gitblit.Keys;
import com.gitblit.models.RegistrantAccessPermission;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.TicketModel;
import com.gitblit.models.TicketModel.Status;
import com.gitblit.models.UserModel;
import com.gitblit.tickets.QueryBuilder;
import com.gitblit.tickets.QueryResult;
import com.gitblit.tickets.TicketIndexer.Lucene;
import com.gitblit.tickets.TicketLabel;
import com.gitblit.tickets.TicketMilestone;
import com.gitblit.tickets.TicketResponsible;
import com.gitblit.utils.ArrayUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.TicketsUI;
import com.gitblit.wicket.TicketsUI.TicketQuery;
import com.gitblit.wicket.TicketsUI.TicketSort;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.LinkPanel;
import com.gitblit.wicket.panels.TicketListPanel;
import com.gitblit.wicket.panels.TicketSearchForm;

public class TicketsPage extends RepositoryPage {

	final TicketResponsible any;

	public TicketsPage(PageParameters params) {
		super(params);

		if (!app().tickets().isReady()) {
			// tickets prohibited
			setResponsePage(SummaryPage.class, WicketUtils.newRepositoryParameter(repositoryName));
		} else if (!app().tickets().hasTickets(getRepositoryModel())) {
			// no tickets for this repository
			setResponsePage(NoTicketsPage.class, WicketUtils.newRepositoryParameter(repositoryName));
		} else {
			String id = WicketUtils.getObject(params);
			if (id != null) {
				// view the ticket with the TicketPage
				setResponsePage(TicketPage.class, params);
			}
		}

		// set stateless page preference
		setStatelessHint(true);

		any = new TicketResponsible(getString("gb.any"), "[* TO *]", null);

		UserModel user = GitBlitWebSession.get().getUser();
		boolean isAuthenticated = user != null && user.isAuthenticated;

		final String [] statiiParam = params.getStringArray(Lucene.status.name());
		final String assignedToParam = params.getString(Lucene.responsible.name(), null);
		final String milestoneParam = params.getString(Lucene.milestone.name(), null);
		final String queryParam = params.getString("q", null);
		final String searchParam = params.getString("s", null);
		final String sortBy = Lucene.fromString(params.getString("sort", Lucene.created.name())).name();
		final boolean desc = !"asc".equals(params.getString("direction", "desc"));

		// add search form
		add(new TicketSearchForm("ticketSearchForm", repositoryName, searchParam, getClass(), params));

		final String activeQuery;
		if (!StringUtils.isEmpty(searchParam)) {
			activeQuery = searchParam;
		} else if (StringUtils.isEmpty(queryParam)) {
			activeQuery = "";
		} else {
			activeQuery = queryParam;
		}

		// build Lucene query from defaults and request parameters
		QueryBuilder qb = new QueryBuilder(queryParam);
		if (!qb.containsField(Lucene.rid.name())) {
			// specify the repository
			qb.and(Lucene.rid.matches(getRepositoryModel().getRID()));
		}
		if (!qb.containsField(Lucene.responsible.name())) {
			// specify the responsible
			qb.and(Lucene.responsible.matches(assignedToParam));
		}
		if (!qb.containsField(Lucene.milestone.name())) {
			// specify the milestone
			qb.and(Lucene.milestone.matches(milestoneParam));
		}
		if (!qb.containsField(Lucene.status.name()) && !ArrayUtils.isEmpty(statiiParam)) {
			// specify the states
			boolean not = false;
			QueryBuilder q = new QueryBuilder();
			for (String state : statiiParam) {
				if (state.charAt(0) == '!') {
					not = true;
					q.and(Lucene.status.doesNotMatch(state.substring(1)));
				} else {
					q.or(Lucene.status.matches(state));
				}
			}
			if (not) {
				qb.and(q.toString());
			} else {
				qb.and(q.toSubquery().toString());
			}
		}
		final String luceneQuery = qb.build();

		// open milestones
		List<TicketMilestone> milestones = app().tickets().getMilestones(getRepositoryModel(), Status.Open);
		TicketMilestone currentMilestone = null;
		if (!StringUtils.isEmpty(milestoneParam)) {
			for (TicketMilestone tm : milestones) {
				if (tm.name.equals(milestoneParam)) {
					// get the milestone (queries the index)
					currentMilestone = app().tickets().getMilestone(getRepositoryModel(), milestoneParam);
					break;
				}
			}

			if (currentMilestone == null) {
				// milestone not found, create a temporary one
				currentMilestone = new TicketMilestone(milestoneParam);
				String q = QueryBuilder.q(Lucene.rid.matches(getRepositoryModel().getRID())).and(Lucene.milestone.matches(milestoneParam)).build();
				currentMilestone.tickets = app().tickets().queryFor(q, 1, 0, Lucene.number.name(), true);
				milestones.add(currentMilestone);
			}
		}

		Fragment milestonePanel;
		if (currentMilestone == null) {
			milestonePanel = new Fragment("milestonePanel", "noMilestoneFragment", this);
			add(milestonePanel);
		} else {
			milestonePanel = new Fragment("milestonePanel", "milestoneProgressFragment", this);
			milestonePanel.add(new Label("currentMilestone", currentMilestone.name));
			if (currentMilestone.due == null) {
				milestonePanel.add(new Label("currentDueDate", getString("gb.notSpecified")));
			} else {
				milestonePanel.add(WicketUtils.createDateLabel("currentDueDate", currentMilestone.due, GitBlitWebSession
						.get().getTimezone(), getTimeUtils(), false));
			}
			Label label = new Label("progress");
			WicketUtils.setCssStyle(label, "width:" + currentMilestone.getProgress() + "%;");
			milestonePanel.add(label);

			milestonePanel.add(new LinkPanel("openTickets", null,
					MessageFormat.format(getString("gb.nOpenTickets"), currentMilestone.getOpenTickets()),
					TicketsPage.class,
					queryParameters(null, currentMilestone.name, TicketsUI.openStatii, null, sortBy, desc, 1)));

			milestonePanel.add(new LinkPanel("closedTickets", null,
					MessageFormat.format(getString("gb.nClosedTickets"), currentMilestone.getClosedTickets()),
					TicketsPage.class,
					queryParameters(null, currentMilestone.name, TicketsUI.closedStatii, null, sortBy, desc, 1)));

			milestonePanel.add(new Label("totalTickets", MessageFormat.format(getString("gb.nTotalTickets"), currentMilestone.getTotalTickets())));
			add(milestonePanel);
		}

		Fragment milestoneDropdown = new Fragment("milestoneDropdown", "milestoneDropdownFragment", this);
		PageParameters resetMilestone = queryParameters(queryParam, null, statiiParam, assignedToParam, sortBy, desc, 1);
		milestoneDropdown.add(new BookmarkablePageLink<Void>("resetMilestone", TicketsPage.class, resetMilestone));

		ListDataProvider<TicketMilestone> milestonesDp = new ListDataProvider<TicketMilestone>(milestones);
		DataView<TicketMilestone> milestonesMenu = new DataView<TicketMilestone>("milestone", milestonesDp) {
			private static final long serialVersionUID = 1L;

			@Override
			public void populateItem(final Item<TicketMilestone> item) {
				final TicketMilestone tm = item.getModelObject();
				PageParameters params = queryParameters(queryParam, tm.name, statiiParam, assignedToParam, sortBy, desc, 1);
				item.add(new LinkPanel("milestoneLink", null, tm.name, TicketsPage.class, params).setRenderBodyOnly(true));
			}
		};
		milestoneDropdown.add(milestonesMenu);
		milestonePanel.add(milestoneDropdown);

		// search or query tickets
		int page = Math.max(1,  WicketUtils.getPage(params));
		int pageSize = app().settings().getInteger(Keys.tickets.perPage, 25);
		List<QueryResult> results;
		if (StringUtils.isEmpty(searchParam)) {
			results = app().tickets().queryFor(luceneQuery, page, pageSize, sortBy, desc);
		} else {
			results = app().tickets().searchFor(getRepositoryModel(), searchParam, page, pageSize);
		}
		int totalResults = results.size() == 0 ? 0 : results.get(0).totalResults;

		// standard queries
		add(new BookmarkablePageLink<Void>("changesQuery", TicketsPage.class,
				queryParameters(
						Lucene.type.matches(TicketModel.Type.Proposal.name()),
						milestoneParam,
						statiiParam,
						assignedToParam,
						sortBy,
						desc,
						1)));

		add(new BookmarkablePageLink<Void>("bugsQuery", TicketsPage.class,
				queryParameters(
						Lucene.type.matches(TicketModel.Type.Bug.name()),
						milestoneParam,
						statiiParam,
						assignedToParam,
						sortBy,
						desc,
						1)));

		add(new BookmarkablePageLink<Void>("enhancementsQuery", TicketsPage.class,
				queryParameters(
						Lucene.type.matches(TicketModel.Type.Enhancement.name()),
						milestoneParam,
						statiiParam,
						assignedToParam,
						sortBy,
						desc,
						1)));

		add(new BookmarkablePageLink<Void>("tasksQuery", TicketsPage.class,
				queryParameters(
						Lucene.type.matches(TicketModel.Type.Task.name()),
						milestoneParam,
						statiiParam,
						assignedToParam,
						sortBy,
						desc,
						1)));

		add(new BookmarkablePageLink<Void>("questionsQuery", TicketsPage.class,
				queryParameters(
						Lucene.type.matches(TicketModel.Type.Question.name()),
						milestoneParam,
						statiiParam,
						assignedToParam,
						sortBy,
						desc,
						1)));
		
		add(new BookmarkablePageLink<Void>("maintenanceQuery", TicketsPage.class,
				queryParameters(
						Lucene.type.matches(TicketModel.Type.Maintenance.name()),
						milestoneParam,
						statiiParam,
						assignedToParam,
						sortBy,
						desc,
						1)));

		add(new BookmarkablePageLink<Void>("resetQuery", TicketsPage.class,
				queryParameters(
						null,
						milestoneParam,
						TicketsUI.openStatii,
						null,
						null,
						true,
						1)));

		if (isAuthenticated) {
			add(new Label("userDivider"));
			add(new BookmarkablePageLink<Void>("createdQuery", TicketsPage.class,
					queryParameters(
							Lucene.createdby.matches(user.username),
							milestoneParam,
							statiiParam,
							assignedToParam,
							sortBy,
							desc,
							1)));

			add(new BookmarkablePageLink<Void>("watchedQuery", TicketsPage.class,
					queryParameters(
							Lucene.watchedby.matches(user.username),
							milestoneParam,
							statiiParam,
							assignedToParam,
							sortBy,
							desc,
							1)));
			add(new BookmarkablePageLink<Void>("mentionsQuery", TicketsPage.class,
					queryParameters(
							Lucene.mentions.matches(user.username),
							milestoneParam,
							statiiParam,
							assignedToParam,
							sortBy,
							desc,
							1)));
		} else {
			add(new Label("userDivider").setVisible(false));
			add(new Label("createdQuery").setVisible(false));
			add(new Label("watchedQuery").setVisible(false));
			add(new Label("mentionsQuery").setVisible(false));
		}

		Set<TicketQuery> dynamicQueries = new TreeSet<TicketQuery>();
		for (TicketLabel label : app().tickets().getLabels(getRepositoryModel())) {
			String q = QueryBuilder.q(Lucene.labels.matches(label.name)).build();
			dynamicQueries.add(new TicketQuery(label.name, q).color(label.color));
		}

		for (QueryResult ticket : results) {
			if (!StringUtils.isEmpty(ticket.topic)) {
				String q = QueryBuilder.q(Lucene.topic.matches(ticket.topic)).build();
				dynamicQueries.add(new TicketQuery(ticket.topic, q));
			}

			if (!ArrayUtils.isEmpty(ticket.labels)) {
				for (String label : ticket.labels) {
					String q = QueryBuilder.q(Lucene.labels.matches(label)).build();
					dynamicQueries.add(new TicketQuery(label, q));
				}
			}
		}

		if (dynamicQueries.size() == 0) {
			add(new Label("dynamicQueries").setVisible(false));
		} else {
			Fragment fragment = new Fragment("dynamicQueries", "dynamicQueriesFragment", this);
			ListDataProvider<TicketQuery> dynamicQueriesDp = new ListDataProvider<TicketQuery>(new ArrayList<TicketQuery>(dynamicQueries));
			DataView<TicketQuery> dynamicQueriesList = new DataView<TicketQuery>("dynamicQuery", dynamicQueriesDp) {
				private static final long serialVersionUID = 1L;

				@Override
				public void populateItem(final Item<TicketQuery> item) {
					final TicketQuery tq = item.getModelObject();
					Component swatch = new Label("swatch", "&nbsp;").setEscapeModelStrings(false);
					if (StringUtils.isEmpty(tq.color)) {
						// calculate a color
						tq.color = StringUtils.getColor(tq.name);
					}
					String background = MessageFormat.format("background-color:{0};", tq.color);
					swatch.add(new SimpleAttributeModifier("style", background));
					item.add(swatch);
					if (activeQuery.contains(tq.query)) {
						// selected
						String q = QueryBuilder.q(activeQuery).remove(tq.query).build();
						PageParameters params = queryParameters(q, milestoneParam, statiiParam, assignedToParam, sortBy, desc, 1);
						item.add(new LinkPanel("link", "active", tq.name, TicketsPage.class, params).setRenderBodyOnly(true));
						Label checked = new Label("checked");
						WicketUtils.setCssClass(checked, "iconic-o-x");
						item.add(checked);
						item.add(new SimpleAttributeModifier("style", background));
					} else {
						// unselected
						String q = QueryBuilder.q(queryParam).toSubquery().and(tq.query).build();
						PageParameters params = queryParameters(q, milestoneParam, statiiParam, assignedToParam, sortBy, desc, 1);
						item.add(new LinkPanel("link", null, tq.name, TicketsPage.class, params).setRenderBodyOnly(true));
						item.add(new Label("checked").setVisible(false));
					}
				}
			};
			fragment.add(dynamicQueriesList);
			add(fragment);
		}

		// states
		if (ArrayUtils.isEmpty(statiiParam)) {
			add(new Label("selectedStatii", getString("gb.all")));
		} else {
			add(new Label("selectedStatii", StringUtils.flattenStrings(Arrays.asList(statiiParam), ",")));
		}
		add(new BookmarkablePageLink<Void>("openTickets", TicketsPage.class, queryParameters(queryParam, milestoneParam, TicketsUI.openStatii, assignedToParam, sortBy, desc, 1)));
		add(new BookmarkablePageLink<Void>("closedTickets", TicketsPage.class, queryParameters(queryParam, milestoneParam, TicketsUI.closedStatii, assignedToParam, sortBy, desc, 1)));
		add(new BookmarkablePageLink<Void>("allTickets", TicketsPage.class, queryParameters(queryParam, milestoneParam, null, assignedToParam, sortBy, desc, 1)));

		// by status
		List<Status> statii = new ArrayList<Status>(Arrays.asList(Status.values()));
		statii.remove(Status.Closed);
		ListDataProvider<Status> resolutionsDp = new ListDataProvider<Status>(statii);
		DataView<Status> statiiLinks = new DataView<Status>("statii", resolutionsDp) {
			private static final long serialVersionUID = 1L;

			@Override
			public void populateItem(final Item<Status> item) {
				final Status status = item.getModelObject();
				PageParameters p = queryParameters(queryParam, milestoneParam, new String [] { status.name().toLowerCase() }, assignedToParam, sortBy, desc, 1);
				String css = TicketsUI.getStatusClass(status);
				item.add(new LinkPanel("statusLink", css, status.toString(), TicketsPage.class, p).setRenderBodyOnly(true));
			}
		};
		add(statiiLinks);

		// responsible filter
		List<TicketResponsible> responsibles = new ArrayList<TicketResponsible>();
		for (RegistrantAccessPermission perm : app().repositories().getUserAccessPermissions(getRepositoryModel())) {
			if (perm.permission.atLeast(AccessPermission.PUSH)) {
				UserModel u = app().users().getUserModel(perm.registrant);
				responsibles.add(new TicketResponsible(u));
			}
		}
		Collections.sort(responsibles);
		responsibles.add(0, any);

		TicketResponsible currentResponsible = null;
		for (TicketResponsible u : responsibles) {
			if (u.username.equals(assignedToParam)) {
				currentResponsible = u;
				break;
			}
		}

		add(new Label("currentResponsible", currentResponsible == null ? "" : currentResponsible.displayname));
		ListDataProvider<TicketResponsible> responsibleDp = new ListDataProvider<TicketResponsible>(responsibles);
		DataView<TicketResponsible> responsibleMenu = new DataView<TicketResponsible>("responsible", responsibleDp) {
			private static final long serialVersionUID = 1L;

			@Override
			public void populateItem(final Item<TicketResponsible> item) {
				final TicketResponsible u = item.getModelObject();
				PageParameters params = queryParameters(queryParam, milestoneParam, statiiParam, u.username, sortBy, desc, 1);
				item.add(new LinkPanel("responsibleLink", null, u.displayname, TicketsPage.class, params).setRenderBodyOnly(true));
			}
		};
		add(responsibleMenu);
		PageParameters resetResponsibleParams = queryParameters(queryParam, milestoneParam, statiiParam, null, sortBy, desc, 1);
		add(new BookmarkablePageLink<Void>("resetResponsible", TicketsPage.class, resetResponsibleParams));

		List<TicketSort> sortChoices = new ArrayList<TicketSort>();
		sortChoices.add(new TicketSort(getString("gb.sortNewest"), Lucene.created.name(), true));
		sortChoices.add(new TicketSort(getString("gb.sortOldest"), Lucene.created.name(), false));
		sortChoices.add(new TicketSort(getString("gb.sortMostRecentlyUpdated"), Lucene.updated.name(), true));
		sortChoices.add(new TicketSort(getString("gb.sortLeastRecentlyUpdated"), Lucene.updated.name(), false));
		sortChoices.add(new TicketSort(getString("gb.sortMostComments"), Lucene.comments.name(), true));
		sortChoices.add(new TicketSort(getString("gb.sortLeastComments"), Lucene.comments.name(), false));
		sortChoices.add(new TicketSort(getString("gb.sortMostPatchsetRevisions"), Lucene.patchsets.name(), true));
		sortChoices.add(new TicketSort(getString("gb.sortLeastPatchsetRevisions"), Lucene.patchsets.name(), false));
		sortChoices.add(new TicketSort(getString("gb.sortMostVotes"), Lucene.votes.name(), true));
		sortChoices.add(new TicketSort(getString("gb.sortLeastVotes"), Lucene.votes.name(), false));
		sortChoices.add(new TicketSort(getString("gb.sortHighestPriority"), Lucene.priority.name(), true));
		sortChoices.add(new TicketSort(getString("gb.sortLowestPriority"), Lucene.priority.name(), false));
		sortChoices.add(new TicketSort(getString("gb.sortHighestSeverity"), Lucene.severity.name(), true));
		sortChoices.add(new TicketSort(getString("gb.sortLowestSeverity"), Lucene.severity.name(), false));
		
		TicketSort currentSort = sortChoices.get(0);
		for (TicketSort ts : sortChoices) {
			if (ts.sortBy.equals(sortBy) && desc == ts.desc) {
				currentSort = ts;
				break;
			}
		}
		add(new Label("currentSort", currentSort.name));

		ListDataProvider<TicketSort> sortChoicesDp = new ListDataProvider<TicketSort>(sortChoices);
		DataView<TicketSort> sortMenu = new DataView<TicketSort>("sort", sortChoicesDp) {
			private static final long serialVersionUID = 1L;

			@Override
			public void populateItem(final Item<TicketSort> item) {
				final TicketSort ts = item.getModelObject();
				PageParameters params = queryParameters(queryParam, milestoneParam, statiiParam, assignedToParam, ts.sortBy, ts.desc, 1);
				item.add(new LinkPanel("sortLink", null, ts.name, TicketsPage.class, params).setRenderBodyOnly(true));
			}
		};
		add(sortMenu);


		// paging links
		buildPager(queryParam, milestoneParam, statiiParam, assignedToParam, sortBy, desc, page, pageSize, results.size(), totalResults);

		add(new TicketListPanel("ticketList", results, false, false));

		// new milestone link
		RepositoryModel repositoryModel = getRepositoryModel();
		final boolean acceptingUpdates = app().tickets().isAcceptingTicketUpdates(repositoryModel)
				 && user != null && user.canAdmin(getRepositoryModel());
		if (acceptingUpdates) {
			add(new LinkPanel("newMilestone", null, getString("gb.newMilestone"),
				NewMilestonePage.class, WicketUtils.newRepositoryParameter(repositoryName)));
		} else {
			add(new Label("newMilestone").setVisible(false));
		}

		// milestones list
		List<TicketMilestone> openMilestones = new ArrayList<TicketMilestone>();
		List<TicketMilestone> closedMilestones = new ArrayList<TicketMilestone>();
		for (TicketMilestone milestone : app().tickets().getMilestones(repositoryModel)) {
			if (milestone.isOpen()) {
				openMilestones.add(milestone);
			} else {
				closedMilestones.add(milestone);
			}
		}
		Collections.sort(openMilestones, new Comparator<TicketMilestone>() {
			@Override
			public int compare(TicketMilestone o1, TicketMilestone o2) {
				return o2.due.compareTo(o1.due);
			}
		});

		Collections.sort(closedMilestones, new Comparator<TicketMilestone>() {
			@Override
			public int compare(TicketMilestone o1, TicketMilestone o2) {
				return o2.due.compareTo(o1.due);
			}
		});

		DataView<TicketMilestone> openMilestonesList = milestoneList("openMilestonesList", openMilestones, acceptingUpdates);
		add(openMilestonesList);

		DataView<TicketMilestone> closedMilestonesList = milestoneList("closedMilestonesList", closedMilestones, acceptingUpdates);
		add(closedMilestonesList);
	}

	protected DataView<TicketMilestone> milestoneList(String wicketId, List<TicketMilestone> milestones, final boolean acceptingUpdates) {
		ListDataProvider<TicketMilestone> milestonesDp = new ListDataProvider<TicketMilestone>(milestones);
		DataView<TicketMilestone> milestonesList = new DataView<TicketMilestone>(wicketId, milestonesDp) {
			private static final long serialVersionUID = 1L;

			@Override
			public void populateItem(final Item<TicketMilestone> item) {
				Fragment entryPanel = new Fragment("entryPanel", "milestoneListFragment", this);
				item.add(entryPanel);

				final TicketMilestone tm = item.getModelObject();
				String [] states;
				if (tm.isOpen()) {
					states = TicketsUI.openStatii;
				} else {
					states = TicketsUI.closedStatii;
				}
				PageParameters params = queryParameters(null, tm.name, states, null, null, true, 1);
				entryPanel.add(new LinkPanel("milestoneName", null, tm.name, TicketsPage.class, params).setRenderBodyOnly(true));

				String css;
				String status = tm.status.name();
				switch (tm.status) {
				case Open:
					if (tm.isOverdue()) {
						css = "aui-lozenge aui-lozenge-subtle aui-lozenge-error";
						status = "overdue";
					} else {
						css = "aui-lozenge aui-lozenge-subtle";
					}
					break;
				default:
					css = "aui-lozenge";
					break;
				}
				Label stateLabel = new Label("milestoneState", status);
				WicketUtils.setCssClass(stateLabel, css);
				entryPanel.add(stateLabel);

				if (tm.due == null) {
					entryPanel.add(new Label("milestoneDue", getString("gb.notSpecified")));
				} else {
					entryPanel.add(WicketUtils.createDatestampLabel("milestoneDue", tm.due, getTimeZone(), getTimeUtils()));
				}
				if (acceptingUpdates) {
					entryPanel.add(new LinkPanel("editMilestone", null, getString("gb.edit"), EditMilestonePage.class,
						WicketUtils.newObjectParameter(repositoryName, tm.name)));
				} else {
					entryPanel.add(new Label("editMilestone").setVisible(false));
				}

				if (tm.isOpen()) {
					// re-load milestone with query results
					TicketMilestone m = app().tickets().getMilestone(getRepositoryModel(), tm.name);

					Fragment milestonePanel = new Fragment("milestonePanel", "openMilestoneFragment", this);
					Label label = new Label("progress");
					WicketUtils.setCssStyle(label, "width:" + m.getProgress() + "%;");
					milestonePanel.add(label);

					milestonePanel.add(new LinkPanel("openTickets", null,
							MessageFormat.format(getString("gb.nOpenTickets"), m.getOpenTickets()),
							TicketsPage.class,
							queryParameters(null, tm.name, TicketsUI.openStatii, null, null, true, 1)));

					milestonePanel.add(new LinkPanel("closedTickets", null,
							MessageFormat.format(getString("gb.nClosedTickets"), m.getClosedTickets()),
							TicketsPage.class,
							queryParameters(null, tm.name, TicketsUI.closedStatii, null, null, true, 1)));

					milestonePanel.add(new Label("totalTickets", MessageFormat.format(getString("gb.nTotalTickets"), m.getTotalTickets())));
					entryPanel.add(milestonePanel);
				} else {
					entryPanel.add(new Label("milestonePanel").setVisible(false));
				}
			}
		};
		return milestonesList;
	}

	protected PageParameters queryParameters(
			String query,
			String milestone,
			String[] states,
			String assignedTo,
			String sort,
			boolean descending,
			int page) {

		PageParameters params = WicketUtils.newRepositoryParameter(repositoryName);
		if (!StringUtils.isEmpty(query)) {
			params.add("q", query);
		}
		if (!StringUtils.isEmpty(milestone)) {
			params.add(Lucene.milestone.name(), milestone);
		}
		if (!ArrayUtils.isEmpty(states)) {
			for (String state : states) {
				params.add(Lucene.status.name(), state);
			}
		}
		if (!StringUtils.isEmpty(assignedTo)) {
			params.add(Lucene.responsible.name(), assignedTo);
		}
		if (!StringUtils.isEmpty(sort)) {
			params.add("sort", sort);
		}
		if (!descending) {
			params.add("direction", "asc");
		}
		if (page > 1) {
			params.add("pg", "" + page);
		}
		return params;
	}

	protected PageParameters newTicketParameter(QueryResult ticket) {
		return WicketUtils.newObjectParameter(repositoryName, "" + ticket.number);
	}

	@Override
	protected String getPageName() {
		return getString("gb.tickets");
	}

	protected void buildPager(
			final String query,
			final String milestone,
			final String [] states,
			final String assignedTo,
			final String sort,
			final boolean desc,
			final int page,
			int pageSize,
			int count,
			int total) {

		boolean showNav = total > (2 * pageSize);
		boolean allowPrev = page > 1;
		boolean allowNext = (pageSize * (page - 1) + count) < total;
		add(new BookmarkablePageLink<Void>("prevLink", TicketsPage.class, queryParameters(query, milestone, states, assignedTo, sort, desc, page - 1)).setEnabled(allowPrev).setVisible(showNav));
		add(new BookmarkablePageLink<Void>("nextLink", TicketsPage.class, queryParameters(query, milestone, states, assignedTo, sort, desc, page + 1)).setEnabled(allowNext).setVisible(showNav));

		if (total <= pageSize) {
			add(new Label("pageLink").setVisible(false));
			return;
		}

		// determine page numbers to display
		int pages = count == 0 ? 0 : ((total / pageSize) + (total % pageSize == 0 ? 0 : 1));
		// preferred number of pagelinks
		int segments = 5;
		if (pages < segments) {
			// not enough data for preferred number of page links
			segments = pages;
		}
		int minpage = Math.min(Math.max(1, page - 2), pages - (segments - 1));
		int maxpage = Math.min(pages, minpage + (segments - 1));
		List<Integer> sequence = new ArrayList<Integer>();
		for (int i = minpage; i <= maxpage; i++) {
			sequence.add(i);
		}

		ListDataProvider<Integer> pagesDp = new ListDataProvider<Integer>(sequence);
		DataView<Integer> pagesView = new DataView<Integer>("pageLink", pagesDp) {
			private static final long serialVersionUID = 1L;

			@Override
			public void populateItem(final Item<Integer> item) {
				final Integer i = item.getModelObject();
				LinkPanel link = new LinkPanel("page", null, "" + i, TicketsPage.class, queryParameters(query, milestone, states, assignedTo, sort, desc, i));
				link.setRenderBodyOnly(true);
				if (i == page) {
					WicketUtils.setCssClass(item, "active");
				}
				item.add(link);
			}
		};
		add(pagesView);
	}
}
