/*******************************************************************************
 * Copyright (c) 2006 Sybase, Inc. 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:
 * Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.pagedesigner.jsf.ui.elementedit.jsfhtml;

import java.util.Iterator;
import java.util.List;

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.DragTracker;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.requests.DropRequest;
import org.eclipse.gef.requests.LocationRequest;
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.action.Separator;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jst.jsf.common.dom.TagIdentifier;
import org.eclipse.jst.jsf.core.internal.tld.IJSFConstants;
import org.eclipse.jst.pagedesigner.actions.single.SelectEditPartAction;
import org.eclipse.jst.pagedesigner.editors.PageDesignerActionConstants;
import org.eclipse.jst.pagedesigner.editpolicies.DragMoveEditPolicy;
import org.eclipse.jst.pagedesigner.editpolicies.ElementResizableEditPolicy;
import org.eclipse.jst.pagedesigner.jsf.core.dom.JSFDOMUtil;
import org.eclipse.jst.pagedesigner.jsf.ui.JSFUIPlugin;
import org.eclipse.jst.pagedesigner.jsf.ui.actions.DeleteHColumnHeaderFooterAction;
import org.eclipse.jst.pagedesigner.jsf.ui.actions.DeleteHeaderFooterAction;
import org.eclipse.jst.pagedesigner.jsf.ui.actions.InsertHColumnHeaderFooterAction;
import org.eclipse.jst.pagedesigner.jsf.ui.actions.InsertHeaderFooterAction;
import org.eclipse.jst.pagedesigner.jsf.ui.commands.jsfhtml.DataTableDeleteColumnCommand;
import org.eclipse.jst.pagedesigner.jsf.ui.commands.jsfhtml.DataTableDeleteColumnHeaderCommand;
import org.eclipse.jst.pagedesigner.jsf.ui.commands.jsfhtml.DataTableDeleteHeaderCommand;
import org.eclipse.jst.pagedesigner.jsf.ui.commands.jsfhtml.DataTableInsertColumnCommand;
import org.eclipse.jst.pagedesigner.jsf.ui.commands.jsfhtml.DataTableInsertColumnHeaderCommand;
import org.eclipse.jst.pagedesigner.jsf.ui.commands.jsfhtml.DataTableInsertHeaderCommand;
import org.eclipse.jst.pagedesigner.jsf.ui.elementedit.request.DeleteHColumnHeaderFooterRequest;
import org.eclipse.jst.pagedesigner.jsf.ui.elementedit.request.DeleteHeaderFooterRequest;
import org.eclipse.jst.pagedesigner.jsf.ui.elementedit.request.InsertHColumnHeaderFooterRequest;
import org.eclipse.jst.pagedesigner.jsf.ui.elementedit.request.InsertHeaderFooterRequest;
import org.eclipse.jst.pagedesigner.jsf.ui.elementedit.util.DataTableUtil;
import org.eclipse.jst.pagedesigner.parts.ElementEditPart;
import org.eclipse.jst.pagedesigner.parts.NodeEditPart;
import org.eclipse.jst.pagedesigner.tableedit.DeleteRowColumnAction;
import org.eclipse.jst.pagedesigner.tableedit.InsertRowColumnAction;
import org.eclipse.jst.pagedesigner.tableedit.TableInsertRequest;
import org.eclipse.jst.pagedesigner.tableedit.TableResizeRequest;
import org.eclipse.jst.pagedesigner.tableedit.TableRowColumnDeleteRequest;
import org.eclipse.jst.pagedesigner.tools.ObjectModeDragTracker;
import org.eclipse.jst.pagedesigner.validation.caret.ActionData;
import org.eclipse.jst.pagedesigner.validation.caret.DefaultPositionRule;
import org.eclipse.jst.pagedesigner.validation.caret.DnDPositionValidator;
import org.eclipse.jst.pagedesigner.validation.caret.DropActionData;
import org.eclipse.jst.pagedesigner.validation.caret.IPositionMediator;
import org.eclipse.jst.pagedesigner.validation.caret.Target;
import org.eclipse.jst.pagedesigner.validation.caret.DropActionData.DropData;
import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Image;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

/**
 * @author mengbo
 * @version 1.5
 */
