/*******************************************************************************
 * Copyright (c) 2011 Google, Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Google, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.wb.core.controls.flyout;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseTrackAdapter;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Sash;
import org.eclipse.swt.widgets.Tracker;
import org.eclipse.wb.core.controls.Messages;
import org.eclipse.wb.draw2d.IColorConstants;
import org.eclipse.wb.draw2d.ICursorConstants;
import org.eclipse.wb.internal.core.utils.ui.DrawUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * {@link FlyoutControlComposite} is container for two {@link Control}'s. One (client control) is
 * used to fill client area. Second (flyout control) can be docked to any enabled position or
 * temporary hidden.
 *
 * @author scheglov_ke
 * @coverage core.control
 */
public final class FlyoutControlComposite extends Composite {
  private static final int RESIZE_WIDTH = 5;
  private static final int TITLE_LINES = 30;
  private static final int TITLE_MARGIN = 5;
  private static final Font TITLE_FONT = JFaceResources.getFontRegistry().getBold(
      JFaceResources.DEFAULT_FONT);
  ////////////////////////////////////////////////////////////////////////////
  //
  // Images
  //
  ////////////////////////////////////////////////////////////////////////////
  private static final Image PIN = loadImage("icons/pin.gif");
  private static final Image ARROW_LEFT = loadImage("icons/arrow_left.gif");
  private static final Image ARROW_RIGHT = loadImage("icons/arrow_right.gif");
  private static final Image ARROW_TOP = loadImage("icons/arrow_top.gif");
  private static final Image ARROW_BOTTOM = loadImage("icons/arrow_bottom.gif");

