//   Course Number: COSC 650 Data Comm/Networks
//      Class Name: GriddedPanel.java
//  Project Number: 2
//         Authors: Brian Hoffman
//                  Mike McKinney
//                  Javier Carrasco
//     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. 

// 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);
    }
}