/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2021 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * 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.jboss.installer.screens;

import org.jboss.installer.common.UiResources;
import org.jboss.installer.core.InstallationData;
import org.jboss.installer.core.LanguageUtils;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static org.jboss.installer.Installer.EAP_VERSION;

public class ComponentSelectionScreen  extends DefaultScreen {

    public static final String NAME = "ComponentSelectionScreen";
    public static final String TITLE_KEY = "component_selection.title";
    public static final String NOTE_KEY = "component_selection.note";
    public static final String EAP_KEY = "component_selection.eap";
    public static final String EAP_DESCRIPTION_KEY = "component_selection.eap_description";
    public static final String APPCLIENT_KEY = "component_selection.appclient";
    public static final String APPCLIENT_DESCRIPTION_KEY = "component_selection.appclient_description";
    public static final String DOCS_KEY = "component_selection.docs";
    public static final String DOCS_DESCRIPTION_KEY = "component_selection.docs_description";
    public static final String MODULES_KEY = "component_selection.modules";
    public static final String MODULES_DESCRIPTION_KEY = "component_selection.modules_description";
    public static final String WELCOME_KEY = "component_selection.welcome";
    public static final String WELCOME_DESCRIPTION_KEY = "component_selection.welcome_description";
    public static final String DESCRIPTION_TAG_KEY = "component_selection.description_tag";
    public static final String APPCLIENT_PACKAGE = "appclient";
    public static final String DOCS_PACKAGE = "docs";

    private final JCheckBox eapCheckbox = createEmptyCheckBox(false, true);
    private final JCheckBox appClientCheckbox = createEmptyCheckBox(true, true);
    private final JCheckBox docsCheckbox = createEmptyCheckBox(true, true);
    private final JCheckBox modulesCheckbox = createEmptyCheckBox(false, true);
    private final JCheckBox welcomeCheckbox = createEmptyCheckBox(false, true);
    private final JLabel eapLabel = createOnClickLabel(EAP_KEY, langUtils.getString(EAP_DESCRIPTION_KEY, EAP_VERSION), eapCheckbox);
    private final JLabel appClientLabel = createOnClickLabel(APPCLIENT_KEY, langUtils.getString(APPCLIENT_DESCRIPTION_KEY), appClientCheckbox);
    private final JLabel docsLabel = createOnClickLabel(DOCS_KEY, langUtils.getString(DOCS_DESCRIPTION_KEY), docsCheckbox);
    private final JLabel modulesLabel = createOnClickLabel(MODULES_KEY, langUtils.getString(MODULES_DESCRIPTION_KEY), modulesCheckbox);
    private final JLabel welcomeLabel = createOnClickLabel(WELCOME_KEY, langUtils.getString(WELCOME_DESCRIPTION_KEY), welcomeCheckbox);
    private final JLabel descriptionLabel = createFieldLabel(" ", false);



    public ComponentSelectionScreen(LanguageUtils langUtils) {
        super(langUtils);
    }

    @Override
    public String getTitle() {
        return langUtils.getString(TITLE_KEY);
    }

    @Override
    public String getName() {
        return NAME;
    }

    @Override
    public JPanel getContent() {
        JPanel content = new JPanel(new GridBagLayout());
        GridBagConstraints c = UiResources.initializeConstraints();

        content.add(createFieldLabel(NOTE_KEY), c);
        c.gridy++;

        content.add(getPackageSelectorPanel(), c);
        c.gridy++;

        c.insets = NO_INSET;
        content.add(Box.createRigidArea(new Dimension(CONTENT_PANEL_WIDTH, 200)), c);
        c.gridy++;

        c.insets = new Insets(0,10,0,0);
        content.add(createFieldLabel(DESCRIPTION_TAG_KEY), c);
        c.gridy++;

        c.insets = NO_INSET;
        content.add(getDescriptionPanel(), c);
        c.gridy++;

        fillEmptySpace(content, c);

        return content;
    }

