// Stack.java -- partially written source file for Lab07

package lab07;

import java.awt.*;

/**
 *
 * @author J.K. Daugherty
 */

public class Stack implements Paintable {

    private Node topNode;
    private int itemCount;

    // Constants for graphical display...
    
    public static final int CELL_WIDTH = 120;
    public static final int CELL_HEIGHT = 30;
    public static final Color CELL_COLOR = new Color (0xEC,0xEC,0xEC);
    public static final Color ARROW_COLOR = Color.black;

    // Dual (x,y) arrays, used to draw an arrow pointing to the top of
    // the stack. These represent relative values, where the tip of the
    // (leftward pointing) arrow is at (0,0). To render this arrow at
    // a specific location in the display window, fixed offsets must
    // be added to these values (see below).

    int[] xvalues = {0,  20,  20, 70,  70, 20, 20};
    int[] yvalues = {0, -10,  -5, -5,   5,  5, 10};
    
    /** Creates an empty Stack object. */
    public Stack () {
        topNode = null;
        itemCount = 0;
    }

    /** Pushes the specified value onto the stack.
     *
     * @param value The object to be pushed.
     */
    public void push (Object value) {

                          // STUB -- implement this method
    }
    
    /** Pops the topmost item from the stack. The method assumes
     * as a precondition that the stack is not already empty,
     * and it throws an IllegalStateException if this is violated.
     *
     * @return The item popped from the stack.
     */
    public Object pop () throws IllegalStateException {

      return null;         // STUB -- remove this line and implement...

    }

    /** Indicates whether the stack is empty.
     * @return true if the stack is empty, false otherwise.
     */
    public boolean isEmpty () {

      return false;         // STUB -- remove this line and implement...

    }

    /** Returns the number of items currently stored in the stack.
     * @return The number of stored items.
     */
    public int size () {

      return 0;         // STUB -- remove this line and implement...

    }

    /**
     * Removes all values currently stored on the stack.
     */
    public void removeAll () {

                          // STUB -- implement this method
    }
    
    /** Renders the stack in a graphical display window. The window
     * dimensions and its associated graphics context
     * (java.awt.Graphics object) are both supplied as input
     * parameters.
     * @param g Graphics context associated with the display window.
     * A Graphics object provides rendering methods as well as the
     * reference frame for pixel coordinates.
     * @param panelSize Width and height of the display area, in pixels.
     */
    public void render (Graphics g, Dimension panelSize) {
        int panelWidth = (int) panelSize.getWidth();
        int panelHeight = (int) panelSize.getHeight();

        // Choose horizontal "baseline" (bottom of array)
        
        int ybase = panelHeight - CELL_HEIGHT - 20; 

        // Find x-coordinate of upper left-hand corner of each cell
        
        int xloc = (panelWidth - CELL_WIDTH) / 2;

        Node curNode = topNode;
        
        for (int cell = itemCount - 1; cell >= 0; cell--) {
            g.setColor (CELL_COLOR);
            int yloc = ybase - (cell + 1) * CELL_HEIGHT;

            g.fill3DRect (xloc, yloc, CELL_WIDTH, CELL_HEIGHT, true);

            g.setColor(Color.black);
            if (cell < 10) {
                g.drawString (" " + cell, xloc - 20, yloc + CELL_HEIGHT - 10);
            }
            else {
                g.drawString ("" + cell, xloc - 20, yloc + CELL_HEIGHT - 10);
            }
            g.drawString ("" + curNode.value, xloc + 10, yloc + CELL_HEIGHT - 10);
            curNode = curNode.next;
        }

        // Arrow-drawing code...

        int[] xarrow = new int[7];
        int[] yarrow = new int[7];

        for (int k = 0; k < 7; k++) {
            xarrow[k] = xvalues[k] + (panelWidth + CELL_WIDTH) / 2 + 10;
//            yarrow[k] = yvalues[k] + ybase - (2 * itemCount + 1) * CELL_HEIGHT / 2;
            yarrow[k] = yvalues[k] + ybase - (2 * itemCount - 1) * CELL_HEIGHT / 2;
        }

        g.setColor (Color.black);
        g.fillPolygon (xarrow, yarrow, xarrow.length);

        // "Top" label on arrow...
    
        g.setColor(Color.black);
        Font topfont = new Font("Arial", Font.BOLD, 18);
        Font currentfont = g.getFont();
        g.setFont(topfont);
        g.drawString("Top", xarrow[3] + 10, yarrow[3] + 5 + 5);
        g.setFont(currentfont);
    }
    
    private class Node {
        Object value;
        Node next;
        
        public Node (Object value, Node next) {
            this.value = value;
            this.next = next;
        }
    }

}
