/*
 * Copyright 2014 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.DateFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.TreeSet;

import javax.servlet.http.HttpServletRequest;

import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.PageParameters;
import org.apache.wicket.RestartResponseException;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.behavior.IBehavior;
import org.apache.wicket.behavior.SimpleAttributeModifier;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.image.ContextImage;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.link.ExternalLink;
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 org.apache.wicket.model.Model;
import org.apache.wicket.protocol.http.WebRequest;
import org.eclipse.jgit.diff.DiffEntry.ChangeType;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;

import com.gitblit.Constants;
import com.gitblit.Constants.AccessPermission;
import com.gitblit.Constants.AuthorizationControl;
import com.gitblit.Keys;
import com.gitblit.git.PatchsetCommand;
import com.gitblit.git.PatchsetReceivePack;
import com.gitblit.models.PathModel.PathChangeModel;
import com.gitblit.models.RegistrantAccessPermission;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.RepositoryUrl;
import com.gitblit.models.SubmoduleModel;
import com.gitblit.models.TicketModel;
import com.gitblit.models.TicketModel.Change;
import com.gitblit.models.TicketModel.CommentSource;
import com.gitblit.models.TicketModel.Field;
import com.gitblit.models.TicketModel.Patchset;
import com.gitblit.models.TicketModel.PatchsetType;
import com.gitblit.models.TicketModel.Review;
import com.gitblit.models.TicketModel.Score;
import com.gitblit.models.TicketModel.Status;
import com.gitblit.models.UserModel;
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.JGitUtils;
import com.gitblit.utils.JGitUtils.MergeStatus;
import com.gitblit.utils.MarkdownUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.utils.TimeUtils;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.TicketsUI;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.BasePanel.JavascriptTextPrompt;
import com.gitblit.wicket.panels.CommentPanel;
import com.gitblit.wicket.panels.DiffStatPanel;
import com.gitblit.wicket.panels.GravatarImage;
import com.gitblit.wicket.panels.IconAjaxLink;
import com.gitblit.wicket.panels.LinkPanel;
import com.gitblit.wicket.panels.ShockWaveComponent;
import com.gitblit.wicket.panels.SimpleAjaxLink;

/**
 * The ticket page handles viewing and updating a ticket.
 *
 * @author James Moger
 *
 */
public class TicketPage extends RepositoryPage {

	static final String NIL = "<nil>";

	static final String ESC_NIL = StringUtils.escapeForHtml(NIL,  false);

	final int avatarWidth = 40;

	final TicketModel ticket;

