package org.jboss.installer.screens;

import org.jboss.installer.common.FontResources;

import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class ConfigSummaryPanel extends JComponent {

    /**
     * This key marks text that should be displayed using 2-column width with no key.
     */
    public static final String NOTICE = "";

    private static final SectionIcon HIDDEN_ICON = new SectionIcon('+');
    private static final SectionIcon VISIBLE_ICON = new SectionIcon('-');
    private final String description;
    private final JPanel tablePanel;

    public ConfigSummaryPanel(String description, HashMap<String, String> values) {
        this.description = description;

        this.setLayout(new GridBagLayout());
        final GridBagConstraints c = new GridBagConstraints();
        c.weightx = 1;
        c.gridx = 0;
        c.gridy = 0;
        c.anchor = GridBagConstraints.WEST;

        final JLabel descLabel = new JLabel(description, HIDDEN_ICON, SwingConstants.LEFT);
        descLabel.setFont(FontResources.getOpenSansLightSubHeading());
        tablePanel = new JPanel(new GridBagLayout());
        tablePanel.setVisible(false);
        descLabel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                tablePanel.setVisible(!tablePanel.isVisible());
                descLabel.setIcon(tablePanel.isVisible()?VISIBLE_ICON:HIDDEN_ICON);
            }
        });

        this.add(descLabel, c);
        c.gridy++;
        c.fill = GridBagConstraints.HORIZONTAL;
        this.add(tablePanel, c);

        createAttributeList(values);
    }

    public String getDescription() {
        return description;
    }

    public void updateAttrs(HashMap<String, String> attrs) {
        tablePanel.removeAll();

        createAttributeList(attrs);

        tablePanel.invalidate();
    }

    private void createAttributeList(HashMap<String, String> values) {
        final GridBagConstraints c1 = new GridBagConstraints();
        c1.insets = new Insets(0, 5, 0, 5);
        c1.weightx = 1;
        c1.gridx = 0;
        c1.gridy = 0;
        c1.anchor = GridBagConstraints.WEST;
        c1.fill = GridBagConstraints.HORIZONTAL;

        final Map<String, String> sortedMap = new TreeMap<>(values);
        for (Map.Entry<String, String> entry : sortedMap.entrySet()) {
            if (entry.getKey().isEmpty()) {
                continue;
            }
            c1.gridy++;
            final JLabel keyLabel = new JLabel(entry.getKey());
            keyLabel.setFont(FontResources.getOpenSansRegular());
            tablePanel.add(keyLabel, c1);

            // use non-editable TextArea to enable text wrap on long text
            final JTextArea ta = createValueText(entry, false);
            c1.gridx = 1;
            tablePanel.add(ta, c1);

            c1.gridx = 0;
        }

        for (Map.Entry<String, String> entry : sortedMap.entrySet()) {
            if (!entry.getKey().isEmpty()) {
                continue;
            }

            final JTextArea ta = createValueText(entry, true);
            c1.gridy++;
            c1.gridwidth = 2;
            tablePanel.add(ta, c1);
        }
    }

    private static JTextArea createValueText(Map.Entry<String, String> entry, boolean wordWrap) {
        final JTextArea ta = new JTextArea();
        ta.setEditable(false);
        ta.setText(entry.getValue());
        ta.setBackground(Color.WHITE);
        ta.setColumns(30);
        ta.setLineWrap(true);
        ta.setWrapStyleWord(wordWrap);
        ta.setFont(FontResources.getOpenSansRegular().deriveFont(Font.ITALIC));
        return ta;
    }

    static class SectionIcon implements Icon {

        private static final int SIZE = 9;

        private final char type;

        public SectionIcon(char type) {
            this.type = type;
        }

        public void paintIcon(Component c, Graphics g, int x, int y) {
            g.setColor(UIManager.getColor("Panel.background"));
            g.fillRect(x, y, SIZE - 1, SIZE - 1);

            g.setColor(Color.LIGHT_GRAY);
            g.drawRect(x, y, SIZE - 1, SIZE - 1);

            g.setColor(Color.DARK_GRAY);
            g.drawLine(x + 2, y + SIZE / 2, x + SIZE - 3, y + SIZE / 2);
            if (type == '+') {
                g.drawLine(x + SIZE / 2, y + 2, x + SIZE / 2, y + SIZE - 3);
            }
        }

        public int getIconWidth() {
            return SIZE;
        }

        public int getIconHeight() {
            return SIZE;
        }
    }
}
