/*
 * Copyright (c) 2015-2017 Eike Stepper (Loehne, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 *    Yatta Solutions - [466264] Enhance UX in simple installer
 */
package org.eclipse.oomph.setup.internal.installer;

import org.eclipse.oomph.base.Annotation;
import org.eclipse.oomph.internal.setup.SetupProperties;
import org.eclipse.oomph.internal.ui.AccessUtil;
import org.eclipse.oomph.internal.ui.FlatButton;
import org.eclipse.oomph.internal.ui.ImageHoverButton;
import org.eclipse.oomph.internal.ui.ToggleSwitchButton;
import org.eclipse.oomph.p2.core.BundlePool;
import org.eclipse.oomph.p2.core.P2Util;
import org.eclipse.oomph.p2.core.ProfileTransaction.Resolution;
import org.eclipse.oomph.p2.internal.ui.AgentManagerDialog;
import org.eclipse.oomph.setup.AnnotationConstants;
import org.eclipse.oomph.setup.Index;
import org.eclipse.oomph.setup.Product;
import org.eclipse.oomph.setup.ProductCatalog;
import org.eclipse.oomph.setup.ProductVersion;
import org.eclipse.oomph.setup.Scope;
import org.eclipse.oomph.setup.User;
import org.eclipse.oomph.setup.internal.core.util.CatalogManager;
import org.eclipse.oomph.setup.internal.core.util.ECFURIHandlerImpl;
import org.eclipse.oomph.setup.internal.core.util.IndexManager;
import org.eclipse.oomph.setup.internal.installer.SimpleInstallerMenu.InstallerMenuItem;
import org.eclipse.oomph.setup.internal.installer.SimpleMessageOverlay.ControlRelocator;
import org.eclipse.oomph.setup.p2.util.MarketPlaceListing;
import org.eclipse.oomph.setup.ui.SetupUIPlugin;
import org.eclipse.oomph.setup.ui.wizards.ConfigurationProcessor;
import org.eclipse.oomph.setup.ui.wizards.ExtensionsDialog;
import org.eclipse.oomph.setup.ui.wizards.MarketPlaceListingProcessor;
import org.eclipse.oomph.setup.ui.wizards.ProjectPage;
import org.eclipse.oomph.setup.ui.wizards.SetupWizard.SelectionMemento;
import org.eclipse.oomph.ui.ErrorDialog;
import org.eclipse.oomph.ui.StatusDialog;
import org.eclipse.oomph.ui.UIUtil;
import org.eclipse.oomph.util.ExceptionHandler;
import org.eclipse.oomph.util.IOExceptionWithCause;
import org.eclipse.oomph.util.IOUtil;
import org.eclipse.oomph.util.OS;
import org.eclipse.oomph.util.ObjectUtil;
import org.eclipse.oomph.util.OomphPlugin.BundleFile;
import org.eclipse.oomph.util.OomphPlugin.Preference;
import org.eclipse.oomph.util.PropertiesUtil;
import org.eclipse.oomph.util.StringUtil;

import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.ui.provider.ExtendedColorRegistry;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Drawable;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

/**
 * @author Eike Stepper
 */
public final class SimpleInstallerDialog extends AbstractSimpleDialog implements InstallerUI
{
  private static final String CATALOGS_MENU_ITEM_TEXT = ProductCatalogsDialog.TITLE.toUpperCase() + StringUtil.HORIZONTAL_ELLIPSIS;

  private static final String APPLY_CONFIGURATION_MENU_ITEM_TEXT = Messages.SimpleInstallerDialog_AppyConfiguration_label;

  private static final String APPLY_CONFIGURATION_MENU_ITEM_DESCRIPTION = Messages.SimpleInstallerDialog_ApplyConfiguration_message;

  private static final String APPLY_MARKET_PLACE_LISTING_MENU_ITEM_TEXT = Messages.SimpleInstallerDialog_ApplyMarketplaceListing_label
      + StringUtil.HORIZONTAL_ELLIPSIS;

  private static final String APPLY_MARKET_PLACE_LISTING_MENU_ITEM_DESCRIPTION = Messages.SimpleInstallerDialog_ApplyMarketplaceListing_message;

  private static final String EXTENSIONS_MENU_ITEM_TEXT = Messages.SimpleInstallerDialog_Extensions_label + StringUtil.HORIZONTAL_ELLIPSIS;

  static final String EXTENSIONS_MENU_ITEM_DESCRIPTION = Messages.SimpleInstallerDialog_Extensions_message;

  private static final String SWITCH_CATALOG_INDEX_MENU_ITEM_TEXT = Messages.SimpleInstallerDialog_SwitchIndex_label;

  private static final String BUNDLE_POOLS_MENU_ITEM_TEXT = Messages.SimpleInstallerDialog_BundlePools_label + StringUtil.HORIZONTAL_ELLIPSIS;

  private static final String UPDATE_MENU_ITEM_TEXT = Messages.SimpleInstallerDialog_Update_label;

  private static final String ADVANCED_MENU_ITEM_TEXT = Messages.SimpleInstallerDialog_AdvancedMode_label + StringUtil.HORIZONTAL_ELLIPSIS;

  private static final String WEB_LINKS_MENU_ITEM_TEXT = Messages.SimpleInstallerDialog_WebLinks_label + StringUtil.HORIZONTAL_ELLIPSIS;

  static final String WEB_LINKS_MENU_ITEM_DESCRIPTION = Messages.SimpleInstallerDialog_WebLinks_message;

  private static final String TRUST_MENU_ITEM_TEXT = Messages.SimpleInstallerDialog_Trust_label + StringUtil.HORIZONTAL_ELLIPSIS;

  static final String TRUST_MENU_ITEM_DESCRIPTION = Messages.SimpleInstallerDialog_Trust_message;

  private static final String MARKET_PLACE_MENU_ITEM_TEXT = Messages.SimpleInstallerDialog_Marketplace_label + StringUtil.HORIZONTAL_ELLIPSIS;

  private static final String ASK_A_QUESTION_MENU_ITEM_TEXT = Messages.SimpleInstallerDialog_AskQuestion_label + StringUtil.HORIZONTAL_ELLIPSIS;

  private static final String REPORT_A_PROBLEM_MENU_ITEM_TEXT = Messages.SimpleInstallerDialog_ReportProblem_label + StringUtil.HORIZONTAL_ELLIPSIS;

  private static final String CONTRIBUTE_MENU_ITEM_TEXT = Messages.SimpleInstallerDialog_Contribute_label + StringUtil.HORIZONTAL_ELLIPSIS;

  private static final String ABOUT_MENU_ITEM_TEXT = Messages.SimpleInstallerDialog_About_label;

  private static final String EXIT_MENU_ITEM_TEXT = Messages.SimpleInstallerDialog_Exit_label;

  private static final Preference PREF_POOL_ENABLED = SetupInstallerPlugin.INSTANCE.getConfigurationPreference("poolEnabled"); //$NON-NLS-1$

  private static final boolean MARKETPLACE_MENU_ITEM_ENABLED = !"false".equals(PropertiesUtil.getProperty(SetupProperties.PROP_SETUP_INSTALLER_MARKETPLACE)); //$NON-NLS-1$

  private static final String HOST = PropertiesUtil.getProperty("oomph.setup.installer.host", "https://www.eclipse.org/setups/installer"); //$NON-NLS-1$ //$NON-NLS-2$

  private static final String PROBLEM_REPORT_URL = PropertiesUtil.getProperty(SetupProperties.PROP_SETUP_INSTALLER_PROBLEM_REPORT, HOST + "/problem/"); //$NON-NLS-1$

  private static final String FORUM_URL = PropertiesUtil.getProperty(SetupProperties.PROP_SETUP_INSTALLER_FORUM, HOST + "/question/"); //$NON-NLS-1$