	public TicketPage(PageParameters params) {
		super(params);

		final UserModel user = GitBlitWebSession.get().getUser() == null ? UserModel.ANONYMOUS : GitBlitWebSession.get().getUser();
		final RepositoryModel repository = getRepositoryModel();
		final String id = WicketUtils.getObject(params);
		long ticketId = Long.parseLong(id);
		ticket = app().tickets().getTicket(repository, ticketId);

		if (ticket == null) {
			// ticket not found
			throw new RestartResponseException(TicketsPage.class, WicketUtils.newRepositoryParameter(repositoryName));
		}

		final List<Change> revisions = new ArrayList<Change>();
		List<Change> comments = new ArrayList<Change>();
		List<Change> statusChanges = new ArrayList<Change>();
		List<Change> discussion = new ArrayList<Change>();
		for (Change change : ticket.changes) {
			if (change.hasComment() || (change.isStatusChange() && (change.getStatus() != Status.New))) {
				discussion.add(change);
			}
			if (change.hasComment()) {
				comments.add(change);
			}
			if (change.hasPatchset()) {
				revisions.add(change);
			}
			if (change.isStatusChange() && !change.hasPatchset()) {
				statusChanges.add(change);
			}
		}

		final Change currentRevision = revisions.isEmpty() ? null : revisions.get(revisions.size() - 1);
		final Patchset currentPatchset = ticket.getCurrentPatchset();

		/*
		 * TICKET HEADER
		 */
		String href = urlFor(TicketsPage.class, params).toString();
		add(new ExternalLink("ticketNumber", href, "#" + ticket.number));
		Label headerStatus = new Label("headerStatus", ticket.status.toString());
		WicketUtils.setCssClass(headerStatus, TicketsUI.getLozengeClass(ticket.status, false));
		add(headerStatus);
		add(new Label("ticketTitle", ticket.title));
		if (currentPatchset == null) {
			add(new Label("diffstat").setVisible(false));
		} else {
			// calculate the current diffstat of the patchset
			add(new DiffStatPanel("diffstat", ticket.insertions, ticket.deletions));
		}


		/*
		 * TAB TITLES
		 */
		add(new Label("commentCount", "" + comments.size()).setVisible(!comments.isEmpty()));
		add(new Label("commitCount", "" + (currentPatchset == null ? 0 : currentPatchset.commits)).setVisible(currentPatchset != null));


		/*
		 * TICKET AUTHOR and DATE (DISCUSSION TAB)
		 */
		UserModel createdBy = app().users().getUserModel(ticket.createdBy);
		if (createdBy == null) {
			add(new Label("whoCreated", ticket.createdBy));
		} else {
			add(new LinkPanel("whoCreated", null, createdBy.getDisplayName(),
					UserPage.class, WicketUtils.newUsernameParameter(createdBy.username)));
		}

		if (ticket.isProposal()) {
			// clearly indicate this is a change ticket
			add(new Label("creationMessage", getString("gb.proposedThisChange")));
		} else {
			// standard ticket
			add(new Label("creationMessage", getString("gb.createdThisTicket")));
		}

		String dateFormat = app().settings().getString(Keys.web.datestampLongFormat, "EEEE, MMMM d, yyyy");
		String timestampFormat = app().settings().getString(Keys.web.datetimestampLongFormat, "EEEE, MMMM d, yyyy");
		final TimeZone timezone = getTimeZone();
		final DateFormat df = new SimpleDateFormat(dateFormat);
		df.setTimeZone(timezone);
		final DateFormat tsf = new SimpleDateFormat(timestampFormat);
		tsf.setTimeZone(timezone);
		final Calendar cal = Calendar.getInstance(timezone);

		String fuzzydate;
		TimeUtils tu = getTimeUtils();
		Date createdDate = ticket.created;
		if (TimeUtils.isToday(createdDate, timezone)) {
			fuzzydate = tu.today();
		} else if (TimeUtils.isYesterday(createdDate, timezone)) {
			fuzzydate = tu.yesterday();
		} else {
			// calculate a fuzzy time ago date
        	cal.setTime(createdDate);
        	cal.set(Calendar.HOUR_OF_DAY, 0);
        	cal.set(Calendar.MINUTE, 0);
        	cal.set(Calendar.SECOND, 0);
        	cal.set(Calendar.MILLISECOND, 0);
        	createdDate = cal.getTime();
			fuzzydate = getTimeUtils().timeAgo(createdDate);
		}
		Label when = new Label("whenCreated", fuzzydate + ", " + df.format(createdDate));
		WicketUtils.setHtmlTooltip(when, tsf.format(ticket.created));
		add(when);

		String exportHref = urlFor(ExportTicketPage.class, params).toString();
		add(new ExternalLink("exportJson", exportHref, "json"));


		/*
		 * RESPONSIBLE (DISCUSSION TAB)
		 */
		if (StringUtils.isEmpty(ticket.responsible)) {
			add(new Label("responsible"));
		} else {
			UserModel responsible = app().users().getUserModel(ticket.responsible);
			if (responsible == null) {
				add(new Label("responsible", ticket.responsible));
			} else {
				add(new LinkPanel("responsible", null, responsible.getDisplayName(),
						UserPage.class, WicketUtils.newUsernameParameter(responsible.username)));
			}
		}

		/*
		 * MILESTONE PROGRESS (DISCUSSION TAB)
		 */
		if (StringUtils.isEmpty(ticket.milestone)) {
			add(new Label("milestone"));
		} else {
			// link to milestone query
			TicketMilestone tm = app().tickets().getMilestone(repository, ticket.milestone);
			if (tm == null) {
				tm = new TicketMilestone(ticket.milestone);
			}
			PageParameters milestoneParameters;
			if (tm.isOpen()) {
				milestoneParameters = WicketUtils.newOpenTicketsParameter(repositoryName);
			} else {
				milestoneParameters = WicketUtils.newRepositoryParameter(repositoryName);
			}
			milestoneParameters.put(Lucene.milestone.name(), ticket.milestone);
			int progress = 0;
			int open = 0;
			int closed = 0;
			if (tm != null) {
				progress = tm.getProgress();
				open = tm.getOpenTickets();
				closed = tm.getClosedTickets();
			}

			Fragment milestoneProgress = new Fragment("milestone", "milestoneProgressFragment", this);
			milestoneProgress.add(new LinkPanel("link", null, ticket.milestone, TicketsPage.class, milestoneParameters));
			Label label = new Label("progress");
			WicketUtils.setCssStyle(label, "width:" + progress + "%;");
			milestoneProgress.add(label);
			WicketUtils.setHtmlTooltip(milestoneProgress, MessageFormat.format(getString("gb.milestoneProgress"), open, closed));
			add(milestoneProgress);
		}


		/*
		 * TICKET DESCRIPTION (DISCUSSION TAB)
		 */
		String desc;
		if (StringUtils.isEmpty(ticket.body)) {
			desc = getString("gb.noDescriptionGiven");
		} else {
			String bugtraq = bugtraqProcessor().processText(getRepository(), repositoryName, ticket.body);
			desc = MarkdownUtils.transformGFM(app().settings(), bugtraq, ticket.repository);
		}
		add(new Label("ticketDescription", desc).setEscapeModelStrings(false));


		/*
		 * PARTICIPANTS (DISCUSSION TAB)
		 */
		if (app().settings().getBoolean(Keys.web.allowGravatar, true)) {
			// gravatar allowed
			List<String> participants = ticket.getParticipants();
			add(new Label("participantsLabel", MessageFormat.format(getString(participants.size() > 1 ? "gb.nParticipants" : "gb.oneParticipant"),
					"<b>" + participants.size() + "</b>")).setEscapeModelStrings(false));
			ListDataProvider<String> participantsDp = new ListDataProvider<String>(participants);
			DataView<String> participantsView = new DataView<String>("participants", participantsDp) {
				private static final long serialVersionUID = 1L;

				@Override
				public void populateItem(final Item<String> item) {
					String username = item.getModelObject();
					UserModel user = app().users().getUserModel(username);
					if (user == null) {
						user = new UserModel(username);
					}
					item.add(new GravatarImage("participant", user.getDisplayName(),
							user.emailAddress, null, 25, true));
				}
			};
			add(participantsView);
		} else {
			// gravatar prohibited
			add(new Label("participantsLabel").setVisible(false));
			add(new Label("participants").setVisible(false));
		}


		/*
		 * LARGE STATUS INDICATOR WITH ICON (DISCUSSION TAB->SIDE BAR)
		 */
		Fragment ticketStatus = new Fragment("ticketStatus", "ticketStatusFragment", this);
		Label ticketIcon = TicketsUI.getStateIcon("ticketIcon", ticket);
		ticketStatus.add(ticketIcon);
		ticketStatus.add(new Label("ticketStatus", ticket.status.toString()));
		WicketUtils.setCssClass(ticketStatus, TicketsUI.getLozengeClass(ticket.status, false));
		add(ticketStatus);


		/*
		 * UPDATE FORM (DISCUSSION TAB)
		 */
		if (user.canEdit(ticket, repository) && app().tickets().isAcceptingTicketUpdates(repository)) {
			if (user.canAdmin(ticket, repository) && ticket.isOpen()) {
				/*
				 * OPEN TICKET
				 */
				Fragment controls = new Fragment("controls", "openControlsFragment", this);

				/*
				 * STATUS
				 */
				List<Status> choices = new ArrayList<Status>();
				if (ticket.isProposal()) {
					choices.addAll(Arrays.asList(TicketModel.Status.proposalWorkflow));
				} else if (ticket.isBug()) {
					choices.addAll(Arrays.asList(TicketModel.Status.bugWorkflow));
				} else {
					choices.addAll(Arrays.asList(TicketModel.Status.requestWorkflow));
				}
				choices.remove(ticket.status);

				ListDataProvider<Status> workflowDp = new ListDataProvider<Status>(choices);
				DataView<Status> statusView = new DataView<Status>("newStatus", workflowDp) {
					private static final long serialVersionUID = 1L;

					@Override
					public void populateItem(final Item<Status> item) {
						SimpleAjaxLink<Status> link = new SimpleAjaxLink<Status>("link", item.getModel()) {

							private static final long serialVersionUID = 1L;

							@Override
							public void onClick(AjaxRequestTarget target) {
								Status status = getModel().getObject();
								Change change = new Change(user.username);
								change.setField(Field.status, status);
								if (!ticket.isWatching(user.username)) {
									change.watch(user.username);
								}
								TicketModel update = app().tickets().updateTicket(repository, ticket.number, change);
								app().tickets().createNotifier().sendMailing(update);
								setResponsePage(TicketsPage.class, getPageParameters());
							}
						};
						String css = TicketsUI.getStatusClass(item.getModel().getObject());
						WicketUtils.setCssClass(link, css);
						item.add(link);
					}
				};
				controls.add(statusView);

				/*
				 * RESPONSIBLE LIST
				 */
				Set<String> userlist = new TreeSet<String>(ticket.getParticipants());
				if (UserModel.ANONYMOUS.canPush(getRepositoryModel())
						|| AuthorizationControl.AUTHENTICATED == getRepositoryModel().authorizationControl) {
					// 	authorization is ANONYMOUS or AUTHENTICATED (i.e. all users can be set responsible)
					userlist.addAll(app().users().getAllUsernames());
				} else {
					// authorization is by NAMED users (users with PUSH permission can be set responsible)
					for (RegistrantAccessPermission rp : app().repositories().getUserAccessPermissions(getRepositoryModel())) {
						if (rp.permission.atLeast(AccessPermission.PUSH)) {
							userlist.add(rp.registrant);
						}
					}
				}
				List<TicketResponsible> responsibles = new ArrayList<TicketResponsible>();
				if (!StringUtils.isEmpty(ticket.responsible)) {
					// exclude the current responsible
					userlist.remove(ticket.responsible);
				}
				for (String username : userlist) {
					UserModel u = app().users().getUserModel(username);
					if (u != null) {
						responsibles.add(new TicketResponsible(u));
					}
				}
				Collections.sort(responsibles);
				responsibles.add(new TicketResponsible(ESC_NIL, "", ""));
				ListDataProvider<TicketResponsible> responsibleDp = new ListDataProvider<TicketResponsible>(responsibles);
				DataView<TicketResponsible> responsibleView = new DataView<TicketResponsible>("newResponsible", responsibleDp) {
					private static final long serialVersionUID = 1L;

					@Override
					public void populateItem(final Item<TicketResponsible> item) {
						SimpleAjaxLink<TicketResponsible> link = new SimpleAjaxLink<TicketResponsible>("link", item.getModel()) {

							private static final long serialVersionUID = 1L;

							@Override
							public void onClick(AjaxRequestTarget target) {
								TicketResponsible responsible = getModel().getObject();
								Change change = new Change(user.username);
								change.setField(Field.responsible, responsible.username);
								if (!StringUtils.isEmpty(responsible.username)) {
									if (!ticket.isWatching(responsible.username)) {
										change.watch(responsible.username);
									}
								}
								if (!ticket.isWatching(user.username)) {
									change.watch(user.username);
								}
								TicketModel update = app().tickets().updateTicket(repository, ticket.number, change);
								app().tickets().createNotifier().sendMailing(update);
								setResponsePage(TicketsPage.class, getPageParameters());
							}
						};
						item.add(link);
					}
				};
				controls.add(responsibleView);

				/*
				 * MILESTONE LIST
				 */
				List<TicketMilestone> milestones = app().tickets().getMilestones(repository, Status.Open);
				if (!StringUtils.isEmpty(ticket.milestone)) {
					for (TicketMilestone milestone : milestones) {
						if (milestone.name.equals(ticket.milestone)) {
							milestones.remove(milestone);
							break;
						}
					}
				}
				milestones.add(new TicketMilestone(ESC_NIL));
				ListDataProvider<TicketMilestone> milestoneDp = new ListDataProvider<TicketMilestone>(milestones);
				DataView<TicketMilestone> milestoneView = new DataView<TicketMilestone>("newMilestone", milestoneDp) {
					private static final long serialVersionUID = 1L;

					@Override
					public void populateItem(final Item<TicketMilestone> item) {
						SimpleAjaxLink<TicketMilestone> link = new SimpleAjaxLink<TicketMilestone>("link", item.getModel()) {

							private static final long serialVersionUID = 1L;

							@Override
							public void onClick(AjaxRequestTarget target) {
								TicketMilestone milestone = getModel().getObject();
								Change change = new Change(user.username);
								if (NIL.equals(milestone.name) || ESC_NIL.equals(milestone.name)) {
									change.setField(Field.milestone, "");
								} else {
									change.setField(Field.milestone, milestone.name);
								}
								if (!ticket.isWatching(user.username)) {
									change.watch(user.username);
								}
								TicketModel update = app().tickets().updateTicket(repository, ticket.number, change);
								app().tickets().createNotifier().sendMailing(update);
								setResponsePage(TicketsPage.class, getPageParameters());
							}
						};
						item.add(link);
					}
				};
				controls.add(milestoneView);

				String editHref = urlFor(EditTicketPage.class, params).toString();
				controls.add(new ExternalLink("editLink", editHref, getString("gb.edit")));

				add(controls);
			} else {
				/*
				 * CLOSED TICKET
				 */
				Fragment controls = new Fragment("controls", "closedControlsFragment", this);

				String editHref = urlFor(EditTicketPage.class, params).toString();
				controls.add(new ExternalLink("editLink", editHref, getString("gb.edit")));

				add(controls);
			}
		} else {
			add(new Label("controls").setVisible(false));
		}


		/*
		 * TICKET METADATA
		 */
		add(new Label("ticketType", ticket.type.toString()));
		if (StringUtils.isEmpty(ticket.topic)) {
			add(new Label("ticketTopic").setVisible(false));
		} else {
			// process the topic using the bugtraq config to link things
			String topic = bugtraqProcessor().processText(getRepository(), repositoryName, ticket.topic);
			add(new Label("ticketTopic", topic).setEscapeModelStrings(false));
		}


		/*
		 * VOTERS
		 */
		List<String> voters = ticket.getVoters();
		Label votersCount = new Label("votes", "" + voters.size());
		if (voters.size() == 0) {
			WicketUtils.setCssClass(votersCount, "badge");
		} else {
			WicketUtils.setCssClass(votersCount, "badge badge-info");
		}
		add(votersCount);
		if (user.isAuthenticated && app().tickets().isAcceptingTicketUpdates(repository)) {
			Model<String> model;
			if (ticket.isVoter(user.username)) {
				model = Model.of(getString("gb.removeVote"));
			} else {
				model = Model.of(MessageFormat.format(getString("gb.vote"), ticket.type.toString()));
			}
			SimpleAjaxLink<String> link = new SimpleAjaxLink<String>("voteLink", model) {

				private static final long serialVersionUID = 1L;

				@Override
				public void onClick(AjaxRequestTarget target) {
					Change change = new Change(user.username);
					if (ticket.isVoter(user.username)) {
						change.unvote(user.username);
					} else {
						change.vote(user.username);
					}
					app().tickets().updateTicket(repository, ticket.number, change);
					setResponsePage(TicketsPage.class, getPageParameters());
				}
			};
			add(link);
		} else {
			add(new Label("voteLink").setVisible(false));
		}


		/*
		 * WATCHERS
		 */
		List<String> watchers = ticket.getWatchers();
		Label watchersCount = new Label("watchers", "" + watchers.size());
		if (watchers.size() == 0) {
			WicketUtils.setCssClass(watchersCount, "badge");
		} else {
			WicketUtils.setCssClass(watchersCount, "badge badge-info");
		}
		add(watchersCount);
		if (user.isAuthenticated && app().tickets().isAcceptingTicketUpdates(repository)) {
			Model<String> model;
			if (ticket.isWatching(user.username)) {
				model = Model.of(getString("gb.stopWatching"));
			} else {
				model = Model.of(MessageFormat.format(getString("gb.watch"), ticket.type.toString()));
			}
			SimpleAjaxLink<String> link = new SimpleAjaxLink<String>("watchLink", model) {

				private static final long serialVersionUID = 1L;

				@Override
				public void onClick(AjaxRequestTarget target) {
					Change change = new Change(user.username);
					if (ticket.isWatching(user.username)) {
						change.unwatch(user.username);
					} else {
						change.watch(user.username);
					}
					app().tickets().updateTicket(repository, ticket.number, change);
					setResponsePage(TicketsPage.class, getPageParameters());
				}
			};
			add(link);
		} else {
			add(new Label("watchLink").setVisible(false));
		}


		/*
		 * TOPIC & LABELS (DISCUSSION TAB->SIDE BAR)
		 */
		ListDataProvider<String> labelsDp = new ListDataProvider<String>(ticket.getLabels());
		DataView<String> labelsView = new DataView<String>("labels", labelsDp) {
			private static final long serialVersionUID = 1L;

			@Override
			public void populateItem(final Item<String> item) {
				final String value = item.getModelObject();
				Label label = new Label("label", value);
				TicketLabel tLabel = app().tickets().getLabel(repository, value);
				String background = MessageFormat.format("background-color:{0};", tLabel.color);
				label.add(new SimpleAttributeModifier("style", background));
				item.add(label);
			}
		};

		add(labelsView);


		/*
		 * COMMENTS & STATUS CHANGES (DISCUSSION TAB)
		 */
		if (comments.size() == 0) {
			add(new Label("discussion").setVisible(false));
		} else {
			Fragment discussionFragment = new Fragment("discussion", "discussionFragment", this);
			ListDataProvider<Change> discussionDp = new ListDataProvider<Change>(discussion);
			DataView<Change> discussionView = new DataView<Change>("discussion", discussionDp) {
				private static final long serialVersionUID = 1L;

				@Override
				public void populateItem(final Item<Change> item) {
					final Change entry = item.getModelObject();
					if (entry.isMerge()) {
						/*
						 * MERGE
						 */
						String resolvedBy = entry.getString(Field.mergeSha);

						// identify the merged patch, it is likely the last
						Patchset mergedPatch = null;
						for (Change c : revisions) {
							if (c.patchset.tip.equals(resolvedBy)) {
								mergedPatch = c.patchset;
								break;
							}
						}

						String commitLink;
						if (mergedPatch == null) {
							// shouldn't happen, but just-in-case
							int len = app().settings().getInteger(Keys.web.shortCommitIdLength, 6);
							commitLink = resolvedBy.substring(0, len);
						} else {
							// expected result
							commitLink = mergedPatch.toString();
						}

						Fragment mergeFragment = new Fragment("entry", "mergeFragment", this);
						mergeFragment.add(new LinkPanel("commitLink", null, commitLink,
								CommitPage.class, WicketUtils.newObjectParameter(repositoryName, resolvedBy)));
						mergeFragment.add(new Label("toBranch", MessageFormat.format(getString("gb.toBranch"),
								"<b>" + ticket.mergeTo + "</b>")).setEscapeModelStrings(false));
						addUserAttributions(mergeFragment, entry, 0);
						addDateAttributions(mergeFragment, entry);

						item.add(mergeFragment);
					} else if (entry.isStatusChange()) {
						/*
						 *  STATUS CHANGE
						 */
						Fragment frag = new Fragment("entry", "statusFragment", this);
						Label status = new Label("statusChange", entry.getStatus().toString());
						String css = TicketsUI.getLozengeClass(entry.getStatus(), false);
						WicketUtils.setCssClass(status, css);
						for (IBehavior b : status.getBehaviors()) {
							if (b instanceof SimpleAttributeModifier) {
								SimpleAttributeModifier sam = (SimpleAttributeModifier) b;
								if ("class".equals(sam.getAttribute())) {
									status.add(new SimpleAttributeModifier("class", "status-change " + sam.getValue()));
									break;
								}
							}
						}
						frag.add(status);
						addUserAttributions(frag, entry, avatarWidth);
						addDateAttributions(frag, entry);
						item.add(frag);
					} else {
						/*
						 * COMMENT
						 */
						String bugtraq = bugtraqProcessor().processText(getRepository(), repositoryName, entry.comment.text);
						String comment = MarkdownUtils.transformGFM(app().settings(), bugtraq, repositoryName);
						Fragment frag = new Fragment("entry", "commentFragment", this);
						Label commentIcon = new Label("commentIcon");
						if (entry.comment.src == CommentSource.Email) {
							WicketUtils.setCssClass(commentIcon, "iconic-mail");
						} else {
							WicketUtils.setCssClass(commentIcon, "iconic-comment-alt2-stroke");
						}
						frag.add(commentIcon);
						frag.add(new Label("comment", comment).setEscapeModelStrings(false));
						addUserAttributions(frag, entry, avatarWidth);
						addDateAttributions(frag, entry);
						item.add(frag);
					}
				}
			};
			discussionFragment.add(discussionView);
			add(discussionFragment);
		}

		/*
		 * ADD COMMENT PANEL
		 */
		if (UserModel.ANONYMOUS.equals(user)
				|| !repository.isBare
				|| repository.isFrozen
				|| repository.isMirror) {

			// prohibit comments for anonymous users, local working copy repos,
			// frozen repos, and mirrors
			add(new Label("newComment").setVisible(false));
		} else {
			// permit user to comment
			Fragment newComment = new Fragment("newComment", "newCommentFragment", this);
			GravatarImage img = new GravatarImage("newCommentAvatar", user.username, user.emailAddress,
					"gravatar-round", avatarWidth, true);
			newComment.add(img);
			CommentPanel commentPanel = new CommentPanel("commentPanel", user, ticket, null, TicketsPage.class);
			commentPanel.setRepository(repositoryName);
			newComment.add(commentPanel);
			add(newComment);
		}


		/*
		 *  PATCHSET TAB
		 */
		if (currentPatchset == null) {
			// no patchset available
			RepositoryUrl repoUrl = getRepositoryUrl(user, repository);
			boolean canPropose = repoUrl != null && repoUrl.permission.atLeast(AccessPermission.CLONE) && !UserModel.ANONYMOUS.equals(user);
			if (ticket.isOpen() && app().tickets().isAcceptingNewPatchsets(repository) && canPropose) {
				// ticket & repo will accept a proposal patchset
				// show the instructions for proposing a patchset
				Fragment changeIdFrag = new Fragment("patchset", "proposeFragment", this);
				changeIdFrag.add(new Label("proposeInstructions", MarkdownUtils.transformMarkdown(getString("gb.proposeInstructions"))).setEscapeModelStrings(false));
				changeIdFrag.add(new Label("ptWorkflow", MessageFormat.format(getString("gb.proposeWith"), "Barnum")));
				changeIdFrag.add(new Label("ptWorkflowSteps", getProposeWorkflow("propose_pt.md", repoUrl.url, ticket.number)).setEscapeModelStrings(false));
				changeIdFrag.add(new Label("gitWorkflow", MessageFormat.format(getString("gb.proposeWith"), "Git")));
				changeIdFrag.add(new Label("gitWorkflowSteps", getProposeWorkflow("propose_git.md", repoUrl.url, ticket.number)).setEscapeModelStrings(false));
				add(changeIdFrag);
			} else {
				// explain why you can't propose a patchset
				Fragment fragment = new Fragment("patchset", "canNotProposeFragment", this);
				String reason = "";
				if (ticket.isClosed()) {
					reason = getString("gb.ticketIsClosed");
				} else if (repository.isMirror) {
					reason = getString("gb.repositoryIsMirror");
				} else if (repository.isFrozen) {
					reason = getString("gb.repositoryIsFrozen");
				} else if (!repository.acceptNewPatchsets) {
					reason = getString("gb.repositoryDoesNotAcceptPatchsets");
				} else if (!canPropose) {
					if (UserModel.ANONYMOUS.equals(user)) {
						reason = getString("gb.anonymousCanNotPropose");
					} else {
						reason = getString("gb.youDoNotHaveClonePermission");
					}
				} else {
					reason = getString("gb.serverDoesNotAcceptPatchsets");
				}
				fragment.add(new Label("reason", reason));
				add(fragment);
			}
		} else {
			// show current patchset
			Fragment patchsetFrag = new Fragment("patchset", "patchsetFragment", this);
			patchsetFrag.add(new Label("commitsInPatchset", MessageFormat.format(getString("gb.commitsInPatchsetN"), currentPatchset.number)));

			patchsetFrag.add(createMergePanel(user, repository));

			if (ticket.isOpen()) {
				// current revision
				MarkupContainer panel = createPatchsetPanel("panel", repository, user);
				patchsetFrag.add(panel);
				addUserAttributions(patchsetFrag, currentRevision, avatarWidth);
				addUserAttributions(panel, currentRevision, 0);
				addDateAttributions(panel, currentRevision);
			} else {
				// current revision
				patchsetFrag.add(new Label("panel").setVisible(false));
			}

			// commits
			List<RevCommit> commits = JGitUtils.getRevLog(getRepository(), currentPatchset.base, currentPatchset.tip);
			ListDataProvider<RevCommit> commitsDp = new ListDataProvider<RevCommit>(commits);
			DataView<RevCommit> commitsView = new DataView<RevCommit>("commit", commitsDp) {
				private static final long serialVersionUID = 1L;

				@Override
				public void populateItem(final Item<RevCommit> item) {
					RevCommit commit = item.getModelObject();
					PersonIdent author = commit.getAuthorIdent();
					item.add(new GravatarImage("authorAvatar", author.getName(), author.getEmailAddress(), null, 16, false));
					item.add(new Label("author", commit.getAuthorIdent().getName()));
					item.add(new LinkPanel("commitId", null, getShortObjectId(commit.getName()),
							CommitPage.class, WicketUtils.newObjectParameter(repositoryName, commit.getName()), true));
					item.add(new LinkPanel("diff", "link", getString("gb.diff"), CommitDiffPage.class,
							WicketUtils.newObjectParameter(repositoryName, commit.getName()), true));
					item.add(new Label("title", StringUtils.trimString(commit.getShortMessage(), Constants.LEN_SHORTLOG_REFS)));
					item.add(WicketUtils.createDateLabel("commitDate", JGitUtils.getCommitDate(commit), GitBlitWebSession
							.get().getTimezone(), getTimeUtils(), false));
					item.add(new DiffStatPanel("commitDiffStat", 0, 0, true));
				}
			};
			patchsetFrag.add(commitsView);
			add(patchsetFrag);
		}


		/*
		 * ACTIVITY TAB
		 */
		Fragment revisionHistory = new Fragment("activity", "activityFragment", this);
		List<Change> events = new ArrayList<Change>(ticket.changes);
		Collections.sort(events);
		Collections.reverse(events);
		ListDataProvider<Change> eventsDp = new ListDataProvider<Change>(events);
		DataView<Change> eventsView = new DataView<Change>("event", eventsDp) {
			private static final long serialVersionUID = 1L;

			@Override
			public void populateItem(final Item<Change> item) {
				Change event = item.getModelObject();

				addUserAttributions(item, event, 16);

				if (event.hasPatchset()) {
					// patchset
					Patchset patchset = event.patchset;
					String what;
					if (event.isStatusChange() && (Status.New == event.getStatus())) {
						what = getString("gb.proposedThisChange");
					} else if (patchset.rev == 1) {
						what = MessageFormat.format(getString("gb.uploadedPatchsetN"), patchset.number);
					} else {
						if (patchset.added == 1) {
							what = getString("gb.addedOneCommit");
						} else {
							what = MessageFormat.format(getString("gb.addedNCommits"), patchset.added);
						}
					}
					item.add(new Label("what", what));

					LinkPanel psr = new LinkPanel("patchsetRevision", null, patchset.number + "-" + patchset.rev,
							ComparePage.class, WicketUtils.newRangeParameter(repositoryName, patchset.parent == null ? patchset.base : patchset.parent, patchset.tip), true);
					WicketUtils.setHtmlTooltip(psr, patchset.toString());
					item.add(psr);
					String typeCss = getPatchsetTypeCss(patchset.type);
					Label typeLabel = new Label("patchsetType", patchset.type.toString());
					if (typeCss == null) {
						typeLabel.setVisible(false);
					} else {
						WicketUtils.setCssClass(typeLabel, typeCss);
					}
					item.add(typeLabel);

					// show commit diffstat
					item.add(new DiffStatPanel("patchsetDiffStat", patchset.insertions, patchset.deletions, patchset.rev > 1));
				} else if (event.hasComment()) {
					// comment
					item.add(new Label("what", getString("gb.commented")));
					item.add(new Label("patchsetRevision").setVisible(false));
					item.add(new Label("patchsetType").setVisible(false));
					item.add(new Label("patchsetDiffStat").setVisible(false));
				} else if (event.hasReview()) {
					// review
					String score;
					switch (event.review.score) {
					case approved:
						score = "<span style='color:darkGreen'>" + getScoreDescription(event.review.score) + "</span>";
						break;
					case vetoed:
						score = "<span style='color:darkRed'>" + getScoreDescription(event.review.score) + "</span>";
						break;
					default:
						score = getScoreDescription(event.review.score);
					}
					item.add(new Label("what", MessageFormat.format(getString("gb.reviewedPatchsetRev"),
							event.review.patchset, event.review.rev, score))
							.setEscapeModelStrings(false));
					item.add(new Label("patchsetRevision").setVisible(false));
					item.add(new Label("patchsetType").setVisible(false));
					item.add(new Label("patchsetDiffStat").setVisible(false));
				} else {
					// field change
					item.add(new Label("patchsetRevision").setVisible(false));
					item.add(new Label("patchsetType").setVisible(false));
					item.add(new Label("patchsetDiffStat").setVisible(false));

					String what = "";
					if (event.isStatusChange()) {
					switch (event.getStatus()) {
					case New:
						if (ticket.isProposal()) {
							what = getString("gb.proposedThisChange");
						} else {
							what = getString("gb.createdThisTicket");
						}
						break;
					default:
						break;
					}
					}
					item.add(new Label("what", what).setVisible(what.length() > 0));
				}

				addDateAttributions(item, event);

				if (event.hasFieldChanges()) {
					StringBuilder sb = new StringBuilder();
					sb.append("<table class=\"summary\"><tbody>");
					for (Map.Entry<Field, String> entry : event.fields.entrySet()) {
						String value;
						switch (entry.getKey()) {
							case body:
								String body = entry.getValue();
								if (event.isStatusChange() && Status.New == event.getStatus() && StringUtils.isEmpty(body)) {
									// ignore initial empty description
									continue;
								}
								// trim body changes
								if (StringUtils.isEmpty(body)) {
									value = "<i>" + ESC_NIL + "</i>";
								} else {
									value = StringUtils.trimString(body, Constants.LEN_SHORTLOG_REFS);
								}
								break;
							case status:
								// special handling for status
								Status status = event.getStatus();
								String css = TicketsUI.getLozengeClass(status, true);
								value = String.format("<span class=\"%1$s\">%2$s</span>", css, status.toString());
								break;
							default:
								value = StringUtils.isEmpty(entry.getValue()) ? ("<i>" + ESC_NIL + "</i>") : StringUtils.escapeForHtml(entry.getValue(), false);
								break;
						}
						sb.append("<tr><th style=\"width:70px;\">");
						try {
							sb.append(getString("gb." + entry.getKey().name()));
						} catch (Exception e) {
							sb.append(entry.getKey().name());
						}
						sb.append("</th><td>");
						sb.append(value);
						sb.append("</td></tr>");
					}
					sb.append("</tbody></table>");
					item.add(new Label("fields", sb.toString()).setEscapeModelStrings(false));
				} else {
					item.add(new Label("fields").setVisible(false));
				}
			}
		};
		revisionHistory.add(eventsView);
		add(revisionHistory);
	}