public class DataTableElementEdit extends DefaultJSFHTMLElementEdit
{
    private final static Action     EMPTY_ACTION     = new Action()
    {
        // TODO: why?
    };
    private final static int FAKE_INDEX = -10;

    /* (non-Javadoc)
     * @see org.eclipse.jst.pagedesigner.elementedit.IElementEdit#fillContextMenu(org.eclipse.jface.action.IMenuManager, org.w3c.dom.Element)
     */
    public void fillContextMenu(IMenuManager contextMenu, Element ele)
    {
        super.fillContextMenu(contextMenu, ele);

        final IMenuManager tableMenu = new MenuManager(JSFUIPlugin.getResourceString("ElementEdit.Submenu.DataTable"));//$NON-NLS-1$
        final ElementEditPart editPart = (ElementEditPart) ((IDOMElement) ele).getAdapterFor(EditPart.class);
        // ok, we passed the checking, now let's create the actions.
        tableMenu.add(EMPTY_ACTION);
        tableMenu.addMenuListener(new IMenuListener()
        {
            public void menuAboutToShow(IMenuManager manager)
            {
                tableMenu.removeAll();
                fillTableMenu(editPart, FAKE_INDEX, tableMenu);
            }
        });

        contextMenu.appendToGroup(PageDesignerActionConstants.GROUP_CONTAINER, tableMenu);
    }

    /* (non-Javadoc)
     * @see org.eclipse.jst.pagedesigner.elementedit.IElementEdit#fillContainerContextMenu(org.eclipse.jface.action.IMenuManager, org.eclipse.jst.pagedesigner.parts.ElementEditPart, org.eclipse.jst.pagedesigner.parts.NodeEditPart, org.eclipse.jface.viewers.ISelection)
     */
    public boolean fillContainerContextMenu(IMenuManager contextMenu, final ElementEditPart elePart,
            NodeEditPart nodePart, ISelection innerSelection)
    {
        Element table = (Element) elePart.getModel();
        Node node = (Node) nodePart.getModel();

        DataTableUtil util = new DataTableUtil(table);
        Element columnParent = util.findHColumnParent(node);

        final int cellColumn = util.getColumnIndex(columnParent);

        final IMenuManager tableMenu = new MenuManager(JSFUIPlugin.getResourceString("ElementEdit.Submenu.DataTable"));//$NON-NLS-1$

        // ok, we passed the checking, now let's create the actions.
        tableMenu.add(EMPTY_ACTION);
        tableMenu.addMenuListener(new IMenuListener()
        {
            public void menuAboutToShow(IMenuManager manager)
            {
                tableMenu.removeAll();
                fillTableMenu(elePart, cellColumn, tableMenu);
            }
        });

        contextMenu.appendToGroup(PageDesignerActionConstants.GROUP_CONTAINER, tableMenu);
        return true;

    }

