C:\upload\java\Life\source\java\Vars.java
/* *********************************************************************

C:\VisualCafe\Projects\Life\Life.html

    This class contains & handles variables to "hide" them and avoid
    dangerous globals. Variables have to be shared between classes,
    and this simplifies communication over having a zillion 'get' 
    and 'set' methods in every class.

    Because "Life" contains so many variables, this class is long.

    History: the program and its classes kept growing and growing, and the
    writer realized that things were getting unmanageable. So he made a
    decision to do a major re-write, and have as few global variables as
    possible, using "Get" and "Set" accessor methods to reference variables.

    Another consideration was bothersome function calls with huge parameter
    lists. This enables the passing of one parameter of type < Vars > and
    let the function itself deal with what it needs.

    Yes, this is bothersome and messy. But it was worse before.

    Not the constructor sets everyone to "garbage" values except the single
    Frame variable. As soon as board width & height are know, we set some
    board-related values in < setDefaults() >.
   ********************************************************************* */

import java.awt.*;

final class Vars implements Constants, Strings
{
    private PopupWindow error;  // In case something goes wrong.

    /* There should be no problem instantiating, but we return a boolean
       just in case something truly weird happens.
    */
    private boolean instantiationsSucceeded;    // Our variable. In case of error in instantiations.

    private int rows, columns;        /* Rows and columns of 
                                         playing board.
                                      */
    private static Frame parentFrame; /* A frame to which windows are attached.
                               */
   // Sometimes we need to know where on the screen the user clicks (next are in pixels).

    private static int mouseX, mouseY; /* These store mouse x & y values 
                                   when the user clicks on the screen, 
                                   when the user is editing the board.
                                */
    private static boolean mouseClicked;      /* Tells the program that the 
                                          mouse has been clicked. 
                        Parameters < mouseX > and < mouseY > above
                        above tell us where.                   */

    private static boolean editingGame;      // Set "true" when we are editing the game.
    private static boolean justEditedBoard;  // Have we just edited the board?

    // Cursors follow:

    private static Cursor handCursor;
    private static Cursor defaultCursor;
    /* The board can have certain min & max sizes. We set 
       these in routine < setDefaults() >.
    */
    private static int minNumberOfColumns, minNumberOfRows,
                maxNumberOfColumns, maxNumberOfRows;

    // Cell size on a side, in pixels, variables follow.

    private static int pixelsPerCell,        // Pixels per cell, and ...
                minPixelsPerCell,     // Bounds on
                maxPixelsPerCell;     // these numbers.

    private static int generation; // What generation we are on.

    /* Next, boards: this generation, next generation, and a 3-D 
       board containing old boards to check if we are in a 
       repeating pattern.                                   */

    private static int   [][] lastGeneration;
    private static int   [][] thisGeneration;  // We'll define
    private static int   [][] nextGeneration;  // the size of
    private static int [][][] oldBoards;       // these later.

    private static int appletWidth, appletHeight;  /* Width & height of entire 
                                               screen.                */
    private static Point appletLocation;       // Our location on the screen.

    private static int boardWidth, boardHeight;    /* Size of actual board in 
                                                      pixels.
                                                   */
    private static int farthestLeftAComponentLives;

    private static boolean waitForTimeDelay;  /* Set "true" when 
                                          the user wants to
                          cycle through generations automatically
                          via a time delay; set "false" when the 
                          user presses a button.                    */

    private static boolean clickLiveCellsViaMouse;    /* Decide which cells 
                                                         are alive via 
                          clicking on them with the mouse, as 
                          opposed to setting "lives" and "deads" 
                          probablistically.                         */

    private static int probability;    /* If the board is input probalistically,
                                     this is the probability, as a number, 
                                     1 -- 100.
                                  */
    private static int timeBetweenGenerations;  /* This is how long we wait
                                            between generations, should 
                                            the user set a time delay. */

    private static Point genNumLocation;            // We store
    private static Point keepGoingButtonLocation;   // good
    private static Point editGameButtonLocation;    // screen
    private static Point quitGameButtonLocation;    // locations

/* *********************************************************************
    Constructor follows:
   ********************************************************************* */
    