	protected void addUserAttributions(MarkupContainer container, Change entry, int avatarSize) {
		UserModel commenter = app().users().getUserModel(entry.author);
		if (commenter == null) {
			// unknown user
			container.add(new GravatarImage("changeAvatar", entry.author,
					entry.author, null, avatarSize, false).setVisible(avatarSize > 0));
			container.add(new Label("changeAuthor", entry.author.toLowerCase()));
		} else {
			// known user
			container.add(new GravatarImage("changeAvatar", commenter.getDisplayName(),
					commenter.emailAddress, avatarSize > 24 ? "gravatar-round" : null,
							avatarSize, true).setVisible(avatarSize > 0));
			container.add(new LinkPanel("changeAuthor", null, commenter.getDisplayName(),
					UserPage.class, WicketUtils.newUsernameParameter(commenter.username)));
		}
	}

	protected void addDateAttributions(MarkupContainer container, Change entry) {
		container.add(WicketUtils.createDateLabel("changeDate", entry.date, GitBlitWebSession
				.get().getTimezone(), getTimeUtils(), false));

		// set the id attribute
		if (entry.hasComment()) {
			container.setOutputMarkupId(true);
			container.add(new AttributeModifier("id", Model.of(entry.getId())));
			ExternalLink link = new ExternalLink("changeLink", "#" + entry.getId());
			container.add(link);
		} else {
			container.add(new Label("changeLink").setVisible(false));
		}
	}