    private JPanel getPackageSelectorPanel() {
        JPanel checkBoxPanel = new JPanel(new GridBagLayout());
        GridBagConstraints c = UiResources.initializeConstraints();
        resetBackground();
        checkBoxPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));

        c.weightx = 0;
        c.insets = new Insets(0,0,0,20);
        checkBoxPanel.add(eapCheckbox, c);

        c.gridx = 1;
        c.weightx = 1;
        c.insets = new Insets(0, -20, 0, 0);
        checkBoxPanel.add(eapLabel, c);
        c.gridx = 0;
        c.gridy++;

        createCheckboxLabel(checkBoxPanel, appClientCheckbox, c, appClientLabel);

        createCheckboxLabel(checkBoxPanel, docsCheckbox, c, docsLabel);

        createCheckboxLabel(checkBoxPanel, modulesCheckbox, c, modulesLabel);

        createCheckboxLabel(checkBoxPanel, welcomeCheckbox, c, welcomeLabel);

        return checkBoxPanel;
    }

    @Override
    public JComponent getDefaultFocusComponent() {
        return appClientCheckbox;
    }

    private JPanel getDescriptionPanel() {
        JPanel descriptionPanel = new JPanel(new GridBagLayout());
        GridBagConstraints c = UiResources.initializeConstraints();
        descriptionPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
        c.insets = new Insets(10,10,10,10);
        descriptionPanel.add(descriptionLabel, c);

        return descriptionPanel;
    }

    private void createCheckboxLabel(JPanel checkboxes, JCheckBox checkBox, GridBagConstraints cc, JLabel label) {
        cc.weightx = 0;
        cc.insets = new Insets(0,20,0,0);
        checkboxes.add(checkBox, cc);

        cc.gridx = 1;
        cc.weightx = 1;
        cc.insets = NO_INSET;
        checkboxes.add(label, cc);
        cc.gridx = 0;
        cc.gridy++;
    }

    private JLabel createOnClickLabel(String textKey, String description, JCheckBox checkBox) {
        JLabel label = createFieldLabel(textKey);
        label.setOpaque(true);
        checkBox.setOpaque(true);
        label.addMouseListener(getMouseListener(label, description, checkBox));
        checkBox.addMouseListener(getMouseListener(label, description, checkBox));
        checkBox.addFocusListener(getFocusListener(label, description, checkBox));
        return label;
    }

    public void resetBackground() {
        eapLabel.setBackground(Color.WHITE);
        eapCheckbox.setBackground(Color.WHITE);
        appClientLabel.setBackground(Color.WHITE);
        appClientCheckbox.setBackground(Color.WHITE);
        docsLabel.setBackground(Color.WHITE);
        docsCheckbox.setBackground(Color.WHITE);
        welcomeLabel.setBackground(Color.WHITE);
        welcomeCheckbox.setBackground(Color.WHITE);
        modulesLabel.setBackground(Color.WHITE);
        modulesCheckbox.setBackground(Color.WHITE);
    }

    private MouseListener getMouseListener(JLabel label, String description, JCheckBox checkBox) {
        return new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent mouseEvent) {
                resetBackground();
                label.setBackground(Color.LIGHT_GRAY);
                checkBox.setBackground(Color.LIGHT_GRAY);
                descriptionLabel.setText(description);
            }

            @Override
            public void mousePressed(MouseEvent mouseEvent) {

            }

            @Override
            public void mouseReleased(MouseEvent mouseEvent) {

            }

            @Override
            public void mouseEntered(MouseEvent mouseEvent) {

            }

            @Override
            public void mouseExited(MouseEvent mouseEvent) {

            }
        };
    }

    @Override
    public void record(InstallationData installationData) {
        List<String> excludedPackages = new ArrayList<>();
        List<String> selectedPackages = new ArrayList<>(Arrays.asList(EAP_KEY, APPCLIENT_KEY, DOCS_KEY, MODULES_KEY, WELCOME_KEY));
        if (!appClientCheckbox.isSelected()) {
            excludedPackages.add(APPCLIENT_PACKAGE);
            selectedPackages.remove(APPCLIENT_KEY);
        }
        if (!docsCheckbox.isSelected()) {
            excludedPackages.add(DOCS_PACKAGE);
            selectedPackages.remove(DOCS_KEY);
        }
        installationData.setExcludedPackages(excludedPackages);
        installationData.setSelectedPackages(selectedPackages);
    }

    private FocusListener getFocusListener(JLabel label, String description, JCheckBox checkBox) {
        return new FocusListener() {
            @Override
            public void focusGained(FocusEvent e) {
                resetBackground();
                label.setBackground(Color.LIGHT_GRAY);
                checkBox.setBackground(Color.LIGHT_GRAY);
                descriptionLabel.setText(description);
            }
            @Override
            public void focusLost(FocusEvent e) {
                resetBackground();
            }
        };

    }
}
