/*******************************************************************************
 * Copyright (c) 2004, 2011 Ken Sueda and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Ken Sueda - initial API and implementation
 *     Tasktop Technologies - improvements
 *******************************************************************************/

package org.eclipse.mylyn.tasks.tests;

import java.util.Date;
import java.util.List;
import java.util.Vector;

import junit.framework.TestCase;

import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
import org.eclipse.mylyn.internal.tasks.core.TaskCategory;
import org.eclipse.mylyn.internal.tasks.core.TaskList;
import org.eclipse.mylyn.internal.tasks.ui.MoveToCategoryMenuContributor;
import org.eclipse.mylyn.internal.tasks.ui.TaskPriorityFilter;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
import org.eclipse.mylyn.internal.tasks.ui.actions.NewCategoryAction;
import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
import org.eclipse.mylyn.internal.tasks.ui.views.TaskListView;
import org.eclipse.mylyn.tasks.core.IRepositoryElement;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.mylyn.tasks.core.ITask.PriorityLevel;
import org.eclipse.mylyn.tasks.tests.connector.MockRepositoryQuery;
import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
import org.eclipse.swt.widgets.TreeItem;

/**
 * Tests TaskListView's filtering mechanism.
 * 
 * @author Ken Sueda
 * @author Steffen Pingel
 */
public class TaskListUiTest extends TestCase {

	private TaskCategory cat1 = null;

	private AbstractTask cat1task1 = null;

	private AbstractTask cat1task2 = null;

	private AbstractTask cat1task3 = null;

	private AbstractTask cat1task4 = null;

	private AbstractTask cat1task5 = null;

	private AbstractTask cat1task1sub1 = null;

	private TaskCategory cat2 = null;

	private AbstractTask cat2task1 = null;

	private AbstractTask cat2task2 = null;

	private AbstractTask cat2task3 = null;

	private AbstractTask cat2task4 = null;

	private AbstractTask cat2task5 = null;

	private AbstractTask cat2task1sub1 = null;

	private TaskList taskList;

	private final static int CHECK_COMPLETE_FILTER = 1;

	private final static int CHECK_INCOMPLETE_FILTER = 2;

	private final static int CHECK_PRIORITY_FILTER = 3;

	@Override
	public void setUp() throws Exception {
		taskList = TasksUiPlugin.getTaskList();

		// make sure no unmatched folders exist
		TaskTestUtil.resetTaskListAndRepositories();
		TasksUiPlugin.getDefault().getLocalTaskRepository();
		TasksUiUtil.openTasksViewInActivePerspective();

		cat1 = new TaskCategory("First Category");
		taskList.addCategory(cat1);

		cat1task1 = TasksUiInternal.createNewLocalTask("task 1");
		cat1task1.setPriority(PriorityLevel.P1.toString());
		cat1task1.setCompletionDate(new Date());
		taskList.addTask(cat1task1, cat1);

		cat1task1sub1 = TasksUiInternal.createNewLocalTask("sub task 1");
		cat1task1sub1.setPriority(PriorityLevel.P1.toString());
		cat1task1sub1.setCompletionDate(new Date());
		taskList.addTask(cat1task1sub1, cat1task1);

		cat1task2 = TasksUiInternal.createNewLocalTask("task 2");
		cat1task2.setPriority(PriorityLevel.P2.toString());
		taskList.addTask(cat1task2, cat1);

		cat1task3 = TasksUiInternal.createNewLocalTask("task 3");
		cat1task3.setPriority(PriorityLevel.P3.toString());
		cat1task3.setCompletionDate(new Date());
		taskList.addTask(cat1task3, cat1);

		cat1task4 = TasksUiInternal.createNewLocalTask("task 4");
		cat1task4.setPriority(PriorityLevel.P4.toString());
		taskList.addTask(cat1task4, cat1);

		cat1task5 = TasksUiInternal.createNewLocalTask("task 5");
		cat1task5.setPriority(PriorityLevel.P5.toString());
		cat1task5.setCompletionDate(new Date());
		taskList.addTask(cat1task5, cat1);

		assertEquals(cat1.getChildren().size(), 5);

		cat2 = new TaskCategory("Second Category");
		taskList.addCategory(cat2);

		cat2task1 = TasksUiInternal.createNewLocalTask("task 1");
		cat2task1.setPriority(PriorityLevel.P1.toString());
		taskList.addTask(cat2task1, cat2);

		cat2task1sub1 = TasksUiInternal.createNewLocalTask("sub task 1");
		cat2task1sub1.setPriority(PriorityLevel.P1.toString());
		taskList.addTask(cat2task1sub1, cat2task1);

		cat2task2 = TasksUiInternal.createNewLocalTask("task 2");
		cat2task2.setPriority(PriorityLevel.P2.toString());
		cat2task2.setCompletionDate(new Date());
		taskList.addTask(cat2task2, cat2);

		cat2task3 = TasksUiInternal.createNewLocalTask("task 3");
		cat2task3.setPriority(PriorityLevel.P3.toString());
		taskList.addTask(cat2task3, cat2);

		cat2task4 = TasksUiInternal.createNewLocalTask("task 4");
		cat2task4.setPriority(PriorityLevel.P4.toString());
		cat2task4.setCompletionDate(new Date());
		taskList.addTask(cat2task4, cat2);

		cat2task5 = TasksUiInternal.createNewLocalTask("task 5");
		cat2task5.setPriority(PriorityLevel.P5.toString());
		taskList.addTask(cat2task5, cat2);
	}

