//------------------------------------------------------------------------------
// 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.io.File;
import java.util.Collection;

import org.eclipse.epf.authoring.gef.viewer.ActivityDiagramService;
import org.eclipse.epf.authoring.ui.AuthoringUIImages;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.authoring.ui.BrowsingPerspective;
import org.eclipse.epf.authoring.ui.UIActionDispatcher;
import org.eclipse.epf.common.utils.PerspectiveUtil;
import org.eclipse.epf.library.ILibraryManager;
import org.eclipse.epf.library.ILibraryServiceListener;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.events.ILibraryChangeListener;
import org.eclipse.epf.library.layout.ElementLayoutManager;
import org.eclipse.epf.library.layout.HtmlBuilder;
import org.eclipse.epf.library.ui.preferences.LibraryUIPreferences;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveListener;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;

/**
 * The Content view.
 * <p>
 * Displays the HTML representation of a Method element.
 * 
 * @author Jinhua Xi
 * @author Kelvin Low
 * @since 1.0
 */
public class ContentView extends ViewPart {

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

	private ElementHTMLViewer contentViewer;

	private Object displayedElement;

	private IPartListener partListener = new IPartListener() {
		public void partActivated(IWorkbenchPart part) {
			handleSelection(UIActionDispatcher.getInstance()
					.getSelectionSource(), UIActionDispatcher.getInstance()
					.getSelection());
		}

		public void partBroughtToTop(IWorkbenchPart part) {
		}

		public void partClosed(IWorkbenchPart part) {
		}

		public void partDeactivated(IWorkbenchPart part) {
		}

		public void partOpened(IWorkbenchPart part) {
		}
	};

	private ISelectionChangedListener selectionChangeListener = new ISelectionChangedListener() {
		public void selectionChanged(SelectionChangedEvent event) {
			handleSelection(event.getSource(), event.getSelection());
		}
	};

	private ILibraryChangeListener libraryChangeListener = new ILibraryChangeListener() {
		public void libraryChanged(int option, Collection changedItems) {
//			if (option == ILibraryChangeListener.OPTION_LOADED
//					|| option == ILibraryChangeListener.OPTION_CREATED) {
//				if (contentViewer != null) {
//					contentViewer.setHtmlBuilder(new HtmlBuilder());
//					contentViewer.getBrowser().redraw();
//				}
//			}

			if (changedItems != null && displayedElement != null) {
				if (changedItems.contains(displayedElement)) {
					displayedElement = null;
				}
			}
		}
	};

	private ILibraryServiceListener libSvcListener = new ILibraryServiceListener() {

		public void configurationSet(MethodConfiguration config) {
			// System.out.println("configuration set: " + LibraryUtil.getTypeName(config));
			contentViewer.getBrowser().setUrl("about:blank"); //$NON-NLS-1$
			displayedElement = null;
		}

		public void libraryClosed(MethodLibrary library) {
			// System.out.println("Library closed: " + LibraryUtil.getTypeName(library));
		}

		public void libraryCreated(MethodLibrary library) {
			// System.out.println("Library created: " + LibraryUtil.getTypeName(library));
			cleanup();
		}

		public void libraryOpened(MethodLibrary library) {
			// System.out.println("Library opened: " + LibraryUtil.getTypeName(library));
			cleanup();
		}

		public void libraryReopened(MethodLibrary library) {
			// System.out.println("Library reopened: " + LibraryUtil.getTypeName(library));
			cleanup();
		}

		public void librarySet(MethodLibrary library) {
			// System.out.println("Library set: " + LibraryUtil.getTypeName(library));
		}
		
		private void cleanup() {
			if (contentViewer != null) {
				contentViewer.setHtmlBuilder(new HtmlBuilder());
				contentViewer.getBrowser().redraw();
			}
		}
	};
	
	// Page navigation actions.
	private Action backAction;

	private Action forwardAction;

	private Action stopAction;

	private Action refreshAction;

	private Action printAction;

	// A hidden composite to hold the diagram viewer for diagram image
	// generation.
	private Composite diagramViewerHolder;

	/**
	 * Creates a new instance.
	 */
	public ContentView() {
	}