	protected String getProposeWorkflow(String resource, String url, long ticketId) {
		String md = readResource(resource);
		md = md.replace("${url}", url);
		md = md.replace("${repo}", StringUtils.getLastPathElement(StringUtils.stripDotGit(repositoryName)));
		md = md.replace("${ticketId}", "" + ticketId);
		md = md.replace("${patchset}", "" + 1);
		md = md.replace("${reviewBranch}", Repository.shortenRefName(PatchsetCommand.getTicketBranch(ticketId)));
		String integrationBranch = Repository.shortenRefName(getRepositoryModel().mergeTo);
		if (!StringUtils.isEmpty(ticket.mergeTo)) {
			integrationBranch = ticket.mergeTo;
		}
		md = md.replace("${integrationBranch}", integrationBranch);
		return MarkdownUtils.transformMarkdown(md);
	}

	protected Fragment createPatchsetPanel(String wicketId, RepositoryModel repository, UserModel user) {
		final Patchset currentPatchset = ticket.getCurrentPatchset();
		List<Patchset> patchsets = new ArrayList<Patchset>(ticket.getPatchsetRevisions(currentPatchset.number));
		patchsets.remove(currentPatchset);
		Collections.reverse(patchsets);

		Fragment panel = new Fragment(wicketId, "collapsiblePatchsetFragment", this);

		// patchset header
		String ps = "<b>" + currentPatchset.number + "</b>";
		if (currentPatchset.rev == 1) {
			panel.add(new Label("uploadedWhat", MessageFormat.format(getString("gb.uploadedPatchsetN"), ps)).setEscapeModelStrings(false));
		} else {
			String rev = "<b>" + currentPatchset.rev + "</b>";
			panel.add(new Label("uploadedWhat", MessageFormat.format(getString("gb.uploadedPatchsetNRevisionN"), ps, rev)).setEscapeModelStrings(false));
		}
		panel.add(new LinkPanel("patchId", null, "rev " + currentPatchset.rev,
				CommitPage.class, WicketUtils.newObjectParameter(repositoryName, currentPatchset.tip), true));

		// compare menu
		panel.add(new LinkPanel("compareMergeBase", null, getString("gb.compareToMergeBase"),
				ComparePage.class, WicketUtils.newRangeParameter(repositoryName, currentPatchset.base, currentPatchset.tip), true));

		ListDataProvider<Patchset> compareMenuDp = new ListDataProvider<Patchset>(patchsets);
		DataView<Patchset> compareMenu = new DataView<Patchset>("comparePatch", compareMenuDp) {
			private static final long serialVersionUID = 1L;
			@Override
			public void populateItem(final Item<Patchset> item) {
				Patchset patchset = item.getModelObject();
				LinkPanel link = new LinkPanel("compareLink", null,
						MessageFormat.format(getString("gb.compareToN"), patchset.number + "-" + patchset.rev),
						ComparePage.class, WicketUtils.newRangeParameter(getRepositoryModel().name,
								patchset.tip, currentPatchset.tip), true);
				item.add(link);

			}
		};
		panel.add(compareMenu);


		// reviews
		List<Change> reviews = ticket.getReviews(currentPatchset);
		ListDataProvider<Change> reviewsDp = new ListDataProvider<Change>(reviews);
		DataView<Change> reviewsView = new DataView<Change>("reviews", reviewsDp) {
			private static final long serialVersionUID = 1L;

			@Override
			public void populateItem(final Item<Change> item) {
				Change change = item.getModelObject();
				final String username = change.author;
				UserModel user = app().users().getUserModel(username);
				if (user == null) {
					item.add(new Label("reviewer", username));
				} else {
					item.add(new LinkPanel("reviewer", null, user.getDisplayName(),
							UserPage.class, WicketUtils.newUsernameParameter(username)));
				}

				// indicate review score
				Review review = change.review;
				Label scoreLabel = new Label("score");
				String scoreClass = getScoreClass(review.score);
				String tooltip = getScoreDescription(review.score);
				WicketUtils.setCssClass(scoreLabel, scoreClass);
				if (!StringUtils.isEmpty(tooltip)) {
					WicketUtils.setHtmlTooltip(scoreLabel, tooltip);
				}
				item.add(scoreLabel);
			}
		};
		panel.add(reviewsView);


		if (ticket.isOpen() && user.canReviewPatchset(repository) && app().tickets().isAcceptingTicketUpdates(repository)) {
			// can only review open tickets
			Review myReview = null;
			for (Change change : ticket.getReviews(currentPatchset)) {
				if (change.author.equals(user.username)) {
					myReview = change.review;
				}
			}

			// user can review, add review controls
			Fragment reviewControls = new Fragment("reviewControls", "reviewControlsFragment", this);

			// show "approve" button if no review OR not current score
			if (user.canApprovePatchset(repository) && (myReview == null || Score.approved != myReview.score)) {
				reviewControls.add(createReviewLink("approveLink", Score.approved));
			} else {
				reviewControls.add(new Label("approveLink").setVisible(false));
			}

			// show "looks good" button if no review OR not current score
			if (myReview == null || Score.looks_good != myReview.score) {
				reviewControls.add(createReviewLink("looksGoodLink", Score.looks_good));
			} else {
				reviewControls.add(new Label("looksGoodLink").setVisible(false));
			}

			// show "needs improvement" button if no review OR not current score
			if (myReview == null || Score.needs_improvement != myReview.score) {
				reviewControls.add(createReviewLink("needsImprovementLink", Score.needs_improvement));
			} else {
				reviewControls.add(new Label("needsImprovementLink").setVisible(false));
			}

			// show "veto" button if no review OR not current score
			if (user.canVetoPatchset(repository) && (myReview == null || Score.vetoed != myReview.score)) {
				reviewControls.add(createReviewLink("vetoLink", Score.vetoed));
			} else {
				reviewControls.add(new Label("vetoLink").setVisible(false));
			}
			panel.add(reviewControls);
		} else {
			// user can not review
			panel.add(new Label("reviewControls").setVisible(false));
		}

		String insertions = MessageFormat.format("<span style=\"color:darkGreen;font-weight:bold;\">+{0}</span>", ticket.insertions);
		String deletions = MessageFormat.format("<span style=\"color:darkRed;font-weight:bold;\">-{0}</span>", ticket.deletions);
		panel.add(new Label("patchsetStat", MessageFormat.format(StringUtils.escapeForHtml(getString("gb.diffStat"), false),
				insertions, deletions)).setEscapeModelStrings(false));

		// changed paths list
		List<PathChangeModel> paths = JGitUtils.getFilesInRange(getRepository(), currentPatchset.base, currentPatchset.tip);
		ListDataProvider<PathChangeModel> pathsDp = new ListDataProvider<PathChangeModel>(paths);
		DataView<PathChangeModel> pathsView = new DataView<PathChangeModel>("changedPath", pathsDp) {
			private static final long serialVersionUID = 1L;
			int counter;

			@Override
			public void populateItem(final Item<PathChangeModel> item) {
				final PathChangeModel entry = item.getModelObject();
				Label changeType = new Label("changeType", "");
				WicketUtils.setChangeTypeCssClass(changeType, entry.changeType);
				setChangeTypeTooltip(changeType, entry.changeType);
				item.add(changeType);

				boolean hasSubmodule = false;
				String submodulePath = null;
				if (entry.isTree()) {
					// tree
					item.add(new LinkPanel("pathName", null, entry.path, TreePage.class,
							WicketUtils
									.newPathParameter(repositoryName, currentPatchset.tip, entry.path), true));
					item.add(new Label("diffStat").setVisible(false));
				} else if (entry.isSubmodule()) {
					// submodule
					String submoduleId = entry.objectId;
					SubmoduleModel submodule = getSubmodule(entry.path);
					submodulePath = submodule.gitblitPath;
					hasSubmodule = submodule.hasSubmodule;

					item.add(new LinkPanel("pathName", "list", entry.path + " @ " +
							getShortObjectId(submoduleId), TreePage.class,
							WicketUtils.newPathParameter(submodulePath, submoduleId, ""), true).setEnabled(hasSubmodule));
					item.add(new Label("diffStat").setVisible(false));
				} else {
					// blob
					String displayPath = entry.path;
					String path = entry.path;
					if (entry.isSymlink()) {
						RevCommit commit = JGitUtils.getCommit(getRepository(), PatchsetCommand.getTicketBranch(ticket.number));
						path = JGitUtils.getStringContent(getRepository(), commit.getTree(), path);
						displayPath = entry.path + " -> " + path;
					}

					if (entry.changeType.equals(ChangeType.ADD)) {
						// add show view
						item.add(new LinkPanel("pathName", "list", displayPath, BlobPage.class,
								WicketUtils.newPathParameter(repositoryName, currentPatchset.tip, path), true));
					} else if (entry.changeType.equals(ChangeType.DELETE)) {
						// delete, show label
						item.add(new Label("pathName", displayPath));
					} else {
						// mod, show diff
						item.add(new LinkPanel("pathName", "list", displayPath, BlobDiffPage.class,
								WicketUtils.newPathParameter(repositoryName, currentPatchset.tip, path), true));
					}
					item.add(new DiffStatPanel("diffStat", entry.insertions, entry.deletions, true));
				}

				// quick links
				if (entry.isSubmodule()) {
					// submodule
					item.add(setNewTarget(new BookmarkablePageLink<Void>("diff", BlobDiffPage.class, WicketUtils
							.newPathParameter(repositoryName, entry.commitId, entry.path)))
							.setEnabled(!entry.changeType.equals(ChangeType.ADD)));
					item.add(new BookmarkablePageLink<Void>("view", CommitPage.class, WicketUtils
							.newObjectParameter(submodulePath, entry.objectId)).setEnabled(hasSubmodule));
				} else {
					// tree or blob
					item.add(setNewTarget(new BookmarkablePageLink<Void>("diff", BlobDiffPage.class, WicketUtils
							.newBlobDiffParameter(repositoryName, currentPatchset.base, currentPatchset.tip, entry.path)))
							.setEnabled(!entry.changeType.equals(ChangeType.ADD)
									&& !entry.changeType.equals(ChangeType.DELETE)));
					item.add(setNewTarget(new BookmarkablePageLink<Void>("view", BlobPage.class, WicketUtils
							.newPathParameter(repositoryName, currentPatchset.tip, entry.path)))
							.setEnabled(!entry.changeType.equals(ChangeType.DELETE)));
				}

				WicketUtils.setAlternatingBackground(item, counter);
				counter++;
			}
		};
		panel.add(pathsView);

		addPtCheckoutInstructions(user, repository, panel);
		addGitCheckoutInstructions(user, repository, panel);

		return panel;
	}

