/*******************************************************************************
 * Copyright (c) 2001, 2007 Oracle Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Oracle Corporation - initial API and implementation
 *******************************************************************************/
/**
 * 
 */
package org.eclipse.jst.pagedesigner.editpolicies;

import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Locator;
import org.eclipse.draw2d.MouseEvent;
import org.eclipse.draw2d.MouseListener;
import org.eclipse.draw2d.MouseMotionListener;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PrecisionRectangle;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jst.pagedesigner.PDPlugin;
import org.eclipse.jst.pagedesigner.parts.ElementEditPart;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;

/**
 * A child decorator that supports mouse selection
 * 
 * @author cbateman
 *
 */
class MouseSelectableChildDecorator extends NonVisualChildDecorator
{
    // no visual or affordance showing
    private static final int           STATE_START = 0;
    
    // the host is showing hover feedback, but is not selected
    private static final int           STATE_HOST_HOVER = 1;
    
    // the host has primary selection
    private static final int           STATE_HOST_SELECTED = 2;
    
    // the selection handle for the decorator has mouse hover
    private static final int           STATE_HANDLE_HOVER = 3;
    
    // the selection handle has been selected (is showing)
    private static final int           STATE_HANDLE_MENU_BAR_SHOWING = 4;
    
    // the menu bar has hover
    private static final int           STATE_HANDLE_MENU_BAR_HOVER = 5;
    
    // the menu bar has primary selection
    private static final int           STATE_HANDLE_MENU_BAR_SELECTED = 6;
    
    /**
     * An event indicating the host received hover
     */
    public static final int           EVENT_HOST_HOVER_RECEIVED = 31;
    /**
     * An event indicating the host lost hover
     */
    public static final int           EVENT_HOST_HOVER_LOST = 32;
    /**
     * An event indicating the host received selection
     */
    public static final int           EVENT_HOST_SELECTION_RECEIVED = 33;
    /**
     * An event indicating the host lost selection
     */
    public static final int           EVENT_HOST_SELECTION_LOST = 34;
    private static final int          EVENT_HANDLE_HOVER_RECEIVED = 35;
    private static final int          EVENT_HANDLE_HOVER_LOST = 36;
    private static final int          EVENT_HANDLE_SELECTED = 37;
    private static final int          EVENT_ALL_SELECTION_LOST = 38;
    private static final int          EVENT_MENU_BAR_SELECTION_RECEIVED = 39;
    
    private MouseMotionListener      _motionListener;
    private MouseListener            _mouseListener;
    private boolean                  _isMouseOver = false;
    private ElementMenuBar           _elementMenuBar;

    private DisplayStateMachine      _stateMachine;
    private VerticalMenuLocator      _menuLocator;
    private AnimatedHideLocator      _hideLocator;
    private IFigure                  _hoverParent;
    private IFigure                  _selectionParent;

    private ISelectionChangedListener _menuSelectionListener;
    
    MouseSelectableChildDecorator(final GraphicalEditPart hostPart, int location, 
            IFigure hoverParent, IFigure selectionParent) {
        super(hostPart, location);
        _menuLocator = new VerticalMenuLocator(hostPart, this);
        _hideLocator = new AnimatedHideLocator();
        _elementMenuBar = ((ElementEditPart)hostPart).getElementMenuBar();
        _stateMachine = new DisplayStateMachine();
        _hoverParent = hoverParent;
        _selectionParent = selectionParent;
        
        _motionListener = new MouseMotionListener.Stub()
        {
            public void mouseEntered(MouseEvent me) {
                _isMouseOver = true;
                updateState(EVENT_HANDLE_HOVER_RECEIVED);
            }
    
            public void mouseExited(MouseEvent me) {
                _isMouseOver = false;
                updateState(EVENT_HANDLE_HOVER_LOST);
            }
        };
        addMouseMotionListener(_motionListener);
            
        _mouseListener = new MouseListener.Stub()
        {
            public void mousePressed(MouseEvent me) {
                updateState(EVENT_HANDLE_SELECTED);
            }
        };
        addMouseListener(_mouseListener);
        
        _menuSelectionListener = new ISelectionChangedListener()
        {
            public void selectionChanged(SelectionChangedEvent event) {
                IStructuredSelection selection = (IStructuredSelection) event.getSelection();
                if (selection.size() == 0)
                {
                    // if the host part has been given back selection, then
                    // we have a host selection event
                    if (getOwner().getSelected() == EditPart.SELECTED_PRIMARY)
                    {
                        updateState(EVENT_HOST_SELECTION_RECEIVED);
                    }
                    // otherwise, both the host and the non-visual children are lost,
                    // so fire all selection lost
                    else
                    {
                        updateState(EVENT_ALL_SELECTION_LOST);
                    }
                }
                // otherwise, one or more non-visual children have selection
                else
                {
                    updateState(EVENT_MENU_BAR_SELECTION_RECEIVED);
                }
            }
        };
        _elementMenuBar.addSelectionChangedListener(_menuSelectionListener);
    }
    
