/**
 * Copyright (C) 2004-2011 Jive Software. All rights reserved.
 *
 * 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 org.jivesoftware.sparkimpl.plugin.viewer;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.UIManager;

import org.jivesoftware.resource.Default;
import org.jivesoftware.resource.Res;
import org.jivesoftware.resource.SparkRes;
import org.jivesoftware.spark.PluginManager;
import org.jivesoftware.spark.component.RolloverButton;
import org.jivesoftware.spark.plugin.PublicPlugin;
import org.jivesoftware.spark.util.BrowserLauncher;
import org.jivesoftware.spark.util.URLFileSystem;
import org.jivesoftware.spark.util.log.Log;

import static java.awt.GridBagConstraints.EAST;
import static java.awt.GridBagConstraints.HORIZONTAL;
import static java.awt.GridBagConstraints.NONE;
import static java.awt.GridBagConstraints.WEST;

/**
 * GUI dialog to manage plugins: Deactivate and activate back, install.
 */
public class SparkPlugUI extends JPanel {
    private final PublicPlugin _plugin;
    private final JButton installButton = new JButton();
    private final JButton deactivateButton = new JButton();
    private final JLabel imageIcon = new JLabel();
    private final JLabel titleLabel = new JLabel();
    private final JLabel versionLabel = new JLabel();
    private final JTextArea descriptionLabel = new JTextArea();

    public SparkPlugUI(PublicPlugin plugin) {
        _plugin = plugin;
        setLayout(new GridBagLayout());
        setBackground(Color.white);

        imageIcon.setIcon(SparkRes.getImageIcon(SparkRes.Icon.PLUGIN_IMAGE));
        add(imageIcon, new GridBagConstraints(0, 0, 1, 1, 0, 0, WEST, NONE, new Insets(5, 5, 5, 5), 0, 0));

        add(titleLabel, new GridBagConstraints(1, 0, 1, 1, 0, 0, WEST, NONE, new Insets(5, 5, 5, 0), 0, 0));
        titleLabel.setFont(new Font("Dialog", Font.BOLD, 12));
        titleLabel.setForeground(UIManager.getColor("Component.linkColor"));

        add(versionLabel, new GridBagConstraints(2, 0, 1, 1, 0, 0, WEST, HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0));

        titleLabel.setText(plugin.getName());
        if (plugin.getVersion() != null && plugin.getAuthor() != null) {
            versionLabel.setText(_plugin.getVersion() + " by " + _plugin.getAuthor());
        }
        descriptionLabel.setText(plugin.getDescription());
        descriptionLabel.setLineWrap(true);
        descriptionLabel.setWrapStyleWord(true);
        descriptionLabel.setEditable(false);
        descriptionLabel.setFocusable(false);
        descriptionLabel.setOpaque(false);
        descriptionLabel.setBorder(null);
        descriptionLabel.setFont(UIManager.getFont("Label.font"));
        descriptionLabel.setSize(new Dimension(500, Short.MAX_VALUE));
        descriptionLabel.setMaximumSize(new Dimension(500, Short.MAX_VALUE));
        descriptionLabel.setPreferredSize(new Dimension(500, descriptionLabel.getPreferredSize().height));

        installButton.setIcon(SparkRes.getImageIcon(SparkRes.Icon.SMALL_ADD_IMAGE));
        deactivateButton.setIcon(SparkRes.getImageIcon(SparkRes.Icon.SMALL_DELETE));

        Insets insets = new Insets(0, 5, 5, 5);
        add(installButton, new GridBagConstraints(4, 0, 1, 2, 1, 0, EAST, NONE, insets, 0, 0));
        add(deactivateButton, new GridBagConstraints(5, 0, 1, 2, 1, 0, EAST, NONE, insets, 0, 0));

        if (_plugin.getChangeLog() != null && _plugin.getReadMeURL() != null) {
            RolloverButton changeLogButton = new RolloverButton(SparkRes.getImageIcon(SparkRes.Icon.CHANGELOG_IMAGE));
            RolloverButton readMeButton = new RolloverButton(SparkRes.getImageIcon(SparkRes.Icon.README_IMAGE));
            changeLogButton.addActionListener(e -> {
                BrowserLauncher.openURL(_plugin.getChangeLog());
            });

            readMeButton.addActionListener(e -> {
                BrowserLauncher.openURL(_plugin.getReadMeURL());
            });

            final JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
            buttonPanel.setOpaque(false);
            buttonPanel.add(changeLogButton);
            buttonPanel.add(readMeButton);

            changeLogButton.setToolTipText(Res.getString("tooltip.view.changelog"));
            readMeButton.setToolTipText(Res.getString("tooltip.view.readme"));
            add(descriptionLabel, new GridBagConstraints(1, 1, 2, 1, 0, 0, WEST, HORIZONTAL, insets, 0, 0));
            add(buttonPanel, new GridBagConstraints(3, 1, 1, 1, 1, 0, WEST, HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
        } else {
            add(descriptionLabel, new GridBagConstraints(1, 1, 2, 1, 1, 0, WEST, HORIZONTAL, insets, 0, 0));
        }

        installButton.setVisible(false);
        deactivateButton.setVisible(false);
    }

    public void showOperationButton() {
        final PluginManager pluginManager = PluginManager.getInstance();
        if (!pluginManager.isInstalled(_plugin)) {
            installButton.setVisible(true);
            deactivateButton.setVisible(false);
        } else {
            installButton.setVisible(false);
            deactivateButton.setVisible(true);
        }
    }

    public void setSelected(boolean isSelected) {
        if (isSelected) {
            setBackground(new Color(234, 230, 212));
            showOperationButton();
            setBorder(BorderFactory.createEtchedBorder());
            if (Default.getBoolean(Default.UNINSTALL_PLUGINS_DISABLED)) {
                deactivateButton.setVisible(false);
            }
        } else {
            setBackground(Color.white);
            installButton.setVisible(false);
            deactivateButton.setVisible(false);
            setBorder(null);
        }
    }

    public void updateState() {
        showOperationButton();
    }

    public PublicPlugin getPlugin() {
        return _plugin;
    }

    public JButton getInstallButton() {
        return installButton;
    }

    public JButton getDeactivateButton() {
        return deactivateButton;
    }

    public void useLocalIcon() {
        File pluginDIR = _plugin.getPluginDir();
        try {
            File smallIcon = new File(pluginDIR, "logo_small.gif");
            File largeIcon = new File(pluginDIR, "logo_large.gif");
            if (largeIcon.exists()) {
                setIcon(new ImageIcon(largeIcon.toURI().toURL()));
            } else if (smallIcon.exists()) {
                setIcon(new ImageIcon(smallIcon.toURI().toURL()));
            }
        } catch (MalformedURLException e) {
            Log.error(e);
        }
    }

    /**
     * Returns the Filename of provided Download URL
     */
    public String getFilename() {
        String filename = null;
        try {
            URL downloadURL = new URL(_plugin.getDownloadURL());
            filename = URLFileSystem.getFileName(downloadURL);
        } catch (MalformedURLException e) {
            Log.error(e);
        }
        return filename;
    }

    public void setIcon(Icon icon) {
        imageIcon.setIcon(icon);
    }
}