  private static final String CONTRIBUTE_URL = PropertiesUtil.getProperty(SetupProperties.PROP_SETUP_INSTALLER_CONTRIBUTE, HOST + "/notification/"); //$NON-NLS-1$

  private static final File FILE_BRANDING_NOTIFICTION_URIS = new File(SetupInstallerPlugin.INSTANCE.getUserLocation().toFile(), "brandingNotificationURIs.txt"); //$NON-NLS-1$

  private static Font defaultFont;

  private static Point defaultSize;

  private static String css;

  private static String pageTemplate;

  private static String productTemplate;

  private static String productTemplateLarge;

  private final Installer installer;

  private final boolean restarted;

  private final CatalogManager catalogManager;

  private final PageStack pageStack = new PageStack();

  private Composite stack;

  private StackLayout stackLayout;

  private SimpleProductPage productPage;

  private SimpleVariablePage variablePage;

  private SimpleReadmePage readmePage;

  private SimpleInstallationLogPage installationLogPage;

  private SimpleKeepInstallerPage keepInstallerPage;

  private SimpleInstallerMenu installerMenu;

  private SimpleInstallerMenuButton menuButton;

  private NotifictionButton notificationButton;

  private boolean poolEnabled;

  private BundlePool pool;

  private Resolution updateResolution;

  private SimpleMessageOverlay currentMessage;

  private ToggleSwitchButton bundlePoolSwitch;

  private ToggleSwitchButton webLinksSwitch;

  private boolean showProductCatalogsItem;

  public SimpleInstallerDialog(Display display, Installer installer, boolean restarted)
  {
    super(display, SWT.NO_TRIM, getDefaultSize(display).x, getDefaultSize(display).y);
    setMinimumSize(385, 75);
    this.installer = installer;
    this.restarted = restarted;
    catalogManager = installer.getCatalogManager();
  }

  protected void applyConfiguration()
  {
    MarketPlaceListingProcessor marketPlaceListingProcessor = new MarketPlaceListingProcessor(installer);
    if (marketPlaceListingProcessor.isMarketPlaceListing())
    {
      marketPlaceListingProcessor.processMarketPlaceListing();
      IStatus status = marketPlaceListingProcessor.getStatus();
      if (!status.isOK())
      {
        new StatusDialog(getShell(), Messages.SimpleInstallerDialog_MPCProblems_title, null, status, Diagnostic.ERROR).open();
      }
    }
    else
    {
      ConfigurationProcessor configurationProcessor = new ConfigurationProcessor(installer)
      {
        @Override
        protected void handleSwitchToAdvancedMode()
        {
          switchToAdvancedMode();
        }

        @Override
        protected boolean applyEmptyProductVersion()
        {
          applyInstallation();
          return true;
        }

        @Override
        protected boolean applyProductVersion(ProductVersion productVersion)
        {
          applyInstallation();

          productPage.handleFilter(""); //$NON-NLS-1$
          productPage.productSelected(productVersion.getProduct());
          variablePage.setProductVersion(productVersion);
          return true;
        }
      };

      if (configurationProcessor.processWorkspace())
      {
        configurationProcessor.processInstallation();
      }

      IStatus status = configurationProcessor.getStatus();
      if (!status.isOK())
      {
        new StatusDialog(getShell(), Messages.SimpleInstallerDialog_ConfigurationProblems_title, null, status, Diagnostic.ERROR).open();
      }
    }
  }

  @Override
  protected IDialogSettings getDialogSizeSettings()
  {
    return SetupInstallerPlugin.INSTANCE.getDialogSettings("SimpleInstaller"); //$NON-NLS-1$
  }

  @Override
  protected int getTitleColumnCount()
  {
    return super.getTitleColumnCount() + 1;
  }

  @Override
  protected GridData createTitleImageGridData()
  {
    GridData gridData = super.createTitleImageGridData();
    gridData.grabExcessHorizontalSpace = false;
    return gridData;
  }

