/*
 * Copyright (c) 2016 Ed Merks (Berlin, 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:
 *    Ed Merks - initial API and implementation
 */
package org.eclipse.oomph.ui;

import org.eclipse.oomph.internal.ui.UIPlugin;
import org.eclipse.oomph.util.CollectionUtil;
import org.eclipse.oomph.util.OS;
import org.eclipse.oomph.util.ReflectUtil;
import org.eclipse.oomph.util.StringUtil;

import org.eclipse.emf.edit.provider.ComposedImage;
import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;

import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PerspectiveAdapter;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * A Dialog in a non-modal shell associated with a workbench window where it can be docked.
 * Generally the constructor is not used to create an instance but rather the {@link #openFor(Class, Factory, IWorkbenchWindow) open} method which maintains one instance per workbench window.
 *
 * @author Ed Merks
 */
public abstract class DockableDialog extends Dialog
{
  /**
   * @author Ed Merks
   */
  public static class Dockable
  {
    private final List<WeakReference<IAction>> actions = new ArrayList<WeakReference<IAction>>();

    private Dialog dialog;

    public Dockable(Dialog dialog)
    {
      this.dialog = dialog;
    }

    public Dialog getDialog()
    {
      return dialog;
    }

    public Shell getShell()
    {
      return dialog.getShell();
    }

    public boolean handleWorkbenchPart(IWorkbenchPart part)
    {
      return true;
    }

    /**
     * The associated action will be checked and unchecked based on the visibility of the dialog.
     */
    public void associate(IAction action)
    {
      if (!getActions().contains(action))
      {
        actions.add(new WeakReference<IAction>(action));
        action.setChecked(true);
      }
    }

    public List<IAction> getActions()
    {
      List<IAction> result = new ArrayList<IAction>();
      for (Iterator<WeakReference<IAction>> it = actions.iterator(); it.hasNext();)
      {
        WeakReference<IAction> actionReference = it.next();
        IAction referencedAction = actionReference.get();
        if (referencedAction == null)
        {
          it.remove();
        }
        else
        {
          result.add(referencedAction);
        }
      }

      return result;
    }

    public IDialogSettings getBoundsSettings()
    {
      return ReflectUtil.invokeMethod("getDialogBoundsSettings", dialog);
    }

    public int open()
    {
      return dialog.open();
    }

    public boolean close()
    {
      return dialog.close();
    }

    public void setWorkbenchPart(IWorkbenchPart part)
    {
      Shell shell = getShell();
      // If there is no support for this workbench part, hide the shell, otherwise show the shell.
      if (!handleWorkbenchPart(part))
      {
        // Only force it invisible if it isn't already invisible.
        // The use may have minimized it himself, so we don't want to mark it forced unless we make it invisible.
        if (shell.isVisible())
        {
          updateVisibility(shell, false);
        }
      }
      else if (Boolean.TRUE.equals(shell.getData("forced")))
      {
        updateVisibility(shell, true);
      }
    }
  }

  /**
   * @author Ed Merks
   */
  public interface Factory<T extends Dialog>
  {
    public T create(IWorkbenchWindow workbenchWindow);
  }

  /**
   * There can be at most one per workbench window.
   */
  private static final Map<IWorkbenchWindow, Map<Class<?>, Dockable>> DIALOGS = new HashMap<IWorkbenchWindow, Map<Class<?>, Dockable>>();

  /**
   * Remember where the dialog is docked per workbench window.
   */
  private static final Map<IWorkbenchWindow, Map<Class<?>, Set<IWorkbenchPartReference>>> DOCKED_PARTS = new HashMap<IWorkbenchWindow, Map<Class<?>, Set<IWorkbenchPartReference>>>();

  /**
   * Be sure to clean the workbench from the map when the workbench window.
   */
  private static final DisposeListener WORKBENCH_DISPOSE_LISTENER = new DisposeListener()
  {
    public void widgetDisposed(DisposeEvent e)
    {
      DIALOGS.remove(e.getSource());
      DOCKED_PARTS.remove(e.getSource());
    }
  };

  private final IWorkbenchWindow workbenchWindow;

  private final Dockable dockable = new Dockable(this)
  {
    @Override
    public boolean handleWorkbenchPart(IWorkbenchPart part)
    {
      return DockableDialog.this.handleWorkbenchPart(part);
    }
  };

  protected DockableDialog(IWorkbenchWindow workbenchWindow)
  {
    super(workbenchWindow.getShell());

    // On the Mac, you can't have an invisible minimized child shell.
    // Minimizing the child shell will minimize the parent shell.
    // On Linux, it just works very poorly.
    setShellStyle(getShellStyle() ^ SWT.APPLICATION_MODAL | SWT.MODELESS | SWT.RESIZE | SWT.MAX | (OS.INSTANCE.isWin() ? SWT.MIN : SWT.NONE));
    setBlockOnOpen(false);

    this.workbenchWindow = workbenchWindow;
  }

  public abstract boolean handleWorkbenchPart(IWorkbenchPart part);

  public Dockable getDockable()
  {
    return dockable;
  }

  public IWorkbenchWindow getWorkbenchWindow()
  {
    return workbenchWindow;
  }

  private static void updateVisibility(Shell shell, boolean visible)
  {
    if (visible)
    {
      shell.setData("forced", null);

      if (OS.INSTANCE.isWin())
      {
        shell.setMinimized(false);
      }

      shell.setVisible(true);
      shell.notifyListeners(SWT.Deiconify, new Event());
    }
    else
    {
      shell.setData("forced", true);

      shell.setVisible(false);
      if (OS.INSTANCE.isWin())
      {
        shell.setMinimized(true);
      }

      shell.notifyListeners(SWT.Iconify, new Event());
    }
  }

  private static Image[] getDockedImages(Image[] images)
  {
    Image[] dockedImages = new Image[images.length];
    for (int i = 0, length = images.length; i < length; ++i)
    {
      dockedImages[i] = getDockedImage(images[i]);
    }

    return dockedImages;
  }

  private static Image getDockedImage(Image image)
  {
    if (image == null)
    {
      return null;
    }

    List<Image> images = new ArrayList<Image>();
    images.add(image);
    images.add(UIPlugin.INSTANCE.getSWTImage("docked_overlay"));
    return ExtendedImageRegistry.INSTANCE.getImage(new DockedOverlayImage(images));
  }

  /**
   * @author Ed Merks
   */
  private static class DockedOverlayImage extends ComposedImage
  {
    private DockedOverlayImage(Collection<?> images)
    {
      super(images);
    }

    @Override
    public List<Point> getDrawPoints(Size size)
    {
      List<Point> result = new ArrayList<Point>();
      result.add(new Point());
      Point overlay = new Point();
      overlay.x = size.width - 7;
      result.add(overlay);
      return result;
    }
  }

  /**
   * Return the instance for this workbench window, if there is one.
   */
  public static <T extends Dialog> T getFor(Class<T> type, IWorkbenchWindow workbenchWindow)
  {
    Map<Class<?>, Dockable> typedDialogs = DIALOGS.get(workbenchWindow);
    if (typedDialogs != null)
    {
      Dockable dockable = typedDialogs.get(type);
      if (dockable != null)
      {
        @SuppressWarnings("unchecked")
        T dialog = (T)dockable.getDialog();
        return dialog;
      }
    }

    return null;
  }

  /**
   * Close the instance for this workbench window, if there is one.
   */
  public static void closeFor(Class<? extends Dialog> type, IWorkbenchWindow workbenchWindow)
  {
    Map<Class<?>, Dockable> typedDialogs = DIALOGS.get(workbenchWindow);
    if (typedDialogs != null)
    {
      Dockable dockable = typedDialogs.get(type);
      if (dockable != null)
      {
        Shell shell = dockable.getShell();
        shell.notifyListeners(SWT.Close, new Event());
        dockable.close();
      }
    }
  }

  /**
   * Reopen or create the instance for this workbench window.
   */
  public static <T extends Dialog> T openFor(final Class<T> type, Factory<T> factory, final IWorkbenchWindow workbenchWindow)
  {
    // Create a new one if there isn't an existing one.
    Map<Class<?>, Dockable> typedDialogs = DIALOGS.get(workbenchWindow);

    Dockable dockable = typedDialogs == null ? null : typedDialogs.get(type);
    if (dockable == null)
    {
      dockable = ReflectUtil.invokeMethod("getDockable", factory.create(workbenchWindow));
      if (typedDialogs == null)
      {
        typedDialogs = new HashMap<Class<?>, Dockable>();
        DIALOGS.put(workbenchWindow, typedDialogs);
      }

      typedDialogs.put(type, dockable);

      dockable.open();

      Map<Class<?>, Set<IWorkbenchPartReference>> typedDockedParts = DOCKED_PARTS.get(workbenchWindow);
      Set<IWorkbenchPartReference> dockedParts = typedDockedParts == null ? null : typedDockedParts.get(type);
      boolean isInitial = false;
      if (dockedParts == null)
      {
        isInitial = true;
        dockedParts = new HashSet<IWorkbenchPartReference>();
        if (typedDockedParts == null)
        {
          typedDockedParts = new HashMap<Class<?>, Set<IWorkbenchPartReference>>();
          DOCKED_PARTS.put(workbenchWindow, typedDockedParts);
        }

        typedDockedParts.put(type, dockedParts);
      }

      // Clean up if the workbench window is disposed.
      final Shell windowShell = workbenchWindow.getShell();
      windowShell.addDisposeListener(WORKBENCH_DISPOSE_LISTENER);

      /**
       * This monitors the shell events, such as dragging to a new position.
       * It's primary purpose to to support docking of the dialog shell into a part stack on a workbench window.
       *
       * @author Ed Merks
       */
      class ShellHandler extends ShellAdapter implements ControlListener, DisposeListener, Runnable
      {
        private final Dockable dockableDialog;

        private final Shell shell;

        private final Display display;

        /**
         * A map from a tab folder (corresponding to a part stack) to the absolute display bounds where it is located.
         */
        private final Map<CTabFolder, Rectangle> tabFolders = new HashMap<CTabFolder, Rectangle>();

        /**
         * A map from a tab folder to the part references in that part stack.
         */
        private final Map<CTabFolder, Set<IWorkbenchPartReference>> tabFolderParts = new HashMap<CTabFolder, Set<IWorkbenchPartReference>>();

        /**
         * The cursor we show when in a docking location.
         */
        private final Cursor sizeAllCursor;

        /**
         * A listener that listens to the tab folder and to the overall workbench window to track resizing and movement so that the docking position can be maintained.
         */
        private final ControlListener dockingListener = new ControlListener()
        {
          public void controlResized(ControlEvent e)
          {
            update();
          }

          public void controlMoved(ControlEvent e)
          {
            update();
          }
        };

        /**
         * The point at which we most recently hovered in a location where we could dock the shell.
         */
        private Point snapPoint;

        /**
         * This is true only while we are doing the positioning of the shell.
         */
        private boolean ignoreControlMoved;

        /**
         * Because we don't receive events such as mouse moves or mouse clicks from the shell, we keep track of how and whether the cursor is moving.
         * @see #run()
         */
        private Point cursorLocation;

        /**
         * This records the most recent time the cursor has been moved to a different location.
         * @see #run()
         */
        private long timeOfLastCursorChange;

        /**
         * This records the most recent time {@link #update()} called {@link #setBounds(Rectangle)}.
         * @see #run()
         */
        private long timeOfLastUpdate;

        /**
         * This is the most recent bounds where we can dock the shell.
         */
        private Rectangle hotZone;

        /**
         * Because we want to be able to drag the docked shell slightly away from the docking site to undock it,
         * we keep track of the hot zone changes and ignore it initially for a short period of time.
         */
        private long timeOfLastHotZoneChange;

        /**
         * It's very hard to clear the hotZone and the snapPoint because we could just get no events when the interaction ends.
         * So we keep track of when the last time a moved happened and if a short period of time passes, we assume we're starting a new interaction.
         */
        private long timeOfLastMove;

        /**
         * This is set after docking.
         * When we hover in a docking position for a short period of time, we set the shell to be at that bounds of that hot zone.
         * But when the mouse is released the shell automatically will move to it's original position, for which we get an event,
         * and then we can use these bounds to set the shell back yet again to the right bounds.
         *
         * @see #dock(Rectangle)
         */
        private Rectangle snapBounds;

        /**
         * This the part stack where we are docked and that we will track when it resizes or moves.
         */
        private CTabFolder dockedTabFolder;

        /**
         * These are the part references at the part stack.
         * We record these so that if we turn to a new perspective, we can try to dock at a different part stack that contains one of the part references.
         */
        private final Set<IWorkbenchPartReference> dockedParts;

        private final Image shellImage;

        private final Image dockedShellImage;

        private final Image[] shellImages;

        private final Image[] dockedShellImages;

        public ShellHandler(Dockable dockableDialog, Set<IWorkbenchPartReference> dockedParts)
        {
          this.dockableDialog = dockableDialog;
          shell = dockableDialog.getShell();
          this.dockedParts = dockedParts;

          display = shell.getDisplay();
          sizeAllCursor = display.getSystemCursor(SWT.CURSOR_SIZEALL);

          shell.addShellListener(this);
          shell.addControlListener(this);
          shell.addDisposeListener(this);

          shellImage = shell.getImage();
          dockedShellImage = getDockedImage(shellImage);
          shellImages = shell.getImages();
          dockedShellImages = getDockedImages(shellImages);
        }

        @Override
        public void shellIconified(ShellEvent e)
        {
          updateActions(false);

          if (!OS.INSTANCE.isMac() && shell.isVisible())
          {
            shell.setVisible(false);
          }
        }

        @Override
        public void shellDeiconified(ShellEvent e)
        {
          if (shell.isVisible())
          {
            updateActions(true);
          }
        }

        protected void updateActions(boolean checked)
        {
          for (IAction action : dockableDialog.getActions())
          {
            action.setChecked(checked);
          }
        }

        public void controlResized(ControlEvent e)
        {
          if (OS.INSTANCE.isMac() && !ignoreControlMoved)
          {
            dock(null);
          }
        }

        public void controlMoved(ControlEvent e)
        {
          // When the shell is maximized, we get a moved event, and we can use that to clear the snap bounds
          // so that the restore goes back to the right position rather than the snap position.
          //
          boolean maximized = shell.getMaximized();
          if (maximized)
          {
            snapBounds = null;
          }

          // We do nothing if we are the ones moving the shell or the shell is maximized.
          // On Linux we see moves of the shell even when we did the update so use the time to guard it.
          if (!ignoreControlMoved && !maximized && (!OS.INSTANCE.isLinux() || System.currentTimeMillis() - timeOfLastUpdate > 500))
          {
            // We have snap bounds to apply, because releasing the mouse after docking moved the shell yet again, we can apply it now, and we never have to do
            // it again.
            if (snapBounds != null)
            {
              if (!OS.INSTANCE.isMac() || System.currentTimeMillis() - timeOfLastMove < 200)
              {
                setBounds(snapBounds);
                dock(snapBounds);
              }

              snapBounds = null;
            }
            // If we have a docking site...
            else if (dockedTabFolder != null)
            {
              // And we moved outside of it...
              if (!getBounds(dockedTabFolder).equals(shell.getBounds()))
              {
                // Undock the shell.
                dock(null);
              }
              else
              {
                // Otherwise we have moved to exactly the docking site, in which case we don't want to do anything!
                return;
              }
            }

            // If we haven't moved the shell for a short while, assume we're staring a new interaction.
            long newTimeOfLastMove = System.currentTimeMillis();
            if (newTimeOfLastMove - timeOfLastMove > 1000)
            {
              // On the Mac, we don't see any move events until the user stops moving the shell for a short while.
              // As such, the very first move event could be the last move event we'll ever see.
              // So in this case, start a new interaction only if we've not seen the cursor move for while.
              if (!OS.INSTANCE.isMac() || newTimeOfLastMove - timeOfLastCursorChange > 1000)
              {
                hotZone = null;
                snapPoint = null;
                snapBounds = null;
              }

              if (OS.INSTANCE.isMac())
              {
                // For the Mac, we want to start the heart beat runnable and there we'll monitor whether the cursor stays over the shell title for a period of
                // time.
                display.timerExec(100, this);
              }
            }

            timeOfLastMove = newTimeOfLastMove;

            // Determine the hot zone at the cursor location.
            Point cursorLocation = display.getCursorLocation();
            Rectangle newHotZone = getHotZone(cursorLocation);
            if (newHotZone != null)
            {
              // If it's a new one...
              if (!newHotZone.equals(hotZone))
              {
                // Keep track of when we first entered this new hot zone.
                timeOfLastHotZoneChange = System.currentTimeMillis();
                hotZone = newHotZone;
              }

              // If we've been in this hot zone for a short period of time...
              if (System.currentTimeMillis() - timeOfLastHotZoneChange > 400)
              {
                // If we have no snap point for this yet...
                if (snapPoint == null)
                {
                  // Show a different cursor and start the heart beat runnable.
                  shell.setCursor(sizeAllCursor);
                  updateShellImage(true);
                  display.timerExec(100, this);
                }

                // keep track of where we started.
                snapPoint = cursorLocation;
              }
            }
            else
            {
              // If we're outside of a hot zone, reset all the state.
              shell.setCursor(null);
              updateShellImage(false);
              snapPoint = null;
              hotZone = null;
              dock(null);
            }
          }
        }

        /**
         * This is the heart beat runnable that's started once we've hovered over a hot zone for a short period of time.
         */
        public void run()
        {
          if (shell.isDisposed())
          {
            return;
          }

          // Keep track of cursor movements, so that only if you hover for a while in the same location will the shell be snapped to the hot zone.
          Point newCursorLocation = display.getCursorLocation();
          if (cursorLocation == null || !cursorLocation.equals(newCursorLocation))
          {
            timeOfLastCursorChange = System.currentTimeMillis();
            cursorLocation = newCursorLocation;
          }

          // On the Mac, we'll check each time of the cursor control is not any part of any other window managed by SWT, i.e., it's staying inside the title
          // area of the shell.
          if (snapPoint == null && (!OS.INSTANCE.isMac() || display.getCursorControl() != null))
          {
            // Not in hot zone.
            shell.setCursor(null);
          }
          else if (System.currentTimeMillis() - timeOfLastCursorChange > 500)
          {
            // Get the bounds for the hot zone, and dock to that location.
            // The case of the snapPoint being null happens only on the Mac, in which case we use the current cursor location as the snap point.
            snapBounds = getHotZone(snapPoint == null ? cursorLocation : snapPoint);
            if (snapBounds != null)
            {
              setBounds(snapBounds);
              snapPoint = null;
              timeOfLastCursorChange = System.currentTimeMillis();
              dock(snapBounds);
              shell.setCursor(null);
            }
          }
          else
          {
            // Still moving the cursor, so check again in a while.
            display.timerExec(100, this);
          }
        }

        /**
         * Returns the hot zone rectangle if the cursor is within the tab area of that zone.
         */
        private Rectangle getHotZone(Point cursorLocation)
        {
          for (Rectangle rectangle : getHotZones())
          {
            final Rectangle hotZone = new Rectangle(rectangle.x, rectangle.y, rectangle.width, 30);
            if (hotZone.contains(cursorLocation))
            {
              return rectangle;
            }
          }

          return null;
        }

        /**
         * We call this when we set to bounds of the shell so that we can ignore the events we're causing ourselves.
         */
        private void setBounds(Rectangle bounds)
        {
          // On Linux we'll see later event for the move; one that we want to ignore.
          if (OS.INSTANCE.isLinux())
          {
            snapBounds = bounds;
            timeOfLastMove = System.currentTimeMillis();
          }

          ignoreControlMoved = true;
          shell.setBounds(bounds);
          ignoreControlMoved = false;
        }

        /**
         * Docks the shell at this rectangle.
         * We listen to the tab folder and the workbench window shell, so we need to maintain those listeners properly.
         */
        private void dock(Rectangle rectangle)
        {
          gatherTabFolders();

          // Remove any existing listeners.
          windowShell.removeControlListener(dockingListener);
          if (dockedTabFolder != null)
          {
            dockedTabFolder.removeControlListener(dockingListener);
          }

          // Clean up the docking points; they'll be populated new, if possible.
          dockedParts.clear();

          for (Map.Entry<CTabFolder, Rectangle> entry : tabFolders.entrySet())
          {
            if (entry.getValue().equals(rectangle))
            {
              // If we find an appropriate part stack,
              // add the listeners and record the information about the docking site and the part references associated with it.
              windowShell.addControlListener(dockingListener);
              dockedTabFolder = entry.getKey();
              dockedTabFolder.addControlListener(dockingListener);
              dockedParts.addAll(tabFolderParts.get(dockedTabFolder));
              updateShellImage(true);
              return;
            }
          }

          // Clear the recorded information to undock the shell.
          dockedTabFolder = null;
          updateShellImage(false);
        }

        private void updateShellImage(boolean docking)
        {
          if (shellImage != null)
          {
            shell.setImage(docking ? dockedShellImage : shellImage);
          }

          if (shellImages != null)
          {
            shell.setImages(docking ? dockedShellImages : shellImages);
          }

        }

        private void dispose()
        {
          // Clear up any docking listeners that might currently be in place.
          if (!windowShell.isDisposed())
          {
            windowShell.removeControlListener(dockingListener);
          }

          if (dockedTabFolder != null && !dockedTabFolder.isDisposed())
          {
            dockedTabFolder.removeControlListener(dockingListener);
          }
        }

        public void widgetDisposed(DisposeEvent e)
        {
          Map<Class<?>, Dockable> typedDialogs = DIALOGS.get(workbenchWindow);
          if (typedDialogs != null)
          {
            typedDialogs.remove(type);
          }

          for (IAction action : dockableDialog.getActions())
          {
            action.setChecked(false);
          }

          IDialogSettings dialogBoundsSettings = dockableDialog.getBoundsSettings();
          if (dialogBoundsSettings != null)
          {
            StringBuilder partIDs = new StringBuilder();
            for (IWorkbenchPartReference partReference : dockedParts)
            {
              if (partIDs.length() != 0)
              {
                partIDs.append(' ');
              }

              partIDs.append(partReference.getId());
            }

            dialogBoundsSettings.put("dockedParts", partIDs.toString());
          }

          dispose();
        }

        /**
         * This is called when the docking site or workbench window shell moves or changes because of perspective switching.
         */
        private void update()
        {
          if (!dockedParts.isEmpty() && (dockedTabFolder == null || !dockedTabFolder.isDisposed()))
          {
            gatherTabFolders();

            // If our docking site available or isn't visible...
            if (dockedTabFolder == null || !dockedTabFolder.isVisible())
            {
              // Find a new corresponding docking site, i.e., one that contains one of the part references in the part stack to which we're currently docked.
              for (IWorkbenchPartReference partReference : dockedParts)
              {
                for (Map.Entry<CTabFolder, Set<IWorkbenchPartReference>> entry : tabFolderParts.entrySet())
                {
                  if (entry.getValue().contains(partReference))
                  {
                    // Dock to this new replacement.
                    CTabFolder tabFolder = entry.getKey();
                    Rectangle bounds = getBounds(tabFolder);
                    setBounds(bounds);
                    dock(bounds);

                    timeOfLastUpdate = System.currentTimeMillis();

                    // If we've been forced to minimize the shell because there is no docking site in the perspective, but now we do have a docking site,
                    // make the shell visible again.
                    if (!shell.isVisible() && Boolean.TRUE.equals(shell.getData("forced")))
                    {
                      updateVisibility(shell, true);
                    }

                    return;
                  }
                }
              }

              if (dockedTabFolder != null)
              {
                updateVisibility(shell, false);
              }
            }
            else
            {
              // Get the new bounds for the docking site and apply them.
              // Restore the shell if it's been forced into minimized state.
              Rectangle bounds = getBounds(dockedTabFolder);
              setBounds(bounds);
              timeOfLastUpdate = System.currentTimeMillis();
              if (!shell.isVisible() && Boolean.TRUE.equals(shell.getData("forced")))
              {
                updateVisibility(shell, true);
              }
            }
          }
        }

        private void initialize()
        {
          IDialogSettings dialogBoundsSettings = dockableDialog.getBoundsSettings();
          if (dialogBoundsSettings != null)
          {
            String dockedPartIDs = dialogBoundsSettings.get("dockedParts");
            if (!StringUtil.isEmpty(dockedPartIDs))
            {
              gatherTabFolders();
              List<String> ids = StringUtil.explode(dockedPartIDs, " ");
              for (Set<IWorkbenchPartReference> partReferences : tabFolderParts.values())
              {
                for (IWorkbenchPartReference partReference : partReferences)
                {
                  if (ids.contains(partReference.getId()))
                  {
                    dockedParts.add(partReference);
                  }
                }
              }
            }
          }
        }

        private Collection<Rectangle> getHotZones()
        {
          gatherTabFolders();
          return tabFolders.values();
        }

        /**
         * Gets the bounds for the tab folder in display absolute coordinates.
         */
        private Rectangle getBounds(CTabFolder tabFolder)
        {
          Rectangle bounds = tabFolder.getBounds();
          Point displayPoint = tabFolder.getParent().toDisplay(bounds.x, bounds.y);
          bounds.x = displayPoint.x;
          bounds.y = displayPoint.y;

          // Make the bounds one pixel smaller on on sizes so that the shell's resize handles don't completely cover the tab folder's resize handles.
          if (OS.INSTANCE.isMac())
          {
            ++bounds.x;
            bounds.width -= 2;

            ++bounds.y;
            bounds.height -= 2;
          }

          return bounds;
        }

        public void gatherTabFolders()
        {
          tabFolders.clear();
          tabFolderParts.clear();

          // Visit all the part references of the page.
          IWorkbenchPage page = workbenchWindow.getActivePage();
          if (page != null)
          {
            IViewReference[] viewReferences = page.getViewReferences();
            for (IViewReference viewReference : viewReferences)
            {
              gatherTabFolders(viewReference);
            }

            IEditorReference[] editorReferences = page.getEditorReferences();
            for (IEditorReference editorReference : editorReferences)
            {
              gatherTabFolders(editorReference);
            }
          }
        }

        private void gatherTabFolders(IWorkbenchPartReference partReference)
        {
          // Get the widget associated the the part...
          Object part = ReflectUtil.getValue("part", partReference);
          if (part != null)
          {
            Object widget = ReflectUtil.invokeMethod("getWidget", part);
            if (widget instanceof Control)
            {
              // Walk up until we hit a visible tab folder.
              for (Control control = (Control)widget; control != null; control = control.getParent())
              {
                if (control.isVisible() && control instanceof CTabFolder)
                {
                  // Add it to the map, keeping track of the part references in each part stack.
                  CTabFolder tabFolder = (CTabFolder)control;
                  tabFolders.put(tabFolder, getBounds(tabFolder));
                  CollectionUtil.add(tabFolderParts, tabFolder, partReference);
                }
              }
            }
          }
        }
      }

      // Listen for shell and control events.
      final Shell shell = dockable.getShell();
      final ShellHandler shellHandler = new ShellHandler(dockable, dockedParts);

      // Listen to perspective changes so we can update the docking site as needed.
      workbenchWindow.addPerspectiveListener(new PerspectiveAdapter()
      {
        @Override
        public void perspectiveActivated(IWorkbenchPage page, IPerspectiveDescriptor perspective)
        {
          UIUtil.asyncExec(shell, new Runnable()
          {
            public void run()
            {
              shellHandler.update();
            }
          });
        }
      });

      if (isInitial)
      {
        shellHandler.initialize();
      }

      shellHandler.update();
    }
    else
    {
      // Show the shell if it already exists.
      final Shell shell = dockable.getShell();
      updateVisibility(shell, true);
    }

    @SuppressWarnings("unchecked")
    T dialog = (T)dockable.getDialog();
    return dialog;
  }
}
