/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.netbeans.modules.java.project.ui;

import java.awt.Component;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JList;
import org.netbeans.api.annotations.common.NonNull;
import org.netbeans.api.java.platform.JavaPlatform;
import org.netbeans.api.java.platform.JavaPlatformManager;
import org.netbeans.api.java.platform.PlatformsCustomizer;
import org.netbeans.api.java.platform.Specification;
import org.openide.modules.SpecificationVersion;
import org.openide.util.Parameters;

/**
 *
 * @author Tomas Zezula
 */
public final class FixProjectSourceLevel extends javax.swing.JPanel {

    private final SpecificationVersion platformVersion;
    private final SpecificationVersion minVersion;

    public FixProjectSourceLevel(
            @NonNull final String type,
            @NonNull final SpecificationVersion minVersion,
            @NonNull final SpecificationVersion platformVersion,
            @NonNull final SpecificationVersion minProjectSupportedVersion) {
        Parameters.notNull("type", type);
        Parameters.notNull("minVersion", minVersion);
        Parameters.notNull("minProjectSupportedVersion", minProjectSupportedVersion);
        this.platformVersion = platformVersion;
        this.minVersion =  minVersion.compareTo(minProjectSupportedVersion) < 0 ?
                minProjectSupportedVersion :
                minVersion;
        initComponents();
        postInit(type, minVersion, platformVersion.compareTo(minProjectSupportedVersion)>=0);
    }


    boolean isDowngradeLevel() {
        return this.downgradeLevel.isSelected();
    }

    final JavaPlatform getSelectedPlatform() {
        if (!this.useOtherPlatform.isSelected()) {
            throw new IllegalStateException();
        }
        return (JavaPlatform) platforms.getSelectedItem();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        buttonGroup1 = new javax.swing.ButtonGroup();
        downgradeLevel = new javax.swing.JRadioButton();
        useOtherPlatform = new javax.swing.JRadioButton();
        jLabel1 = new javax.swing.JLabel();
        platforms = new javax.swing.JComboBox();
        managePlatforms = new javax.swing.JButton();
        jLabel2 = new javax.swing.JLabel();

        buttonGroup1.add(downgradeLevel);
        org.openide.awt.Mnemonics.setLocalizedText(downgradeLevel, org.openide.util.NbBundle.getMessage(FixProjectSourceLevel.class, "FixProjectSourceLevel.downgradeLevel.text", platformVersion)); // NOI18N

        buttonGroup1.add(useOtherPlatform);
        org.openide.awt.Mnemonics.setLocalizedText(useOtherPlatform, org.openide.util.NbBundle.getMessage(FixProjectSourceLevel.class, "FixProjectSourceLevel.useOtherPlatform.text")); // NOI18N

        jLabel1.setLabelFor(platforms);
        org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(FixProjectSourceLevel.class, "FixProjectSourceLevel.jLabel1.text")); // NOI18N

        platforms.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));

        org.openide.awt.Mnemonics.setLocalizedText(managePlatforms, org.openide.util.NbBundle.getMessage(FixProjectSourceLevel.class, "FixProjectSourceLevel.managePlatforms.text")); // NOI18N
        managePlatforms.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                managePlatforms(evt);
            }
        });

        org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(FixProjectSourceLevel.class, "FixProjectSourceLevel.jLabel2.text", minVersion));

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(29, 29, 29)
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(platforms, 0, 148, Short.MAX_VALUE)
                        .addGap(18, 18, 18)
                        .addComponent(managePlatforms))
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(downgradeLevel)
                            .addComponent(useOtherPlatform)
                            .addComponent(jLabel2))
                        .addGap(0, 0, Short.MAX_VALUE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel2)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(useOtherPlatform)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(platforms, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(managePlatforms))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(downgradeLevel)
                .addContainerGap(29, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void managePlatforms(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_managePlatforms
        PlatformsCustomizer.showCustomizer(null);
        ((PlatformModel)platforms.getModel()).refresh();
    }//GEN-LAST:event_managePlatforms

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.ButtonGroup buttonGroup1;
    private javax.swing.JRadioButton downgradeLevel;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JButton managePlatforms;
    private javax.swing.JComboBox platforms;
    private javax.swing.JRadioButton useOtherPlatform;
    // End of variables declaration//GEN-END:variables

    private void postInit(
            @NonNull String type,
            @NonNull SpecificationVersion minVersion,
            final boolean allowDowngrade) {
        useOtherPlatform.setSelected(true);
        platforms.setModel(new PlatformModel(type, minVersion));
        platforms.setRenderer(new PlatformRenderer());
        downgradeLevel.setEnabled(allowDowngrade);
    }


    private static final class PlatformModel extends DefaultComboBoxModel {

        private final String type;
        private final SpecificationVersion minVersion;


        PlatformModel(
                @NonNull final String type,
                @NonNull final SpecificationVersion minVersion) {
            this.type = type;
            this.minVersion = minVersion;
            refresh();
        }


        void refresh() {
            removeAllElements();
            final JavaPlatform[] platforms = JavaPlatformManager.getDefault().getPlatforms(
                    null,
                    new Specification(type, null));
            for (JavaPlatform jp : platforms) {
                if (minVersion.compareTo(jp.getSpecification().getVersion())<=0) {
                    addElement(jp);
                }
            }
        }
    }

    private static class PlatformRenderer extends DefaultListCellRenderer {

        @Override
        public Component getListCellRendererComponent(
                final JList list,
                Object value,
                final int index,
                final boolean isSelected,
                final boolean cellHasFocus) {
            if (value instanceof JavaPlatform) {
                value = ((JavaPlatform)value).getDisplayName();
            }
            return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        }

    }
}

