//   Course Number: COSC 645 Applied Cryptography
//      Class Name: ChatMessage
//  Project Number: 2
//         Authors: Brian Hoffman
//     Description: This class extends JPanel and serves as a helper to assist
//                  in creating complex GridBag layouts. It provides a variety 
//                  methods with simple arguments that are more intuitive than 
//                  the standard GridBag constants. This class is based on the 
//                  one found in Swing 2nd Ed. by Robinson and Vorobeiv.

// Java Core Packages 
import java.awt.*;

// Java Extension Packages
import javax.swing.*;

public class GriddedPanel extends JPanel
{ 
    private GridBagConstraints constraints;
    
    //default constraints value definitions
    public static final int C_HORZ = GridBagConstraints.HORIZONTAL;
    public static final int C_NONE = GridBagConstraints.NONE;
    public static final int C_WEST = GridBagConstraints.WEST;
    public static final int C_WIDTH = 1;
    public static final int C_HEIGHT = 1;
    
    // ------------------------------------------------------------------------
    // default constructor with default values
    //-------------------------------------------------------------------------
    public GriddedPanel()
    {
        this(new Insets(2,2,2,2));
    }
 
    // ------------------------------------------------------------------------
    //  default constructor with the specified insets 
    //-------------------------------------------------------------------------
    public GriddedPanel(Insets insets)
    {
        super(new GridBagLayout());
        constraints = new GridBagConstraints();
        constraints.anchor = GridBagConstraints.WEST;
        constraints.insets = insets;
    }
    
    // ------------------------------------------------------------------------
    // addComponent() - add a component to the specified row and column 
    //------------------------------------------------------------------------- 
    public void addComponent(JComponent component, int row, int column)
    {
        addComponent(component, row, column, C_WIDTH, C_HEIGHT, C_WEST, C_NONE);
    }  
    
    // ------------------------------------------------------------------------
    // addComponent() - add a component to the specified row and column 
    //                  spanning across the specified number of columns and
    //                  rows
    //------------------------------------------------------------------------- 
    public void addComponent(JComponent component, int row, int column,
                              int width, int height)
    {
        addComponent(component, row, column, width, height, C_WEST, C_NONE);
    }
    
    // ------------------------------------------------------------------------
    // addAnchoredComponent() - add a component to the specified row and column 
    //                          using the specified anchor constraint
    //-------------------------------------------------------------------------
    public void addAnchoredComponent(JComponent component, int row, int column,
                                     int anchor)
    {
        addComponent(component, row, column, C_WIDTH, C_HEIGHT, anchor, C_NONE);
    }
    
    // ------------------------------------------------------------------------
    // addAnchoredComponent() - add a component to the specified row and column 
    //                          spanning across the specified number of columns  
    //                          and rows with the provided anchor value
    //-------------------------------------------------------------------------
    public void addAnchoredComponent(JComponent component, int row, int column,
                                     int width, int height, int anchor)
    {
       addComponent(component, row, column, width, height, anchor, C_NONE);
    }
    
    // ------------------------------------------------------------------------
    // addFilledComponent() - add a component to the specified row and column 
    //                        filling the column horizontally
    //-------------------------------------------------------------------------
    public void addFilledComponent(JComponent component, int row, int column)
    {
       addComponent(component, row, column, C_WIDTH, C_HEIGHT, C_WEST, C_HORZ);
    }
    
    // ------------------------------------------------------------------------
    // addFilledComponent() - add a component to the specified row and column 
    //                        with the specified fill constraint
    //-------------------------------------------------------------------------
    public void addFilledComponent(JComponent component, int row, int column,
                                   int fill)
    {
       addComponent(component, row, column, C_WIDTH, C_HEIGHT, C_WEST, fill);
    }
    
    // ------------------------------------------------------------------------
    // addFilledComponent() - add a component to the specified row and column 
    //                        spanning a specified number of columns and rows
    //                        with the specified fill constraint
    //-------------------------------------------------------------------------
    public void addFilledComponent(JComponent component, int row, int column,
                                   int width, int height, int fill)
    {
       addComponent(component, row, column, width, height, C_WEST, fill);
    }
    
    // ------------------------------------------------------------------------
    // addComponent() - the generic addComponent routine that allows any 
    //                  combination of position, fill, and anchor. It is
    //                  used by all the other methods placed above.
    //-------------------------------------------------------------------------
    public void addComponent(JComponent component, int row, int column,
                             int width, int height, int anchor, int fill)
    {
        constraints.gridx = column;
        constraints.gridy = row;
        constraints.gridwidth = width;
        constraints.gridheight= height;
        constraints.anchor = anchor;
        double weightx = 0.0;
        double weighty = 0.0;
        
        // only use extra horizontal or vertical space if a component spans
        // more than one column and/or row
        if (width > 1)  weightx = 1.0;
        if (height > 1) weighty = 1.0;
        
        switch(fill)
        {
            case GridBagConstraints.HORIZONTAL:
                 constraints.weightx = weightx;
                 constraints.weighty = 0.0;
                 break;
            case GridBagConstraints.VERTICAL:
                 constraints.weightx = 0.0;
                 constraints.weighty = weighty;
                 break;
            case GridBagConstraints.BOTH:
                 constraints.weightx = weightx;
                 constraints.weighty = weighty;
                 break;
            case GridBagConstraints.NONE:
                 constraints.weightx = 0.0;
                 constraints.weighty = 0.0;
                 break;
            default: break;
        }
        
        constraints.fill = fill;
        add(component, constraints);
    }
}