	@Override
	public void tearDown() throws Exception {
		// clear everything
	}

	public void testUiFilter() {
		assertNotNull(TaskListView.getFromActivePerspective());
		TreeViewer viewer = TaskListView.getFromActivePerspective().getViewer();
		TaskListView.getFromActivePerspective().addFilter(TaskListView.getFromActivePerspective().getCompleteFilter());
		viewer.refresh();
		viewer.expandAll();
		TreeItem[] items = viewer.getTree().getItems();
		assertTrue(checkFilter(CHECK_COMPLETE_FILTER, items));
		TaskListView.getFromActivePerspective().removeFilter(
				TaskListView.getFromActivePerspective().getCompleteFilter());

		TaskPriorityFilter filter = TaskListView.getFromActivePerspective().getPriorityFilter();
		filter.displayPrioritiesAbove("P2");
		TaskListView.getFromActivePerspective().addFilter(filter);
		viewer.refresh();
		viewer.expandAll();
		items = viewer.getTree().getItems();

		// check priority tasks
		assertTrue(checkFilter(CHECK_PRIORITY_FILTER, items));
	}

	/**
	 * Tests that TaskEditors remove all listeners when closed
	 */
	// FIXME re-enable test
	//	public void testListenersRemoved() {
//		int numListenersBefore = 0;
//		int numListenersDuring = 0;
//		int numListenersAfter = 0;
//
//		IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
//		assertTrue(activePage.closeAllEditors(false));
//
//		Set<ITaskListChangeListener> listeners = taskList.getChangeListeners();
//		numListenersBefore = listeners.size();
//
//		TasksUiUtil.openTask(cat1task1);
//		TasksUiUtil.openTask(cat1task2);
//
//		listeners = taskList.getChangeListeners();
//		numListenersDuring = listeners.size();
//
//		// each editor adds a listener for the editor and planning part
//		assertEquals(numListenersDuring, numListenersBefore + 4);
//
//		assertTrue(activePage.closeAllEditors(false));
//
//		listeners = taskList.getChangeListeners();
//		numListenersAfter = listeners.size();
//		assertEquals(numListenersBefore, numListenersAfter);
//	}

	/**
	 * Tests whether an additional NewCategory action is added to the category
	 */
	public void testGetSubMenuManagerContainsAllCategoriesPlusNewCategory() {
		// setup
		MoveToCategoryMenuContributor moveToMenuContrib = new MoveToCategoryMenuContributor();
		List<IRepositoryElement> selectedElements = new Vector<IRepositoryElement>();
		selectedElements.add(cat1task1);
		int numCategories = taskList.getCategories().size();
		int numSeparators = 1;
		// adding a separator and the New Category... action
		int expectedNrOfSubMenuEntries = numCategories + numSeparators + 1;
		NewCategoryAction newCatActon = new NewCategoryAction();

		// execute sytem under test
		MenuManager menuManager = moveToMenuContrib.getSubMenuManager(selectedElements);
		IContributionItem[] items = menuManager.getItems();
		IContributionItem item = items[menuManager.getItems().length - 1];

		// +1 for separator
		assertEquals(expectedNrOfSubMenuEntries, menuManager.getItems().length);

		if (item instanceof NewCategoryAction) {
			NewCategoryAction action = (NewCategoryAction) item;
			assertEquals(newCatActon.getText(), action.getText());
		}

		// teardown
	}

