/**
 * An encapsulation of a picture frame.
 *
 * This version makes use of static attributes.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 4.0
 */
public class PictureFrame
{
//[staticattributes1
    private static final double DOLLARS_PER_IN_OF_FRAME    = 0.15;
    private static final double DOLLARS_PER_SQ_IN_OF_GLASS = 0.05;    
//]staticattributes1
    private boolean    stand;    
    private double     height, matte, width;
    
    /**
     * Construct a PictureFrame object.
     *
     * Note: Negative values are converted to positive values 
     * and the width and height are put in canonical form 
     * (i.e., a portrait orientation).
     *
     * @param width   The width (in inches)
     * @param height  The height (in inches)
     * @param matte   The size of the matte (in inches) on all 4 sides
     * @param stand   true if there is a built-in stand
     */
    public PictureFrame(double width, double height, double matte, 
                        boolean stand)
    {
        double     h, w;
        
        h = Math.abs(height);
        w = Math.abs(width);

        this.width  = Math.min(w, h);
        this.height = Math.max(w, h);
        this.matte  = Math.abs(matte);
        this.stand  = stand;
    }

    /**
     * Calculate the area of this PictureFrame.
     *
     * @return  The area (in square inches)
     */
    private double area()
    {
        return width * height;
    }

    /**
     * Calculate the area of the matte.
     *
     * @return  The area (in square inches)
     */
    private double matteArea()
    {
               // Top and Bottom   + Sides (not including the top and bottom)
        return 2.0*(matte * width) + 2.0*(matte * (height - 2.0*matte));
    }

    /**
     * Calculate the perimeter of this PictureFrame.
     *
     * @return  The area (in inches)
     */
    private double perimeter()
    {
        return 2.0*width + 2.0*height;
    }

    /**
     * Return true if the owning PictureFrame and the given PictureFrame
     * have the same attributes.
     *
     * @return  true if the attributes are the same; false otherwise
     */
    public boolean equals(PictureFrame other)
    {
        return (this.width == other.width) && (this.height == other.height)
            && (this.matte == other.matte) && (this.stand == other.stand);
    }

//[staticattributes2
    /**
     * Return the cost of this PictureFrame (which is a function
     * of the perimeter and the area) in dollars.
     *
     * @return   The cost
     */
    public double getCost()
    {
        double     frame, glass;
        
        frame = perimeter() * DOLLARS_PER_IN_OF_FRAME;
        glass = area() * DOLLARS_PER_SQ_IN_OF_GLASS;

        return frame+glass;
    }
//]staticattributes2

    /**
     * Get the height of this PictureFrame.
     *
     * @return   The height
     */
    public double getHeight()
    {
        return height;
    }

    /**
     * Get the size of the matte.
     *
     * @return   The size of the matte
     */
    public double getMatte()
    {
        return matte;
    }

    /**
     * Get the width of this PictureFrame.
     *
     * @return   The width
     */
    public double getWidth()
    {
        return width;
    }

    /**
     * Return the visible area (in square inches) of the content
     * contained in this PictureFrame.
     *
     * @return   The visible area
     */
    public double getVisibleArea()
    {
        return area() - matteArea();
    }

    /**
     * Return a human-readable String representation of this PictureFrame.
     *
     * @return  The String representation
     */
    public String toString()
    {
        String      result;
        
        result = String.format("%5.2f in. x %5.2f in.", width, height);
        if (matte > 0.0)
            result += String.format(" with a %5.2f in. matte", matte);
        if (stand)
            result += " (w/ stand)";
        
        return result;
    }
}