    public void paintFigure(Graphics g) {
        // TODO: could we use an image label toggle button here instead?    
        Image  arrowImage = null;
        
        if (_stateMachine.isMenuShowing())
        {
            arrowImage = PDPlugin.getDefault().getImage("pin_down.gif");
        }
        else
        {
            arrowImage = PDPlugin.getDefault().getImage("pin_up.gif");
        }
        
        Rectangle r = getBounds();
        g.setAlpha(75);
        g.setBackgroundColor(getFillColor());
        g.fillRectangle(r.x, r.y, r.width, r.height);
        g.setAlpha(getAlpha());
        g.drawImage(arrowImage, r.x+1, r.y+1);
        g.setForegroundColor(getBorderColor()); 
        g.drawRectangle(r.x, r.y, r.width-1, r.height-1);
    }

    /**
     * @param event
     */
    public void updateState(int event)
    {
        int oldState = _stateMachine.doTransition(event);
        updateVisual(oldState);
    }
    
    /**
     * @param oldState
     */
    protected void updateVisual(int oldState)
    {
        // overriding all other considerations is whether the menu bar even has
        // any items to show.  If not don't show anything
        if (!_elementMenuBar.hasChildParts())
        {
            if (getParent() != null)
            {
                getParent().remove(this);
            }
            
            return;
        }
        
        switch (_stateMachine._curState)
        {
            case STATE_START:
                hide(_elementMenuBar, false);
                IFigure parent = getParent();
                if (parent != null)
                {
                    parent.remove(this);
                }
            break;
            
            case STATE_HOST_HOVER:
                if (_hoverParent != null)
                {
                    _hoverParent.add(this);
                    validate();
                }
                show(_elementMenuBar, false);
                setVisible(false);
            break;
            
            case STATE_HOST_SELECTED:
                if (_selectionParent != null)
                {
                    _selectionParent.add(this);
                    validate();
                }

                setVisible(true);

                if (oldState != STATE_HOST_SELECTED
                        && oldState != STATE_HANDLE_HOVER)
                {
                    show(_elementMenuBar, true);
                    hide(_elementMenuBar, true);
                }
                else
                {
                    if (!_hideLocator._isAnimating)
                    {
                        hide(_elementMenuBar, false);
                    }
                }
                repaint();
            break;
            
            case STATE_HANDLE_HOVER:
                if (_stateMachine.isMenuShowing(oldState))
                {
                    hide(_elementMenuBar, false);
                }
                else
                {
                    show(_elementMenuBar, false);
                }
                repaint();
            break;
            
            case STATE_HANDLE_MENU_BAR_SHOWING:
                show(_elementMenuBar, true);
                repaint();
            break;
            
            case STATE_HANDLE_MENU_BAR_HOVER:
            case STATE_HANDLE_MENU_BAR_SELECTED:
                //revalidate();
            break;
            
            
            default:
                
        }
    }

    protected void init() {
        setPreferredSize(new Dimension(12, 12));
    }
    
    /**
     * 
     */
    public void dispose()
    {
        hide(_elementMenuBar, false);
        
        if (_motionListener != null)
        {
            removeMouseMotionListener(_motionListener);
            _motionListener = null;
        }
        
        if (_mouseListener != null)
        {
            removeMouseListener(_mouseListener);
            _mouseListener = null;
        }
        
        if (_menuSelectionListener != null)
        {
            _elementMenuBar.removeSelectionChangedListener(_menuSelectionListener);
            _menuSelectionListener = null;
        }
    }
    
    private void hide(ElementMenuBar menuBar, boolean animate)
    {
        if (animate)
        {
            final Point endPoint = this.getLocation().getCopy();
            //TODO: don't understand when translation is necessary...
            //this.translateToAbsolute(endPoint);
            
            endPoint.x += this.getBounds().width / 2;
            endPoint.y += this.getBounds().height / 2;
            _hideLocator.setHideEndPoint(endPoint);
            _hideLocator.relocate(menuBar);
        }
        else 
        {
            if (menuBar.getParent() != null)
            {
                getParent().remove(menuBar);
            }
        }
    }
    
