/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
 *
 *  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 org.apache.ivyde.eclipse.resolvevisualizer;

import java.awt.Dimension;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Stack;

import org.apache.ivy.core.report.ResolveReport;
import org.apache.ivyde.eclipse.cp.IvyClasspathContainer;
import org.apache.ivyde.eclipse.resolvevisualizer.label.ILabelDecoratorAlgorithm;
import org.apache.ivyde.eclipse.resolvevisualizer.model.IvyNodeElement;
import org.apache.ivyde.eclipse.resolvevisualizer.model.IvyNodeElementAdapter;
import org.apache.ivyde.eclipse.resolvevisualizer.model.IvyNodeElementFilterAdapter;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.zest.core.viewers.AbstractZoomableViewer;
import org.eclipse.zest.core.viewers.EntityConnectionData;
import org.eclipse.zest.core.viewers.GraphViewer;
import org.eclipse.zest.core.viewers.IZoomableWorkbenchPart;
import org.eclipse.zest.core.viewers.ZoomContributionViewItem;
import org.eclipse.zest.core.widgets.Graph;
import org.eclipse.zest.core.widgets.GraphItem;
import org.eclipse.zest.core.widgets.GraphNode;
import org.eclipse.zest.core.widgets.ZestStyles;
import org.eclipse.zest.layouts.LayoutAlgorithm;
import org.eclipse.zest.layouts.LayoutStyles;
import org.eclipse.zest.layouts.algorithms.CompositeLayoutAlgorithm;
import org.eclipse.zest.layouts.algorithms.DirectedGraphLayoutAlgorithm;
import org.eclipse.zest.layouts.algorithms.HorizontalShift;

public class ResolveVisualizerView extends ViewPart implements IZoomableWorkbenchPart {
    private GraphViewer viewer;
    private FormToolkit toolKit;

    private Action focusDialogAction;
    private Action focusDialogActionToolbar;
    private Action focusOnSelectionAction;
    private Action hideSelectionAction;
    private Action showHiddenAction;
    private Action applyDefaultLayoutAction;
    private Action historyAction;
    private Action forwardAction;
    private Action refreshAction;

    private ZoomContributionViewItem contextZoomContributionViewItem;
    private ZoomContributionViewItem toolbarZoomContributionViewItem;

    private Stack/* <IvyNodeElement> */historyStack;
    private Stack/* <IvyNodeElement> */forwardStack;

    private IvyNodeElement currentRoot;
    private IvyNodeElement currentSelection;
    private IvyClasspathContainer currentContainer;

    private ResolveVisualizerContentProvider contentProvider = new ResolveVisualizerContentProvider();
    private MessageContentProvider messageContentProvider = new MessageContentProvider();
    private IvyNodeLabelProvider labelProvider;
    private ResolveVisualizerForm visualizationForm;

    private ForceHiddenFilter forceHiddenFilter;

    public ResolveVisualizerView() {
        historyStack = new Stack/* <IvyNodeElement> */();
        forwardStack = new Stack/* <IvyNodeElement> */();

        forceHiddenFilter = new ForceHiddenFilter();
        forceHiddenFilter.setEnabled(true);
        contentProvider.addFilter(forceHiddenFilter);
    }

