public class Biosphere
{
    public static final int ROWS = 10;
    public static final int COLUMNS = 10;
    public static final int MIN_ROW = 0;
    public static final int MAX_ROW = 9;
    public static final int MIN_COLUMN = 0;
    public static final int MAX_COLUMN = 9;
    public static final String HORIZONTAL_LINE = "  - - - - - - - - - -";
    public static final String HORIZONTAL_COUNT = "  0 1 2 3 4 5 6 7 8 9 ";

    private Critter [][] previous;
    private Critter [][] current; 
    private int generation;

    public Biosphere ()
    {
        int r;
        int c;
        generation = 0;
        previous = new Critter [ROWS][COLUMNS];
        current = new Critter [ROWS][COLUMNS]; 
        for (r = 0; r < ROWS; r++)
        {
            for (c = 0; c < COLUMNS; c++)
            {
                previous[r][c] = new Critter(Critter.EMPTY);
                current[r][c] = new Critter(Critter.EMPTY);
            }
        }
      }

    public void initialize (int sphereType)
    {
        switch (sphereType)
        {
            case 1:
                initializeCase1 ();
                break;

            case 2:
                initializeCase2 ();
                break;

            case 3:
                initializeCase3();
                break;
    
            case 4:
                initializeCase4 ();
                break;
	    
            case 5:
              initializeCase5();
              break;

            case 6:
                initializeCase6 ();
                break;
           
            case 7:
                initializeCase7 ();
                break;

            case 8:
                initializeCase8 ();
                break;
        }
    }
    
    // Completely empty
    private void initializeCase1 ()
    {
        int r;
        int c;
        for (r = 0; r < ROWS; r++)
        {
            for (c = 0; c < COLUMNS; c++)
            {
                previous[r][c] = new Critter(Critter.EMPTY);
                current[r][c] = new Critter(Critter.EMPTY);
            }
        }
    }

    // Single critter
    private void initializeCase2 ()
    {
        int r;
        int c;
        for (r = 0; r < ROWS; r++)
        {
        for (c = 0; c < COLUMNS; c++)
        {
            previous[r][c] = new Critter(Critter.EMPTY);
            current[r][c] = new Critter(Critter.EMPTY);
        }
    }
    previous[MIN_ROW][MIN_COLUMN] = new Critter(Critter.REGULAR);
    current[MIN_ROW][MIN_COLUMN] = new Critter(Critter.REGULAR);	
    }

    // Single birth (3 critters)
    private void initializeCase3 ()
    {
        int r;
        int c;
        for (r = 0; r < ROWS; r++)
        {
        for (c = 0; c < COLUMNS; c++)
        {
            previous[r][c] = new Critter(' ');
            current[r][c] = new Critter (' ');
        }
        }
        current[1][1] = new Critter('*');
        previous[1][1] = new Critter('*');
        current[2][3] = new Critter('*');
        previous[2][3] = new Critter('*');
        current[3][1] = new Critter('*');
        previous[3][1] = new Critter('*');
    }
    
    // Simple pattern in middle
    private void initializeCase4 ()
    {
        int r;
        int c;
        for (r = 0; r < ROWS; r++)
        {
            for (c = 0; c < COLUMNS; c++)
            {
                previous[r][c] = new Critter(Critter.EMPTY);
                current[r][c] = new Critter(Critter.EMPTY);
            }
        }
    previous[1][1] = new Critter(Critter.REGULAR);
    current[1][1] = new Critter(Critter.REGULAR);	
    previous[2][3] = new Critter(Critter.REGULAR);
    current[2][3] = new Critter(Critter.REGULAR);
    previous[2][2] = new Critter(Critter.REGULAR);
    current[2][2] = new Critter(Critter.REGULAR);			
    previous[3][1] = new Critter(Critter.REGULAR);
    current[3][1] = new Critter(Critter.REGULAR);	
    previous[3][3] = new Critter(Critter.REGULAR);
    current[3][3] = new Critter(Critter.REGULAR);
    }