    private void show(ElementMenuBar menuBar, boolean enabled)
    {
        menuBar.setEnabled(enabled);
        getParent().add(menuBar);
        _menuLocator.relocate(menuBar);
    }
    
    protected int getAlpha() 
    {
        return (_isMouseOver || _stateMachine.isMenuShowing()) ? 255 : 75;
    }
    
    private class DisplayStateMachine
    {
        private int _curState = STATE_START;
        
        /**
         * @param event
         * @return execute a state machine transition on event
         */
        public int doTransition(int event)
        {
            final int     oldState = _curState;
            
            switch(_curState)
            {
                case STATE_START:
                    // can only transition from start state
                    // on a host event
                    if (event == EVENT_HOST_HOVER_RECEIVED)
                    {
                        _curState = STATE_HOST_HOVER;
                    }
                    else if (event == EVENT_HOST_SELECTION_RECEIVED)
                    {
                        _curState = STATE_HOST_SELECTED;
                    }
                break;
                
                case STATE_HOST_HOVER:
                    if (event == EVENT_HOST_SELECTION_RECEIVED)
                    {
                        _curState = STATE_HOST_SELECTED;
                    }
                    else if (event == EVENT_HOST_SELECTION_LOST
                            || event == EVENT_HOST_HOVER_LOST)
                    {
                        _curState = STATE_START;
                    }
                    else if (event == EVENT_HOST_HOVER_RECEIVED)
                    {
                        // preserve state in this case
                    }
                break;

                case STATE_HOST_SELECTED:
                    // once the host is selected,the only host event that
                    // that can change state is selection lost
                    if (event == EVENT_HOST_SELECTION_LOST)
                    {
                        _curState = STATE_START;
                    }
                    else if (event == EVENT_HANDLE_HOVER_RECEIVED)
                    {
                        _curState = STATE_HANDLE_HOVER;
                    }
                    else if (event == EVENT_HANDLE_SELECTED)
                    {
                        _curState = STATE_HANDLE_MENU_BAR_SHOWING;
                    }
                    else if (event == EVENT_ALL_SELECTION_LOST)
                    {
                        _curState = STATE_START;
                    }
                break;
                    
                case STATE_HANDLE_HOVER:
                    if (event == EVENT_HANDLE_HOVER_LOST)
                    {
                        _curState = STATE_HOST_SELECTED;
                    }
                    else if (event == EVENT_HANDLE_SELECTED)
                    {
                        _curState = STATE_HANDLE_MENU_BAR_SHOWING;
                    }
                    else if (event == EVENT_HOST_SELECTION_LOST)
                    {
                        _curState = STATE_START;
                    }
                break;
                case STATE_HANDLE_MENU_BAR_SHOWING:
                    if (event == EVENT_HANDLE_SELECTED)
                    {
                        _curState = STATE_HANDLE_HOVER;
                    }
                    else if (event == EVENT_MENU_BAR_SELECTION_RECEIVED)
                    {
                        _curState = STATE_HANDLE_MENU_BAR_SELECTED;
                    }
                    else if (event == EVENT_ALL_SELECTION_LOST)
                    {
                        _curState = STATE_START;
                    }
                break;

                case STATE_HANDLE_MENU_BAR_HOVER:
                break;                    

                case STATE_HANDLE_MENU_BAR_SELECTED:
                    if (event == EVENT_ALL_SELECTION_LOST)
                    {
                        _curState = STATE_START;
                    }
                    else if (event == EVENT_HANDLE_SELECTED)
                    {
                        _curState = STATE_HANDLE_HOVER;
                    }
                break;
                
            }
            
            
            return oldState;
        }

        /**
         * @return true if the  menu should be showing in the  current state
         */
        public boolean isMenuShowing()
        {
            return isMenuShowing(_curState);
        }

        /**
         * @param state
         * @return true if state is one in which the menu should be showing
         */ 
        public boolean isMenuShowing(int state)
        {
            return _curState == STATE_HANDLE_MENU_BAR_SHOWING 
                    || _curState == STATE_HANDLE_MENU_BAR_HOVER
                    || _curState == STATE_HANDLE_MENU_BAR_SELECTED;
        }
    }
    
