/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.eclipse.org/org/documents/epl-v10.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.ide.eclipse.adt.internal.editors.layout.gle2;

import static com.android.SdkConstants.FD_RESOURCES;
import static com.android.SdkConstants.FD_RES_ANIMATOR;
import static com.android.ide.eclipse.adt.AdtConstants.WS_SEP;

import com.android.ide.common.rendering.api.Capability;
import com.android.ide.common.rendering.api.IAnimationListener;
import com.android.ide.common.rendering.api.RenderSession;
import com.android.ide.common.rendering.api.Result;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
import com.android.ide.eclipse.adt.internal.wizards.newxmlfile.NewXmlFileWizard;
import com.android.resources.ResourceType;
import com.android.utils.Pair;

import org.eclipse.core.resources.IProject;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchWindow;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * "Play Animation" context menu which lists available animations in the project and in
 * the framework, as well as a "Create Animation" shortcut, and allows the animation to be
 * run on the selection
 * <p/>
 * TODO: Add transport controls for play/rewind/pause/loop, and (if possible) scrubbing
 */
public class PlayAnimationMenu extends SubmenuAction {
    /** Associated canvas */
    private final LayoutCanvas mCanvas;
    /** Whether this menu is showing local animations or framework animations */
    private boolean mFramework;

    /**
     * Creates a "Play Animation" menu
     *
     * @param canvas associated canvas
     */
    public PlayAnimationMenu(LayoutCanvas canvas) {
        this(canvas, "Play Animation", false);
    }

    /**
     * Creates an animation menu; this can be used either for the outer Play animation
     * menu, or the inner frameworks-animations list
     *
     * @param canvas the associated canvas
     * @param title menu item name
     * @param framework true to show the framework animations, false for the project (and
     *            nested framework-animation-menu) animations
     */
    private PlayAnimationMenu(LayoutCanvas canvas, String title, boolean framework) {
        super(title);
        mCanvas = canvas;
        mFramework = framework;
    }

    @Override
    protected void addMenuItems(Menu menu) {
        SelectionManager selectionManager = mCanvas.getSelectionManager();
        List<SelectionItem> selection = selectionManager.getSelections();
        if (selection.size() != 1) {
            addDisabledMessageItem("Select exactly one widget");
            return;
        }

        GraphicalEditorPart graphicalEditor = mCanvas.getEditorDelegate().getGraphicalEditor();
        if (graphicalEditor.renderingSupports(Capability.PLAY_ANIMATION)) {
            // List of animations
            Collection<String> animationNames = graphicalEditor.getResourceNames(mFramework,
                    ResourceType.ANIMATOR);
            if (animationNames.size() > 0) {
                // Sort alphabetically
                List<String> sortedNames = new ArrayList<String>(animationNames);
                Collections.sort(sortedNames);

                for (String animation : sortedNames) {
                    String title = animation;
                    IAction action = new PlayAnimationAction(title, animation, mFramework);
                    new ActionContributionItem(action).fill(menu, -1);
                }

                new Separator().fill(menu, -1);
            }

            if (!mFramework) {
                // Not in the framework submenu: include recent list and create new actions

                // "Create New" action
                new ActionContributionItem(new CreateAnimationAction()).fill(menu, -1);

                // Framework resources submenu
                new Separator().fill(menu, -1);
                PlayAnimationMenu sub = new PlayAnimationMenu(mCanvas, "Android Builtin", true);
                new ActionContributionItem(sub).fill(menu, -1);
            }
        } else {
            addDisabledMessageItem(
                    "Not supported for this SDK version; try changing the Render Target");
        }
    }

    private class PlayAnimationAction extends Action {
        private final String mAnimationName;
        private final boolean mIsFrameworkAnim;

        public PlayAnimationAction(String title, String animationName, boolean isFrameworkAnim) {
            super(title, IAction.AS_PUSH_BUTTON);
            mAnimationName = animationName;
            mIsFrameworkAnim = isFrameworkAnim;
        }