	/**
	 * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(Composite)
	 */
	public void createPartControl(Composite parent) {
		try {
			GridLayout layout = new GridLayout();
			layout.marginWidth = 0;
			layout.marginHeight = 0;
			layout.horizontalSpacing = 0;
			layout.verticalSpacing = 0;
			parent.setLayout(layout);
			parent.setLayoutData(new GridData(GridData.FILL_BOTH));

			contentViewer = new ElementHTMLViewer(parent);
			diagramViewerHolder = new Composite(parent, SWT.NONE);
			diagramViewerHolder.setLayoutData(new GridData(1, 1)); // size
			// can't be
			// 0,0
			// otherwise
			// the
			// diagram
			// will not
			// be
			// painted
			diagramViewerHolder.setLayout(new GridLayout());
			diagramViewerHolder.setVisible(false);

			// Create the page navigation tool buttons.
			createActions();

			// Add a part listener to monitor part activation and update this
			// view
			// as and when needed.
			getSite().getWorkbenchWindow().getPartService().addPartListener(
					partListener);

			getSite().getWorkbenchWindow().addPerspectiveListener(
					new IPerspectiveListener() {
						public void perspectiveActivated(IWorkbenchPage page,
								IPerspectiveDescriptor desc) {
						}

						public void perspectiveChanged(IWorkbenchPage page,
								IPerspectiveDescriptor desc, String id) {
							if (desc.getId().equals(
									BrowsingPerspective.PERSPECTIVE_ID)) {
								if (id
										.equals(IWorkbenchPage.CHANGE_EDITOR_AREA_SHOW)) {
									page.setEditorAreaVisible(false);
									AuthoringUIPlugin
											.getDefault()
											.getMsgDialog()
											.displayWarning(
													AuthoringUIResources.warningDialog_title, 
													AuthoringUIResources.addEditorToPerspectiveWarning_msg); 
								}
							}
						}
					});

			// Add selection change listener to update this view as and when
			// needed.
			UIActionDispatcher.getInstance().addSelectionChangedListener(
					selectionChangeListener);

			LibraryService.getInstance().addListener(libSvcListener);

			ILibraryManager manager = LibraryService.getInstance().getCurrentLibraryManager();
			if (manager != null) {
				manager.addListener(libraryChangeListener);
			}
		} catch (Exception e) {
			// TODO: Display an error dialog.
			e.printStackTrace();
		}
	}

	/**
	 * @see org.eclipse.ui.part.WorkbenchPart#setFocus
	 */
	public void setFocus() {
		contentViewer.setFocus();
	}

	/**
	 * @see org.eclipse.ui.part.WorkbenchPart#dispose
	 */
	public void dispose() {
		LibraryService.getInstance().removeListener(libSvcListener);

		ILibraryManager manager = LibraryService.getInstance().getCurrentLibraryManager();
		if (manager != null) {
			manager.removeListener(libraryChangeListener);
		}
		UIActionDispatcher.getInstance().removeSelectionChangedListener(
				selectionChangeListener);
		getSite().getWorkbenchWindow().getPartService().removePartListener(
				partListener);
	}

	/**
	 * Creates the actions for this view.
	 */
	protected void createActions() {
		backAction = new Action() {
			public void run() {
				Browser browser = contentViewer.getBrowser();
				if (browser != null) {
					browser.back();
				}
			}
		};
		backAction.setText(AuthoringUIResources.back_text); 
		backAction.setToolTipText(AuthoringUIResources.back_text); 
		backAction.setImageDescriptor(PlatformUI.getWorkbench()
				.getSharedImages().getImageDescriptor(
						ISharedImages.IMG_TOOL_BACK));

		forwardAction = new Action() {
			public void run() {
				Browser browser = contentViewer.getBrowser();
				if (browser != null) {
					browser.forward();
				}
			}
		};
		forwardAction.setText(AuthoringUIResources.forward_text); 
		forwardAction.setToolTipText(AuthoringUIResources.forward_text); 
		forwardAction.setImageDescriptor(PlatformUI.getWorkbench()
				.getSharedImages().getImageDescriptor(
						ISharedImages.IMG_TOOL_FORWARD));

		stopAction = new Action() {
			public void run() {
				Browser browser = contentViewer.getBrowser();
				if (browser != null) {
					browser.stop();
				}
			}
		};
		stopAction.setText(AuthoringUIResources.stop_text); 
		stopAction.setToolTipText(AuthoringUIResources.stop_text); 
		stopAction.setImageDescriptor(AuthoringUIImages.IMG_DESC_STOP);

		refreshAction = new Action() {
			public void run() {
				// Browser browser = contentViewer.getBrowser();
				// if (browser != null) {
				// browser.refresh();
				// }

				// need to regenerate the content
				contentViewer.refresh();
			}
		};
		refreshAction.setText(AuthoringUIResources.refresh_text); 
		refreshAction.setToolTipText(AuthoringUIResources.refresh_text); 
		refreshAction.setImageDescriptor(AuthoringUIImages.IMG_DESC_REFRESH);

		printAction = new Action() {
			public void run() {
				contentViewer.print();
			}
		};
		printAction.setText(AuthoringUIResources.print_text); 
		printAction.setToolTipText(AuthoringUIResources.print_text); 
		printAction.setImageDescriptor(AuthoringUIImages.IMG_DESC_PRINT);

		IActionBars bars = getViewSite().getActionBars();
		IToolBarManager manager = bars.getToolBarManager();
		manager.add(backAction);
		manager.add(forwardAction);
		manager.add(stopAction);
		manager.add(refreshAction);
		manager.add(printAction);
	}