	protected IconAjaxLink<String> createReviewLink(String wicketId, final Score score) {
		return new IconAjaxLink<String>(wicketId, getScoreClass(score), Model.of(getScoreDescription(score))) {

			private static final long serialVersionUID = 1L;

			@Override
			public void onClick(AjaxRequestTarget target) {
				review(score);
			}
		};
	}

	protected String getScoreClass(Score score) {
		switch (score) {
		case vetoed:
			return "fa fa-exclamation-circle";
		case needs_improvement:
			return "fa fa-thumbs-o-down";
		case looks_good:
			return "fa fa-thumbs-o-up";
		case approved:
			return "fa fa-check-circle";
		case not_reviewed:
		default:
			return "fa fa-minus-circle";
		}
	}

	protected String getScoreDescription(Score score) {
		String description;
		switch (score) {
		case vetoed:
			description = getString("gb.veto");
			break;
		case needs_improvement:
			description = getString("gb.needsImprovement");
			break;
		case looks_good:
			description = getString("gb.looksGood");
			break;
		case approved:
			description = getString("gb.approve");
			break;
		case not_reviewed:
		default:
			description = getString("gb.hasNotReviewed");
		}
		return String.format("%1$s (%2$+d)", description, score.getValue());
	}

	protected void review(Score score) {
		UserModel user = GitBlitWebSession.get().getUser();
		Patchset ps = ticket.getCurrentPatchset();
		Change change = new Change(user.username);
		change.review(ps, score, !ticket.isReviewer(user.username));
		if (!ticket.isWatching(user.username)) {
			change.watch(user.username);
		}
		TicketModel updatedTicket = app().tickets().updateTicket(getRepositoryModel(), ticket.number, change);
		app().tickets().createNotifier().sendMailing(updatedTicket);
		setResponsePage(TicketsPage.class, getPageParameters());
	}

