//------------------------------------------------------------------------------
// 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.publishing.wizards;

import java.lang.reflect.InvocationTargetException;
import java.text.MessageFormat;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.epf.common.serviceability.MsgDialog;
import org.eclipse.epf.library.services.SafeUpdateController;
import org.eclipse.epf.publishing.PublishingResources;
import org.eclipse.epf.publishing.services.AbstractPublishManager;
import org.eclipse.epf.publishing.services.AbstractViewBuilder;
import org.eclipse.epf.publishing.ui.PublishingUIPlugin;
import org.eclipse.epf.publishing.ui.PublishingUIResources;
import org.eclipse.jface.operation.IRunnableWithProgress;
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.program.Program;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;


/**
 * Performs the real work of publishing a Method Configuration.
 * 
 * @author Jinhua Xi
 * @author Kelvin Low
 * @since 1.0
 */
public class PublishingOperation implements IRunnableWithProgress {

	private static final String PUBLISH_CONFIG_ERROR_TITLE = PublishingUIResources.publishConfigDialog_title; //$NON-NLS-1$

	private static final String PUBLISH_CONFIG_ERROR_MSG = PublishingUIResources.publishConfigError_msg; //$NON-NLS-1$

	private static final String PUBLISH_CONFIG_ERROR_REASON = PublishingUIResources.publishConfigError_reason; //$NON-NLS-1$

	private static final String PREVIEW_CONFIG_ERROR_TITLE = PublishingUIResources.previewConfigError_title; //$NON-NLS-1$

	private static final String PREVIEW_CONFIG_ERROR_MSG = PublishingUIResources.previewConfigError_msg; //$NON-NLS-1$

	private static final String VIEW_REPORT_ERROR_TITLE = PublishingUIResources.viewReportError_title; //$NON-NLS-1$

	private static final String VIEW_REPORT_ERROR_MSG = PublishingUIResources.viewReportError_msg; //$NON-NLS-1$	

	private static final String OPEN_BROWSER_ERROR_REASON = PublishingUIResources.openBrowserError_reason; //$NON-NLS-1$

	private static final String PUBLISH_CONFIG_CANCEL_MSG = PublishingUIResources.cancelPublishConfig_msg; //$NON-NLS-1$

	private AbstractPublishManager publishMgr;

	private String published_url;

	private String report_url;

	private MsgDialog msgDialog;

	private Exception runException;

	/**
	 * Creates a new instance.
	 */
	public PublishingOperation(AbstractPublishManager publishMgr) {
		super();
		this.publishMgr = publishMgr;
		this.msgDialog = PublishingUIPlugin.getDefault().getMsgDialog();
	}

	public AbstractViewBuilder getViewBuilder() {
		return this.publishMgr.getViewBuilder();
	}

	public String getPublishedUrl() {
		return published_url;
	}

	public void run(IProgressMonitor monitor) throws InvocationTargetException,
			InterruptedException {
		runException = null;
		try {
			monitor.setTaskName(PublishingResources.publishingConfigurationTask_name); //$NON-NLS-1$			
			publishMgr.publish(monitor);

			published_url = publishMgr.getPublishedUrl();
			report_url = publishMgr.getPublishReportUrl();
		} catch (Exception e) {
			runException = e;
		}

		final boolean canceled = monitor.isCanceled();

		SafeUpdateController.syncExec(new Runnable() {
			public void run() {
				if (canceled) {
					msgDialog.displayInfo(PUBLISH_CONFIG_ERROR_TITLE,
							PUBLISH_CONFIG_CANCEL_MSG);
					return;
				}

				if (published_url == null || report_url == null) {
					msgDialog.displayError(PUBLISH_CONFIG_ERROR_TITLE,
							PUBLISH_CONFIG_ERROR_MSG,
							PUBLISH_CONFIG_ERROR_REASON, runException);
					return;
				}

				// Launch a HTML browser to view the published site.
				if (openBrowser(published_url) == false) {
					String reason = MessageFormat.format(
							OPEN_BROWSER_ERROR_REASON,
							new Object[] { published_url });
					msgDialog.displayError(PREVIEW_CONFIG_ERROR_TITLE,
							PREVIEW_CONFIG_ERROR_MSG, reason);
				}

				// Launch a HTML browser to view the report on the published
				// site.
				if (openBrowser(report_url) == false) {
					String reason = MessageFormat.format(
							OPEN_BROWSER_ERROR_REASON,
							new Object[] { report_url });
					msgDialog.displayError(VIEW_REPORT_ERROR_TITLE,
							VIEW_REPORT_ERROR_MSG, reason);
				}
			}
		});
	}

	public boolean openBrowser(final String url) {
		boolean success = false;
		try {
			// Launch the default HTML viewer to display the HTML page.
			// On Linux, this can't launch urls, only local files can be
			// launched.
			// Sorry I have use internal class here.
			// hope Eclipse.org can have a public api to do so.
			if (SWT.getPlatform().equals("win32")) { //$NON-NLS-1$
				success = Program.launch(url);
			} else {
//				IBrowser browser = org.eclipse.help.internal.browser.BrowserManager
//						.getInstance().createBrowser(true);
//				if (browser == null) {
//					try {
//						browser.displayURL(url);
//						success = true;
//					} catch (Exception e) {
//						e.printStackTrace();
//					}
//				}
				
				// 155490 - Cannot detected default browser when preview published configuration on Linux
				// changed to use swt browser
				success = true;
				Display.getCurrent().asyncExec(new Runnable()
				{
				    public void run()
					{
//							// open another swt browser since we have no (simple) way of creating a system default browser
//							// the Eclipse guys hide all the good apis as internal
							Shell shell = new Shell();
							shell.setText(url);
							GridLayout layout = new GridLayout();
							layout.marginHeight = 0;
							layout.marginWidth = 0;
							shell.setLayout(layout);
							Browser popup_browser = new Browser(shell, SWT.NONE);
							popup_browser.setLayoutData(new GridData(GridData.FILL_BOTH|GridData.GRAB_HORIZONTAL|GridData.GRAB_VERTICAL));
							popup_browser.setUrl(url);														
							shell.open();
					}
				});			
			}
		} catch (Exception e) {
			e.printStackTrace();
			success = false;
		}

		return success;
	}

}