/*
 * Copyright 2000-2010 JetBrains s.r.o.
 *
 * Licensed 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 com.intellij.ide.util.gotoByName;

import com.intellij.icons.AllIcons;
import com.intellij.ide.util.ElementsChooser;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.JBPopupListener;
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
import com.intellij.openapi.util.Disposer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * This class contains UI related to filtering functionality.
 */
public abstract class ChooseByNameFilter<T> {
  /**
   * a parent popup
   */
  private final ChooseByNamePopup myParentPopup;
  /**
   * action toolbar
   */
  private final ActionToolbar myToolbar;
  /**
   * a file type chooser, only one instance is used
   */
  private final ElementsChooser<T> myChooser;
  /**
   * A panel that contains chooser
   */
  private final JPanel myChooserPanel;
  /**
   * a file type popup, the value is non-null if popup is active
   */
  private JBPopup myPopup;
  /**
   * a project to use. The project is used for dimension service.
   */
  private final Project myProject;

  /**
   * A constructor
   *
   * @param popup               a parent popup
   * @param model               a model for popup
   * @param filterConfiguration storage for selected filter values
   * @param project             a context project
   */
  public ChooseByNameFilter(@NotNull ChooseByNamePopup popup,
                            @NotNull FilteringGotoByModel<T> model,
                            @NotNull ChooseByNameFilterConfiguration<T> filterConfiguration,
                            @NotNull Project project) {
    myParentPopup = popup;
    DefaultActionGroup actionGroup = new DefaultActionGroup("go.to.file.filter", false);
    ToggleAction action = new ToggleAction("Filter", "Filter files by type", AllIcons.General.Filter) {
      @Override
      public boolean isSelected(final AnActionEvent e) {
        return myPopup != null;
      }

      @Override
      public void setSelected(final AnActionEvent e, final boolean state) {
        if (state) {
          createPopup();
        }
        else {
          close();
        }
      }
    };
    actionGroup.add(action);
    myToolbar = ActionManager.getInstance().createActionToolbar("gotfile.filter", actionGroup, true);
    myToolbar.setLayoutPolicy(ActionToolbar.NOWRAP_LAYOUT_POLICY);
    myToolbar.updateActionsImmediately();
    myToolbar.getComponent().setFocusable(false);
    myToolbar.getComponent().setBorder(null);
    myProject = project;
    myChooser = createChooser(model, filterConfiguration);
    myChooserPanel = createChooserPanel();
    popup.setToolArea(myToolbar.getComponent());
  }

  /**
   * @return a panel with chooser and buttons
   */
  private JPanel createChooserPanel() {
    JPanel panel = new JPanel();
    panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
    panel.add(myChooser);
    JPanel buttons = new JPanel();
    JButton all = new JButton("All");
    all.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(final ActionEvent e) {
        myChooser.setAllElementsMarked(true);
      }
    });
    buttons.add(all);
    JButton none = new JButton("None");
    none.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(final ActionEvent e) {
        myChooser.setAllElementsMarked(false);
      }
    });
    buttons.add(none);
    JButton invert = new JButton("Invert");
    invert.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(final ActionEvent e) {
        myChooser.invertSelection();
      }
    });
    buttons.add(invert);
    panel.add(buttons);
    return panel;
  }

  /**
   * Create a file type chooser
   *
   *
   * @param model a model to update
   * @param filterConfiguration
   * @return a created file chooser
   */
  @NotNull
  protected ElementsChooser<T> createChooser(@NotNull final FilteringGotoByModel<T> model,
                                             @NotNull final ChooseByNameFilterConfiguration<T> filterConfiguration) {
    List<T> elements = new ArrayList<T>(getAllFilterValues());
    final ElementsChooser<T> chooser = new ElementsChooser<T>(elements, true) {
      @Override
      protected String getItemText(@NotNull final T value) {
        return textForFilterValue(value);
      }

      @Override
      protected Icon getItemIcon(@NotNull final T value) {
        return iconForFilterValue(value);
      }
    };
    chooser.setFocusable(false);
    final int count = chooser.getElementCount();
    for (int i = 0; i < count; i++) {
      T type = chooser.getElementAt(i);
      if (!DumbService.getInstance(myProject).isDumb() && !filterConfiguration.isFileTypeVisible(type)) {
        chooser.setElementMarked(type, false);
      }
    }
    updateModel(model, chooser, true);
    chooser.addElementsMarkListener(new ElementsChooser.ElementsMarkListener<T>() {
      @Override
      public void elementMarkChanged(final T element, final boolean isMarked) {
        filterConfiguration.setVisible(element, isMarked);
        updateModel(model, chooser, false);
      }
    });
    return chooser;
  }

  protected abstract String textForFilterValue(@NotNull T value);

  @Nullable
  protected abstract Icon iconForFilterValue(@NotNull T value);

  @NotNull
  protected abstract Collection<T> getAllFilterValues();

  /**
   * Update model basing on the chooser state
   *
   * @param gotoFileModel a model
   * @param chooser       a file type chooser
   */
  protected void updateModel(@NotNull FilteringGotoByModel<T> gotoFileModel, @NotNull ElementsChooser<T> chooser, boolean initial) {
    final List<T> markedElements = chooser.getMarkedElements();
    gotoFileModel.setFilterItems(markedElements);
    myParentPopup.rebuildList(initial);
  }

  /**
   * Create and show popup
   */
  private void createPopup() {
    if (myPopup != null) {
      return;
    }
    myPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(myChooserPanel, myChooser).setModalContext(false).setFocusable(false)
        .setResizable(true).setCancelOnClickOutside(false).setMinSize(new Dimension(200, 200))
        .setDimensionServiceKey(myProject, "GotoFile_FileTypePopup", false).createPopup();
    myPopup.addListener(new JBPopupListener.Adapter() {
      @Override
      public void onClosed(LightweightWindowEvent event) {
        myPopup = null;
      }
    });
    myPopup.showUnderneathOf(myToolbar.getComponent());
  }

  /**
   * close the file type filter
   */
  public void close() {
    if (myPopup != null) {
      Disposer.dispose(myPopup);
    }
  }
}