	protected <X extends MarkupContainer> X setNewTarget(X x) {
		x.add(new SimpleAttributeModifier("target", "_blank"));
		return x;
	}

	protected void addGitCheckoutInstructions(UserModel user, RepositoryModel repository, MarkupContainer panel) {
		panel.add(new Label("gitStep1", MessageFormat.format(getString("gb.stepN"), 1)));
		panel.add(new Label("gitStep2", MessageFormat.format(getString("gb.stepN"), 2)));

		String ticketBranch  = Repository.shortenRefName(PatchsetCommand.getTicketBranch(ticket.number));

		String step1 = "git fetch origin";
		String step2 = MessageFormat.format("git checkout {0} && git pull --ff-only\nOR\ngit checkout {0} && git reset --hard origin/{0}", ticketBranch);

		panel.add(new Label("gitPreStep1", step1));
		panel.add(new Label("gitPreStep2", step2));

		panel.add(createCopyFragment("gitCopyStep1", step1.replace("\n", " && ")));
		panel.add(createCopyFragment("gitCopyStep2", step2.replace("\n", " && ")));
	}

	protected void addPtCheckoutInstructions(UserModel user, RepositoryModel repository, MarkupContainer panel) {
		String step1 = MessageFormat.format("pt checkout {0,number,0}", ticket.number);
		panel.add(new Label("ptPreStep", step1));
		panel.add(createCopyFragment("ptCopyStep", step1));
	}