  private static Image loadImage(String path) {
    return DrawUtils.loadImage(FlyoutControlComposite.class, path);
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // Instance fields
  //
  ////////////////////////////////////////////////////////////////////////////
  private final IFlyoutPreferences m_preferences;
  private final FlyoutContainer m_flyoutContainer;
  private int m_minWidth = 150;
  private int m_validDockLocations = -1;
  private final List<IFlyoutMenuContributor> m_menuContributors =
      new ArrayList<IFlyoutMenuContributor>();

  ////////////////////////////////////////////////////////////////////////////
  //
  // Constructor
  //
  ////////////////////////////////////////////////////////////////////////////
  public FlyoutControlComposite(Composite parent, int style, IFlyoutPreferences preferences) {
    super(parent, style);
    m_preferences = preferences;
    // add listeners
    addListener(SWT.Resize, new Listener() {
      @Override
    public void handleEvent(Event event) {
        if (getShell().getMinimized()) {
          return;
        }
        layout();
      }
    });
    // create container for flyout control
    m_flyoutContainer = new FlyoutContainer(this, SWT.NO_BACKGROUND);
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // Parents
  //
  ////////////////////////////////////////////////////////////////////////////
  /**
   * @return the parent {@link Composite} for flyout {@link Control}.
   */
  public Composite getFlyoutParent() {
    return m_flyoutContainer;
  }

  /**
   * @return the parent {@link Composite} for client {@link Control}.
   */
  public Composite getClientParent() {
    return this;
  }

  /**
   * Sets the bit set with valid docking locations.
   */
  public void setValidDockLocations(int validDockLocations) {
    m_validDockLocations = validDockLocations;
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // Access
  //
  ////////////////////////////////////////////////////////////////////////////
  /**
   * Sets the minimal width of flyout.
   */
  public void setMinWidth(int minWidth) {
    m_minWidth = minWidth;
  }

  /**
   * Sets the text of title.
   */
  public void setTitleText(String text) {
    m_flyoutContainer.setTitleText(text);
  }

  /**
   * Adds new {@link IFlyoutMenuContributor}.
   */
  public void addMenuContributor(IFlyoutMenuContributor contributor) {
    if (!m_menuContributors.contains(contributor)) {
      m_menuContributors.add(contributor);
    }
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // Layout
  //
  ////////////////////////////////////////////////////////////////////////////
  @Override
  public void layout() {
    Rectangle clientArea = getClientArea();
    int state = m_preferences.getState();
    Control client = getChildren()[1];
    // check, may be "clientArea" is empty, for example because CTabFolder page is not visible
    if (clientArea.width == 0 || clientArea.height == 0) {
      return;
    }
    // check, maybe flyout has no Control, so "client" should fill client area
    if (m_flyoutContainer.getControl() == null
            // BEGIN ADT MODIFICATIONS
            || !m_flyoutContainer.getControl().getVisible()
            // END ADT MODIFICATIONS
            ) {
      m_flyoutContainer.setBounds(0, 0, 0, 0);
      client.setBounds(clientArea);
      return;
    }
    // prepare width to display
    int width;
    int offset;
    if (state == IFlyoutPreferences.STATE_OPEN) {
      width = m_preferences.getWidth();
      // limit maximum value
      if (isHorizontal()) {
        width = Math.min(clientArea.width / 2, width);
      } else {
        width = Math.min(clientArea.height / 2, width);
      }
      // limit minimum value
      width = Math.max(width, m_minWidth);
      width = Math.max(width, 2 * m_flyoutContainer.m_titleHeight + m_flyoutContainer.m_titleWidth);
      // remember actual width
      m_preferences.setWidth(width);
      //
      offset = width;
    } else if (state == IFlyoutPreferences.STATE_EXPANDED) {
      offset = m_flyoutContainer.m_titleHeight;
      width = m_preferences.getWidth();
    } else {
      width = m_flyoutContainer.m_titleHeight;
      offset = width;
    }
    // change bounds for flyout container and client control
    {
      if (isWest()) {
        m_flyoutContainer.setBounds(0, 0, width, clientArea.height);
        client.setBounds(offset, 0, clientArea.width - offset, clientArea.height);
      } else if (isEast()) {
        m_flyoutContainer.setBounds(clientArea.width - width, 0, width, clientArea.height);
        client.setBounds(0, 0, clientArea.width - offset, clientArea.height);
      } else if (isNorth()) {
        m_flyoutContainer.setBounds(0, 0, clientArea.width, width);
        client.setBounds(0, offset, clientArea.width, clientArea.height - offset);
      } else if (isSouth()) {
        m_flyoutContainer.setBounds(0, clientArea.height - width, clientArea.width, width);
        client.setBounds(0, 0, clientArea.width, clientArea.height - offset);
      }
    }
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // Internal utils
  //
  ////////////////////////////////////////////////////////////////////////////
  private boolean isHorizontal() {
    return isWest() || isEast();
  }

  private boolean isWest() {
    return getDockLocation() == IFlyoutPreferences.DOCK_WEST;
  }

  private boolean isEast() {
    return getDockLocation() == IFlyoutPreferences.DOCK_EAST;
  }

  private boolean isNorth() {
    return getDockLocation() == IFlyoutPreferences.DOCK_NORTH;
  }

  private boolean isSouth() {
    return getDockLocation() == IFlyoutPreferences.DOCK_SOUTH;
  }

  /**
   * @return <code>true</code> if given docking location is valid.
   */
  private boolean isValidDockLocation(int location) {
    return (location & m_validDockLocations) == location;
  }

  /**
   * @return current docking location.
   */
  private int getDockLocation() {
    return m_preferences.getDockLocation();
  }

  /**
   * Sets new docking location.
   */
  private void setDockLocation(int dockLocation) {
    m_preferences.setDockLocation(dockLocation);
    layout();
  }

  // BEGIN ADT MODIFICATIONS
  /** If the flyout hover is showing, dismiss it */
  public void dismissHover() {
      if (m_flyoutContainer != null) {
          m_flyoutContainer.dismissHover();
      }
  }

  /** Sets a listener to be modified when windows are opened, collapsed and expanded */
  public void setListener(IFlyoutListener listener) {
      assert m_listener == null; // Only one listener supported
      m_listener = listener;
  }
  private IFlyoutListener m_listener;
  // END ADT MODIFICATIONS

  ////////////////////////////////////////////////////////////////////////////
  //
  // FlyoutContainer
  //
  ////////////////////////////////////////////////////////////////////////////
  /**
   * Container for flyout {@link Control}.
   *
   * @author scheglov_ke
   */
  private final class FlyoutContainer extends Composite {
    ////////////////////////////////////////////////////////////////////////////
    //
    // Container
    //
    ////////////////////////////////////////////////////////////////////////////
    public FlyoutContainer(Composite parent, int style) {
      super(parent, style);
      configureMenu();
      updateTitleImage("Flyout");
      // add listeners
      addListener(SWT.Dispose, new Listener() {
        @Override
        public void handleEvent(Event event) {
          if (m_titleImage != null) {
            m_titleImage.dispose();
            m_titleImageRotated.dispose();
            m_titleImage = null;
            m_titleImageRotated = null;
          }
          if (m_backImage != null) {
            m_backImage.dispose();
            m_backImage = null;
          }
        }
      });
      {
        Listener listener = new Listener() {
          @Override
        public void handleEvent(Event event) {
            layout();
          }
        };
        addListener(SWT.Move, listener);
        addListener(SWT.Resize, listener);
      }
      addListener(SWT.Paint, new Listener() {
        @Override
        public void handleEvent(Event event) {
          handlePaint(event.gc);
        }
      });
      // mouse listeners
      addMouseListener(new MouseAdapter() {
        @Override
        public void mouseDown(MouseEvent event) {
          if (event.button == 1) {
            handle_mouseDown(event);
          }
        }

        @Override
        public void mouseUp(MouseEvent event) {
          if (event.button == 1) {
            handle_mouseUp(event);
          }
        }
      });
      addMouseTrackListener(new MouseTrackAdapter() {
        @Override
        public void mouseExit(MouseEvent e) {
          m_stateHover = false;
          redraw();
          setCursor(null);
        }

        @Override
        public void mouseHover(MouseEvent e) {
          handle_mouseHover();
        }
      });
      addMouseMoveListener(new MouseMoveListener() {
        @Override
        public void mouseMove(MouseEvent event) {
          handle_mouseMove(event);
        }
      });
    }

    // BEGIN ADT MODIFICATIONS
    private void dismissHover() {
      int state = m_preferences.getState();
      if (state == IFlyoutPreferences.STATE_EXPANDED) {
        state = IFlyoutPreferences.STATE_COLLAPSED;
        m_preferences.setState(state);
        redraw();
        FlyoutControlComposite.this.layout();
        if (m_listener != null) {
            m_listener.stateChanged(IFlyoutPreferences.STATE_EXPANDED, state);
        }
      }
    }
    // END END MODIFICATIONS

    ////////////////////////////////////////////////////////////////////////////
    //
    // Events: mouse
    //
    ////////////////////////////////////////////////////////////////////////////
    private boolean m_resize;
    private boolean m_stateHover;

    /**
     * Handler for {@link SWT#MouseDown} event.
     */
    private void handle_mouseDown(MouseEvent event) {
      if (m_stateHover) {
        int state = m_preferences.getState();
        // BEGIN ADT MODIFICATIONS
        int oldState = state;
        // END ADT MODIFICATIONS
        if (state == IFlyoutPreferences.STATE_OPEN) {
          state = IFlyoutPreferences.STATE_COLLAPSED;
        } else {
          state = IFlyoutPreferences.STATE_OPEN;
        }
        m_preferences.setState(state);
        redraw();
        FlyoutControlComposite.this.layout();
        // BEGIN ADT MODIFICATIONS
        if (m_listener != null) {
          m_listener.stateChanged(oldState, state);
        }
        // END ADT MODIFICATIONS
      } else if (getCursor() == ICursorConstants.SIZEWE || getCursor() == ICursorConstants.SIZENS) {
        m_resize = true;
      } else if (getCursor() == ICursorConstants.SIZEALL) {
        handleDocking();
      }
    }

    /**
     * Handler for {@link SWT#MouseUp} event.
     */
    private void handle_mouseUp(MouseEvent event) {
      if (m_resize) {
        m_resize = false;
        handle_mouseMove(event);
      }
    }

    /**
     * Handler for {@link SWT#MouseMove} event.
     */
    private void handle_mouseMove(MouseEvent event) {
      final FlyoutControlComposite container = FlyoutControlComposite.this;
      if (m_resize) {
        // prepare width
        int width;
        if (isHorizontal()) {
          width = getSize().x;
        } else {
          width = getSize().y;
        }
        // prepare new width
        int newWidth = width;
        if (isWest()) {
          newWidth = event.x + RESIZE_WIDTH / 2;
        } else if (isEast()) {
          newWidth = width - event.x + RESIZE_WIDTH / 2;
        } else if (isNorth()) {
          newWidth = event.y + RESIZE_WIDTH / 2;
        } else if (isSouth()) {
          newWidth = width - event.y + RESIZE_WIDTH / 2;
        }
        // update width
        if (newWidth != width) {
          m_preferences.setWidth(newWidth);
          redraw();
          container.layout();
        }
      } else {
        Rectangle clientArea = getClientArea();
        boolean inside = clientArea.contains(event.x, event.y);
        int x = event.x;
        int y = event.y;
        if (inside) {
          // check for state
          {
            boolean oldStateHover = m_stateHover;
            if (isEast()) {
              m_stateHover = x > clientArea.width - m_titleHeight && y < m_titleHeight;
            } else {
              m_stateHover = x < m_titleHeight && y < m_titleHeight;
            }
            if (m_stateHover != oldStateHover) {
              redraw();
            }
            if (m_stateHover) {
              setCursor(null);
              return;
            }
          }
          // check for resize band
          if (isOpenExpanded()) {
            if (isWest() && x >= clientArea.width - RESIZE_WIDTH) {
              setCursor(ICursorConstants.SIZEWE);
            } else if (isEast() && x <= RESIZE_WIDTH) {
              setCursor(ICursorConstants.SIZEWE);
            } else if (isNorth() && y >= clientArea.height - RESIZE_WIDTH) {
              setCursor(ICursorConstants.SIZENS);
            } else if (isSouth() && y <= RESIZE_WIDTH) {
              setCursor(ICursorConstants.SIZENS);
            } else {
              setCursor(null);
            }
          }
          // check for docking
          if (getCursor() == null) {
            setCursor(ICursorConstants.SIZEALL);
          }
        } else {
          setCursor(null);
        }
      }
    }

    /**
     * Handler for {@link SWT#MouseHover} event - temporary expands flyout and collapse again when
     * mouse moves above client.
     */
    private void handle_mouseHover() {
      if (m_preferences.getState() == IFlyoutPreferences.STATE_COLLAPSED && !m_stateHover) {
        m_preferences.setState(IFlyoutPreferences.STATE_EXPANDED);
        //
        final FlyoutControlComposite container = FlyoutControlComposite.this;
        container.layout();
        // BEGIN ADT MODIFICATIONS
        if (m_listener != null) {
            m_listener.stateChanged(IFlyoutPreferences.STATE_COLLAPSED,
                    IFlyoutPreferences.STATE_EXPANDED);
        }
        // END ADT MODIFICATIONS
        // add listeners
        Listener listener = new Listener() {
          @Override
        public void handleEvent(Event event) {
            if (event.type == SWT.Dispose) {
              getDisplay().removeFilter(SWT.MouseMove, this);
            } else {
              Point p = ((Control) event.widget).toDisplay(event.x, event.y);
              // during resize mouse can be temporary outside of flyout - ignore
              if (m_resize) {
                return;
              }
              // mouse in in flyout container - ignore
              if (getClientArea().contains(toControl(p.x, p.y))) {
                return;
              }
              // mouse is in full container - collapse
              if (container.getClientArea().contains(container.toControl(p.x, p.y))) {
                getDisplay().removeFilter(SWT.MouseMove, this);
                // it is possible, that user restored (OPEN) flyout, so collapse only if we still in expand state
                if (m_preferences.getState() == IFlyoutPreferences.STATE_EXPANDED) {
                  m_preferences.setState(IFlyoutPreferences.STATE_COLLAPSED);
                  container.layout();
                  // BEGIN ADT MODIFICATIONS
                  if (m_listener != null) {
                      m_listener.stateChanged(IFlyoutPreferences.STATE_EXPANDED,
                              IFlyoutPreferences.STATE_COLLAPSED);
                  }
                  // END ADT MODIFICATIONS
                }
              }
            }
          }
        };
        addListener(SWT.Dispose, listener);
        getDisplay().addFilter(SWT.MouseMove, listener);
      }
    }

    /**
     * Handler for docking.
     */
    private void handleDocking() {
      final FlyoutControlComposite container = FlyoutControlComposite.this;
      final int width = m_preferences.getWidth();
      final int oldDockLocation = getDockLocation();
      final int[] newDockLocation = new int[]{oldDockLocation};
      final Tracker dockingTracker = new Tracker(container, SWT.NONE);
      dockingTracker.setRectangles(new Rectangle[]{getBounds()});
      dockingTracker.setStippled(true);
      dockingTracker.addListener(SWT.Move, new Listener() {
        @Override
        public void handleEvent(Event event2) {
          Rectangle clientArea = container.getClientArea();
          Point location = container.toControl(event2.x, event2.y);
          int h3 = clientArea.height / 3;
          // check locations
          if (location.y < h3 && isValidDockLocation(IFlyoutPreferences.DOCK_NORTH)) {
            dockingTracker.setRectangles(new Rectangle[]{new Rectangle(0,
                0,
                clientArea.width,
                width)});
            newDockLocation[0] = IFlyoutPreferences.DOCK_NORTH;
          } else if (location.y > 2 * h3 && isValidDockLocation(IFlyoutPreferences.DOCK_SOUTH)) {
            dockingTracker.setRectangles(new Rectangle[]{new Rectangle(0,
                clientArea.height - width,
                clientArea.width,
                width)});
            newDockLocation[0] = IFlyoutPreferences.DOCK_SOUTH;
          } else if (location.x < clientArea.width / 2
              && isValidDockLocation(IFlyoutPreferences.DOCK_WEST)) {
            dockingTracker.setRectangles(new Rectangle[]{new Rectangle(0,
                0,
                width,
                clientArea.height)});
            newDockLocation[0] = IFlyoutPreferences.DOCK_WEST;
          } else if (isValidDockLocation(IFlyoutPreferences.DOCK_EAST)) {
            dockingTracker.setRectangles(new Rectangle[]{new Rectangle(clientArea.width - width,
                0,
                width,
                clientArea.height)});
            newDockLocation[0] = IFlyoutPreferences.DOCK_EAST;
          } else {
            dockingTracker.setRectangles(new Rectangle[]{getBounds()});
            newDockLocation[0] = oldDockLocation;
          }
        }
      });
      // start tracking
      if (dockingTracker.open()) {
        setDockLocation(newDockLocation[0]);
      }
      // dispose tracker
      dockingTracker.dispose();
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // Access
    //
    ////////////////////////////////////////////////////////////////////////////
    /**
     * @return the {@link Control} installed on this {@link FlyoutControlComposite}, or
     *         <code>null</code> if there are no any {@link Control}.
     */
    private Control getControl() {
      Control[] children = getChildren();
      return children.length == 1 ? children[0] : null;
    }

    /**
     * Sets the text of title.
     */
    public void setTitleText(String text) {
      updateTitleImage(text);
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // Layout
    //
    ////////////////////////////////////////////////////////////////////////////
    @Override
    public void layout() {
      Control control = getControl();
      if (control == null) {
        return;
      }
      // OK, we have control, so can continue layout
      Rectangle clientArea = getClientArea();
      if (isOpenExpanded()) {
        if (isWest()) {
          int y = m_titleHeight;
          control.setBounds(0, y, clientArea.width - RESIZE_WIDTH, clientArea.height - y);
        } else if (isEast()) {
          int y = m_titleHeight;
          control.setBounds(RESIZE_WIDTH, y, clientArea.width - RESIZE_WIDTH, clientArea.height - y);
        } else if (isNorth()) {
          int y = m_titleHeight;
          control.setBounds(0, y, clientArea.width, clientArea.height - y - RESIZE_WIDTH);
        } else if (isSouth()) {
          int y = RESIZE_WIDTH + m_titleHeight;
          control.setBounds(0, y, clientArea.width, clientArea.height - y);
        }
      } else {
        control.setBounds(0, 0, 0, 0);
      }
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // Paint
    //
    ////////////////////////////////////////////////////////////////////////////
    private Image m_backImage;

    /**
     * Handler for {@link SWT#Paint} event.
     */
    private void handlePaint(GC paintGC) {
      Rectangle clientArea = getClientArea();
      // prepare back image
      GC gc;
      {
        if (m_backImage == null || !m_backImage.getBounds().equals(clientArea)) {
          if (m_backImage != null) {
            m_backImage.dispose();
          }
          m_backImage = new Image(getDisplay(), clientArea.width, clientArea.height);
        }
        // prepare GC
        gc = new GC(m_backImage);
        gc.setBackground(paintGC.getBackground());
        gc.setForeground(paintGC.getForeground());
        gc.fillRectangle(clientArea);
      }
      //
      if (isOpenExpanded()) {
        // draw header
        {
          // draw title
          if (isWest()) {
            drawStateImage(gc, 0, 0);
            gc.drawImage(m_titleImage, m_titleHeight, 0);
          } else if (isEast()) {
            int x = clientArea.width - m_titleHeight;
            drawStateImage(gc, x, 0);
            gc.drawImage(m_titleImage, x - m_titleWidth, 0);
          } else if (isNorth()) {
            drawStateImage(gc, 0, 0);
            gc.drawImage(m_titleImage, m_titleHeight, 0);
          } else if (isSouth()) {
            int y = RESIZE_WIDTH;
            drawStateImage(gc, 0, y);
            gc.drawImage(m_titleImage, m_titleHeight, y);
          }
        }
        // draw resize band
        drawResizeBand(gc);
      } else {
        if (isHorizontal()) {
          drawStateImage(gc, 0, 0);
          gc.drawImage(m_titleImageRotated, 0, m_titleHeight);
        } else {
          drawStateImage(gc, 0, 0);
          gc.drawImage(m_titleImage, m_titleHeight, 0);
        }
        DrawUtils.drawHighlightRectangle(gc, 0, 0, clientArea.width, clientArea.height);
      }
      // flush back image
      {
        gc.dispose();
        paintGC.drawImage(m_backImage, 0, 0);
      }
    }

    /**
     * Draws the state image (arrow) at given location.
     */
    private void drawStateImage(GC gc, int x, int y) {
      DrawUtils.drawImageCHCV(gc, getStateImage(), x, y, m_titleHeight, m_titleHeight);
      if (m_stateHover) {
        DrawUtils.drawHighlightRectangle(gc, x, y, m_titleHeight, m_titleHeight);
      }
    }

    /**
     * @return the {@link Image} corresponding to current state (open or collapsed).
     */
    private Image getStateImage() {
      int location = getDockLocation();
      int state = m_preferences.getState();
      if (state == IFlyoutPreferences.STATE_OPEN) {
        switch (location) {
          case IFlyoutPreferences.DOCK_WEST :
            return ARROW_LEFT;
          case IFlyoutPreferences.DOCK_EAST :
            return ARROW_RIGHT;
          case IFlyoutPreferences.DOCK_NORTH :
            return ARROW_TOP;
          case IFlyoutPreferences.DOCK_SOUTH :
            return ARROW_BOTTOM;
        }
      } else if (state == IFlyoutPreferences.STATE_EXPANDED) {
        return PIN;
      } else {
        switch (location) {
          case IFlyoutPreferences.DOCK_WEST :
            return ARROW_RIGHT;
          case IFlyoutPreferences.DOCK_EAST :
            return ARROW_LEFT;
          case IFlyoutPreferences.DOCK_NORTH :
            return ARROW_BOTTOM;
          case IFlyoutPreferences.DOCK_SOUTH :
            return ARROW_TOP;
        }
      }
      //
      return null;
    }

    /**
     * Draws that resize band, {@link Sash} like.
     */
    private void drawResizeBand(GC gc) {
      Rectangle clientArea = getClientArea();
      // prepare locations
      int x, y, width, height;
      if (isHorizontal()) {
        if (isWest()) {
          x = clientArea.width - RESIZE_WIDTH;
        } else {
          x = 0;
        }
        y = 0;
        width = RESIZE_WIDTH;
        height = clientArea.height;
      } else {
        x = 0;
        if (isNorth()) {
          y = clientArea.height - RESIZE_WIDTH;
        } else {
          y = 0;
        }
        width = clientArea.width;
        height = RESIZE_WIDTH;
      }
      // draw band
      DrawUtils.drawHighlightRectangle(gc, x, y, width, height);
    }

    /**
     * @return <code>true</code> if flyout is open or expanded.
     */
    private boolean isOpenExpanded() {
      int state = m_preferences.getState();
      return state == IFlyoutPreferences.STATE_OPEN || state == IFlyoutPreferences.STATE_EXPANDED;
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // Title image
    //
    ////////////////////////////////////////////////////////////////////////////
    private int m_titleWidth;
    private int m_titleHeight;
    private Image m_titleImage;
    private Image m_titleImageRotated;

    /**
     * Creates {@link Image} for given title text.
     */
    private void updateTitleImage(String text) {
      // prepare size of text
      Point textSize;
      {
        GC gc = new GC(this);
        gc.setFont(TITLE_FONT);
        textSize = gc.textExtent(text);
        gc.dispose();
      }
      // dispose existing image
      if (m_titleImage != null) {
        m_titleImage.dispose();
        m_titleImageRotated.dispose();
      }
      // prepare new image
      {
        m_titleWidth = textSize.x + 2 * TITLE_LINES + 4 * TITLE_MARGIN;
        m_titleHeight = textSize.y;
        m_titleImage = new Image(getDisplay(), m_titleWidth, m_titleHeight);
        GC gc = new GC(m_titleImage);
        try {
          gc.setBackground(getBackground());
          gc.fillRectangle(0, 0, m_titleWidth, m_titleHeight);
          int x = 0;
          // draw left lines
          {
            x += TITLE_MARGIN;
            drawTitleLines(gc, x, m_titleHeight, TITLE_LINES);
            x += TITLE_LINES + TITLE_MARGIN;
          }
          // draw text
          {
            gc.setForeground(IColorConstants.black);
            gc.setFont(TITLE_FONT);
            gc.drawText(text, x, 0);
            x += textSize.x;
          }
          // draw right lines
          {
            x += TITLE_MARGIN;
            drawTitleLines(gc, x, m_titleHeight, TITLE_LINES);
          }
        } finally {
          gc.dispose();
        }
      }
      // prepare rotated image
      m_titleImageRotated = DrawUtils.createRotatedImage(m_titleImage);
    }

    /**
     * Draws two title lines.
     */
    private void drawTitleLines(GC gc, int x, int height, int width) {
      drawTitleLine(gc, x, height / 3, width);
      drawTitleLine(gc, x, 2 * height / 3, width);
    }

    /**
     * Draws single title line.
     */
    private void drawTitleLine(GC gc, int x, int y, int width) {
      int right = x + TITLE_LINES;
      //
      gc.setForeground(IColorConstants.buttonLightest);
      gc.drawLine(x, y, right - 2, y);
      gc.drawLine(x, y + 1, right - 2, y + 1);
      //
      gc.setForeground(IColorConstants.buttonDarker);
      gc.drawLine(right - 2, y, right - 1, y);
      gc.drawLine(x + 2, y + 1, right - 2, y + 1);
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // Menu
    //
    ////////////////////////////////////////////////////////////////////////////
    private void configureMenu() {
      final MenuManager manager = new MenuManager();
      manager.setRemoveAllWhenShown(true);
      manager.addMenuListener(new IMenuListener() {
        @Override
        public void menuAboutToShow(IMenuManager menuMgr) {
          addDockActions();
          for (IFlyoutMenuContributor contributor : m_menuContributors) {
            contributor.contribute(manager);
          }
        }

        private void addDockActions() {
          MenuManager dockManager = new MenuManager(Messages.FlyoutControlComposite_dockManager);
          addDockAction(
              dockManager,
              Messages.FlyoutControlComposite_dockLeft,
              IFlyoutPreferences.DOCK_WEST);
          addDockAction(
              dockManager,
              Messages.FlyoutControlComposite_dockRight,
              IFlyoutPreferences.DOCK_EAST);
          addDockAction(
              dockManager,
              Messages.FlyoutControlComposite_dockTop,
              IFlyoutPreferences.DOCK_NORTH);
          addDockAction(
              dockManager,
              Messages.FlyoutControlComposite_dockBottom,
              IFlyoutPreferences.DOCK_SOUTH);
          manager.add(dockManager);
        }

        private void addDockAction(MenuManager dockManager, String text, int location) {
          if ((m_validDockLocations & location) != 0) {
            dockManager.add(new DockAction(text, location));
          }
        }
      });
      // set menu
      setMenu(manager.createContextMenu(this));
      // dispose it later
      addDisposeListener(new DisposeListener() {
        @Override
        public void widgetDisposed(DisposeEvent e) {
          manager.dispose();
        }
      });
    }
  }
  ////////////////////////////////////////////////////////////////////////////
  //
  // DockAction
  //
  ////////////////////////////////////////////////////////////////////////////
  private class DockAction extends Action {
    private final int m_location;

    ////////////////////////////////////////////////////////////////////////////
    //
    // Constructor
    //
    ////////////////////////////////////////////////////////////////////////////
    public DockAction(String text, int location) {
      super(text, AS_RADIO_BUTTON);
      m_location = location;
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // Action
    //
    ////////////////////////////////////////////////////////////////////////////
    @Override
    public boolean isChecked() {
      return getDockLocation() == m_location;
    }

    @Override
    public void run() {
      setDockLocation(m_location);
    }
  }
}