    private static class VerticalMenuLocator implements Locator
    {
        private IFigure  _referenceFigure;
        
        VerticalMenuLocator(GraphicalEditPart owner, IFigure reference)
        {
            _referenceFigure = reference;
        }
        
        public void relocate(IFigure target) 
        {
            final Rectangle finalBounds = getFinalMenuBounds(target);
            target.setBounds(finalBounds);
        }
        
        
        private Rectangle getInitialMenuBounds(final IFigure target)
        {
            Rectangle targetBounds = 
                new PrecisionRectangle(_referenceFigure.getBounds().getResized(-1, -1));
            _referenceFigure.translateToAbsolute(targetBounds);
            target.translateToRelative(targetBounds);
            return targetBounds;
        }

        private Rectangle getFinalMenuBounds(final IFigure target)
        {
            final IFigure referenceFigure =  _referenceFigure;
            
            Rectangle targetBounds = getInitialMenuBounds(target);
            Dimension targetSize = target.getPreferredSize();

            // copied from super.relocate because relativeX/Y are private in super
            // changed from super to remove div by 2 that centers target; we want
            // it to be corner-to-corner
            targetBounds.x
                += targetBounds.width+4;
            targetBounds.y
                  -= (targetSize.height / 2) - referenceFigure.getBounds().height/2;
            targetBounds.setSize(targetSize);
            //target.setBounds(targetBounds);

//            final Rectangle viewPortRect = 
//                ((IHTMLGraphicalViewer)_owner.getViewer()).getViewport().getBounds();
//            final Rectangle targetRect = targetBounds.getCopy();
//            
//            targetRect.intersect(viewPortRect);

//            int width = targetBounds.width - targetRect.width;
//            int height = targetBounds.height - targetRect.height;
            
//            if (width != 0)
//            {
//                targetBounds.x -= width;
//            }
//            
//            if (height != 0)
//            {
//                targetBounds.y += height;
//            }
            
            return targetBounds;
        }
    }
    
    private static class AnimatedHideLocator implements Locator
    {
        private Point _endPoint;
        private boolean _isAnimating;
        
        /**
         * @param endPoint -- must be absolute coordinate
         */
        public void setHideEndPoint(Point endPoint)
        {
            _endPoint = endPoint;
        }
        
        public void relocate(IFigure target) 
        {
            final Point newEndPoint = _endPoint.getCopy();
            target.translateToRelative(_endPoint);
            Rectangle startBounds = target.getBounds().getCopy();
            animateBoundsChange(target, startBounds, newEndPoint);
        }

        private void animateBoundsChange(final IFigure target, 
                final Rectangle startBounds, 
                final Point endPoint)
        {
            final int numSteps = 5;
            final int numMs = 500;
            final int timeSteps = numMs/numSteps;
            
            int xDelta = endPoint.x - startBounds.x;
            int yDelta = endPoint.y - startBounds.y;
            
            final int widthIncrement = -1 * startBounds.width / numSteps;
            final int heightIncrement = -1 * startBounds.height / numSteps;
            int xIncrement = xDelta / numSteps;
            int yIncrement = yDelta  / numSteps;
            
            target.setBounds(startBounds);
            if (widthIncrement != 0 || heightIncrement != 0)
            {
                _isAnimating = true;
                doAnimation(numMs, timeSteps, widthIncrement, heightIncrement, xIncrement, yIncrement, endPoint, target);
            }
        }
        
        private void doAnimation(final int remainingTime, 
                final int timeIncrement, 
                final int widthIncrement, final int heightIncrement
                , final int xIncrement, final int yIncrement
                , final Point endPoint
                , final IFigure target)
        {
            Display.getCurrent().timerExec(timeIncrement, 
            new Runnable()
            {
            public void run() 
            {
               if (remainingTime <= 0)
               {
                   if (target.getParent() != null)
                   {
                       target.getParent().remove(target);
                   }
                   _isAnimating = false;
               }
               else
               {
                   final Rectangle curBounds = target.getBounds().getCopy();
                   curBounds.width += widthIncrement;
                   curBounds.height += heightIncrement;
                   curBounds.x += xIncrement;
                   curBounds.y += yIncrement;
                   target.setBounds(curBounds);
                   target.revalidate();
                   doAnimation(remainingTime-timeIncrement, timeIncrement, widthIncrement, heightIncrement, xIncrement, yIncrement, endPoint, target);
               }
            }
            });
         }
    }
}

