//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation 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:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.authoring.ui.views;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.authoring.ui.editors.ConfigurationEditor;
import org.eclipse.epf.library.configuration.ConfigurationClosure;
import org.eclipse.epf.library.configuration.ElementDependencyError;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;


/**
 * The Message view.
 * <p>
 * Displays the Method Library error and warning messages
 * 
 * @author Jinhua Xi
 * @since 1.0
 */
public class MessageView extends ViewPart implements ISelectionProvider,
		IPartListener {

	/**
	 * The view ID.
	 */
	public static final String VIEW_ID = MessageView.class.getName();

	public static final int ERROR_MESSAGE_COLUMN = 0;

	public static final int ERROR_ELEMENT_COLUMN = 1;

	public static final int CAUSE_ELEMENT_COLUMN = 2;

	protected MessageViewer tableViewer;

	protected Collection selectionChangedListeners = new ArrayList();

	private ISelectionChangedListener selectionChangedListener = null;

	protected ISelection currentSelection = StructuredSelection.EMPTY;

	private ConfigurationClosure closure = null;

	public MessageView() {
	}

	public void configurationFactoryChanged(ConfigurationClosure closure) {
		this.closure = closure;

		ComposedAdapterFactory adapterFactory = null;
		if (closure != null) {
			adapterFactory = (ComposedAdapterFactory) closure
					.getConfigurationManager().getAdapterFactory();
			tableViewer.setLabelProvider(new MessageLabelProvider(
					adapterFactory));
		}
		tableViewer.setContentProvider(new MessageContentProvider(closure));

		updateMessage();
	}

	public void addSelectionChangedListener(ISelectionChangedListener listener) {
		selectionChangedListeners.add(listener);
	}

	public void removeSelectionChangedListener(
			ISelectionChangedListener listener) {
		selectionChangedListeners.remove(listener);
	}

	public ISelection getSelection() {
		return currentSelection;
	}

	public void setSelection(ISelection selection) {
		currentSelection = selection;

		for (Iterator listeners = new ArrayList(selectionChangedListeners)
				.iterator(); listeners.hasNext();) {
			ISelectionChangedListener listener = (ISelectionChangedListener) listeners
					.next();
			listener
					.selectionChanged(new SelectionChangedEvent(this, selection));
		}
	}

	private void createViewer(Composite composite) {
		tableViewer = new MessageViewer(composite);

		IViewSite site = (IViewSite) this.getSite();
		site.setSelectionProvider(this);

		if (selectionChangedListener == null) {
			// Create the listener
			selectionChangedListener = new ISelectionChangedListener() {
				// This just notifies those things that are affected by the
				// section.
				public void selectionChanged(SelectionChangedEvent event) {
					System.out
							.println(AuthoringUIResources.MessageView_selected_text + event.getSelection()); //$NON-NLS-1$
					setSelection(event.getSelection());
				}
			};

			tableViewer.addSelectionChangedListener(selectionChangedListener);
		}

		// Set column info.
		setColumns();
	}

	private void setColumns() {
		Tree table = tableViewer.getTree();
		table.setHeaderVisible(true);
		table.setLinesVisible(true);

		TreeColumn column;

		column = new TreeColumn(table, SWT.NONE, ERROR_MESSAGE_COLUMN);
		column.setText(AuthoringUIResources.MessageView_errmsg_text); //$NON-NLS-1$
		column.setWidth(450);

		column = new TreeColumn(table, SWT.NONE, ERROR_ELEMENT_COLUMN);
		column.setText(AuthoringUIResources.MessageView_errelement_text); //$NON-NLS-1$
		column.setWidth(200);

		column = new TreeColumn(table, SWT.NONE, CAUSE_ELEMENT_COLUMN);
		column.setText(AuthoringUIResources.MessageView_refelement_text); //$NON-NLS-1$
		column.setWidth(200);

	}

	public void createPartControl(Composite parent) {
		createViewer(parent);

		IWorkbenchWindow workbenchWindow = getSite().getWorkbenchWindow();
		workbenchWindow.getPartService().addPartListener(this);
	}

	public void setFocus() {
	}

	public static MessageView getView() {
		try {
			IWorkbenchPage activePage = PlatformUI.getWorkbench()
					.getActiveWorkbenchWindow().getActivePage();
			if (activePage != null) {
				IViewPart view = activePage.findView(VIEW_ID);
				if (view == null) {
					view = activePage.showView(VIEW_ID);
				}
				return (MessageView) view;
			}

		} catch (Exception ex) {
			ex.printStackTrace();
		}

		return null;
	}

	public void updateMessage() {
		if (closure != null) {
			tableViewer.setInput(closure);
		} else {
			tableViewer.setInput(new Object());
		}
	}

	public boolean isDisposed() {
		return (closure == null);
	}

	public void dispose() {
		super.dispose();

		IWorkbenchWindow workbenchWindow = getSite().getWorkbenchWindow();
		workbenchWindow.getPartService().removePartListener(this);

		selectionChangedListeners.clear();
		closure = null;
	}

	/**
	 * Show the error for the element.
	 */
	public void showError(Object e) {
		ElementDependencyError error = closure.getError(e);
		if (error != null) {
			tableViewer.setSelection(error);
		}
	}

	public class MessageViewer extends TreeViewer {

		public MessageViewer(Composite parent) {
			this(parent, SWT.FULL_SELECTION);
		}

		public MessageViewer(Composite parent, int style) {
			super(parent, style);

			Tree tree = getTree();
			tree.setHeaderVisible(true);
			tree.setLinesVisible(true);

		}

		public void setSelection(Object element) {
			super.expandToLevel(element, 1);
			Widget ctrl = super.findItem(element);
			if (ctrl != null) {
				List items = new ArrayList();
				items.add(ctrl);
				super.setSelection(items);
			}
		}
	}

	public void partActivated(IWorkbenchPart part) {
		if (part instanceof ConfigurationEditor) {
			ConfigurationClosure c = ((ConfigurationEditor) part).getClosure();
			if (c != closure) {
				configurationFactoryChanged(c);
			}
		}
	}

	public void partBroughtToTop(IWorkbenchPart part) {
	}

	public void partClosed(IWorkbenchPart part) {
		if (part instanceof ConfigurationEditor) {
			ConfigurationClosure c = ((ConfigurationEditor) part).getClosure();
			if (c == closure) {
				configurationFactoryChanged(null);
			}
		}
	}

	public void partDeactivated(IWorkbenchPart part) {
	}

	public void partOpened(IWorkbenchPart part) {
	}

}