    Vars(Frame parentFrame, ScreenLocations screenLocations)
    {
        this.parentFrame = parentFrame;                  // We need an error class --
        error = new PopupWindow(this.parentFrame, screenLocations, ERROR_WINDOW_NAME);// For errors.

        /* Set everybody else to junk values. These are not known at
           instantiation.
        */
        pixelsPerCell                       = GARBAGE_VALUE;
        columns                             = GARBAGE_VALUE;
        rows                                = GARBAGE_VALUE;
        maxNumberOfColumns                  = GARBAGE_VALUE;
        maxNumberOfRows                     = GARBAGE_VALUE;
        maxPixelsPerCell                    = GARBAGE_VALUE;
        minPixelsPerCell                    = GARBAGE_VALUE;
        minNumberOfRows                     = GARBAGE_VALUE;
        minNumberOfColumns                  = GARBAGE_VALUE;
        timeBetweenGenerations              = GARBAGE_VALUE;
        probability                         = GARBAGE_VALUE;
        appletWidth                         = GARBAGE_VALUE;
        appletHeight                        = GARBAGE_VALUE;
        boardWidth                          = GARBAGE_VALUE; 
        boardHeight                         = GARBAGE_VALUE;
        farthestLeftAComponentLives         = GARBAGE_VALUE;
        mouseX                              = GARBAGE_VALUE;
        mouseY                              = GARBAGE_VALUE;

        appletLocation                      = new Point(GARBAGE_VALUE, GARBAGE_VALUE);

        thisGeneration                      = null; // Pointers to
        nextGeneration                      = null; // something.
        oldBoards                           = null;
        parentFrame                         = null;
        handCursor                          = null;
        defaultCursor                       = null;
        waitForTimeDelay                    = false;
        clickLiveCellsViaMouse              = false;
        mouseClicked                        = false;
        editingGame                         = false;
        justEditedBoard                     = false;

        genNumLocation                      = null;
        keepGoingButtonLocation             = null;
        editGameButtonLocation              = null;
        quitGameButtonLocation              = null;

        instantiationsSucceeded             = false;    // Only we use this.

        // Define the cursors

        SetHandCursor(new Cursor(Cursor.HAND_CURSOR));        // "Active" cursor
        SetDefaultCursor(new Cursor(Cursor.DEFAULT_CURSOR));  // "Inactive" cursor
    }


/*******************************************************************
    The next routine make the boards.
 ******************************************************************* */

    protected void MakeBoards()
    {
        /* Why the "+ 2" ' s in the below? The user sees the 
           board from 1 to rows, 1 to columns. The program itself, 
           when computing who is alive and dead in the next 
           generation, goes from 0 to (rows + 1) and 0 to (columns + 1); 
           due to how the next generation is computed, we need an 
           extra row of zeros on the edges.                     */

        int height = rows + 2;      // Rows, and ...
        int width  = columns + 2;   // Columns.

        /* So as the program goes 1 beyond edges, we need to define the 
           boards two beyond the edges. See routine AliveInNext in 
           class boardUtilities for more info.

           If the boards have been previously instantiated, AND, the 
           dimensions have not changed, we do not clog the
           garbage collector with drivel objects               */

        boolean skipInstantiations = false;

        // Have boards already been instantiated? If so, have dimensions changed?

        if ((thisGeneration != null) && 
            (nextGeneration != null) && 
            (oldBoards != null))
        {
            // Check EVERYBODY, just in case something weird happened.

            skipInstantiations = 
                (thisGeneration.length == height) && 
                (thisGeneration[0].length == width) &&
                (nextGeneration.length == height) &&
                (nextGeneration[0].length == width) &&
                (oldBoards[0].length == height) && 
                (oldBoards[0][0].length == width);
        }
        if (!skipInstantiations)
        {
            thisGeneration = new int[height][columns + 2];
            nextGeneration = new int[height][columns + 2];
            oldBoards = new int[NUMBER_OF_OLDBOARDS][height][width];
        }
        else
        {
            ;   // Dimensions have not changed. Do not
        }       // clog the garbage collector.
    }

    /* "Get" and "Set" routines follow. Note all are < protected final > for speed.
        A few are not used, but we define them for completeness, as they may be
        down the line.

        They are pretty brainless, and there is a minimum of documentation.
    */

    // Integer variables:

    // Rows:

    protected final void SetRows(int rows)
    {
        this.rows = rows;
    }
    protected final int GetRows()
    {
        return rows;
    }
    
    // Columns:

    protected final void SetColumns(int columns)
    {
        this.columns = columns;
    }

    protected final int GetColumns()
    {
        return columns;
    }

    // Max number of rows:

    protected final void SetMaxNumberOfRows(int maxNumberOfRows)
    {
        this.maxNumberOfRows = maxNumberOfRows;
    }
    protected final int GetMaxNumberOfRows()
    {
        return maxNumberOfRows;
    }