	/**
	 * Tests visibility of SubMenuManager
	 */
	public void testVisibilityOfSubMenuManager() {
		//setup
		MoveToCategoryMenuContributor moveToMenuContrib = new MoveToCategoryMenuContributor();
		MenuManager menuManager = null;
		List<IRepositoryElement> selectedElements = new Vector<IRepositoryElement>();
		selectedElements.add(cat1task1);

		List<IRepositoryElement> emptySelection = new Vector<IRepositoryElement>();

		List<IRepositoryElement> categorySelection = new Vector<IRepositoryElement>();
		categorySelection.add(cat1);

		List<IRepositoryElement> querySelection = new Vector<IRepositoryElement>();
		querySelection.add(new MockRepositoryQuery("query", null));

		//execute system under test & assert
		menuManager = moveToMenuContrib.getSubMenuManager(selectedElements);
		assertTrue(menuManager.isVisible());

		menuManager = null;
		menuManager = moveToMenuContrib.getSubMenuManager(emptySelection);
		assertFalse(menuManager.isVisible());

		menuManager = null;
		menuManager = moveToMenuContrib.getSubMenuManager(categorySelection);
		assertFalse(menuManager.isVisible());

		menuManager = null;
		menuManager = moveToMenuContrib.getSubMenuManager(querySelection);
		assertFalse(menuManager.isVisible());

		//teardown
	}

	/**
	 * Tests that the category name is shown in the Move To Category submenu, even when they have an @ in their name
	 */
	public void testCategoryNameIsShownInMoveToCategoryAction() {
		String catNameWithAtBefore = "@CatName";
		String catNameWithAtExpected = "@CatName@";
		String catNameWithAtActual = "";

		String catNameNoAtBefore = "CatName";
		String catNameNoAtExpected = "CatName";
		String catNameNoAtActual = "";

		MoveToCategoryMenuContributor menuContrib = new MoveToCategoryMenuContributor();

		catNameWithAtActual = menuContrib.handleAcceleratorKeys(catNameWithAtBefore);
		catNameNoAtActual = menuContrib.handleAcceleratorKeys(catNameNoAtBefore);

		assertEquals(catNameWithAtExpected, catNameWithAtActual);
		assertEquals(catNameNoAtExpected, catNameNoAtActual);
	}

	public boolean checkFilter(int type, TreeItem[] items) {
		switch (type) {
		case CHECK_COMPLETE_FILTER:
			return checkCompleteIncompleteFilter(items, false);
		case CHECK_INCOMPLETE_FILTER:
			return checkCompleteIncompleteFilter(items, true);
		case CHECK_PRIORITY_FILTER:
			return checkPriorityFilter(items);
		default:
			return false;
		}
	}

	public boolean checkCompleteIncompleteFilter(TreeItem[] items, boolean checkComplete) {
		assertEquals(2, items.length);
		int count = 0;
		for (TreeItem item : items) {
			if (item.getData() instanceof TaskCategory) {
				TreeItem[] sub = item.getItems();
				for (TreeItem element : sub) {
					assertTrue(element.getData() instanceof ITask);
					ITask task = (ITask) element.getData();
					if (checkComplete) {
						assertTrue(task.isCompleted());
					} else {
						assertFalse(task.isCompleted());
					}
					count++;
				}
			}
		}
		assertEquals(5, count);
		return true;
	}

	public boolean checkPriorityFilter(TreeItem[] items) {
		assertEquals(2, items.length);
		int p2Count = 0;
		int p1Count = 0;
		for (TreeItem item : items) {
			if (item.getData() instanceof TaskCategory) {
				TreeItem[] sub = item.getItems();
				for (TreeItem element : sub) {
					assertTrue(element.getData() instanceof ITask);
					ITask task = (ITask) element.getData();
					assertTrue(task.getPriority().equals("P2") || task.getPriority().equals("P1"));
					if (task.getPriority().equals("P2")) {
						p2Count++;
					} else {
						p1Count++;
					}
				}
			}
		}
		assertEquals(2, p1Count);
		assertEquals(2, p2Count);
		return true;
	}

}
