/*
 * BitMaskPanel.java
 * 
 * Copyright (c) 2003-2004 Digi International
 * This program and the information contained in it is confidential and
 * proprietary to Digi International and may not be used, copied, or re-
 * produced without the prior written permission of Digi International.
 * 
 */

package com.digi.config.ui;

import com.digi.config.core.*;
import com.digi.config.util.*;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
import java.net.*;




/** 
 * This class graphically displays a bitmask field. Each bit in the bitmask
 * can have one of three states: X, 1, 0
 *
 * The bitmask can be constructed to contain as many bits as necessary and each bit. The
 * values of each bit can also be specified. The bitmas will be displayed graphically in a 
 * row and the user can toggle through the bitmask values by clicking on the bit they want to
 * change.
 * 
 */
public class BitMaskPanel extends JPanel {


    /**
     * Defines a MultiState Button. The potential states is an enumeration from 0-n
     */
    public class BitButton extends JPanel {
        JButton button;
        ImageIcon images[];
        String text[];
        int state = 0;
        int bitDepth = 0;

        private BitButton() {
            button = new JButton();
            button.setFocusPainted(false);
            button.setOpaque(true);
            button.setBackground(Color.white);
            button.setMinimumSize(new Dimension(15,15));
            button.setPreferredSize(new Dimension(15,15));
            button.setBorder(BorderFactory.createRaisedBevelBorder());
//            button.setBorderPainted(false);
            add(button);

        }

        public BitButton(String textLabels[]) {
            this();
            text = textLabels;
            bitDepth = text.length;
            ActionListener listener = new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    state = (state+1) % text.length;
                    button.setText(text[state]);
                    forwardActionEvent(e);
                }
            };
            button.addActionListener(listener);
            button.setText(text[state]);
        }

        public BitButton(ImageIcon bitImages[]) {
            this();
            images = bitImages;
            bitDepth = images.length;
            ActionListener listener = new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    state = (state+1) % images.length;
                    button.setText(text[state]);
                    forwardActionEvent(e);
                }
            };
            button.addActionListener(listener);
            button.setIcon(images[0]);
        }

        public int getState() {
            return state;
        }

        public void setState(int state) {
            if ((state<0) || (state>=bitDepth)) {
                SystemLog.log("GeneralException", new Serializable[] {"BitButton.setState"}, new Exception("state out of range:"+state));
            } else {
                this.state = state;
                if (images!=null) {
                    button.setIcon(images[state]);
                }
                if (text!=null) {
                    button.setText(text[state]);
                }
            }
        }

        public void setToolTipText(String text) {
            button.setToolTipText(text);
        }
    }

    Vector listeners = new Vector();
    ImageIcon states[];
    String labels[];
    BitButton buttons[];
    int bits[];
    String name;

    public BitMaskPanel(String name) {
        this.name = name;
        this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
        this.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        this.setOpaque(true);
        this.setBackground(Color.WHITE);
    }

    public BitMaskPanel(String name, int bits[]) {
        this(name);
        if (bits!=null) {
            setBits(bits);
        }
    }

    public void setBits(int bits[]) {
        // take out any old buttons
        this.removeAll(); 
        // record the new bits
        this.bits = bits;
        // define the states
        states = new ImageIcon[3];
        labels = new String[3];
        states[0] = ConfigResource.getImageRbIcon("DontCare");
        states[1] = ConfigResource.getImageRbIcon("Asserted");
        states[2] = ConfigResource.getImageRbIcon("UnAsserted");
        labels[0]="X";
        labels[1]="1";
        labels[2]="0";
        
        // create the buttons
        buttons = new BitButton[bits.length];
        for (int i=0; i<bits.length; i++) {
            //buttons[i] = new BitButton(states);
            buttons[i] = new BitButton(labels);
            buttons[i].setState(bits[i]);
            String key = name+"Bit"+i+"Desc";
            String hoverText = ConfigResource.getUiRbString(key);
            if (!hoverText.equals(key)) {
                buttons[i].setToolTipText(hoverText);
            }
            add(buttons[i]);
        }
    }

    public int[] getBits() {
        for (int i=0;i<bits.length; i++) {
            bits[i] = buttons[i].getState();
        }
        return this.bits;
    }


    public void addActionListener(ActionListener l) {
        listeners.add(l);
    }

    public void removeActionListener(ActionListener l) {
        listeners.remove(l);
    }

    protected void forwardActionEvent(ActionEvent e) {
        e.setSource(this);
        for (Iterator i=listeners.iterator(); i.hasNext();) {
            ActionListener l = (ActionListener) i.next();
            if (l!=null) {
                l.actionPerformed(e);
            }
        }
    }

    public void setEnabled(boolean enabled) {
        super.setEnabled(enabled);
        setContainerEnabled(this,enabled);
    }

    public void setContainerEnabled(Container c, boolean enabled) {
        Component[] components = c.getComponents();
        for (int i=0; i<components.length; i++) {
            components[i].setEnabled(enabled);
            if (components[i] instanceof Container) {
                setContainerEnabled((Container)components[i], enabled);
            }
        }
    }


}