    /**
     * @param elePart
     * @param cellColumn
     * @param tableMenu
     */
    private void fillTableMenu(ElementEditPart elePart, int cellColumn, IMenuManager tableMenu)
    {
        SelectEditPartAction action = SelectEditPartAction.create(JSFUIPlugin
                .getResourceString("ElementEdit.Submenu.DataTable.SelectTable"), elePart);//$NON-NLS-1$
        tableMenu.add(action);

        tableMenu.add(new Separator());

        {
            InsertRowColumnAction insertColumnBeforeAction = new InsertRowColumnAction(JSFUIPlugin
                    .getResourceString("ElementEdit.Submenu.DataTable.InsertColumnBefore"), //$NON-NLS-1$
                    elePart, cellColumn, false, true);
            tableMenu.add(insertColumnBeforeAction);

            InsertRowColumnAction insertColumnAfterAction = new InsertRowColumnAction(JSFUIPlugin
                    .getResourceString("ElementEdit.Submenu.DataTable.InsertColumnAfter"),//$NON-NLS-1$ 
                    elePart, cellColumn, false, false);
            tableMenu.add(insertColumnAfterAction);

            tableMenu.add(new Separator());
        }

        {
            DeleteRowColumnAction deleteColumnAction = new DeleteRowColumnAction(JSFUIPlugin
                    .getResourceString("ElementEdit.Submenu.DataTable.DeleteColumn"), //$NON-NLS-1$
                    elePart, cellColumn, false);
            tableMenu.add(deleteColumnAction);
            tableMenu.add(new Separator());
        }

        {
            InsertHeaderFooterAction headerAction = new InsertHeaderFooterAction(JSFUIPlugin
                    .getResourceString("ElementEdit.Submenu.InsertTableHeader"), elePart, true);//$NON-NLS-1$
            tableMenu.add(headerAction);

            InsertHeaderFooterAction footerAction = new InsertHeaderFooterAction(JSFUIPlugin
                    .getResourceString("ElementEdit.Submenu.InsertTableFooter"), elePart, false);//$NON-NLS-1$
            tableMenu.add(footerAction);

            DeleteHeaderFooterAction delHeaderAction = new DeleteHeaderFooterAction(JSFUIPlugin
                    .getResourceString("ElementEdit.Submenu.DeleteTableHeader"), elePart, true);//$NON-NLS-1$
            tableMenu.add(delHeaderAction);

            DeleteHeaderFooterAction delFooterAction = new DeleteHeaderFooterAction(JSFUIPlugin
                    .getResourceString("ElementEdit.Submenu.DeleteTableFooter"), elePart, false);//$NON-NLS-1$
            tableMenu.add(delFooterAction);
            tableMenu.add(new Separator());
        }

        {
            InsertHColumnHeaderFooterAction hColHeaderAction = new InsertHColumnHeaderFooterAction(JSFUIPlugin
                    .getResourceString("ElementEdit.Submenu.InsertColumnHeader"),//$NON-NLS-1$
                    elePart, true);
            tableMenu.add(hColHeaderAction);

            InsertHColumnHeaderFooterAction hColFooterAction = new InsertHColumnHeaderFooterAction(JSFUIPlugin
                    .getResourceString("ElementEdit.Submenu.InsertColumnFooter"),//$NON-NLS-1$
                    elePart, false);
            tableMenu.add(hColFooterAction);

            DeleteHColumnHeaderFooterAction delColHeader = new DeleteHColumnHeaderFooterAction(JSFUIPlugin
                    .getResourceString("ElementEdit.Submenu.DeleteColumnHeader"),//$NON-NLS-1$
                    elePart, true);
            tableMenu.add(delColHeader);

            DeleteHColumnHeaderFooterAction delColFooter = new DeleteHColumnHeaderFooterAction(JSFUIPlugin
                    .getResourceString("ElementEdit.Submenu.DeleteColumnFooter"),//$NON-NLS-1$
                    elePart, false);
            tableMenu.add(delColFooter);
        }
    }

