package org.eclipse.swt.examples.ole.win32;

/*
 * (c) Copyright IBM Corp. 2000, 2002.
 * This file is made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 */

import org.eclipse.swt.*;import org.eclipse.swt.events.*;import org.eclipse.swt.layout.*;import org.eclipse.swt.ole.win32.*;import org.eclipse.swt.widgets.*;import org.eclipse.ui.part.*;

/**
 * Ole uses <code>org.eclipse.swt</code> to demonstrate Win32 OLE / ActiveX
 * integration.
 * 
 * @see ViewPart
 */
public class OleBrowserView extends ViewPart {

	private Composite      displayArea;

	private OleFrame       webFrame;
	private OleWebBrowser  webBrowser;
	private Text           webUrl;
	private OleControlSite webControlSite;
	private ProgressBar    webProgress;
	private Label          webStatus;
	private Button         webNavigateButton;
	
	private ToolItem webCommandBackward;
	private ToolItem webCommandForward;
	private ToolItem webCommandHome;
	private ToolItem webCommandStop;
	private ToolItem webCommandRefresh;
	private ToolItem webCommandSearch;
	
	private boolean activated = false;

	/**
	 * Constructs the OLE browser view.
	 */
	public OleBrowserView() {
		OlePlugin.initResources();
	}

	/**
	 * Creates the example.
	 * 
	 * @see ViewPart#createPartControl
	 */
	public void createPartControl(Composite parent) {
		displayArea = new Composite(parent, SWT.NONE);

		GridLayout gridLayout = new GridLayout();
		gridLayout.numColumns = 3;
		displayArea.setLayout(gridLayout);
		
		createToolbar();
		createBrowserFrame();		
		createStatusArea();
		createBrowserControl();	
	}
	
	/**
	 * Cleanup
	 */
	public void dispose() {
		if (activated) {
			webControlSite.deactivateInPlaceClient();
			activated = false;
		}
		if (webBrowser != null) webBrowser.dispose();
		webBrowser = null;
		super.dispose();
	}
	
	/**
	 * Called when we must grab focus.
	 * 
	 * @see org.eclipse.ui.part.ViewPart#setFocus
	 */
	public void setFocus()  {
		webUrl.setFocus();
	}