    // Minimum number of rows:

    protected final void SetMinNumberOfRows(int minNumberOfRows)
    {
        this.minNumberOfRows = minNumberOfRows;
    }
    protected final int GetMinNumberOfRows()
    {
        return minNumberOfRows;
    }

    // Minimum number of columns:

    protected final void SetMinNumberOfColumns(int minNumberOfColumns)
    {
        this.minNumberOfColumns = minNumberOfColumns;
    }
    protected final int GetMinNumberOfColumns()
    {
        return minNumberOfColumns;
    }

    // Max number of columns:

    protected final void SetMaxNumberOfColumns(int maxNumberOfColumns)
    {
        this.maxNumberOfColumns = maxNumberOfColumns;
    }
    protected final int GetMaxNumberOfColumns()
    {
        return maxNumberOfColumns;
    }

    // Pixels per cell:

    protected final void SetPixelsPerCell(int pixelsPerCell)
    {
        this.pixelsPerCell = pixelsPerCell;
    }
    protected final int GetPixelsPerCell()
    {
        return pixelsPerCell;
    }

    // Min pixels per cell:

    protected final void SetMinPixelsPerCell(int minPixelsPerCell)
    {
        this.minPixelsPerCell = minPixelsPerCell;
    }
    protected final int GetMinPixelsPerCell()
    {
        return minPixelsPerCell;
    }

    // Max pixels per cell:

    protected final void SetMaxPixelsPerCell(int maxPixelsPerCell)
    {
        this.maxPixelsPerCell = maxPixelsPerCell;
    }
    protected final int GetMaxPixelsPerCell()
    {
        return maxPixelsPerCell;
    }

    // Applet location
     
    protected final void SetAppletLocation(Point appletLocation)
    {
        this.appletLocation = appletLocation;
    }
    protected final Point GetAppletLocation()
    {
        return appletLocation;
    }

    // Applet width:

    protected final void SetAppletWidth(int appletWidth)
    {
        this.appletWidth = appletWidth;
    }
    protected final int GetAppletWidth()
    {
        return appletWidth;
    }

    // Applet height:

    protected final void SetAppletHeight(int appletHeight)
    {
        this.appletHeight = appletHeight;
    }
    protected final int GetAppletHeight()
    {
        return appletHeight;
    }

    // Applet height:

    protected final void SetFarthestLeftAComponentLives(int farthestLeftAComponentLives)
    {
        this.farthestLeftAComponentLives = farthestLeftAComponentLives;
    }
    protected final int GetFarthestLeftAComponentLives()
    {
        return farthestLeftAComponentLives;
    }
    // Board width:

    protected final void SetBoardWidth(int boardWidth)
    {
        this.boardWidth = boardWidth;
    }
    protected final int GetBoardWidth()
    {
        return boardWidth;
    }

    // Board height:

    protected final void SetBoardHeight(int boardHeight)
    {
        this.boardHeight = boardHeight;
    }
    protected final int GetBoardHeight()
    {
        return boardHeight;
    }

    // Probability:

    protected final void SetProbability(int probability)
    {
        this.probability = probability;
    }
    protected final int GetProbability()
    {
        return probability;
    }

    // Time between generations:

    protected final void SetTimeBetweenGenerations(int timeBetweenGenerations)
    {
        this.timeBetweenGenerations = timeBetweenGenerations;
    }
    protected final int GetTimeBetweenGenerations()
    {
        return timeBetweenGenerations;
    }

    // Current generation:

    protected final void SetGenerationNumber(int generation)
    {
        this.generation = generation;
    }
    // Increment generation 1:
    protected final void BumpGenerationNumber()
    {
        generation++;
    }
    protected final int GetGenerationNumber()
    {
        return generation;
    }

    // Mouse < x > value:

    protected final void SetMouseX(int mouseX)
    {
        this.mouseX = mouseX;
    }
    protected final int GetMouseX()
    {
        return mouseX;
    }

    // Mouse < y > value:

    protected final void SetMouseY(int mouseY)
    {
        this.mouseY = mouseY;
    }
    protected final int GetMouseY()
    {
        return mouseY;
    }

    // Arrays:

    /* Last generation -- no "set" routine, only a "get" routine.
       Note zero index gets mapped to length minus one.

       Note modular arithmetic.
    */
    protected final int [][] GetLastGeneration()
    {
        int index;
        if (generation % oldBoards.length == 0)
        {
            index = oldBoards.length - 1;
        }
        else
        {
            index = generation % oldBoards.length - 1;
        }
        return oldBoards[index];
    }