    /* (non-Javadoc)
     * @see org.eclipse.jst.pagedesigner.elementedit.IElementEdit#createEditPolicies(org.eclipse.jst.pagedesigner.parts.ElementEditPart)
     */
    public void createEditPolicies(ElementEditPart part)
    {
        part.installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE, new DataTableResizePolicy(part));
        part.installEditPolicy(EditPolicy.PRIMARY_DRAG_ROLE,
                new MyDragMoveEditPolicy());
    }

    static class DataTableResizePolicy extends ElementResizableEditPolicy
    {
        ElementEditPart _part;
        Cursor          _columnSelectCursor;

        /**
         * @param part
         */
        public DataTableResizePolicy(ElementEditPart part)
        {
            _part = part;
        }

        public void deactivate() {
            super.deactivate();
            if (_columnSelectCursor != null && !_columnSelectCursor.isDisposed())
            {
                _columnSelectCursor.dispose();
                _columnSelectCursor = null;
            }
        }

        private Cursor getColumnSelectCursor()
        {
            if (_columnSelectCursor == null)
            {
                final Image cursorImage = JSFUIPlugin.getDefault().getImage("column_select.gif");
                _columnSelectCursor = new Cursor(null, cursorImage.getImageData(), 2, 5);
            }
            
            return _columnSelectCursor;
        }
        /* (non-Javadoc)
         * @see org.eclipse.gef.editpolicies.ResizableEditPolicy#getCommand(org.eclipse.gef.Request)
         */
        public Command getCommand(Request request)
        {
            IHTMLGraphicalViewer viewer = (IHTMLGraphicalViewer) _part.getViewer();
            Element dataTable = (Element) _part.getIDOMNode();
            if (request instanceof TableResizeRequest)
            {
                return super.getCommand(request);
            }
            else if (request instanceof TableInsertRequest)
            {
                TableInsertRequest tableInsertRequest = (TableInsertRequest) request;
                if (tableInsertRequest.isRow())
                {
                    // don't support insert row.
                    return null;
                }
                int index = tableInsertRequest.getIndex() + (tableInsertRequest.isBefore() ? 0 : 1);
                return new DataTableInsertColumnCommand(viewer, dataTable, index);
            }
            else if (request instanceof InsertHeaderFooterRequest)
            {
                InsertHeaderFooterRequest req = (InsertHeaderFooterRequest) request;
                boolean isHeader = req.isHeader();
                return new DataTableInsertHeaderCommand(viewer, dataTable, isHeader);
            }
            else if (request instanceof DeleteHeaderFooterRequest)
            {
                DeleteHeaderFooterRequest req = (DeleteHeaderFooterRequest) request;
                boolean isHeader = req.isHeader();
                return new DataTableDeleteHeaderCommand(viewer, dataTable, isHeader);
            }
            else if (request instanceof InsertHColumnHeaderFooterRequest)
            {
                InsertHColumnHeaderFooterRequest req = (InsertHColumnHeaderFooterRequest) request;
                boolean isHeader = req.isHeader();
                return new DataTableInsertColumnHeaderCommand(viewer, dataTable, isHeader);
            }
            else if (request instanceof DeleteHColumnHeaderFooterRequest)
            {
                DeleteHColumnHeaderFooterRequest req = (DeleteHColumnHeaderFooterRequest) request;
                boolean isHeader = req.isHeader();
                return new DataTableDeleteColumnHeaderCommand(viewer, dataTable, isHeader);
            }
            else if (request instanceof TableRowColumnDeleteRequest)
            {
                TableRowColumnDeleteRequest deleteReq = (TableRowColumnDeleteRequest) request;
                if (deleteReq.isRow())
                {
                    return null;
                }
                return new DataTableDeleteColumnCommand(viewer, dataTable, deleteReq.getIndex());
            }
            return super.getCommand(request);
        }

        public Cursor getSelectionToolCursor(Point mouseLocation) 
        {
            if (hitTestColumnSelection(mouseLocation))
            {
                return getColumnSelectCursor();
            }
            
            return null;
        }

        protected DragTracker getSelectionTracker(LocationRequest request) {
            final Point mouseLocator = request.getLocation();
            if (hitTestColumnSelection(mouseLocator))
            {
                ObjectModeDragTracker dragTracker =  new ObjectModeDragTracker(getHost())
                {
                    protected boolean handleButtonDown(int button)
                    {
                        // only customize the case where we are in a column selection mode
                        if (button == 1)
                        {
                            EditPart retarget = 
                                getRetargetSelectionEditPart(mouseLocator);
                            
                            if (retarget != null)
                            {
                                setSourceEditPart(retarget);
                            }
                        }
                        
                        // default
                        return super.handleButtonDown(button);
                    }
                };
                
                dragTracker.setDefaultCursor(getSelectionToolCursor(mouseLocator));
                return dragTracker;
            }
            return new ObjectModeDragTracker(getHost());
        }

        public DragTracker getSelectionDragTracker(LocationRequest request) {
            return getSelectionTracker(request);
        }

        /**
         * @param mouseLocation
         * @return the edit part fo the given mouse location
         */
        public EditPart getRetargetSelectionEditPart(Point mouseLocation) {
            if (hitTestColumnSelection(mouseLocation))
            {
                GraphicalEditPart editPart = (GraphicalEditPart) getHost();
                List children = editPart.getChildren();
                
                for (Iterator it = children.iterator(); it.hasNext();)
                {
                    GraphicalEditPart child = (GraphicalEditPart) it.next();

                    if (child instanceof NodeEditPart)
                    {
                        Node childNode = ((NodeEditPart)child).getDOMNode();

                        if (JSFDOMUtil.isHColumn(childNode))
                        {
                            Point relativeMousePointer = mouseLocation.getCopy();
                            IFigure hostFigure = child.getFigure();
                            hostFigure.translateToRelative(relativeMousePointer);
                            Rectangle hostBounds = hostFigure.getBounds();
                            if (relativeMousePointer.x >= hostBounds.x
                                    && relativeMousePointer.x < hostBounds.x+hostBounds.width)
                            {
                                return child;
                            }
                        }
                    }
                }
            }
            
            // otherwise, don't retarget
            return null;
        }

        private boolean hitTestColumnSelection(Point mouseLocation)
        {
            final GraphicalEditPart part = (GraphicalEditPart) getHost();
            final IFigure panelFigure = part.getFigure();
            
            Point  relativeLocation = mouseLocation.getCopy();
            panelFigure.translateToRelative(relativeLocation);

            final int yoffsetAbs = Math.abs(panelFigure.getBounds().y - relativeLocation.y);
            
            if (yoffsetAbs <= 4)
            {
                return true;
            }
            
            return false;
        }
    }
    
    /**
     * @author cbateman
     *
     */
    public static class MyDragMoveEditPolicy extends DragMoveEditPolicy 
    {
        protected IPositionMediator createDropChildValidator(
                DropRequest r) 
        {
            DropData dropData = createDropData(r);
            
            if (dropData!=null)
            {
                DnDPositionValidator validator = 
                    new DnDPositionValidator(new DropActionData(
                            ActionData.COMPONENT_MOVE, dropData));
                validator.addRule(new OnlyColumnsAndFacetsRule(validator.getActionData()));
                return validator;
            }
            return null;
        }
        
        private static class OnlyColumnsAndFacetsRule extends DefaultPositionRule
        {
            /**
             * @param actionData
             */
            public OnlyColumnsAndFacetsRule(ActionData actionData) {
                super(actionData);
            }

            public boolean isEditable(Target target) {
                if (IJSFConstants.TAG_IDENTIFIER_DATA_TABLE.isSameTagType(target.getTagWrapper()))
                {
                    return isDataDroppable();
                }
                
                return true;
            }
            
            private boolean isDataDroppable()
            {
                ActionData actionData = getActionData();
                if (actionData instanceof DropActionData)
                {
                    DropActionData dropActionData = (DropActionData) actionData;
                    TagIdentifier tagId = 
                        (TagIdentifier) dropActionData.getDropData().getTagIdentifiers().get(0);
                            
                    if (IJSFConstants.TAG_IDENTIFIER_FACET.isSameTagType(tagId)
                            || IJSFConstants.TAG_IDENTIFIER_COLUMN.isSameTagType(tagId))
                    {
                        return true;
                    }
                }
                
                return false;
            }
        }
    }
}