	/**
	 * Adds a merge panel for the patchset to the markup container.  The panel
	 * may just a message if the patchset can not be merged.
	 *
	 * @param c
	 * @param user
	 * @param repository
	 */
	protected Component createMergePanel(UserModel user, RepositoryModel repository) {
		Patchset patchset = ticket.getCurrentPatchset();
		if (patchset == null) {
			// no patchset to merge
			return new Label("mergePanel");
		}

		boolean allowMerge;
		if (repository.requireApproval) {
			// repository requires approval
			allowMerge = ticket.isOpen() && ticket.isApproved(patchset);
		} else {
			// vetoes are binding
			allowMerge = ticket.isOpen() && !ticket.isVetoed(patchset);
		}

		MergeStatus mergeStatus = JGitUtils.canMerge(getRepository(), patchset.tip, ticket.mergeTo, repository.mergeType);
		if (allowMerge) {
			if (MergeStatus.MERGEABLE == mergeStatus) {
				// patchset can be cleanly merged to integration branch OR has already been merged
				Fragment mergePanel = new Fragment("mergePanel", "mergeableFragment", this);
				mergePanel.add(new Label("mergeTitle", MessageFormat.format(getString("gb.patchsetMergeable"), ticket.mergeTo)));
				if (user.canPush(repository)) {
					// user can merge locally
					SimpleAjaxLink<String> mergeButton = new SimpleAjaxLink<String>("mergeButton", Model.of(getString("gb.merge"))) {

						private static final long serialVersionUID = 1L;

						@Override
						public void onClick(AjaxRequestTarget target) {

							// ensure the patchset is still current AND not vetoed
							Patchset patchset = ticket.getCurrentPatchset();
							final TicketModel refreshedTicket = app().tickets().getTicket(getRepositoryModel(), ticket.number);
							if (patchset.equals(refreshedTicket.getCurrentPatchset())) {
								// patchset is current, check for recent veto
								if (!refreshedTicket.isVetoed(patchset)) {
									// patchset is not vetoed

									// execute the merge using the ticket service
									app().tickets().exec(new Runnable() {
										@Override
										public void run() {
											PatchsetReceivePack rp = new PatchsetReceivePack(
													app().gitblit(),
													getRepository(),
													getRepositoryModel(),
													GitBlitWebSession.get().getUser());
											MergeStatus result = rp.merge(refreshedTicket);
											if (MergeStatus.MERGED == result) {
												// notify participants and watchers
												rp.sendAll();
											} else {
												// merge failure
												String msg = MessageFormat.format("Failed to merge ticket {0,number,0}: {1}", ticket.number, result.name());
												logger.error(msg);
												GitBlitWebSession.get().cacheErrorMessage(msg);
											}
										}
									});
								} else {
									// vetoed patchset
									String msg = MessageFormat.format("Can not merge ticket {0,number,0}, patchset {1,number,0} has been vetoed!",
											ticket.number, patchset.number);
									GitBlitWebSession.get().cacheErrorMessage(msg);
									logger.error(msg);
								}
							} else {
								// not current patchset
								String msg = MessageFormat.format("Can not merge ticket {0,number,0}, the patchset has been updated!", ticket.number);
								GitBlitWebSession.get().cacheErrorMessage(msg);
								logger.error(msg);
							}

							setResponsePage(TicketsPage.class, getPageParameters());
						}
					};
					mergePanel.add(mergeButton);
					Component instructions = getMergeInstructions(user, repository, "mergeMore", "gb.patchsetMergeableMore");
					mergePanel.add(instructions);
				} else {
					mergePanel.add(new Label("mergeButton").setVisible(false));
					mergePanel.add(new Label("mergeMore").setVisible(false));
				}
				return mergePanel;
			} else if (MergeStatus.ALREADY_MERGED == mergeStatus) {
				// patchset already merged
				Fragment mergePanel = new Fragment("mergePanel", "alreadyMergedFragment", this);
				mergePanel.add(new Label("mergeTitle", MessageFormat.format(getString("gb.patchsetAlreadyMerged"), ticket.mergeTo)));
				return mergePanel;
			} else {
				// patchset can not be cleanly merged
				Fragment mergePanel = new Fragment("mergePanel", "notMergeableFragment", this);
				mergePanel.add(new Label("mergeTitle", MessageFormat.format(getString("gb.patchsetNotMergeable"), ticket.mergeTo)));
				if (user.canPush(repository)) {
					// user can merge locally
					Component instructions = getMergeInstructions(user, repository, "mergeMore", "gb.patchsetNotMergeableMore");
					mergePanel.add(instructions);
				} else {
					mergePanel.add(new Label("mergeMore").setVisible(false));
				}
				return mergePanel;
			}
		} else {
			// merge not allowed
			if (MergeStatus.ALREADY_MERGED == mergeStatus) {
				// patchset already merged
				Fragment mergePanel = new Fragment("mergePanel", "alreadyMergedFragment", this);
				mergePanel.add(new Label("mergeTitle", MessageFormat.format(getString("gb.patchsetAlreadyMerged"), ticket.mergeTo)));
				return mergePanel;
			} else if (ticket.isVetoed(patchset)) {
				// patchset has been vetoed
				Fragment mergePanel =  new Fragment("mergePanel", "vetoedFragment", this);
				mergePanel.add(new Label("mergeTitle", MessageFormat.format(getString("gb.patchsetNotMergeable"), ticket.mergeTo)));
				return mergePanel;
			} else if (repository.requireApproval) {
				// patchset has been not been approved for merge
				Fragment mergePanel = new Fragment("mergePanel", "notApprovedFragment", this);
				mergePanel.add(new Label("mergeTitle", MessageFormat.format(getString("gb.patchsetNotApproved"), ticket.mergeTo)));
				mergePanel.add(new Label("mergeMore", MessageFormat.format(getString("gb.patchsetNotApprovedMore"), ticket.mergeTo)));
				return mergePanel;
			} else {
				// other case
				return new Label("mergePanel");
			}
		}
	}