    // Current generation:

    protected final void SetThisGeneration(int [][] thisGeneration)
    {
        this.thisGeneration = thisGeneration;
    }
    protected final int [][] GetThisGeneration()
    {
        return thisGeneration;
    }

    // Next generation:

    protected final void SetNextGeneration(int [][] nextGeneration)
    {
        this.nextGeneration = nextGeneration;
    }
    protected final int [][] GetNextGeneration()
    {
        return nextGeneration;
    }

    // Old boards:

    protected final void SetOldBoards(int [][][] oldBoards)
    {
        this.oldBoards = oldBoards;
    }
    protected final int [][][] GetOldBoards()
    {
        return oldBoards;
    }

    // Classes follow:

    /* Do we wait for a time delay, or click on a button to go
       from generation to generation?
    */
    protected final void SetWaitForTimeDelay(boolean waitForTimeDelay)
    {
        this.waitForTimeDelay = waitForTimeDelay;
    }
    protected final boolean GetWaitForTimeDelay()
    {
        return waitForTimeDelay;
    }

    // Click on live cells, or via probability:

    protected final void SetClickLiveCellsViaMouse(boolean clickLiveCellsViaMouse)
    {
        this.clickLiveCellsViaMouse = clickLiveCellsViaMouse;
    }
    protected final boolean GetClickLiveCellsViaMouse()
    {
        return clickLiveCellsViaMouse;
    }

    // Was the mouse just clicked?:

    protected final void SetMouseClicked(boolean mouseClicked)
    {
        this.mouseClicked = mouseClicked;
    }
    protected final boolean GetMouseClicked()
    {
        return mouseClicked;
    }

    // Are we editing the game?

    protected final void SetEditingGame(boolean editingGame)
    {
        this.editingGame = editingGame;
    }
    protected final boolean GetEditingGame()
    {
        return editingGame;
    }

    // Have we just edited the board?

    protected final void SetJustEditedBoard(boolean justEditedBoard)
    {
        this.justEditedBoard = justEditedBoard;
    }
    protected final boolean GetJustEditedBoard()
    {
        return justEditedBoard;
    }

    // Cursors:

    // "Hand" cursor:

    protected final void SetHandCursor(Cursor handCursor)
    {
        this.handCursor = handCursor;
    }
    protected final Cursor GetHandCursor()
    {
        return handCursor;
    }

    // "Default" cursor:

    protected final void SetDefaultCursor(Cursor defaultCursor)
    {
        this.defaultCursor = defaultCursor;
    }
    protected final Cursor GetDefaultCursor()
    {
        return defaultCursor;
    }

    // Screen locations

    protected final void SetGenNumLocation(Point genNumLocation)
    {
        this.genNumLocation = genNumLocation;
//        error.ShowMessage("genNumLocation = " + genNumLocation, OK);
        
    }
    protected final void SetKeepGoingButtonLocation(Point keepGoingButtonLocation)
    {
        this.keepGoingButtonLocation = keepGoingButtonLocation;
//        error.ShowMessage("keepGoingButtonLocation = " + keepGoingButtonLocation, OK);
    }
    protected final void SetEditGameButtonLocation(Point editGameButtonLocation)
    {
        this.editGameButtonLocation = editGameButtonLocation;
//        error.ShowMessage("editGameButtonLocation = " + editGameButtonLocation, OK);
    }
    protected final void SetQuitGameButtonLocation(Point quitGameButtonLocation)
    {
        this.quitGameButtonLocation = quitGameButtonLocation;
//        error.ShowMessage("quitGameButtonLocation = " + quitGameButtonLocation, OK);
    }

    // "Get" screen locations.

    protected final Point GetGenNumLocation()
    {
        return genNumLocation;
    }
    protected final Point GetKeepGoingButtonLocation()
    {
        return keepGoingButtonLocation;
    }
    protected final Point GetEditGameButtonLocation()
    {
        return editGameButtonLocation;
    }
    protected final Point GetQuitGameButtonLocation()
    {
        return quitGameButtonLocation;
    }


    // Parent frame:

    protected final void SetParentFrame(Frame parentFrame)
    {
        this.parentFrame = parentFrame;
    }
    protected final Frame GetParentFrame()
    {
        return parentFrame;
    }
}   // End class < Vars >.