package junit.swingui;

/*-
 * #%L
 * org.eclipse.jdt.ui.junit.sampleproject
 * %%
 * Copyright (C) 2020 Eclipse Foundation
 * %%
 * This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0
 * and Eclipse Distribution License v. 1.0 which accompanies this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 * #L%
 */

import java.awt.*;

import javax.swing.*;
import javax.swing.event.*;
import junit.framework.*;
import junit.runner.BaseTestRunner;

/**
 * A view presenting the test failures as a list.
 */
public class FailureRunView implements TestRunView {
	JList fFailureList;
	TestRunContext fRunContext;

	/**
	 * Renders TestFailures in a JList
	 */
	static class FailureListCellRenderer extends DefaultListCellRenderer {
		private Icon fFailureIcon;
		private Icon fErrorIcon;

		FailureListCellRenderer() {
			super();
			loadIcons();
		}

		void loadIcons() {
			fFailureIcon = TestRunner.getIconResource(getClass(), "icons/failure.gif");
			fErrorIcon = TestRunner.getIconResource(getClass(), "icons/error.gif");
		}

		public Component getListCellRendererComponent(JList list, Object value, int modelIndex, boolean isSelected,
				boolean cellHasFocus) {

			Component c = super.getListCellRendererComponent(list, value, modelIndex, isSelected, cellHasFocus);
			TestFailure failure = (TestFailure) value;
			String text = failure.failedTest().toString();
			String msg = failure.exceptionMessage();
			if (msg != null)
				text += ":" + BaseTestRunner.truncate(msg);

			if (failure.isFailure()) {
				if (fFailureIcon != null)
					setIcon(fFailureIcon);
			} else {
				if (fErrorIcon != null)
					setIcon(fErrorIcon);
			}
			setText(text);
			setToolTipText(text);
			return c;
		}
	}

	public FailureRunView(TestRunContext context) {
		fRunContext = context;
		fFailureList = new JList(fRunContext.getFailures());
		fFailureList.setFont(new Font("Dialog", Font.PLAIN, 12));

		fFailureList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		fFailureList.setCellRenderer(new FailureListCellRenderer());
		fFailureList.setVisibleRowCount(5);

		fFailureList.addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent e) {
				testSelected();
			}
		});
	}

	public Test getSelectedTest() {
		int index = fFailureList.getSelectedIndex();
		if (index == -1)
			return null;

		ListModel model = fFailureList.getModel();
		TestFailure failure = (TestFailure) model.getElementAt(index);
		return failure.failedTest();
	}

	public void activate() {
		testSelected();
	}

	public void addTab(JTabbedPane pane) {
		JScrollPane scrollPane = new JScrollPane(fFailureList, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
				JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		Icon errorIcon = TestRunner.getIconResource(getClass(), "icons/error.gif");
		pane.addTab("Failures", errorIcon, scrollPane, "The list of failed tests");
	}

	public void revealFailure(Test failure) {
		fFailureList.setSelectedIndex(0);
	}

	public void aboutToStart(Test suite, TestResult result) {
	}

	public void runFinished(Test suite, TestResult result) {
	}

	protected void testSelected() {
		fRunContext.handleTestSelected(getSelectedTest());
	}
}