    /**
     * This is a callback that will allow us to create the viewer and initialize it.
     */
    public void createPartControl(Composite parent) {
        toolKit = new FormToolkit(parent.getDisplay());

        visualizationForm = new ResolveVisualizerForm(parent, toolKit, this);
        viewer = visualizationForm.getGraphViewer();

        this.labelProvider = new IvyNodeLabelProvider(this.viewer);
        viewer.setLabelProvider(labelProvider);
        viewer.setContentProvider(contentProvider);
        viewer.setInput(null);
        viewer.setConnectionStyle(ZestStyles.CONNECTIONS_DIRECTED);
        viewer.setLayoutAlgorithm(new CompositeLayoutAlgorithm(LayoutStyles.NO_LAYOUT_NODE_RESIZING,
                new LayoutAlgorithm[] { new DirectedGraphLayoutAlgorithm(LayoutStyles.NO_LAYOUT_NODE_RESIZING),
                                        new HorizontalShift(LayoutStyles.NO_LAYOUT_NODE_RESIZING) }));

        viewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                Object selectedElement = ((IStructuredSelection) event.getSelection()).getFirstElement();
                if (selectedElement instanceof EntityConnectionData) {
                    return;
                }
                ResolveVisualizerView.this.selectionChanged((IvyNodeElement) selectedElement);
            }
        });

        viewer.addDoubleClickListener(new IDoubleClickListener() {
            public void doubleClick(DoubleClickEvent event) {
                focusOnSelectionAction.run();
            }
        });

        visualizationForm.getSearchBox().addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                String textString = visualizationForm.getSearchBox().getText();

                HashMap figureListing = new HashMap();
                ArrayList list = new ArrayList();
                Iterator iterator = viewer.getGraphControl().getNodes().iterator();
                while (iterator.hasNext()) {
                    GraphItem item = (GraphItem) iterator.next();
                    figureListing.put(item.getText(), item);
                }
                iterator = figureListing.keySet().iterator();
                if (textString.length() > 0) {
                    while (iterator.hasNext()) {
                        String string = (String) iterator.next();
                        if (string.toLowerCase().indexOf(textString.toLowerCase()) >= 0) {
                            list.add(figureListing.get(string));
                        }
                    }
                }
                viewer.getGraphControl().setSelection((GraphItem[]) list.toArray(new GraphItem[list.size()]));
            }
        });

        messageContentProvider.setMessageManager(visualizationForm.getManagedForm().getMessageManager());
        contextZoomContributionViewItem = new ZoomContributionViewItem(this);
        toolbarZoomContributionViewItem = new ZoomContributionViewItem(this);

        // Create the help context id for the viewer's control
        makeActions();
        hookContextMenu();
        contributeToActionBars();
    }

    private void hookContextMenu() {
        MenuManager menuMgr = new MenuManager("#PopupMenu");
        menuMgr.setRemoveAllWhenShown(true);
        menuMgr.addMenuListener(new IMenuListener() {
            public void menuAboutToShow(IMenuManager manager) {
                ResolveVisualizerView.this.fillContextMenu(manager);
            }
        });
        Menu menu = menuMgr.createContextMenu(viewer.getControl());
        viewer.getControl().setMenu(menu);
        getSite().registerContextMenu(menuMgr, viewer);
    }

    private void contributeToActionBars() {
        IActionBars bars = getViewSite().getActionBars();
        bars.getMenuManager().add(toolbarZoomContributionViewItem);
        fillLocalPullDown(bars.getMenuManager());
        fillLocalToolBar(bars.getToolBarManager());
    }

    private void fillLocalPullDown(IMenuManager manager) {
    }

    private void fillContextMenu(IMenuManager manager) {
        manager.add(new Separator());
        manager.add(focusDialogAction);
        manager.add(focusOnSelectionAction);
        manager.add(new Separator());
        manager.add(historyAction);
        manager.add(forwardAction);
        manager.add(new Separator());
        manager.add(hideSelectionAction);
        manager.add(showHiddenAction);
        manager.add(new Separator());
        manager.add(refreshAction);
        manager.add(applyDefaultLayoutAction);
        manager.add(new Separator());
        manager.add(contextZoomContributionViewItem);
    }

    private void fillLocalToolBar(IToolBarManager toolBarManager) {
        toolBarManager.add(refreshAction);
        toolBarManager.add(focusDialogActionToolbar);
        toolBarManager.add(new Separator());
        toolBarManager.add(historyAction);
        toolBarManager.add(forwardAction);
    }

    private void makeActions() {
        refreshAction = new Action() {
            public void run() {
                final IvyClasspathContainer container = currentContainer;

                if (container == null) {
                    // nothing as been actually selected
                    return;
                }

                ResolveReport report = container.getResolveReport();
                if (report == null) {
                    // TODO we might want to launch some resolve here
                    // or at least open a popup inviting the end user to launch one
                    return;
                }

                // a resolve report is already saved on the container's state, we will use it
                focusOnContainer(container);

                // When a new container is selected, disable the forward action
                // The forward action only stores history when the back button was used (much like a browser)
                forwardStack.clear();
                forwardAction.setEnabled(false);
            }
        };
        refreshAction.setText("Resolve");
        refreshAction.setEnabled(true);
        refreshAction.setImageDescriptor(Plugin.getImageDescriptor("icons/refresh.gif"));

        focusDialogAction = new Action() {
            public void run() {
                ClasspathContainerSelectionDialog dialog = new ClasspathContainerSelectionDialog(viewer.getControl()
                        .getShell());
                dialog.create();
                int dialogStatus = dialog.open();
                if (dialogStatus == Window.OK) {
                    currentContainer = (IvyClasspathContainer) dialog.getFirstResult();
                    refreshAction.run();
                }
            }
        };
        focusDialogAction.setText("Focus on ivy file...");

        focusDialogActionToolbar = new Action() {
            public void run() {
                focusDialogAction.run();
            }
        };
        focusDialogActionToolbar.setToolTipText("Focus on ivy file...");
        focusDialogActionToolbar.setImageDescriptor(ResolveVisualizerPlugin.getImageDescriptor("icons/focus.gif"));

        focusOnSelectionAction = new Action() {
            public void run() {
                if (currentSelection != null) {
                    if (currentRoot != currentSelection) {
                        if (currentRoot != null) {
                            historyStack.push(currentRoot);
                            historyAction.setEnabled(true);
                        }
                        focusOn(currentSelection);
                    }
                }
            }
        };
        focusOnSelectionAction.setText("Focus on selection");
        focusOnSelectionAction.setEnabled(false);

        historyAction = new Action() {
            public void run() {
                if (historyStack.size() > 0) {
                    IvyNodeElement element = (IvyNodeElement) historyStack.pop();
                    forwardStack.push(currentRoot);
                    forwardAction.setEnabled(true);
                    focusOn(element);
                    if (historyStack.size() <= 0) {
                        historyAction.setEnabled(false);
                    }
                }
            }
        };
        historyAction.setText("Back");
        historyAction.setToolTipText("Back");
        historyAction.setEnabled(false);
        historyAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages()
                .getImageDescriptor(ISharedImages.IMG_TOOL_BACK));

        forwardAction = new Action() {
            public void run() {
                if (forwardStack.size() > 0) {
                    IvyNodeElement element = (IvyNodeElement) forwardStack.pop();

                    historyStack.push(currentRoot);
                    historyAction.setEnabled(true);

                    focusOn(element);
                    if (forwardStack.size() <= 0) {
                        forwardAction.setEnabled(false);
                    }
                }
            }
        };

        forwardAction.setText("Forward");
        forwardAction.setToolTipText("Forward");
        forwardAction.setEnabled(false);
        forwardAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages()
                .getImageDescriptor(ISharedImages.IMG_TOOL_FORWARD));

        hideSelectionAction = new Action() {
            public void run() {
                forceHiddenFilter.addHidden(currentSelection);
                refresh();
            }
        };
        hideSelectionAction.setText("Hide");

        showHiddenAction = new Action() {
            public void run() {
                forceHiddenFilter.clearHidden();
                refresh();
            }
        };
        showHiddenAction.setText("Show hidden");

        applyDefaultLayoutAction = new Action() {
            public void run() {
                viewer.applyLayout();
            }
        };
        applyDefaultLayoutAction.setText("Apply default layout");
    }

    /**
     * Passing the focus request to the viewer's control.
     */
    public void setFocus() {
        viewer.getControl().setFocus();
    }

    private final void focusOnContainer(IvyClasspathContainer container) {
        ResolveReport report = container.getResolveReport();

        if (report != null) {
            forceHiddenFilter.clearHidden();
            visualizationForm.getForm().setText(
                    ResolveVisualizerForm.HeaderText + " - " + container.getConf().getIvyXmlPath() + " in \""
                            + container.getConf().getJavaProject().getProject().getName() + "\"");

            IvyNodeElement nextRoot = IvyNodeElementAdapter.adapt(report);
            if (currentRoot != nextRoot) {
                if (currentRoot != null) {
                    historyStack.push(currentRoot);
                    historyAction.setEnabled(true);
                }
                focusOn(nextRoot);
            }
        }
    }

    /**
     * Update the view to focus on a particular bundle. If record history is set to true, and bundle does not equal the
     * current bundle, then the current bundle will be saved on the history stack
     * 
     * @param focus
     * @param recordHistory
     */
    public void focusOn(IvyNodeElement focus) {
        viewer.setSelection(new StructuredSelection(focus));
        viewer.setFilters(new ViewerFilter[] {});
        viewer.setInput(focus);

        Iterator nodes = viewer.getGraphControl().getNodes().iterator();
        Graph graph = viewer.getGraphControl();
        Dimension centre = new Dimension(graph.getBounds().width / 2, graph.getBounds().height / 2);
        while (nodes.hasNext()) {
            GraphNode graphNode = (GraphNode) nodes.next();
            if (graphNode.getLocation().x <= 1 && graphNode.getLocation().y <= 1) {
                graphNode.setLocation(centre.width, centre.height);
            }
        }

        currentRoot = focus;

        if (viewer.getGraphControl().getNodes().size() > 0) {
            visualizationForm.enableSearchBox(true);
        } else {
            visualizationForm.enableSearchBox(false);
        }
        visualizationForm.enableSearchBox(true);
        focusOnSelectionAction.setEnabled(true);

        selectionChanged(focus);
    }

    /**
     * Handle the select changed. This will update the view whenever a selection occurs.
     * 
     * @param selectedItem
     */
    private void selectionChanged(IvyNodeElement selectedItem) {
        currentSelection = selectedItem;
        labelProvider.setCurrentSelection(currentRoot, selectedItem);
        messageContentProvider.selectionChanged(currentRoot);
        viewer.update(contentProvider.getElements(currentRoot), null);
    }

    public AbstractZoomableViewer getZoomableViewer() {
        return viewer;
    }

    public void setAutoSelectDecorator(ILabelDecoratorAlgorithm algorithm) {
        labelProvider.setAutoSelectDecorator(algorithm);

        if (viewer.getSelection() != null) {
            Object selected = ((IStructuredSelection) viewer.getSelection()).getFirstElement();
            this.selectionChanged((IvyNodeElement) selected);
        }
    }

    public ResolveVisualizerContentProvider getContentProvider() {
        return contentProvider;
    }

    public void refresh() {
        viewer.refresh();
        viewer.applyLayout();
    }

    public IvyNodeElement getCurrentRoot() {
        return currentRoot;
    }

    private class ForceHiddenFilter extends IvyNodeElementFilterAdapter {
        private Collection/* <IvyNodeElement> */forceHidden = new HashSet/* <IvyNodeElement> */();

        public boolean accept(IvyNodeElement unfiltered) {
            return !forceHidden.contains(unfiltered);
        }

        public void addHidden(IvyNodeElement hide) {
            forceHidden.addAll(Arrays.asList(hide.getDeepDependencies()));
        }

        public void clearHidden() {
            forceHidden.clear();
        }
    }
}