/*
 * Copyright 2000-2014 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.customize;

import com.intellij.CommonBundle;
import com.intellij.icons.AllIcons;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.ide.plugins.PluginNode;
import com.intellij.openapi.options.OptionsBundle;
import com.intellij.openapi.progress.util.ProgressIndicatorBase;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.updateSettings.impl.PluginDownloader;
import com.intellij.ui.ColorUtil;
import com.intellij.ui.JBColor;
import com.intellij.ui.border.CustomLineBorder;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.components.labels.LinkLabel;
import com.intellij.ui.components.labels.LinkListener;
import com.intellij.util.ConcurrencyUtil;

import javax.swing.*;
import javax.swing.border.CompoundBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

public class CustomizeFeaturedPluginsStepPanel extends AbstractCustomizeWizardStep {
  private static final int COLS = 3;
  private static ScheduledExecutorService ourService = new ScheduledThreadPoolExecutor(4, ConcurrencyUtil.newNamedThreadFactory(
    "FeaturedPlugins", true, Thread.NORM_PRIORITY));

  public final AtomicBoolean myCanceled = new AtomicBoolean(false);


  public CustomizeFeaturedPluginsStepPanel(PluginGroups pluginGroups) throws OfflineException {
    setLayout(new GridLayout(1, 1));
    JPanel gridPanel = new JPanel(new GridLayout(0, 3));
    JBScrollPane scrollPane =
      new JBScrollPane(gridPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    scrollPane.getVerticalScrollBar().setUnitIncrement(10);
    scrollPane.setBorder(null);

    Map<String, String> config = pluginGroups.getFeaturedPlugins();
    boolean isEmptyOrOffline = true;
    List<IdeaPluginDescriptor> pluginsFromRepository = pluginGroups.getPluginsFromRepository();
    for (Map.Entry<String, String> entry : config.entrySet()) {
      JPanel groupPanel = new JPanel(new GridBagLayout());
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.fill = GridBagConstraints.BOTH;
      gbc.anchor = GridBagConstraints.WEST;
      gbc.gridwidth = GridBagConstraints.REMAINDER;
      gbc.weightx = 1;

      String title = entry.getKey();
      String s = entry.getValue();
      int i = s.indexOf(":");
      String topic = s.substring(0, i);
      int j = s.indexOf(":", i + 1);
      final String description = s.substring(i + 1, j);
      final String pluginId = s.substring(j + 1);
      IdeaPluginDescriptor foundDescriptor = null;
      for (IdeaPluginDescriptor descriptor : pluginsFromRepository) {
        if (descriptor.getPluginId().getIdString().equals(pluginId) && !PluginManagerCore.isBrokenPlugin(descriptor)) {
          foundDescriptor = descriptor;
          isEmptyOrOffline = false;
          break;
        }
      }
      if (foundDescriptor == null) continue;
      final IdeaPluginDescriptor descriptor = foundDescriptor;



      JLabel titleLabel = new JLabel("<html><body><h2 style=\"text-align:left;\">" + title + "</h2></body></html>");
      JLabel topicLabel = new JLabel("<html><body><h4 style=\"text-align:left;\">" + topic + "</h4></body></html>");
      JLabel descriptionLabel = new JLabel("<html><body><i>" + description + "</i></body></html>") {
        @Override
        public Dimension getPreferredSize() {
          Dimension size = super.getPreferredSize();
          size.width = Math.min(size.width, 200);
          return size;
        }
      };
      final CardLayout wrapperLayout = new CardLayout();
      final JPanel buttonWrapper = new JPanel(wrapperLayout);
      final JButton installButton = new JButton("Install");
      final JProgressBar progressBar = new JProgressBar(0, 100);
      progressBar.setStringPainted(true);
      JPanel progressPanel = new JPanel(new VerticalFlowLayout(true, false));
      progressPanel.add(progressBar);
      final LinkLabel cancelLink = new LinkLabel("Cancel", AllIcons.Actions.Cancel);
      JPanel linkWrapper = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
      linkWrapper.add(cancelLink);
      progressPanel.add(linkWrapper);

      JPanel buttonPanel = new JPanel(new VerticalFlowLayout(0, 0));
      buttonPanel.add(installButton);

      buttonWrapper.add(buttonPanel, "button");
      buttonWrapper.add(progressPanel, "progress");

      wrapperLayout.show(buttonWrapper, "button");

      final ProgressIndicatorBase indicator = new ProgressIndicatorBase(true) {

        @Override
        public void start() {
          myCanceled.set(false);
          super.start();
          SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
              wrapperLayout.show(buttonWrapper, "progress");
            }
          });
        }

        @Override
        public void processFinish() {
          super.processFinish();
          SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
              wrapperLayout.show(buttonWrapper, "button");
              installButton.setEnabled(false);
              installButton.setText("Installed");
            }
          });
        }

        @Override
        public void setFraction(final double fraction) {
          super.setFraction(fraction);
          SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
              int value = (int)(100 * fraction + .5);
              progressBar.setValue(value);
              progressBar.setString(value + "%");
            }
          });
        }

        @Override
        public void cancel() {
          stop();
          myCanceled.set(true);
          super.cancel();
          SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
              wrapperLayout.show(buttonWrapper, "button");
              progressBar.setValue(0);
            }
          });
        }
      };
      installButton.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
          wrapperLayout.show(buttonWrapper, "progress");
          ourService.schedule(new Runnable() {
            @Override
            public void run() {
              try {
                indicator.start();
                PluginNode node = new PluginNode(descriptor.getPluginId());
                node.setUrl(descriptor.getUrl());
                PluginDownloader downloader = PluginDownloader.createDownloader(node);
                downloader.prepareToInstall(indicator);
                downloader.install();
                indicator.processFinish();
              }
              catch (Exception ignored) {
                if (!myCanceled.get()) {
                  onFail();
                }
              }
            }

            void onFail() {
              //noinspection SSBasedInspection
              SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                  indicator.stop();
                  wrapperLayout.show(buttonWrapper, "progress");
                  progressBar.setString("Cannot download plugin");
                }
              });
            }
          }, 0, TimeUnit.SECONDS);
        }
      });
      cancelLink.setListener(new LinkListener() {
        @Override
        public void linkSelected(LinkLabel aSource, Object aLinkData) {
          indicator.cancel();
        }
      }, null);
      gbc.insets.bottom = -5;
      groupPanel.add(titleLabel, gbc);
      gbc.insets.bottom = SMALL_GAP;
      groupPanel.add(topicLabel, gbc);
      groupPanel.add(descriptionLabel, gbc);
      gbc.weighty = 1;
      groupPanel.add(Box.createVerticalGlue(), gbc);
      gbc.weighty = 0;
      groupPanel.add(buttonWrapper, gbc);
      gridPanel.add(groupPanel);
    }
    int cursor = 0;
    Component[] components = gridPanel.getComponents();
    int rowCount = components.length / COLS;
    for (Component component : components) {
      ((JComponent)component).setBorder(
        new CompoundBorder(new CustomLineBorder(ColorUtil.withAlpha(JBColor.foreground(), .2), 0, 0, cursor / 3 < rowCount ? 1 : 0,
                                                cursor % COLS != COLS - 1 ? 1 : 0) {
          @Override
          protected Color getColor() {
            return ColorUtil.withAlpha(JBColor.foreground(), .2);
          }
        }, BorderFactory.createEmptyBorder(0, SMALL_GAP, 0, SMALL_GAP)));
      cursor++;
    }

    if (isEmptyOrOffline) throw new OfflineException();
    add(scrollPane);
  }

  @Override
  public String getTitle() {
    return "Featured plugins";
  }

  @Override
  public String getHTMLHeader() {
    return "<html><body><h2>Download featured plugins</h2>" +
           "We have a few plugins in our repository that most users like to download. " +
           "Perhaps, you need them too?</body></html>";
  }

  @Override
  public String getHTMLFooter() {
    return "New plugins can also be downloaded in "
           + CommonBundle.settingsTitle()
           + " | " + OptionsBundle.message("configurable.group.appearance.settings.display.name")
           + " | " + "Plugins";
  }

  public static class OfflineException extends Exception {};
}