  @Override
  protected void createUI(Composite titleComposite)
  {
    Composite notificationContainer = new Composite(titleComposite, SWT.NONE);
    GridLayout notificationContainerLayout = UIUtil.createGridLayout(1);
    // notificationContainerLayout.marginLeft = 20;
    notificationContainerLayout.marginRight = 20;
    notificationContainer.setLayout(notificationContainerLayout);
    notificationContainer.setLayoutData(GridDataFactory.swtDefaults().grab(true, true).align(SWT.END, SWT.BEGINNING).create());

    notificationButton = new NotifictionButton(notificationContainer)
    {
      @Override
      protected void handleWidgetSelected()
      {
        super.handleWidgetSelected();
        handleBrandingNotificationURIOpen(getURI());
      }

      @Override
      protected boolean hasOpenedBrandingNotificationURI(URI uri)
      {
        return SimpleInstallerDialog.this.hasOpenedBrandingNotificationURI(uri);
      }
    };

    notificationButton.setLayoutData(GridDataFactory.swtDefaults().align(SWT.CENTER, SWT.BEGINNING).create());
    notificationButton.setVisible(false);

    Composite exitMenuButtonContainer = new Composite(titleComposite, SWT.NONE);
    exitMenuButtonContainer.setLayout(UIUtil.createGridLayout(1));
    exitMenuButtonContainer.setLayoutData(GridDataFactory.swtDefaults().grab(false, true).align(SWT.CENTER, SWT.FILL).create());

    FlatButton exitButton = new ImageHoverButton(exitMenuButtonContainer, SWT.PUSH, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/exit.png"), //$NON-NLS-1$
        SetupInstallerPlugin.INSTANCE.getSWTImage("simple/exit_hover.png")); //$NON-NLS-1$
    exitButton.setShowButtonDownState(false);
    exitButton.setLayoutData(GridDataFactory.swtDefaults().align(SWT.CENTER, SWT.BEGINNING).create());
    exitButton.setToolTipText(Messages.SimpleInstallerDialog_Exit_message);
    exitButton.addSelectionListener(new SelectionAdapter()
    {
      @Override
      public void widgetSelected(SelectionEvent e)
      {
        exitSelected();
      }
    });

    menuButton = new SimpleInstallerMenuButton(exitMenuButtonContainer);
    menuButton.setLayoutData(GridDataFactory.swtDefaults().grab(false, true).align(SWT.CENTER, SWT.BEGINNING).indent(11, 0).create());
    menuButton.addSelectionListener(new SelectionAdapter()
    {
      @Override
      public void widgetSelected(SelectionEvent e)
      {
        // Don't use the event, it can be null!
        toggleMenu();
      }
    });

    stackLayout = new StackLayout();

    stack = new Composite(this, SWT.NONE);
    stack.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true));
    stack.setLayout(stackLayout);

    SelectionMemento selectionMemento = installer.getSelectionMemento();
    productPage = new SimpleProductPage(stack, this, selectionMemento);
    variablePage = new SimpleVariablePage(stack, this, selectionMemento);

    if (UIUtil.isBrowserAvailable())
    {
      readmePage = new SimpleReadmePage(stack, this);
    }

    installationLogPage = new SimpleInstallationLogPage(stack, this);
    keepInstallerPage = new SimpleKeepInstallerPage(stack, this);

    switchToPage(productPage);

    Display display = getDisplay();

    if (!restarted)
    {
      Thread updateSearcher = new UpdateSearcher(display);
      updateSearcher.start();
    }

    display.timerExec(500, new Runnable()
    {
      @Override
      public void run()
      {
        installer.getResourceSet().getLoadOptions().put(ECFURIHandlerImpl.OPTION_CACHE_HANDLING, ECFURIHandlerImpl.CacheHandling.CACHE_WITHOUT_ETAG_CHECKING);
        installer.loadIndex();
      }
    });

    // Initialize menu.
    getInstallerMenu();

    final PropertyChangeListener catalogManagerListener = new PropertyChangeListener()
    {
      @Override
      public void propertyChange(PropertyChangeEvent evt)
      {
        if (CatalogManager.PROPERTY_INDEX.equals(evt.getPropertyName()))
        {
          indexLoaded((Index)evt.getNewValue());
        }
      }
    };
    catalogManager.addPropertyChangeListener(catalogManagerListener);

    addDisposeListener(new DisposeListener()
    {
      @Override
      public void widgetDisposed(DisposeEvent e)
      {
        catalogManager.removePropertyChangeListener(catalogManagerListener);
      }
    });

    enablePool(SHOW_BUNDLE_POOL_UI && PREF_POOL_ENABLED.get(true));

    updateAvailable(false);

    titleComposite.layout(true);
  }

  private void indexLoaded(Index index)
  {
    @SuppressWarnings("unchecked")
    List<ProductCatalog> productCatalogs = (List<ProductCatalog>)catalogManager.getCatalogs(true);

    int count = 0;
    if (productCatalogs != null)
    {
      for (ProductCatalog productCatalog : productCatalogs)
      {
        if (SimpleProductPage.isIncluded(productCatalog))
        {
          ++count;
        }
      }
    }

    // Show it if there is more than one catalog,
    // or if there are no filters in place and there indices available to switch to.
    // This will not show it for the crippled installer because it has filters in place.
    showProductCatalogsItem = count > 1
        || StringUtil.isEmpty(SimpleInstallerPage.PRODUCT_CATALOG_FILTER.pattern()) && StringUtil.isEmpty(SimpleInstallerPage.PRODUCT_FILTER.pattern())
            && StringUtil.isEmpty(SimpleInstallerPage.PRODUCT_VERSION_FILTER.pattern()) && new IndexManager().getIndexNames(false).size() > 1;

    // Initialize notification button with the default.
    notificationButton.setBrandingNotificationScope(productCatalogs);
  }

  public void setBrandingNotificationScope(Scope scope)
  {
    notificationButton.setBrandingNotificationScope(scope);
  }

  private void toggleMenu()
  {
    SimpleInstallerMenu installerMenu = getInstallerMenu();
    boolean show = !installerMenu.isVisible();

    Installer installer = getInstaller();
    if (show)
    {
      installer.setConfigurationResources(Collections.<Resource> emptySet());
      SimpleInstallerPage topPage = getTopPage();
      if (topPage != null)
      {
        topPage.menuAboutToShow(installerMenu);
      }

      InstallerMenuItem extensionsItem = installerMenu.findMenuItemByName(EXTENSIONS_MENU_ITEM_TEXT);
      extensionsItem.setVisible(!installer.getAppliedConfigurationResources().isEmpty());

      InstallerMenuItem switchCatalogIndexItem = installerMenu.findMenuItemByName(SWITCH_CATALOG_INDEX_MENU_ITEM_TEXT);
      InstallerMenuItem catalogsMenuItem = installerMenu.findMenuItemByName(CATALOGS_MENU_ITEM_TEXT);
      InstallerMenuItem marketPlaceItem = installerMenu.findMenuItemByName(MARKET_PLACE_MENU_ITEM_TEXT);
      InstallerMenuItem applyConfigurationMenuItem = installerMenu.findMenuItemByName(APPLY_CONFIGURATION_MENU_ITEM_TEXT);
      if (applyConfigurationMenuItem == null)
      {
        applyConfigurationMenuItem = installerMenu.findMenuItemByName(APPLY_MARKET_PLACE_LISTING_MENU_ITEM_TEXT);
      }

      if (topPage == productPage)
      {
        Collection<? extends Resource> configurationResources = installer.getUnappliedConfigurationResources();
        URI indexLocation = ProjectPage.ConfigurationListener.getIndexURI(configurationResources);
        boolean visible = !configurationResources.isEmpty() && indexLocation == null;
        if (visible)
        {
          boolean isMarketPlaceListing = false;
          for (Resource resource : configurationResources)
          {
            if (MarketPlaceListing.isMarketPlaceListing(resource.getURI()))
            {
              isMarketPlaceListing = true;
              break;
            }
          }

          applyConfigurationMenuItem.setText(isMarketPlaceListing ? APPLY_MARKET_PLACE_LISTING_MENU_ITEM_TEXT : APPLY_CONFIGURATION_MENU_ITEM_TEXT);
          applyConfigurationMenuItem
              .setToolTipText(isMarketPlaceListing ? APPLY_MARKET_PLACE_LISTING_MENU_ITEM_DESCRIPTION : APPLY_CONFIGURATION_MENU_ITEM_DESCRIPTION);
        }

        applyConfigurationMenuItem.setVisible(visible);
        boolean switchCatalogVisible = indexLocation != null && !catalogManager.isCurrentIndex(indexLocation);
        switchCatalogIndexItem.setVisible(switchCatalogVisible);
        if (switchCatalogVisible)
        {
          switchCatalogIndexItem
              .setToolTipText(NLS.bind(Messages.SimpleInstallerDialog_SwitchCatalogIndex_message, IndexManager.getUnderlyingLocation(indexLocation)));
        }

        catalogsMenuItem.setVisible(showProductCatalogsItem);

        if (marketPlaceItem != null)
        {
          marketPlaceItem.setVisible(true);
        }
      }
      else
      {
        catalogsMenuItem.setVisible(false);
        applyConfigurationMenuItem.setVisible(false);
        switchCatalogIndexItem.setVisible(false);
        if (marketPlaceItem != null)
        {
          marketPlaceItem.setVisible(false);
        }
      }
    }

    installerMenu.layout(true, true);
    installerMenu.setVisible(show);
  }

  public Installer getInstaller()
  {
    return installer;
  }

  public void setButtonsEnabled(boolean enabled)
  {
    menuButton.setEnabled(enabled);
  }

  private void enablePool(boolean poolEnabled)
  {
    if (this.poolEnabled != poolEnabled)
    {
      this.poolEnabled = poolEnabled;
      PREF_POOL_ENABLED.set(poolEnabled);
    }

    if (poolEnabled)
    {
      pool = P2Util.getAgentManager().getDefaultBundlePool(SetupUIPlugin.INSTANCE.getSymbolicName());
    }
    else
    {
      pool = null;
    }

    if (bundlePoolSwitch != null)
    {
      bundlePoolSwitch.setSelected(poolEnabled);
    }
  }

  public BundlePool getPool()
  {
    return pool;
  }

  private SimpleInstallerMenu getInstallerMenu()
  {
    if (installerMenu == null)
    {
      installerMenu = createInstallerMenu();
    }

    return installerMenu;
  }

  private SimpleInstallerMenu createInstallerMenu()
  {
    final SimpleInstallerMenu menu = new SimpleInstallerMenu(this);

    SimpleInstallerMenu.InstallerMenuItem updateInstallerItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
    updateInstallerItem.setDefaultImage(SetupInstallerPlugin.INSTANCE.getSWTImage("simple/exclamation_circle.png")); //$NON-NLS-1$
    updateInstallerItem.setHoverImage(SetupInstallerPlugin.INSTANCE.getSWTImage("simple/exclamation_circle_hover.png")); //$NON-NLS-1$
    updateInstallerItem.setText(UPDATE_MENU_ITEM_TEXT);
    updateInstallerItem.setToolTipText(Messages.SimpleInstallerDialog_InstallUpdates_message);
    updateInstallerItem.addSelectionListener(new SelectionAdapter()
    {
      @Override
      public void widgetSelected(SelectionEvent e)
      {
        Runnable successRunnable = new Runnable()
        {
          @Override
          public void run()
          {
            restart();
          }
        };

        ExceptionHandler<CoreException> exceptionHandler = new ExceptionHandler<CoreException>()
        {
          @Override
          public void handleException(CoreException ex)
          {
            ErrorDialog.open(ex);
          }
        };

        SelfUpdate.update(getShell(), updateResolution, successRunnable, exceptionHandler, null);
      }
    });

    SimpleInstallerMenu.InstallerMenuItem applyConfigurationItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
    applyConfigurationItem.setText(APPLY_CONFIGURATION_MENU_ITEM_TEXT);
    applyConfigurationItem.setToolTipText(APPLY_CONFIGURATION_MENU_ITEM_DESCRIPTION);
    applyConfigurationItem.setVisible(false);
    applyConfigurationItem.addSelectionListener(new SelectionAdapter()
    {
      @Override
      public void widgetSelected(SelectionEvent e)
      {
        applyConfiguration();
      }
    });

    SimpleInstallerMenu.InstallerMenuItem extensionsItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
    extensionsItem.setDefaultImage(SetupInstallerPlugin.INSTANCE.getSWTImage("simple/extension_circle.png")); //$NON-NLS-1$
    extensionsItem.setHoverImage(SetupInstallerPlugin.INSTANCE.getSWTImage("simple/extension_circle_hover.png")); //$NON-NLS-1$
    extensionsItem.setText(EXTENSIONS_MENU_ITEM_TEXT);
    extensionsItem.setToolTipText(EXTENSIONS_MENU_ITEM_DESCRIPTION);
    extensionsItem.setVisible(false);
    extensionsItem.addSelectionListener(new SelectionAdapter()
    {
      @Override
      public void widgetSelected(SelectionEvent e)
      {
        Collection<? extends Resource> appliedConfigurationResources = installer.getAppliedConfigurationResources();
        ExtensionsDialog extensionsDialog = new ExtensionsDialog(getShell(), appliedConfigurationResources);
        if (extensionsDialog.open() == Window.OK)
        {
          Collection<? extends Resource> result = extensionsDialog.getResult();
          for (Resource resource : appliedConfigurationResources)
          {
            if (!result.contains(resource))
            {
              installer.removeAppliedConfigurationResource(resource);
            }
          }
        }
      }
    });

    SimpleInstallerMenu.InstallerMenuItem switchCatalogIndexItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
    switchCatalogIndexItem.setText(SWITCH_CATALOG_INDEX_MENU_ITEM_TEXT);
    switchCatalogIndexItem.setVisible(false);
    switchCatalogIndexItem.addSelectionListener(new SelectionAdapter()
    {
      @Override
      public void widgetSelected(SelectionEvent e)
      {
        applyConfiguration();
      }
    });

    SimpleInstallerMenu.InstallerMenuItem catalogsItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
    catalogsItem.setText(CATALOGS_MENU_ITEM_TEXT);
    catalogsItem.setToolTipText(ProductCatalogsDialog.DESCRIPTION);
    catalogsItem.setVisible(false);
    catalogsItem.addSelectionListener(new SelectionAdapter()
    {
      @Override
      public void widgetSelected(SelectionEvent e)
      {
        ProductCatalogsDialog productCatalogsDialog = new ProductCatalogsDialog(SimpleInstallerDialog.this, getInstaller(), catalogManager);
        productCatalogsDialog.open();
      }
    });
    AccessUtil.setKey(catalogsItem, "catalogs"); //$NON-NLS-1$

    // Label spacer1 = new Label(menu, SWT.NONE);
    // spacer1.setLayoutData(GridDataFactory.swtDefaults().hint(SWT.DEFAULT, 46).create());

    SimpleInstallerMenu.InstallerMenuItem advancedModeItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
    advancedModeItem.setText(ADVANCED_MENU_ITEM_TEXT);
    advancedModeItem.setToolTipText(Messages.SimpleInstallerDialog_SwitchToAdvancedMode_message);
    advancedModeItem.addSelectionListener(new SelectionAdapter()
    {
      @Override
      public void widgetSelected(SelectionEvent e)
      {
        switchToAdvancedMode();
      }
    });

    if (SHOW_BUNDLE_POOL_UI)
    {
      SimpleInstallerMenu.InstallerMenuItemWithToggle bundlePoolsItem = new SimpleInstallerMenu.InstallerMenuItemWithToggle(menu);
      bundlePoolsItem.setText(BUNDLE_POOLS_MENU_ITEM_TEXT);
      bundlePoolsItem.setToolTipText(AgentManagerDialog.MESSAGE);
      // bundlePoolsItem.setDividerVisible(false);
      bundlePoolsItem.addSelectionListener(new SelectionAdapter()
      {
        @Override
        public void widgetSelected(SelectionEvent e)
        {
          manageBundlePools();
        }
      });

      bundlePoolSwitch = bundlePoolsItem.getToggleSwitch();
      bundlePoolSwitch.addSelectionListener(new SelectionAdapter()
      {
        @Override
        public void widgetSelected(SelectionEvent e)
        {
          enablePool(bundlePoolSwitch.isSelected());
        }
      });
    }

    SimpleInstallerMenu.InstallerMenuItemWithToggle webLinksItem = new SimpleInstallerMenu.InstallerMenuItemWithToggle(menu);
    webLinksItem.setText(WEB_LINKS_MENU_ITEM_TEXT);
    webLinksItem.setToolTipText(WEB_LINKS_MENU_ITEM_DESCRIPTION);
    webLinksItem.addSelectionListener(new SelectionAdapter()
    {
      @Override
      public void widgetSelected(SelectionEvent e)
      {
        if (URISchemeUtil.manageRegistrations(getShell()) == URISchemeUtil.RegistrationConfirmation.KEEP_INSTALLER)
        {
          close();
        }
        else
        {
          webLinksSwitch.setSelected(URISchemeUtil.isRegistered());
        }
      }
    });

    webLinksSwitch = webLinksItem.getToggleSwitch();
    webLinksSwitch.setSelected(URISchemeUtil.isRegistered());
    webLinksSwitch.addSelectionListener(new SelectionAdapter()
    {
      @Override
      public void widgetSelected(SelectionEvent e)
      {
        boolean enable = webLinksSwitch.isSelected();
        if (enable)
        {
          switch (URISchemeUtil.confirmRegistration(getShell()))
          {
            case KEEP_INSTALLER:
            {
              showKeepInstaller(true);
              break;
            }
            case OK:
            {
              URISchemeUtil.setRegistered(true);
              break;
            }
            case DONE:
            case CANCEL:
            {
              break;
            }
          }
        }
        else
        {
          URISchemeUtil.setRegistered(false);
        }

        webLinksSwitch.setSelected(URISchemeUtil.isRegistered());
      }
    });

    {
      SimpleInstallerMenu.InstallerMenuItem trustMenuItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
      trustMenuItem.setText(TRUST_MENU_ITEM_TEXT);
      trustMenuItem.setToolTipText(TRUST_MENU_ITEM_DESCRIPTION);
      trustMenuItem.addSelectionListener(new SelectionAdapter()
      {
        @Override
        public void widgetSelected(SelectionEvent e)
        {
          Dialog dialog = new TrustDialog(getShell());
          dialog.open();
        }
      });
    }

    if (MARKETPLACE_MENU_ITEM_ENABLED)
    {
      SimpleInstallerMenu.InstallerMenuItem marketPlaceItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
      marketPlaceItem.setText(MARKET_PLACE_MENU_ITEM_TEXT);
      marketPlaceItem.setToolTipText(Messages.SimpleInstallerDialog_BrowseMPC_message);
      marketPlaceItem.addSelectionListener(new SelectionAdapter()
      {
        @Override
        public void widgetSelected(SelectionEvent e)
        {
          OS.INSTANCE.openSystemBrowser("https://marketplace.eclipse.org"); //$NON-NLS-1$
        }
      });
    }

    if (!StringUtil.isEmpty(FORUM_URL))
    {
      SimpleInstallerMenu.InstallerMenuItem askAQuestionItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
      askAQuestionItem.setText(ASK_A_QUESTION_MENU_ITEM_TEXT);
      askAQuestionItem.setToolTipText(Messages.SimpleInstallerDialog_AskQuestion_message);
      askAQuestionItem.addSelectionListener(new SelectionAdapter()
      {
        @Override
        public void widgetSelected(SelectionEvent e)
        {
          OS.INSTANCE.openSystemBrowser(FORUM_URL + "?version=" + URI.encodeQuery(SelfUpdate.getProductVersion(), false)); //$NON-NLS-1$
        }
      });
    }

    if (!StringUtil.isEmpty(PROBLEM_REPORT_URL))
    {
      SimpleInstallerMenu.InstallerMenuItem reportAProblemItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
      reportAProblemItem.setText(REPORT_A_PROBLEM_MENU_ITEM_TEXT);
      reportAProblemItem.setToolTipText(Messages.SimpleInstallerDialog_ReportProblem_message);
      reportAProblemItem.addSelectionListener(new SelectionAdapter()
      {
        @Override
        public void widgetSelected(SelectionEvent e)
        {
          OS.INSTANCE.openSystemBrowser(PROBLEM_REPORT_URL + "?version=" + URI.encodeQuery(SelfUpdate.getProductVersion(), false)); //$NON-NLS-1$
        }
      });
    }

    if (!StringUtil.isEmpty(CONTRIBUTE_URL))
    {
      SimpleInstallerMenu.InstallerMenuItem reportAProblemItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
      reportAProblemItem.setText(CONTRIBUTE_MENU_ITEM_TEXT);
      reportAProblemItem.setToolTipText(Messages.SimpleInstallerDialog_Contribute_message);
      reportAProblemItem.addSelectionListener(new SelectionAdapter()
      {
        @Override
        public void widgetSelected(SelectionEvent e)
        {
          OS.INSTANCE.openSystemBrowser(CONTRIBUTE_URL + "?version=" + URI.encodeQuery(SelfUpdate.getProductVersion(), false)); //$NON-NLS-1$
        }
      });
    }

    SimpleInstallerMenu.InstallerMenuItem aboutItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
    aboutItem.setText(ABOUT_MENU_ITEM_TEXT);
    aboutItem.setToolTipText(Messages.SimpleInstallerDialog_ShowAbout_message);
    aboutItem.addSelectionListener(new SelectionAdapter()
    {
      @Override
      public void widgetSelected(SelectionEvent e)
      {
        showAbout();
      }
    });

    SimpleInstallerMenu.InstallerMenuItem exitItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
    exitItem.setText(EXIT_MENU_ITEM_TEXT);
    exitItem.setDividerVisible(false);
    exitItem.addSelectionListener(new SelectionAdapter()
    {
      @Override
      public void widgetSelected(SelectionEvent e)
      {
        exitSelected();
      }
    });

    return menu;
  }

  public void setExtensionsAvailable(boolean available)
  {
    menuButton.setExtensionVisible(available);
  }

  private void updateAvailable(boolean available)
  {
    menuButton.setNotificationVisible(available);
    installerMenu.findMenuItemByName(UPDATE_MENU_ITEM_TEXT).setVisible(available);
    installerMenu.layout();
  }

  private void manageBundlePools()
  {
    final boolean[] enabled = { poolEnabled };

    AgentManagerDialog dialog = new AgentManagerDialog(getShell())
    {
      @Override
      protected void createUI(Composite parent)
      {
        final Button enabledButton = new Button(parent, SWT.CHECK);
        enabledButton.setText(Messages.SimpleInstallerDialog_EnableBundlePool_label);
        enabledButton.setSelection(poolEnabled);
        enabledButton.addSelectionListener(new SelectionAdapter()
        {
          @Override
          public void widgetSelected(SelectionEvent e)
          {
            enabled[0] = enabledButton.getSelection();
            getComposite().setEnabled(enabled[0]);
          }
        });

        new Label(parent, SWT.NONE);
        super.createUI(parent);
        getComposite().setEnabled(poolEnabled);
      }

      @Override
      protected void createButtonsForButtonBar(Composite parent)
      {
        super.createButtonsForButtonBar(parent);
        Button button = getButton(IDialogConstants.OK_ID);
        if (button != null)
        {
          button.setEnabled(false);
        }
      }

      @Override
      protected void elementChanged(Object element)
      {
        Button button = getButton(IDialogConstants.OK_ID);
        if (button != null)
        {
          button.setEnabled(getSelectedBundlePool() != null || !enabled[0]);
        }
      }
    };

    if (pool != null)
    {
      dialog.setSelectedPool(pool);
    }

    if (dialog.open() == AgentManagerDialog.OK)
    {
      enablePool(enabled[0]);
      pool = dialog.getSelectedBundlePool();
    }
  }

  @Override
  public boolean refreshJREs()
  {
    if (variablePage != null)
    {
      return variablePage.refreshJREs();
    }

    return false;
  }

  @Override
  public void showAbout()
  {
    String version = SelfUpdate.getProductVersion();
    new AboutDialog(getShell(), version).open();
  }

  @Override
  protected void runEventLoop()
  {
    getInstaller().runEventLoop(getShell());
  }

  public void productSelected(Product product)
  {
    variablePage.setProduct(product);
    switchToPage(variablePage);
  }

  public SimpleInstallerPage getTopPage()
  {
    return (SimpleInstallerPage)stackLayout.topControl;
  }

  private void doSwitch(final SimpleInstallerPage oldPage, final SimpleInstallerPage newPage)
  {
    if (oldPage != null)
    {
      oldPage.aboutToHide();

      if (newPage instanceof SimpleProductPage)
      {
        @SuppressWarnings("unchecked")
        List<ProductCatalog> productCatalogs = (List<ProductCatalog>)catalogManager.getCatalogs(true);
        notificationButton.setBrandingNotificationScope(productCatalogs);
      }
    }

    stackLayout.topControl = newPage;
    stack.layout();

    clearMessage();

    newPage.aboutToShow();
    newPage.setFocus();
  }

  private void switchToPage(final SimpleInstallerPage newPage)
  {
    if (newPage != null)
    {
      SimpleInstallerPage oldPage = pageStack.peek();
      if (oldPage == null || oldPage != newPage)
      {
        pageStack.push(newPage);
        doSwitch(oldPage, newPage);
      }
    }
  }

  public void switchToAdvancedMode()
  {
    installer.setConfigurationResources(Collections.<Resource> emptySet());
    setReturnCode(RETURN_ADVANCED);
    exitSelected();
  }

  public void restart()
  {
    setReturnCode(RETURN_RESTART);
    exitSelected();
  }

  protected void exitQuiet()
  {
    super.exitSelected();
  }

  @Override
  protected void exitSelected()
  {
    for (SimpleInstallerPage page : pageStack)
    {
      if (page instanceof SimpleVariablePage)
      {
        SimpleVariablePage variablePage = (SimpleVariablePage)page;
        if (!variablePage.promptLaunchProduct(Messages.SimpleInstallerDialog_AboutToExit_message))
        {
          return;
        }

        break;
      }
    }

    exitQuiet();
  }

  public void backSelected()
  {
    if (pageStack.size() <= 1)
    {
      return;
    }

    SimpleInstallerPage oldPage = pageStack.pop();
    SimpleInstallerPage newPage = pageStack.peek();

    doSwitch(oldPage, newPage);
  }

  public void showMessage(String message, SimpleMessageOverlay.Type type, boolean dismissAutomatically)
  {
    showMessage(message, type, dismissAutomatically, null);
  }

  public void showMessage(String message, SimpleMessageOverlay.Type type, boolean dismissAutomatically, Runnable action)
  {
    showMessage(message, type, dismissAutomatically, action, null);
  }

  public void showMessage(String message, SimpleMessageOverlay.Type type, boolean dismissAutomatically, Runnable action, Runnable closeAction)
  {
    // Check if we can reuse the current message to reduce flickering.
    if (currentMessage == null || currentMessage.getType() != type || currentMessage.isDismissAutomatically() != dismissAutomatically
        || currentMessage.getAction() != action || currentMessage.getCloseAction() != closeAction)
    {
      clearMessage();

      final Control originalFocusControl = getShell().getDisplay().getFocusControl();
      if (originalFocusControl != null)
      {
        UIUtil.asyncExec(originalFocusControl, new Runnable()
        {
          @Override
          public void run()
          {
            Control focusControl = getShell().getDisplay().getFocusControl();
            if (focusControl != originalFocusControl)
            {
              originalFocusControl.setFocus();
            }
          }
        });
      }

      currentMessage = new SimpleMessageOverlay(this, type, new ControlRelocator()
      {
        @Override
        public void relocate(Control control)
        {
          Rectangle bounds = SimpleInstallerDialog.this.getBounds();
          int x = bounds.x + 5;
          int y = bounds.y + 24;

          int width = bounds.width - 9;

          // Depending on the current page, the height varies.
          int height = pageStack.peek() instanceof SimpleProductPage ? 87 : 70;
          control.setBounds(x, y, width, height);
        }
      }, dismissAutomatically, action, closeAction);
    }

    currentMessage.setMessage(message);
    currentMessage.setVisible(true);
  }

  public void clearMessage()
  {
    if (currentMessage != null)
    {
      if (!currentMessage.isDisposed())
      {
        currentMessage.close();
      }

      currentMessage = null;
    }
  }

  public void showReadme(java.net.URI readmeURI)
  {
    if (readmePage != null)
    {
      readmePage.setReadmeURI(readmeURI);
      switchToPage(readmePage);
    }
    else
    {
      OS.INSTANCE.openSystemBrowser(readmeURI.toString());
    }
  }

  public void showInstallationLog(File installationLogFile)
  {
    installationLogPage.setInstallationLogFile(installationLogFile);
    switchToPage(installationLogPage);
  }

  public void showKeepInstaller(boolean startPermanentInstaller)
  {
    keepInstallerPage.setStartPermanentInstaller(startPermanentInstaller);
    switchToPage(keepInstallerPage);
  }

  @Override
  public void dispose()
  {
    // Ensure that no Browser widget has the focus. See bug 466902.
    menuButton.setFocus();
    super.dispose();
  }

  protected void handleBrandingNotificationURIOpen(URI uri)
  {
    Set<String> brandingNotificationURIs = new LinkedHashSet<String>();
    try
    {
      if (FILE_BRANDING_NOTIFICTION_URIS.isFile())
      {
        brandingNotificationURIs.addAll(IOUtil.readLines(FILE_BRANDING_NOTIFICTION_URIS, "UTF-8")); //$NON-NLS-1$
      }
    }
    catch (RuntimeException ex)
    {
      // Ignore.
    }

    brandingNotificationURIs.add(uri.toString());

    try
    {
      IOUtil.writeLines(FILE_BRANDING_NOTIFICTION_URIS, "UTF-8", new ArrayList<String>(brandingNotificationURIs)); //$NON-NLS-1$
    }
    catch (RuntimeException ex)
    {
      // Ignore.
    }
  }

  protected boolean hasOpenedBrandingNotificationURI(URI uri)
  {
    try
    {
      if (FILE_BRANDING_NOTIFICTION_URIS.isFile())
      {
        return IOUtil.readLines(FILE_BRANDING_NOTIFICTION_URIS, "UTF-8").contains(uri.toString()); //$NON-NLS-1$
      }
    }
    catch (RuntimeException ex)
    {
      // Ignore.
    }

    return false;
  }

  static URI getBrandingSiteURI(Scope scope)
  {
    if (scope != null)
    {
      Annotation annotation = scope.getAnnotation(AnnotationConstants.ANNOTATION_BRANDING_INFO);
      if (annotation != null)
      {
        String detail = annotation.getDetails().get(AnnotationConstants.KEY_SITE_URI);
        if (detail != null)
        {
          return URI.createURI(detail);
        }
      }

      return getBrandingSiteURI(scope.getParentScope());
    }

    return null;
  }

  public static Font getFont(int relativeHeight, String style)
  {
    String height = relativeHeight == 0 ? "" : relativeHeight > 0 ? "+" + relativeHeight : Integer.toString(relativeHeight); //$NON-NLS-1$ //$NON-NLS-2$
    return SetupInstallerPlugin.getFont(getDefaultFont(), org.eclipse.emf.common.util.URI.createURI("font:///" + height + "/" + style)); //$NON-NLS-1$ //$NON-NLS-2$
  }

  static Font getDefaultFont()
  {
    if (defaultFont == null)
    {
      defaultFont = JFaceResources.getFont(SetupInstallerPlugin.FONT_LABEL_DEFAULT);
      if (defaultFont == null)
      {
        defaultFont = UIUtil.getDisplay().getSystemFont();
      }
    }

    return defaultFont;
  }

  static Point getDefaultSize(Drawable drawable)
  {
    if (defaultSize == null)
    {
      defaultSize = computeSize(drawable, getDefaultFont(), 37, 38);
    }

    return defaultSize;
  }

  static Point computeSize(Drawable drawable, Font font, int x, int y)
  {
    GC gc = new GC(drawable);
    gc.setFont(font);

    try
    {
      int height = gc.getFontMetrics().getHeight();
      int totalWidth = height * x;
      int totalHeight = height * y;
      Rectangle monitorArea = Display.getCurrent().getPrimaryMonitor().getClientArea();
      return new Point(Math.min(totalWidth, monitorArea.width / 3), Math.min(totalHeight, 2 * monitorArea.height / 3));
    }
    finally
    {
      gc.dispose();
    }
  }

  static String getCSS()
  {
    if (css == null)
    {
      try
      {
        css = readBundleResource("html/css/simpleInstaller.css"); //$NON-NLS-1$
      }
      catch (IOException ex)
      {
        SetupInstallerPlugin.INSTANCE.log(ex);
      }
    }

    return css;
  }

  static String getPageTemplate()
  {
    if (pageTemplate == null)
    {
      try
      {
        pageTemplate = readBundleResource("html/PageTemplate.html"); //$NON-NLS-1$

        // Embed CSS
        pageTemplate = pageTemplate.replace("%INSTALLER_CSS%", SimpleInstallerDialog.getCSS()); //$NON-NLS-1$
      }
      catch (IOException ex)
      {
        SetupInstallerPlugin.INSTANCE.log(ex);
      }
    }

    return pageTemplate;
  }

  static String getProductTemplate()
  {
    if (productTemplate == null)
    {
      try
      {
        productTemplate = readBundleResource("html/ProductTemplate.html"); //$NON-NLS-1$
      }
      catch (IOException ex)
      {
        SetupInstallerPlugin.INSTANCE.log(ex);
      }
    }

    return productTemplate;
  }

  static String getProductTemplateLarge()
  {
    if (productTemplateLarge == null)
    {
      try
      {
        productTemplateLarge = readBundleResource("html/ProductTemplateLarge.html"); //$NON-NLS-1$
      }
      catch (IOException ex)
      {
        SetupInstallerPlugin.INSTANCE.log(ex);
      }
    }

    return productTemplateLarge;
  }

  private static String readBundleResource(final String name) throws IOException
  {
    try
    {
      BundleFile root = SetupInstallerPlugin.INSTANCE.getRootFile();
      BundleFile child = root.getChild(name);
      return child.getContentsString();
    }
    catch (Exception ex)
    {
      throw new IOExceptionWithCause(ex);
    }
  }

  /**
   * @author Ed Merks
   */
  private static class NotifictionButton extends FlatButton
  {
    /**
     * The color of the button if it's animated, hovered, for focused.
     */
    private static final Color COLOR_INTENSE = SimpleInstallLaunchButton.COLOR_INSTALL;

    /**
     * The color of the button if it's not animated.
     */
    private static final Color COLOR_SUBTLE = SetupInstallerPlugin.getColor(210, 210, 210);

    /**
     * The roundness of the button.
     */
    private static final int CORNER_WIDTH = 10;

    /**
     * The offset when the button is almost completely hidden.
     */
    private static final int MAX_OFFSET = 22;

    /**
     * The current offset that determines how much of the button is showing.
     */
    private int offset = MAX_OFFSET;

    /**
     * Whether the button should be animated.
     */
    private AnimationStyle animationStyle;

    /**
     * The timer executed runnable for animating this button.
     */
    private Runnable animator;

    /**
     * The URI to open.
     */
    private URI uri;

    /**
     * The direction in which the button animates.
     */
    private int direction = -1;

    private Color buttonColor = COLOR_INTENSE;

    private boolean highlight;

    private String scopeLabel;

    public NotifictionButton(Composite parent)
    {
      super(parent, SWT.PUSH);

      setShowButtonDownState(false);
      setCornerWidth(CORNER_WIDTH);
      setAlignment(SWT.CENTER);
      setImage(SetupInstallerPlugin.INSTANCE.getSWTImage("simple/star_white.png")); //$NON-NLS-1$
      setForeground(COLOR_WHITE);
      setBackground(COLOR_SUBTLE);
      setFont(SimpleInstallerDialog.getFont(1, "bold")); //$NON-NLS-1$
      setVisible(false);
      addSelectionListener(new SelectionAdapter()
      {
        @Override
        public void widgetSelected(SelectionEvent e)
        {
          handleWidgetSelected();
        }
      });
    }

    protected void handleWidgetSelected()
    {
      String resolvedURI = uri.toString().replace("${installer.version}", URI.encodeQuery(SelfUpdate.getProductVersion(), true)).replace("${scope}", //$NON-NLS-1$ //$NON-NLS-2$
          URI.encodeQuery(StringUtil.safe(scopeLabel), false).replace("+", "%2B").replace("&", "%26")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
      OS.INSTANCE.openSystemBrowser(resolvedURI);
      update(getURI(), getText(), getToolTipText(), AnimationStyle.NONE, false, buttonColor, scopeLabel);
    }

    public URI getURI()
    {
      return uri;
    }

    public void update(URI uri, String text, String tooltip, AnimationStyle animationStyle, boolean highlight, Color color, String scopeLabel)
    {
      this.scopeLabel = scopeLabel;
      if (!ObjectUtil.equals(uri, this.uri) || this.animationStyle != animationStyle || !ObjectUtil.equals(text, getText())
          || !ObjectUtil.equals(tooltip, getToolTipText()) || !ObjectUtil.equals(color, buttonColor) || this.highlight != highlight)
      {
        this.uri = uri;
        this.highlight = highlight;
        animator = null;
        this.animationStyle = animationStyle;
        buttonColor = color;
        offset = animationStyle != AnimationStyle.NONE ? MAX_OFFSET : 0;
        setVisible(uri != null);
        setBackground(highlight ? buttonColor : COLOR_SUBTLE);

        setText(text);
        setToolTipText(tooltip);

        getParent().getParent().layout(true);

        redraw();
      }
    }

    @Override
    protected void onHover()
    {
      if (isHover())
      {
        animator = null;
        offset = 0;
        setBackground(buttonColor);
        setImage(SetupInstallerPlugin.INSTANCE.getSWTImage("simple/star_black.png")); //$NON-NLS-1$
      }
      else
      {
        setBackground(highlight ? buttonColor : COLOR_SUBTLE);
        setImage(SetupInstallerPlugin.INSTANCE.getSWTImage("simple/star_white.png")); //$NON-NLS-1$
        offset = animationStyle == AnimationStyle.REPEAT ? MAX_OFFSET : 0;
      }
    }

    @Override
    protected void onFocusIn(Event event)
    {
      animator = null;
      offset = 0;
      setBackground(buttonColor);
      setImage(SetupInstallerPlugin.INSTANCE.getSWTImage("simple/star_black.png")); //$NON-NLS-1$
    }

    @Override
    protected void onFocusOut(Event event)
    {
      setBackground(highlight ? buttonColor : COLOR_SUBTLE);
      setImage(SetupInstallerPlugin.INSTANCE.getSWTImage("simple/star_white.png")); //$NON-NLS-1$
      offset = animationStyle == AnimationStyle.REPEAT ? MAX_OFFSET : 0;
      redraw();
    }

    @Override
    protected Point getTotalSize()
    {
      Point totalSize = super.getTotalSize();
      totalSize.x += 20;
      totalSize.y += 8;
      return totalSize;
    }

    private int getEffectiveOffset()
    {
      return isHover() || isFocusControl() ? direction == 1 ? 0 : -CORNER_WIDTH : direction == 1 ? offset * direction : offset * direction - CORNER_WIDTH;
    }

    @Override
    protected void drawFocusState(GC gc, int x, int y, int width, int height)
    {
      super.drawFocusState(gc, x, y + getEffectiveOffset(), width, height + CORNER_WIDTH);
    }

    @Override
    public void drawBackground(GC gc, int x, int y, int width, int height, int offsetX, int offsetY)
    {
      if (animationStyle != AnimationStyle.NONE && animator == null)
      {
        animator = new Animator();
        UIUtil.timerExec(1000, animator);
      }

      super.drawBackground(gc, x, y + getEffectiveOffset(), width, height + CORNER_WIDTH, offsetX, offsetY);
    }

    @Override
    protected void drawText(GC gc, int x, int y)
    {
      int effectiveOffset = getEffectiveOffset();
      if (effectiveOffset != MAX_OFFSET)
      {
        super.drawText(gc, x + 10, y + effectiveOffset + (direction == 0 ? 0 : CORNER_WIDTH - 1));
      }
    }

    @Override
    protected void drawImage(GC gc, int x, int y)
    {
      int effectiveOffset = getEffectiveOffset();
      if (effectiveOffset != MAX_OFFSET)
      {
        super.drawImage(gc, x + 10, y + effectiveOffset + (direction == 0 ? 0 : CORNER_WIDTH - 1));
      }
    }

    protected boolean hasOpenedBrandingNotificationURI(URI uri)
    {
      return false;
    }

    public void setBrandingNotificationScope(List<ProductCatalog> productCatalogs)
    {
      if (productCatalogs != null)
      {
        int targetPriority = Integer.MAX_VALUE;
        ProductCatalog targetProductCatalog = null;
        for (ProductCatalog productCatalog : productCatalogs)
        {
          if (SimpleProductPage.isIncluded(productCatalog))
          {
            int priority = getBrandingNotificationPriority(productCatalog);
            if (priority < targetPriority || targetProductCatalog == null && getBrandingNotificationURI(productCatalog) != null)
            {
              targetPriority = priority;
              targetProductCatalog = productCatalog;
            }
          }
        }

        if (targetProductCatalog != null)
        {
          setBrandingNotificationScope(targetProductCatalog);
        }
      }
    }

    public void setBrandingNotificationScope(Scope scope)
    {
      URI notificationURI = getBrandingNotificationURI(scope);
      String notificationLabel = getBrandingNotificationLabel(scope);
      String notificationTooltip = getBrandingNotificationTooltip(scope);
      String brandingNotificationScopeLabel = getBrandingNotificationScopeLabel(scope);
      if (brandingNotificationScopeLabel == null)
      {
        brandingNotificationScopeLabel = getImplicitBrandingNotificationLabel(scope);
      }

      boolean hasOpenedBrandingNotificationURI = hasOpenedBrandingNotificationURI(notificationURI);
      update(notificationURI, notificationLabel, notificationTooltip,
          hasOpenedBrandingNotificationURI ? AnimationStyle.NONE : getBrandingNotificationAnimationStyle(scope), !hasOpenedBrandingNotificationURI,
          getBrandingNotificationColor(scope), brandingNotificationScopeLabel);
    }

    private static int getBrandingNotificationPriority(Scope scope)
    {
      if (scope != null)
      {
        Annotation annotation = scope.getAnnotation(AnnotationConstants.ANNOTATION_BRANDING_INFO);
        if (annotation != null)
        {
          String detail = annotation.getDetails().get(AnnotationConstants.KEY_NOTIFICATION_PRIORITY);
          if (detail != null)
          {
            try
            {
              return Integer.parseInt(detail);
            }
            catch (RuntimeException ex)
            {
            }
          }
        }
      }

      return Integer.MAX_VALUE;
    }

    private static URI getBrandingNotificationURI(Scope scope)
    {
      if (scope != null)
      {
        Annotation annotation = scope.getAnnotation(AnnotationConstants.ANNOTATION_BRANDING_INFO);
        if (annotation != null)
        {
          String detail = annotation.getDetails().get(AnnotationConstants.KEY_NOTIFICATION_URI);
          if (detail != null)
          {
            return URI.createURI(detail);
          }
        }

        return getBrandingNotificationURI(scope.getParentScope());
      }

      return null;
    }

    private static String getBrandingNotificationLabel(Scope scope)
    {
      if (scope != null)
      {
        Annotation annotation = scope.getAnnotation(AnnotationConstants.ANNOTATION_BRANDING_INFO);
        if (annotation != null)
        {
          String detail = annotation.getDetails().get(AnnotationConstants.KEY_NOTIFICATION_LABEL);
          if (detail != null)
          {
            return detail;
          }
        }

        return getBrandingNotificationLabel(scope.getParentScope());
      }

      return null;
    }

    private static String getImplicitBrandingNotificationLabel(Scope scope)
    {
      if (scope != null)
      {
        String label = scope.getLabel();
        if (label != null)
        {
          Scope parentScope = scope.getParentScope();
          if (parentScope instanceof Product)
          {
            String projectLabel = parentScope.getLabel();
            if (projectLabel != null)
            {
              return projectLabel + "-" + label; //$NON-NLS-1$
            }
          }

          return label;
        }
      }

      return null;
    }

    private static String getBrandingNotificationScopeLabel(Scope scope)
    {
      if (scope != null)
      {
        Annotation annotation = scope.getAnnotation(AnnotationConstants.ANNOTATION_BRANDING_INFO);
        if (annotation != null)
        {
          String detail = annotation.getDetails().get(AnnotationConstants.KEY_NOTIFICATION_SCOPE);
          if (detail != null)
          {
            return detail;
          }
        }

        return getBrandingNotificationScopeLabel(scope.getParentScope());
      }

      return null;
    }

    private static Color getBrandingNotificationColor(Scope scope)
    {
      if (scope != null)
      {
        Annotation annotation = scope.getAnnotation(AnnotationConstants.ANNOTATION_BRANDING_INFO);
        if (annotation != null)
        {
          String detail = annotation.getDetails().get(AnnotationConstants.KEY_NOTIFICATION_COLOR);
          if (detail != null)
          {
            try
            {
              return ExtendedColorRegistry.INSTANCE.getColor(COLOR_WHITE, COLOR_DEFAULT_FOCUS_FOREGROUND, URI.createURI(detail));
            }
            catch (RuntimeException ex)
            {
              //$FALL-THROUGH$
            }
          }
        }

        return getBrandingNotificationColor(scope.getParentScope());
      }

      return COLOR_INTENSE;
    }

    private static String getBrandingNotificationTooltip(Scope scope)
    {
      if (scope != null)
      {
        Annotation annotation = scope.getAnnotation(AnnotationConstants.ANNOTATION_BRANDING_INFO);
        if (annotation != null)
        {
          String detail = annotation.getDetails().get(AnnotationConstants.KEY_NOTIFICATION_TOOLTIP);
          if (detail != null)
          {
            return detail;
          }
        }

        return getBrandingNotificationTooltip(scope.getParentScope());
      }

      return null;
    }

    private static AnimationStyle getBrandingNotificationAnimationStyle(Scope scope)
    {
      if (scope != null)
      {
        Annotation annotation = scope.getAnnotation(AnnotationConstants.ANNOTATION_BRANDING_INFO);
        if (annotation != null)
        {
          String detail = annotation.getDetails().get(AnnotationConstants.KEY_NOTIFICATION_ANIMATION_STYLE);
          if (detail != null)
          {
            try
            {
              return AnimationStyle.valueOf(detail);
            }
            catch (RuntimeException ex)
            {
              //$FALL-THROUGH$
            }
          }
        }

        return getBrandingNotificationAnimationStyle(scope.getParentScope());
      }

      return AnimationStyle.NONE;
    }

    /**
     * @author Ed Merks
     */
    private class Animator implements Runnable
    {
      @Override
      public void run()
      {
        if (animator == this && !isDisposed())
        {
          redraw();
          offset -= 1;
          if (offset == -1)
          {
            if (animationStyle == AnimationStyle.REPEAT)
            {
              offset = MAX_OFFSET;
              UIUtil.timerExec(500, animator);
            }
            else
            {
              offset = 0;
            }
          }
          else if (offset == 0)
          {
            if (animationStyle == AnimationStyle.REPEAT)
            {
              UIUtil.timerExec(2000, animator);
            }
          }
          else
          {
            UIUtil.timerExec(100, animator);
          }
        }
      }
    }

    /**
     * @author Ed Merks
     */
    private enum AnimationStyle
    {
      NONE, ONCE, REPEAT
    }

  }

  /**
   * @author Eike Stepper
   */
  private final class UpdateSearcher extends Thread
  {
    private Display display;

    public UpdateSearcher(Display display)
    {
      super(Messages.SimpleInstallerDialog_UpdateSearcher_job);
      this.display = display;
    }

    @Override
    public void run()
    {
      try
      {
        User user = getInstaller().getUser();
        updateResolution = SelfUpdate.resolve(user, null);
        if (updateResolution != null && !display.isDisposed())
        {
          display.asyncExec(new Runnable()
          {
            @Override
            public void run()
            {
              updateAvailable(true);
            }
          });
        }
      }
      catch (CoreException ex)
      {
        SetupInstallerPlugin.INSTANCE.log(ex);
      }
    }
  }

  /**
   * @author Eike Stepper
   */
  private static final class PageStack extends LinkedList<SimpleInstallerPage>
  {
    private static final long serialVersionUID = 1L;

    @Override
    public void push(SimpleInstallerPage page)
    {
      addLast(page);
    }

    @Override
    public SimpleInstallerPage pop()
    {
      return removeLast();
    }

    @Override
    public SimpleInstallerPage peek()
    {
      return isEmpty() ? null : getLast();
    }
  }
}
