/*
 * 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.cordova.platforms;

import org.netbeans.api.project.Project;
import org.netbeans.modules.web.browser.api.WebBrowser;
import org.netbeans.modules.web.clientproject.spi.platform.ClientProjectEnhancedBrowserImplementation;

/**
 *
 * @author david
 */
public class BrowserConfigurationPanel extends javax.swing.JPanel {

    /**
     * Creates new form BrowserConfigurationPanel
     */
    public BrowserConfigurationPanel(Project project, ClientProjectEnhancedBrowserImplementation cfg, WebBrowser browser) {
        initComponents();
        if (!browser.hasNetBeansIntegration()) {
            jAutoRefreshCheckBox.setVisible(false);
            jHighlightSelectionCheckBox.setVisible(false);
        }
        jAutoRefreshCheckBox.setSelected(cfg.isAutoRefresh());
        jHighlightSelectionCheckBox.setSelected(cfg.isHighlightSelectionEnabled());
    }

    public boolean isAutoRefresh() {
        return jAutoRefreshCheckBox.isSelected();
    }
    
    public boolean isHighlightSelection() {
        return jHighlightSelectionCheckBox.isSelected();
    }
    
    /**
     * 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() {

        jAutoRefreshCheckBox = new javax.swing.JCheckBox();
        jHighlightSelectionCheckBox = new javax.swing.JCheckBox();

        org.openide.awt.Mnemonics.setLocalizedText(jAutoRefreshCheckBox, org.openide.util.NbBundle.getMessage(BrowserConfigurationPanel.class, "BrowserConfigurationPanel.jAutoRefreshCheckBox.text")); // NOI18N

        org.openide.awt.Mnemonics.setLocalizedText(jHighlightSelectionCheckBox, org.openide.util.NbBundle.getMessage(BrowserConfigurationPanel.class, "BrowserConfigurationPanel.jHighlightSelectionCheckBox.text")); // NOI18N

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(0, 0, 0)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jAutoRefreshCheckBox)
                    .addComponent(jHighlightSelectionCheckBox))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(0, 0, 0)
                .addComponent(jAutoRefreshCheckBox)
                .addGap(0, 0, 0)
                .addComponent(jHighlightSelectionCheckBox))
        );
    }// </editor-fold>//GEN-END:initComponents

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JCheckBox jAutoRefreshCheckBox;
    private javax.swing.JCheckBox jHighlightSelectionCheckBox;
    // End of variables declaration//GEN-END:variables

}
