/*
 * Copyright 2014 Red Hat, Inc. and/or its affiliates.
 *
 * Licensed under the Eclipse Public License version 1.0, available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
package org.jboss.forge.plugin.idea.ui;

import com.intellij.icons.AllIcons;
import com.intellij.openapi.ui.popup.JBPopupAdapter;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
import com.intellij.ui.ListCellRendererWrapper;
import com.intellij.ui.components.JBList;
import org.jboss.forge.addon.ui.command.CommandFactory;
import org.jboss.forge.addon.ui.command.UICommand;
import org.jboss.forge.addon.ui.context.UIContext;
import org.jboss.forge.addon.ui.metadata.UICommandMetadata;
import org.jboss.forge.addon.ui.wizard.UIWizardStep;
import org.jboss.forge.plugin.idea.service.ServiceHelper;

import javax.swing.*;
import java.util.ArrayList;
import java.util.List;

/**
 * Lists all UI commands.
 *
 * @author Adam Wyłuda
 */
public class CommandListPopup
{
    // TODO Design and implement CommandListPopup

    private static volatile boolean active;

    private final UIContext uiContext;

    public CommandListPopup(UIContext uiContext)
    {
        this.uiContext = uiContext;
    }

    public static boolean isActive()
    {
        return active;
    }

    public void show()
    {
        if (active)
            return;
        active = true;

        final JBList list = new JBList();
        DefaultListModel model = new DefaultListModel();

        final List<UICommand> allCandidates = getAllCandidates();
        model.setSize(allCandidates.size());

        list.setCellRenderer(new ListCellRendererWrapper<UICommand>()
        {
            @Override
            public void customize(JList list, UICommand data, int index,
                                  boolean selected, boolean hasFocus)
            {
                if (data != null)
                {
                    setIcon(AllIcons.Nodes.Plugin);

                    UICommandMetadata metadata = data.getMetadata(uiContext);

                    setText(metadata.getName());
                    setToolTipText(metadata.getDescription());
                }
            }
        });

        for (int i = 0; i < allCandidates.size(); i++)
        {
            model.set(i, allCandidates.get(i));
        }

        list.setModel(model);

        final PopupChooserBuilder listPopupBuilder = JBPopupFactory
                .getInstance().createListPopupBuilder(list);
        listPopupBuilder.setTitle("Run a Forge command");
        listPopupBuilder.addListener(new JBPopupAdapter()
        {
            @Override
            public void onClosed(LightweightWindowEvent event)
            {
                CommandListPopup.this.active = false;
            }
        });
        listPopupBuilder.setItemChoosenCallback(new Runnable()
        {
            @Override
            public void run()
            {
                int selectedIndex = list.getSelectedIndex();
                UICommand selectedCommand = allCandidates.get(selectedIndex);
                openWizard(selectedCommand);
            }
        }).createPopup().showInFocusCenter();
    }

    private List<UICommand> getAllCandidates()
    {
        List<UICommand> commands = new ArrayList<UICommand>();
        CommandFactory commandFactory = ServiceHelper.getForgeService().getCommandFactory();

        for (UICommand command : commandFactory.getCommands())
        {
            if (isCandidate(command))
            {
                commands.add(command);
            }
        }

        return commands;
    }

    private boolean isCandidate(UICommand command)
    {
        return !(command instanceof UIWizardStep) && command.isEnabled(uiContext);
    }

    private void openWizard(UICommand command)
    {
        // TODO Use CommandController to obtain UICommand metadata
//        ForgeWizardModel model = new ForgeWizardModel(command.getMetadata().getName(), command, files);
//        ForgeWizardDialog dialog = new ForgeWizardDialog(model);
//        dialog.show();
    }
}

@@ -288,30 +288,17 @@
 i.popup.
-JBPopupAdapter
+*
 ;%0Aimport
@@ -315,206 +315,76 @@
 lij.
-openapi.ui.popup.JBPopupFactory;%0Aimport com.intellij.openapi.ui.popup.LightweightWindowEvent;%0Aimport com.intellij.openapi.ui.popup.PopupChooserBuilder;%0Aimport com.intellij.ui.ListCellRendererWrapper
+ui.ListCellRendererWrapper;%0Aimport com.intellij.ui.components.JBList
 ;%0Aim
@@ -402,35 +402,28 @@
 tellij.u
-i.components.JBList
+til.Function
 ;%0Aimport
@@ -2346,33 +2346,16 @@
 pFactory
-%0A                
 .getInst
@@ -2387,24 +2387,24 @@
 lder(list);%0A
+
         list
@@ -2449,16 +2449,61 @@
 mand%22);%0A
+        listPopupBuilder.setResizable(true);%0A
         
@@ -3092,22 +3092,492 @@
   %7D)
-.createPopup()
+;%0A        listPopupBuilder.setFilteringEnabled(new Function%3CObject, String%3E()%0A        %7B%0A            @Override%0A            public String fun(Object object)%0A            %7B%0A                UICommand command = (UICommand) object;%0A                UICommandMetadata metadata = command.getMetadata(uiContext);%0A%0A                return metadata.getCategory().toString() + %22 %22 + metadata.getName();%0A            %7D%0A        %7D);%0A%0A        JBPopup popup = listPopupBuilder.createPopup();%0A        popup
 .sho

Implement command filtering