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

package lab07;

import java.awt.*;

/**
 *
 * @author J.K. Daugherty
 */
public class List implements Paintable {
 
    // List instance variables...

    private Node frontNode;
    private Node rearNode;
    private int itemCount;      // Current size (number of stored items)
    
    // Private constants used to render List...

    private static final int CELL_WIDTH = 60;
    private static final int CELL_HEIGHT = 30;
    private static final Color CELL_COLOR = new Color (0xEC,0xEC,0xEC);
    private static final Color ARROW_COLOR = Color.black;

    private static final int[] X_ARROW = {-4,-4,-10,0,10,4,4};
    private static final int[] Y_ARROW = {50,20,20,0, 20, 20,50};
	
    public List () {
        frontNode = rearNode = null;
        itemCount = 0;
    }

    // --------------------------------------------------------------
    // STUBS for List methods... this is where you come in...
    // --------------------------------------------------------------

    public void add (int index, Object value)
            throws IndexOutOfBoundsException {

                        // STUB -- implement this method
    }
  
    public Object set (int index, Object value)
            throws IndexOutOfBoundsException {

        return null;    // STUB -- remove this line and implement
    }
  
    public Object remove (int index) throws IndexOutOfBoundsException {

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

    public Object get (int index) throws IndexOutOfBoundsException {

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

    // --------------------------------------------------------------
    // END OF STUBS -- all methods below are fully implemented...
    // --------------------------------------------------------------

    /**
     * Adds the specified value to the rear of the List (appends).

     * @param value
     */
    public void add (Object value) {
        Node newNode = new Node (value, null);
        if (itemCount == 0) {
            frontNode = rearNode = newNode;
        }
        else {
            rearNode.next = newNode;
            rearNode = newNode;
        }
        itemCount++;
    }
  
    /** Indicates whether the List is currently empty.
     *  @return true if the List is empty, false otherwise.
     */
    public boolean isEmpty () {
        return (itemCount == 0);
    }

    /** Returns the number of values currently stored in the List.
     * @return Number of stored values.
     */
    public int size () {
        return itemCount;
    }
  
    /** Removes all values stored in the List, without changing
     *  its current capacity.
     */
    public void removeAll () {
        frontNode = rearNode = null;
        itemCount = 0;
    }
  
    /** Renders the List in a graphical display window.
     * 
     * The window dimensions and its associated graphics context
     * (java.awt.Graphics instance) are both supplied as input
     * parameters.
     * @param g The graphics context associated with the display window
     * (which provides rendering methods as well as the reference frame
     * for the pixel coordinates).
     * @param panelSize The 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();

        int xbase = (panelWidth - itemCount * CELL_WIDTH) / 2;
        int ybase = panelHeight / 2;

        // Find x-coordinate of upper left-hand corner of each cell
        
        int xloc = xbase;
        int yloc = ybase - CELL_HEIGHT / 2;

        Node curNode = frontNode;
        for (int i = 0; i < itemCount; i++) {
            g.setColor (CELL_COLOR);
            g.fill3DRect(xloc + i * CELL_WIDTH, yloc,
                   CELL_WIDTH, CELL_HEIGHT, true);
            g.setColor (Color.black);
            g.drawString(curNode.value.toString(),
                 xloc + 2 + i * CELL_WIDTH, yloc + 20);

            g.drawString("" + i,
                    xloc + i * CELL_WIDTH + CELL_WIDTH / 2 - 2, yloc -10);
            curNode = curNode.next;
        }

        // paintArrow (g, xbase, ybase, "Cursor", cursor);
     }
   private void paintArrow (Graphics g, int xbase, int ybase,
        String label, int index) {
        g.setColor (ARROW_COLOR);
    
        int[] xarrow = new int [X_ARROW.length];
        int[] yarrow = new int [Y_ARROW.length];
        int points = X_ARROW.length;
    
        for (int k = 0; k < points; k++) {
            xarrow[k] =  X_ARROW [k] + xbase 
                    + index * CELL_WIDTH + CELL_WIDTH / 2;
            yarrow[k] =  Y_ARROW [k] + ybase + CELL_HEIGHT;
        }

        g.fillPolygon (xarrow, yarrow, points);

        // Draw label...
    
        g.setColor (Color.black);
        Font font = new Font ("Arial", Font.BOLD, 16);
        g.setFont(font);

        g.drawString (label,
                xbase + index * CELL_WIDTH + CELL_WIDTH / 2
                    - g.getFontMetrics(font).stringWidth(label) / 2,
                ybase + Y_ARROW[0] + CELL_HEIGHT + 20);
    }

    private class Node {
        Object value;
        Node next;
        
        Node (Object value, Node next) {
            this.value = value;
            this.next = next;
        }
    }
}