	/**
	 * Handles the given selection.
	 * 
	 * @param source
	 *            The Library or Configuration view.
	 * @param selection
	 *            The selection in the Library or Configuration view.
	 */
	protected void handleSelection(Object source, ISelection selection) {
		if (selection == null) {
			return;
		}

		IWorkbenchPage activePage = getSite().getWorkbenchWindow()
				.getActivePage();
		if (activePage == null) {
			return;
		}

		IViewPart view = activePage.findView(VIEW_ID);
		if (view == null) {
			return;
		}

		if (selection instanceof IStructuredSelection) {
			IStructuredSelection sel = (IStructuredSelection) selection;
			Object[] selectedElements = sel.toArray();
			if (selectedElements != null && selectedElements.length > 0) {
				Object element = selectedElements[0];
				
				// don't unwrap the object. 
				// For activity, we need to wrapped item provider to get the suppress status.
				// Object element = LibraryUtil.unwrap(selectedElement);
				if (displayedElement != null && displayedElement == element) {
					displayedElement = null;
					return;
				}
				if (displayContentPage(source, element)) {
					displayedElement = element;
				}
			}
		}
	}

	/**
	 * Displays the content page for the given ContentElement.
	 * 
	 * @param source
	 *            The Library or Configuration view.
	 * @param element
	 *            The selected Method element.
	 * @return <code>true</code> if the content page is displayed
	 *         successfully.
	 */
	protected boolean displayContentPage(Object source, Object raw_element) {
		Object element = LibraryUtil.unwrap(raw_element);
		element = ViewHelper.handleDangling(element);
		if (element == null) {
			return false;
		}

		ElementLayoutManager layoutMgr = null;
		boolean isBrowsing = PerspectiveUtil
				.isActivePerspective(BrowsingPerspective.PERSPECTIVE_ID);
		boolean isConfigSource = (source != null)
				&& (source instanceof ConfigurationView);

		// if in browsing but the source is not from configruation view
		// ignore it
		if (isBrowsing && !isConfigSource) {
			return false;
		}

		if (isConfigSource) {
			// Get the Element Layout Manager for the current configuration.
			layoutMgr = LibraryService.getInstance()
					.getCurrentConfigurationManager().getElementLayoutManager();

			// Add the activity diagram service to generate diagram images.
			ActivityDiagramService diagramService = (ActivityDiagramService) layoutMgr
					.getActivityDiagramService();
			if (diagramService == null) {
				diagramService = new ActivityDiagramService(
						diagramViewerHolder,
						new File(layoutMgr.getPublishDir()));
				layoutMgr.setActivityDiagramService(diagramService);
			}
			
			// For Activity Detail Diagram 
			boolean option = LibraryUIPreferences.getPublishUnopenActivitydd();
			diagramService.setPublishedUnCreatedADD(option);
			
			// For Activity Diagram 
			option = LibraryUIPreferences.getPublishADForActivityExtension();
			diagramService.setPublishADForActivityExtension(option);
			
		}

		contentViewer.setLayoutManager(layoutMgr);
		contentViewer.showElementContent(raw_element);

		return true;
	}

	/**
	 * Displays the HTML content page for a Method element.
	 * 
	 * @param element
	 *            A Method element.
	 * @return <code>true</code> if the HTML content page is displayed
	 *         successfully.
	 */
	public boolean displayHTMLContentPage(Object element) {
		element = LibraryUtil.unwrap(element);
		element = ViewHelper.handleDangling(element);
		if (element != null) {
			contentViewer.setLayoutManager(null);
			contentViewer.showElementContent(element);
			return true;
		}
		return false;
	}

}
