/*******************************************************************************
 * 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
{
    private static final String PIN_UP_IMAGE_FILE = "pin_up.gif"; //$NON-NLS-1$
    
	private static final String PIN_DOWN_IMAGE_FILE = "pin_down.gif"; //$NON-NLS-1$

	// 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_IMAGE_FILE);
        }
        else
        {
            arrowImage = PDPlugin.getDefault().getImage(PIN_UP_IMAGE_FILE);
        }
        
        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);
               }
            }
            });
         }
    }
}