	/**
	 * Creates the Web browser toolbar.
	 */
	private void createToolbar() {
		// Add a toolbar
		ToolBar bar = new ToolBar(displayArea, SWT.NONE);
		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.horizontalSpan = 3;
		bar.setLayoutData(gridData);
		
		// Add a button to navigate backwards through previously visited web sites
		webCommandBackward = new ToolItem(bar, SWT.NONE);
		webCommandBackward.setToolTipText(OlePlugin.getResourceString("browser.Back.tooltip"));
		webCommandBackward.setText(OlePlugin.getResourceString("browser.Back.text"));
		webCommandBackward.setImage(OlePlugin.images[OlePlugin.biBack]);
		webCommandBackward.setEnabled(false);
		webCommandBackward.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				if (webBrowser == null) return;
				webBrowser.GoBack();
			}
		});
	
		// Add a button to navigate forward through previously visited web sites
		webCommandForward = new ToolItem(bar, SWT.NONE);
		webCommandForward.setToolTipText(OlePlugin.getResourceString("browser.Forward.tooltip"));
		webCommandForward.setText(OlePlugin.getResourceString("browser.Forward.text"));
		webCommandForward.setImage(OlePlugin.images[OlePlugin.biForward]);
		webCommandForward.setEnabled(false);
		webCommandForward.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				if (webBrowser == null) return;
				webBrowser.GoForward();
			}
		});

		// Add a separator
		new ToolItem(bar, SWT.SEPARATOR);
		
		// Add a button to navigate to the Home page
		webCommandHome = new ToolItem(bar, SWT.NONE);
		webCommandHome.setToolTipText(OlePlugin.getResourceString("browser.Home.tooltip"));
		webCommandHome.setText(OlePlugin.getResourceString("browser.Home.text"));
		webCommandHome.setImage(OlePlugin.images[OlePlugin.biHome]);
		webCommandHome.setEnabled(false);
		webCommandHome.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				if (webBrowser == null) return;
				webBrowser.GoHome();
			}
		});

		// Add a button to abort web page loading
		webCommandStop = new ToolItem(bar, SWT.NONE);
		webCommandStop.setToolTipText(OlePlugin.getResourceString("browser.Stop.tooltip"));
		webCommandStop.setText(OlePlugin.getResourceString("browser.Stop.text"));
		webCommandStop.setImage(OlePlugin.images[OlePlugin.biStop]);
		webCommandStop.setEnabled(false);
		webCommandStop.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				if (webBrowser == null) return;
				webBrowser.Stop();
			}
		});

		// Add a button to refresh the current web page
		webCommandRefresh = new ToolItem(bar, SWT.NONE);
		webCommandRefresh.setToolTipText(OlePlugin.getResourceString("browser.Refresh.tooltip"));
		webCommandRefresh.setText(OlePlugin.getResourceString("browser.Refresh.text"));
		webCommandRefresh.setImage(OlePlugin.images[OlePlugin.biRefresh]);
		webCommandRefresh.setEnabled(false);
		webCommandRefresh.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				if (webBrowser == null) return;
				webBrowser.Refresh();
			}
		});

		// Add a separator
		new ToolItem(bar, SWT.SEPARATOR);

		// Add a button to search the web
		webCommandSearch = new ToolItem(bar, SWT.NONE);
		webCommandSearch.setToolTipText(OlePlugin.getResourceString("browser.Search.tooltip"));
		webCommandSearch.setText(OlePlugin.getResourceString("browser.Search.text"));
		webCommandSearch.setImage(OlePlugin.images[OlePlugin.biSearch]);
		webCommandSearch.setEnabled(false);
		webCommandSearch.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				if (webBrowser == null) return;
				webBrowser.GoSearch();
			}
		});

		// Add a text area for Users to enter a url
		Composite addressBar = new Composite(displayArea, SWT.NONE);
		gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
		gridData.horizontalSpan = 3;
		addressBar.setLayoutData(gridData);
		GridLayout gridLayout = new GridLayout();
		gridLayout.numColumns = 3;
		addressBar.setLayout(gridLayout);

		Label addressLabel = new Label(addressBar, SWT.NONE);
		gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL);
		addressLabel.setLayoutData(gridData);
		addressLabel.setText(OlePlugin.getResourceString("browser.Address.label"));
		addressLabel.setFont(OlePlugin.browserFont);
		
		webUrl = new Text(addressBar, SWT.SINGLE | SWT.BORDER);
		webUrl.setFont(OlePlugin.browserFont);
		gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
		webUrl.setLayoutData(gridData);
		webUrl.addFocusListener(new FocusAdapter() {
			public void focusGained(FocusEvent e) {
				webNavigateButton.getShell().setDefaultButton(webNavigateButton);
			}
		});
	
		// Add a button to navigate to the web site specified in the Text area defined above
		webNavigateButton = new Button(addressBar, SWT.PUSH);
		gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL);
		webNavigateButton.setLayoutData(gridData);
		webNavigateButton.setText(OlePlugin.getResourceString("browser.Go.text"));
		webNavigateButton.setFont(OlePlugin.browserFont);
		webNavigateButton.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event event) {
				if (webBrowser == null) return;
				webBrowser.Navigate(webUrl.getText());
			}
		});
	}

	/**
	 * Creates the Web browser OleFrame.
	 */
	private void createBrowserFrame() {
		// Every control must have an associated OleFrame:
		webFrame = new OleFrame(displayArea, SWT.NONE);
		GridData gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL);
		gridData.horizontalSpan = 3;
		webFrame.setLayoutData(gridData);
	}
	
	/**
	 * Creates the Web browser status area.
	 */
	private void createStatusArea() {
		// Add a progress bar to display downloading progress information
		webProgress = new ProgressBar(displayArea, SWT.BORDER);
		GridData gridData = new GridData();
		gridData.horizontalAlignment = GridData.BEGINNING;
		gridData.verticalAlignment = GridData.FILL;
		webProgress.setLayoutData(gridData);		

		// Add a label for displaying status messages as they are received from the control
		webStatus = new Label(displayArea, SWT.SINGLE | SWT.READ_ONLY | SWT.BORDER);
		gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
		gridData.horizontalSpan = 2;
		webStatus.setLayoutData(gridData);
		webStatus.setFont(OlePlugin.browserFont);
	}	

	/**
	 * Creates Web browser control.
	 */
	private void createBrowserControl() {
		try {
			// Create an Automation object for access to extended capabilities
			webControlSite = new OleControlSite(webFrame, SWT.NONE, "Shell.Explorer");
			OleAutomation oleAutomation = new OleAutomation(webControlSite);
			webBrowser = new OleWebBrowser(oleAutomation);
		} catch (SWTException ex) {
			// Creation may have failed because control is not installed on machine
			Label label = new Label(webFrame, SWT.BORDER);
			OlePlugin.logError(OlePlugin.getResourceString("error.CouldNotCreateBrowserControl"), ex);
			label.setText(OlePlugin.getResourceString("error.CouldNotCreateBrowserControl"));
			return;
		}

		// Respond to ProgressChange events by updating the Progress bar
		webControlSite.addEventListener(OleWebBrowser.ProgressChange, new OleListener() {
			public void handleEvent(OleEvent event) {
				Variant progress = event.arguments[0];
				Variant maxProgress = event.arguments[1];
				if (progress == null || maxProgress == null)
					return;
				webProgress.setMaximum(maxProgress.getInt());
				webProgress.setSelection(progress.getInt());
			}
		});
		
		// Respond to StatusTextChange events by updating the Status Text label
		webControlSite.addEventListener(OleWebBrowser.StatusTextChange, new OleListener() {
			public void handleEvent(OleEvent event) {
				Variant statusText = event.arguments[0];
				if (statusText == null)	return;
				String text = statusText.getString();
				if (text != null)
					webStatus.setText(text);
			}
		});
		
		// Listen for changes to the ready state and print out the current state 
		webControlSite.addPropertyListener(OleWebBrowser.DISPID_READYSTATE, new OleListener() {
			public void handleEvent(OleEvent event) {
				if (event.detail == OLE.PROPERTY_CHANGING) return;
				int state = webBrowser.getReadyState();
				switch (state) {
					case OleWebBrowser.READYSTATE_UNINITIALIZED:
						webStatus.setText(
							OlePlugin.getResourceString("browser.State.Uninitialized.text"));
						webCommandBackward.setEnabled(false);
						webCommandForward.setEnabled(false);
						webCommandHome.setEnabled(false);
						webCommandRefresh.setEnabled(false);
						webCommandStop.setEnabled(false);
						webCommandSearch.setEnabled(false);
						break;
					case OleWebBrowser.READYSTATE_LOADING:
						webStatus.setText(
							OlePlugin.getResourceString("browser.State.Loading.text"));
						webCommandHome.setEnabled(true);
						webCommandRefresh.setEnabled(true);
						webCommandStop.setEnabled(true);
						webCommandSearch.setEnabled(true);
						break;
					case OleWebBrowser.READYSTATE_LOADED:
						webStatus.setText(
							OlePlugin.getResourceString("browser.State.Loaded.text"));
						webCommandStop.setEnabled(true);
						break;
					case OleWebBrowser.READYSTATE_INTERACTIVE:
						webStatus.setText(
							OlePlugin.getResourceString("browser.State.Interactive.text"));
						webCommandStop.setEnabled(true);
						break;
					case OleWebBrowser.READYSTATE_COMPLETE:
						webStatus.setText(
							OlePlugin.getResourceString("browser.State.Complete.text"));
						webCommandStop.setEnabled(false);
						break;
				}
			}
		});

		// Listen for changes to the active command states
		webControlSite.addEventListener(OleWebBrowser.CommandStateChange, new OleListener() {
			public void handleEvent(OleEvent event) {
				if (event.type != OleWebBrowser.CommandStateChange) return;
				final int commandID =
					(event.arguments[0] != null) ? event.arguments[0].getInt() : 0;
				final boolean commandEnabled =
					(event.arguments[1] != null) ? event.arguments[1].getBoolean() : false;
				
				switch (commandID) {
					case OleWebBrowser.CSC_NAVIGATEBACK:
					 	webCommandBackward.setEnabled(commandEnabled);
					 	break;
					case OleWebBrowser.CSC_NAVIGATEFORWARD:
					 	webCommandForward.setEnabled(commandEnabled);
						break;
				}
			}
		});

		// in place activate the ActiveX control		
		activated = (webControlSite.doVerb(OLE.OLEIVERB_INPLACEACTIVATE) == OLE.S_OK);
		if (activated) webBrowser.GoHome();
	}
}
