/*
 * 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.panels;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

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.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.eclipse.jgit.lib.Repository;

import com.gitblit.Constants;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
import com.gitblit.tickets.QueryResult;
import com.gitblit.tickets.TicketLabel;
import com.gitblit.utils.ArrayUtils;
import com.gitblit.utils.BugtraqProcessor;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.TicketsUI;
import com.gitblit.wicket.TicketsUI.Indicator;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.pages.TicketsPage;
import com.gitblit.wicket.pages.UserPage;

/**
 *
 * The ticket list panel lists tickets in a table.
 *
 * @author James Moger
 *
 */
public class TicketListPanel extends BasePanel {

	private static final long serialVersionUID = 1L;

	public TicketListPanel(String wicketId, List<QueryResult> list, final boolean showSwatch, final boolean showRepository) {
		super(wicketId);

		final ListDataProvider<QueryResult> dp = new ListDataProvider<QueryResult>(list);
		DataView<QueryResult> dataView = new DataView<QueryResult>("row", dp) {
			private static final long serialVersionUID = 1L;

			@Override
			protected void populateItem(Item<QueryResult> item) {
				final QueryResult ticket = item.getModelObject();

				if (showSwatch) {
					// set repository color
					String color = StringUtils.getColor(StringUtils.stripDotGit(ticket.repository));
					WicketUtils.setCssStyle(item, MessageFormat.format("border-left: 2px solid {0};", color));
				}

				PageParameters tp = WicketUtils.newObjectParameter(ticket.repository, "" + ticket.number);

				if (showRepository) {
					String name = StringUtils.stripDotGit(ticket.repository);
					PageParameters rp =  WicketUtils.newOpenTicketsParameter(ticket.repository);
					LinkPanel link = new LinkPanel("ticketsLink", null, name, TicketsPage.class, rp);
					WicketUtils.setCssBackground(link, name);
					item.add(link);
				} else {
					item.add(new Label("ticketsLink").setVisible(false));
				}

				Label icon = TicketsUI.getStateIcon("state", ticket.type, ticket.status, ticket.severity);
				WicketUtils.addCssClass(icon, TicketsUI.getSeverityClass(ticket.severity));
				item.add(icon);

				item.add(new Label("id", "" + ticket.number));
				UserModel creator = app().users().getUserModel(ticket.createdBy);
				if (creator != null) {
					item.add(new LinkPanel("createdBy", null, creator.getDisplayName(),
							UserPage.class, WicketUtils.newUsernameParameter(ticket.createdBy)));
				} else {
					item.add(new Label("createdBy", ticket.createdBy));
				}
				item.add(WicketUtils.createDateLabel("createDate", ticket.createdAt, GitBlitWebSession
						.get().getTimezone(), getTimeUtils(), false));

				if (ticket.updatedAt == null) {
					item.add(new Label("updated").setVisible(false));
				} else {
					Fragment updated = new Fragment("updated", "updatedFragment", this);
					UserModel updater = app().users().getUserModel(ticket.updatedBy);
					if (updater != null) {
						updated.add(new LinkPanel("updatedBy", null, updater.getDisplayName(),
								UserPage.class, WicketUtils.newUsernameParameter(ticket.updatedBy)));
					} else {
						updated.add(new Label("updatedBy", ticket.updatedBy));
					}
					updated.add(WicketUtils.createDateLabel("updateDate", ticket.updatedAt, GitBlitWebSession
							.get().getTimezone(), getTimeUtils(), false));
					item.add(updated);
				}

				item.add(new LinkPanel("title", "list subject", StringUtils.trimString(
						ticket.title, Constants.LEN_SHORTLOG), TicketsPage.class, tp));

				ListDataProvider<String> labelsProvider = new ListDataProvider<String>(ticket.getLabels());
				DataView<String> labelsView = new DataView<String>("labels", labelsProvider) {
					private static final long serialVersionUID = 1L;

					@Override
					public void populateItem(final Item<String> labelItem) {
						RepositoryModel repository = app().repositories().getRepositoryModel(ticket.repository);
						Label label;
						TicketLabel tLabel;
						if (repository == null) {
							label = new Label("label", labelItem.getModelObject());
							tLabel = new TicketLabel(labelItem.getModelObject());
						} else {
							Repository db = app().repositories().getRepository(repository.name);
							BugtraqProcessor btp  = new BugtraqProcessor(app().settings());
							String content = btp.processText(db, repository.name, labelItem.getModelObject());
							String safeContent = app().xssFilter().relaxed(content);
							db.close();

							label = new Label("label", safeContent);
							label.setEscapeModelStrings(false);

							tLabel = app().tickets().getLabel(repository, labelItem.getModelObject());
						}

						String background = MessageFormat.format("background-color:{0};", tLabel.color);
						label.add(new SimpleAttributeModifier("style", background));
						labelItem.add(label);
					}
				};
				item.add(labelsView);

				if (StringUtils.isEmpty(ticket.responsible)) {
					item.add(new Label("responsible").setVisible(false));
				} else {
					UserModel responsible = app().users().getUserModel(ticket.responsible);
					if (responsible == null) {
						responsible = new UserModel(ticket.responsible);
					}
					AvatarImage avatar = new AvatarImage("responsible", responsible.getDisplayName(),
							responsible.emailAddress, null, 16, true);
					avatar.setTooltip(getString("gb.responsible") + ": " + responsible.getDisplayName());
					item.add(avatar);
				}

				// votes indicator
				Label v = new Label("votes", "" + ticket.votesCount);
				WicketUtils.setHtmlTooltip(v, getString("gb.votes"));
				item.add(v.setVisible(ticket.votesCount > 0));

				// watching indicator
				item.add(new Label("watching").setVisible(ticket.isWatching(GitBlitWebSession.get().getUsername())));

				// priority indicator
				Label priorityIcon = TicketsUI.getPriorityIcon("priority", ticket.priority);
				WicketUtils.addCssClass(priorityIcon, TicketsUI.getPriorityClass(ticket.priority));
				item.add(priorityIcon.setVisible(true));

				// status indicator
				String css = TicketsUI.getLozengeClass(ticket.status, true);
				Label l = new Label("status", ticket.status.toString());
				WicketUtils.setCssClass(l, css);
				item.add(l);

				// add the ticket indicators/icons
				List<Indicator> indicators = new ArrayList<Indicator>();

				// comments
				if (ticket.commentsCount > 0) {
					int count = ticket.commentsCount;
					String pattern = getString("gb.nComments");
					if (count == 1) {
						pattern = getString("gb.oneComment");
					}
					indicators.add(new Indicator("fa fa-comment", count, pattern));
				}

				// participants
				if (!ArrayUtils.isEmpty(ticket.participants)) {
					int count = ticket.participants.size();
					if (count > 1) {
						String pattern = getString("gb.nParticipants");
						indicators.add(new Indicator("fa fa-user", count, pattern));
					}
				}

				// attachments
				if (!ArrayUtils.isEmpty(ticket.attachments)) {
					int count = ticket.attachments.size();
					String pattern = getString("gb.nAttachments");
					if (count == 1) {
						pattern = getString("gb.oneAttachment");
					}
					indicators.add(new Indicator("fa fa-file", count, pattern));
				}

				// patchset revisions
				if (ticket.patchset != null) {
					int count = ticket.patchset.commits;
					String pattern = getString("gb.nCommits");
					if (count == 1) {
						pattern = getString("gb.oneCommit");
					}
					indicators.add(new Indicator("fa fa-code", count, pattern));
				}

				// milestone
				if (!StringUtils.isEmpty(ticket.milestone)) {
					indicators.add(new Indicator("fa fa-bullseye", ticket.milestone));
				}

				ListDataProvider<Indicator> indicatorsDp = new ListDataProvider<Indicator>(indicators);
				DataView<Indicator> indicatorsView = new DataView<Indicator>("indicators", indicatorsDp) {
					private static final long serialVersionUID = 1L;

					@Override
					public void populateItem(final Item<Indicator> item) {
						Indicator indicator = item.getModelObject();
						String tooltip = indicator.getTooltip();

						Label icon = new Label("icon");
						WicketUtils.setCssClass(icon, indicator.css);
						item.add(icon);

						if (indicator.count > 0) {
							Label count = new Label("count", "" + indicator.count);
							item.add(count.setVisible(!StringUtils.isEmpty(tooltip)));
						} else {
							item.add(new Label("count").setVisible(false));
						}

						WicketUtils.setHtmlTooltip(item, tooltip);
					}
				};
				item.add(indicatorsView);
			}
		};

		add(dataView);
	}
}