	protected Component getMergeInstructions(UserModel user, RepositoryModel repository, String markupId, String infoKey) {
		Fragment cmd = new Fragment(markupId, "commandlineMergeFragment", this);
		cmd.add(new Label("instructions", MessageFormat.format(getString(infoKey), ticket.mergeTo)));

		// git instructions
		cmd.add(new Label("mergeStep1", MessageFormat.format(getString("gb.stepN"), 1)));
		cmd.add(new Label("mergeStep2", MessageFormat.format(getString("gb.stepN"), 2)));
		cmd.add(new Label("mergeStep3", MessageFormat.format(getString("gb.stepN"), 3)));

		String ticketBranch = Repository.shortenRefName(PatchsetCommand.getTicketBranch(ticket.number));
		String reviewBranch = PatchsetCommand.getReviewBranch(ticket.number);

		String step1 = MessageFormat.format("git checkout -b {0} {1}", reviewBranch, ticket.mergeTo);
		String step2 = MessageFormat.format("git pull origin {0}", ticketBranch);
		String step3 = MessageFormat.format("git checkout {0}\ngit merge {1}\ngit push origin {0}\ngit branch -d {1}", ticket.mergeTo, reviewBranch);

		cmd.add(new Label("mergePreStep1", step1));
		cmd.add(new Label("mergePreStep2", step2));
		cmd.add(new Label("mergePreStep3", step3));

		cmd.add(createCopyFragment("mergeCopyStep1", step1.replace("\n", " && ")));
		cmd.add(createCopyFragment("mergeCopyStep2", step2.replace("\n", " && ")));
		cmd.add(createCopyFragment("mergeCopyStep3", step3.replace("\n", " && ")));

		// pt instructions
		String ptStep = MessageFormat.format("pt pull {0,number,0}", ticket.number);
		cmd.add(new Label("ptMergeStep", ptStep));
		cmd.add(createCopyFragment("ptMergeCopyStep", step1.replace("\n", " && ")));
		return cmd;
	}

	/**
	 * Returns the primary repository url
	 *
	 * @param user
	 * @param repository
	 * @return the primary repository url
	 */
	protected RepositoryUrl getRepositoryUrl(UserModel user, RepositoryModel repository) {
		HttpServletRequest req = ((WebRequest) getRequest()).getHttpServletRequest();
		List<RepositoryUrl> urls = app().services().getRepositoryUrls(req, user, repository);
		if (ArrayUtils.isEmpty(urls)) {
			return null;
		}
		RepositoryUrl primary = urls.get(0);
		return primary;
	}

	/**
	 * Returns the ticket (if any) that this commit references.
	 *
	 * @param commit
	 * @return null or a ticket
	 */
	protected TicketModel getTicket(RevCommit commit) {
		try {
			Map<String, Ref> refs = getRepository().getRefDatabase().getRefs(Constants.R_TICKETS_PATCHSETS);
			for (Map.Entry<String, Ref> entry : refs.entrySet()) {
				if (entry.getValue().getObjectId().equals(commit.getId())) {
					long id = PatchsetCommand.getTicketNumber(entry.getKey());
					TicketModel ticket = app().tickets().getTicket(getRepositoryModel(), id);
					return ticket;
				}
			}
		} catch (Exception e) {
			logger().error("failed to determine ticket from ref", e);
		}
		return null;
	}

	protected String getPatchsetTypeCss(PatchsetType type) {
		String typeCss;
		switch (type) {
			case Rebase:
			case Rebase_Squash:
				typeCss = TicketsUI.getLozengeClass(Status.Declined, false);
				break;
			case Squash:
			case Amend:
				typeCss = TicketsUI.getLozengeClass(Status.On_Hold, false);
				break;
			case Proposal:
				typeCss = TicketsUI.getLozengeClass(Status.New, false);
				break;
			case FastForward:
			default:
				typeCss = null;
			break;
		}
		return typeCss;
	}

	@Override
	protected String getPageName() {
		return getString("gb.ticket");
	}

	@Override
	protected Class<? extends BasePage> getRepoNavPageClass() {
		return TicketsPage.class;
	}

	@Override
	protected String getPageTitle(String repositoryName) {
		return "#" + ticket.number + " - " + ticket.title;
	}

	protected Fragment createCopyFragment(String wicketId, String text) {
		if (app().settings().getBoolean(Keys.web.allowFlashCopyToClipboard, true)) {
			// clippy: flash-based copy & paste
			Fragment copyFragment = new Fragment(wicketId, "clippyPanel", this);
			String baseUrl = WicketUtils.getGitblitURL(getRequest());
			ShockWaveComponent clippy = new ShockWaveComponent("clippy", baseUrl + "/clippy.swf");
			clippy.setValue("flashVars", "text=" + StringUtils.encodeURL(text));
			copyFragment.add(clippy);
			return copyFragment;
		} else {
			// javascript: manual copy & paste with modal browser prompt dialog
			Fragment copyFragment = new Fragment(wicketId, "jsPanel", this);
			ContextImage img = WicketUtils.newImage("copyIcon", "clippy.png");
			img.add(new JavascriptTextPrompt("onclick", "Copy to Clipboard (Ctrl+C, Enter)", text));
			copyFragment.add(img);
			return copyFragment;
		}
	}
}