    // Pattern near edges
    private void initializeCase5 ()
    {
        int r;
        int c;
        for (r = 0; r < ROWS; r++)
        {
            for (c = 0; c < COLUMNS; c++)
            {
                previous[r][c] = new Critter(Critter.EMPTY);
                current[r][c] = new Critter(Critter.EMPTY);
            }
        }
        previous[MIN_ROW][MIN_COLUMN] = new Critter(Critter.REGULAR);
        current[MIN_ROW][MIN_COLUMN] = new Critter(Critter.REGULAR);
        previous[MIN_ROW][MAX_COLUMN] = new Critter(Critter.REGULAR);
        current[MIN_ROW][MAX_COLUMN] = new Critter(Critter.REGULAR);	
        previous[MAX_ROW][MIN_COLUMN] = new Critter(Critter.REGULAR);
        current[MAX_ROW][MIN_COLUMN] = new Critter(Critter.REGULAR);	
        previous[MAX_ROW][MAX_COLUMN] = new Critter(Critter.REGULAR);
        current[MAX_ROW][MAX_COLUMN] = new Critter(Critter.REGULAR);	
        previous[0][2] = new Critter(Critter.REGULAR);
        current[0][2] = new Critter(Critter.REGULAR);	
        previous[2][1] = new Critter(Critter.REGULAR);
        current[2][1] = new Critter(Critter.REGULAR);	
    }

    private void initializeCase6 ()
    {
        int r;
        int c;
        for (r = 0; r < ROWS; r++)
        {
            for (c = 0; c < COLUMNS; c++)
            {
                previous[r][c] = new Critter(Critter.EMPTY);
                current[r][c] = new Critter(Critter.EMPTY);
            }
            previous[2][MIN_COLUMN] = new Critter(Critter.FERTILE);
            current[2][MIN_COLUMN] = new Critter(Critter.FERTILE);	    
            previous[1][1] = new Critter(Critter.REGULAR);
            current[1][1] = new Critter(Critter.REGULAR);	    
            previous[4][1] = new Critter(Critter.FERTILE);
            current[4][1] = new Critter(Critter.FERTILE);	    
        }
    }

    // Complex pattern, no fertile critters
    private void initializeCase7 ()
    {
        int r;
        int c;
        for (r = 0; r < ROWS; r++)
        {
            for (c = 0; c < COLUMNS; c++)
            {
                previous[r][c] = new Critter(Critter.EMPTY);
                current[r][c] = new Critter(Critter.EMPTY);
            }
        }
        current[1][4] = new Critter ('*');
        previous[1][4] = new Critter ('*');
        current[2][5] = new Critter ('*');
        previous[2][5] = new Critter ('*');
        current[3][3] = new Critter ('*');
        previous[3][3] = new Critter ('*');
        current[3][4] = new Critter ('*');
        previous[3][4] = new Critter ('*');
        current[3][5] = new Critter ('*');
        previous[3][5] = new Critter ('*');
    }

    // Complex pattern, with fertile critters
    private void initializeCase8 ()
    {
        int r;
        int c;
        for (r = 0; r < ROWS; r++)
        {
            for (c = 0; c < COLUMNS; c++)
            {
                previous[r][c] = new Critter(Critter.EMPTY);
                current[r][c] = new Critter(Critter.EMPTY);
            }
        }
        current[2][2]= new Critter (Critter.FERTILE);
        previous[2][2] = new Critter (Critter.FERTILE);
        current[2][3] = new Critter (Critter.REGULAR);
        previous[2][3] = new Critter (Critter.REGULAR);
        current[2][4] = new Critter (Critter.FERTILE);
        previous[2][4] = new Critter (Critter.FERTILE);
        current[4][1] = new Critter (Critter.REGULAR);
        previous[4][1] = new Critter (Critter.REGULAR);
    }

    private void display ()
    {
        int r;
        int c;
        System.out.println("\t\tGeneration: " + generation);
        System.out.println("  PREVIOUS GENERATION" + "\t   CURRENT GENERATION");
        System.out.println(HORIZONTAL_COUNT + " \t " + HORIZONTAL_COUNT);
        for (r = 0; r < ROWS; r++)
        {
        System.out.println(HORIZONTAL_LINE + " \t " + HORIZONTAL_LINE);
        System.out.print(r + "|");
        for (c = 0; c < COLUMNS; c++)
        {
            previous[r][c].display();
            System.out.print('|');
        }
        System.out.print("\t" + r);
        System.out.print(" |");
        for (c = 0; c < COLUMNS; c++)
        {
            current[r][c].display();
            System.out.print('|');
        }
        System.out.println();
    }
    System.out.println(HORIZONTAL_LINE + " \t " + HORIZONTAL_LINE);
    }

    public void runTurn ()
    {
        // You could make display and call it outside the class methods.
        // But all the actions needed during a turn e.g., copy from one array
        // to another etc should not be done outside of this class.
        display();
    }
}