        @Override
        public void run() {
            SelectionManager selectionManager = mCanvas.getSelectionManager();
            List<SelectionItem> selection = selectionManager.getSelections();
            SelectionItem canvasSelection = selection.get(0);
            CanvasViewInfo info = canvasSelection.getViewInfo();

            Object viewObject = info.getViewObject();
            if (viewObject != null) {
                ViewHierarchy viewHierarchy = mCanvas.getViewHierarchy();
                RenderSession session = viewHierarchy.getSession();
                Result r = session.animate(viewObject, mAnimationName, mIsFrameworkAnim,
                        new IAnimationListener() {
                            private boolean mPendingDrawing = false;

                            @Override
                            public void onNewFrame(RenderSession s) {
                                SelectionOverlay selectionOverlay = mCanvas.getSelectionOverlay();
                                if (!selectionOverlay.isHiding()) {
                                    selectionOverlay.setHiding(true);
                                }
                                HoverOverlay hoverOverlay = mCanvas.getHoverOverlay();
                                if (!hoverOverlay.isHiding()) {
                                    hoverOverlay.setHiding(true);
                                }

                                ImageOverlay imageOverlay = mCanvas.getImageOverlay();
                                imageOverlay.setImage(s.getImage(), s.isAlphaChannelImage());
                                synchronized (this) {
                                    if (mPendingDrawing == false) {
                                        mCanvas.getDisplay().asyncExec(new Runnable() {
                                            @Override
                                            public void run() {
                                                synchronized (this) {
                                                    mPendingDrawing = false;
                                                }
                                                mCanvas.redraw();
                                            }
                                        });
                                        mPendingDrawing = true;
                                    }
                                }
                            }

                            @Override
                            public boolean isCanceled() {
                                return false;
                            }

                            @Override
                            public void done(Result result) {
                                SelectionOverlay selectionOverlay = mCanvas.getSelectionOverlay();
                                selectionOverlay.setHiding(false);
                                HoverOverlay hoverOverlay = mCanvas.getHoverOverlay();
                                hoverOverlay.setHiding(false);

                                // Must refresh view hierarchy to force objects back to
                                // their original positions in case animations have left
                                // them elsewhere
                                mCanvas.getDisplay().asyncExec(new Runnable() {
                                    @Override
                                    public void run() {
                                        GraphicalEditorPart graphicalEditor = mCanvas
                                                .getEditorDelegate().getGraphicalEditor();
                                        graphicalEditor.recomputeLayout();
                                    }
                                });
                            }
                        });

                if (!r.isSuccess()) {
                    if (r.getErrorMessage() != null) {
                        AdtPlugin.log(r.getException(), r.getErrorMessage());
                    }
                }
            }
        }
    }

    /**
     * Action which brings up the "Create new XML File" wizard, pre-selected with the
     * animation category
     */
    private class CreateAnimationAction extends Action {
        public CreateAnimationAction() {
            super("Create...", IAction.AS_PUSH_BUTTON);
        }

        @Override
        public void run() {
            Shell parent = mCanvas.getShell();
            NewXmlFileWizard wizard = new NewXmlFileWizard();
            LayoutEditorDelegate editor = mCanvas.getEditorDelegate();
            IWorkbenchWindow workbenchWindow =
                editor.getEditor().getEditorSite().getWorkbenchWindow();
            IWorkbench workbench = workbenchWindow.getWorkbench();
            String animationDir = FD_RESOURCES + WS_SEP + FD_RES_ANIMATOR;
            Pair<IProject, String> pair = Pair.of(editor.getEditor().getProject(), animationDir);
            IStructuredSelection selection = new StructuredSelection(pair);
            wizard.init(workbench, selection);
            WizardDialog dialog = new WizardDialog(parent, wizard);
            dialog.create();
            dialog.open();
        }
    }
}
