/*
 * AllowedModeChooser.java
 *
 * Created on Feb 12, 2010, 6:28:34 AM
 */
package usda.weru.weps.location.chooser;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.EnumMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.swing.JCheckBox;
import javax.swing.event.EventListenerList;
import org.apache.log4j.Logger;
import usda.weru.weps.location.StationMode;

/**
 *
 * @author Joseph Levin <joelevin@weru.ksu.edu>
 */
public class AllowedStationModeChooser extends javax.swing.JPanel implements FocusListener, ActionListener {

    private static final long serialVersionUID = 1L;

    private static final Logger LOGGER = Logger.getLogger(AllowedStationModeChooser.class);

    private Map<StationMode, JCheckBox> c_checkBoxes;

    private StationMode[] c_ignore;

    private final EventListenerList c_listeners;

    /** Creates new form AllowedModeChooser */
    public AllowedStationModeChooser() {
        c_listeners = new EventListenerList();
        initComponents();
        initOptions();
    }

    private void initOptions() {
        c_checkBoxes = new EnumMap<StationMode, JCheckBox>(StationMode.class);

        for (StationMode mode : StationMode.values()) {
            if (isIgnored(mode)) {
                continue;
            }

            JCheckBox box = new JCheckBox(mode.getDisplayName());
            box.addFocusListener(this);
            box.addActionListener(this);
            box.setFont(getFont());

            c_checkBoxes.put(mode, box);
            add(box);
        }

    }

    /**
     *
     * @param modes
     */
    public void setIgnore(StationMode... modes) {
        c_ignore = modes;

        for (Map.Entry<StationMode, JCheckBox> entry : c_checkBoxes.entrySet()) {
            entry.getValue().setVisible(!isIgnored(entry.getKey()));
        }
    }

    /**
     *
     * @return
     */
    public StationMode[] getIgnore() {
        return c_ignore;
    }

    private boolean isIgnored(StationMode mode) {
        if (c_ignore == null) {
            return false;
        }
        for (StationMode ignored : c_ignore) {
            if (mode == ignored) {
                return true;
            }
        }

        return false;
    }

    /** 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() {

        setFont(getFont().deriveFont(getFont().getStyle() & ~java.awt.Font.BOLD));
        setLayout(new javax.swing.BoxLayout(this, javax.swing.BoxLayout.Y_AXIS));
    }// </editor-fold>//GEN-END:initComponents

    /**
     *
     * @param e
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        e = new ActionEvent(this, e.getID(), e.getActionCommand());
        for (ActionListener l : c_listeners.getListeners(ActionListener.class)) {
            l.actionPerformed(e);
        }
    }

    /**
     *
     * @param l
     */
    public void addActionListener(ActionListener l) {
        c_listeners.add(ActionListener.class, l);
    }

    /**
     *
     * @param l
     */
    public void removeActionListener(ActionListener l) {
        c_listeners.remove(ActionListener.class, l);
    }

    /**
     *
     * @param e
     */
    @Override
    public void focusGained(FocusEvent e) {
        e = new FocusEvent(this, e.getID());
        processFocusEvent(e);
    }

    /**
     *
     * @param e
     */
    @Override
    public void focusLost(FocusEvent e) {
        e = new FocusEvent(this, e.getID());
        processFocusEvent(e);
    }

    /**
     *
     * @return
     */
    public StationMode[] getSelectedModes() {
        List<StationMode> modes = new LinkedList<StationMode>();

        for (Map.Entry<StationMode, JCheckBox> entry : c_checkBoxes.entrySet()) {
            if (entry.getValue().isSelected()) {
                modes.add(entry.getKey());
            }
        }

        return modes.toArray(new StationMode[modes.size()]);
    }

    /**
     *
     * @param modes
     */
    public void setSelectedModes(StationMode[] modes) {
        clearSelections();
        if (modes == null) {
            return;
        }
        for (StationMode mode : modes) {
            c_checkBoxes.get(mode).setSelected(true);
        }
    }

    private void clearSelections() {
        for (JCheckBox box : c_checkBoxes.values()) {
            box.setSelected(false);
        }
    }

    /**
     *
     * @return
     */
    public String serializeSelectedModes() {
        StringBuffer buffer = null;
        for (StationMode mode : getSelectedModes()) {
            if (isIgnored(mode)) {
                continue;
            }
            if (buffer == null) {
                buffer = new StringBuffer(mode.getName());
            } else {
                buffer.append(",");
                buffer.append(mode.getName());
            }

        }

        return buffer != null ? buffer.toString() : "";
    }

    /**
     *
     * @param modes
     */
    public void deserializeSelectedModes(String modes) {
        clearSelections();
        String[] parts = modes.split(",");
        for (String part : parts) {
            part = part.trim();
            try {
                StationMode mode = StationMode.parse(part);
                if (!isIgnored(mode)) {
                    c_checkBoxes.get(mode).setSelected(true);
                }
            } catch (Exception e) {
                LOGGER.warn("Unable to parse station mode: " + part);
            }
        }
    }

    /**
     *
     * @param enabled
     */
    @Override
    public void setEnabled(boolean enabled) {
        super.setEnabled(enabled);
        for (JCheckBox box : c_checkBoxes.values()) {
            box.setEnabled(enabled);
        }
    }


    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables
}
