import java.util.Scanner;

public class Memory {

   public static final int SIZE = 100;
   public static final int MAXWVAL = +9999;
   public static final int MINWVAL = -9999;
   public static final int EOINPUT = -99999;
   
   private int[] memory;
   
   
   public Memory() {
      memory = new int[ SIZE ];
   }
   
   
   /* returns the word in memory at the specified address */
   public int load( int addr ) throws MemoryAccessException {
      if ( 0 > addr || addr >= SIZE )
         throw new MemoryAccessException( "Load exception - address: " + addr );
      return memory[ addr ];
   }
   
   
   /* stores a word value into memory at the specified address */
   public void store( int addr, int value ) throws MemoryAccessException {
      if ( 0 > addr || addr >= SIZE )
         throw new MemoryAccessException( "Load exception - address: " + addr );
      memory[ addr ] = value;
   }
   

   
   /* initialize the state of memory from keyboard input */
   public void initialize() {
       int addr = 0;
       int data;

       while ( addr < SIZE && (data = inputWord(addr)) != EOINPUT ) 
           memory[addr++] = data;
           
       while ( addr < SIZE )   /* zero out remainder of memory */
           memory[addr++] = 0;
   }

   
   /* read a word from memory to be stored at the location addr. Note, this
    * method does not actually update the memory, it only uses the addr 
    * parameter as a prompt for the user. If the addr parameter is negative
    * it is not displayed in the prompt
    */   
   static int inputWord( int addr ) {
       int res = 0;
       int data = 0;
       boolean done = false;
       Scanner in = new Scanner( System.in );
       
       while ( !done ) {
           /* Prints loc address in prompt only if addr >= 0 */
           if ( addr >= 0 ) System.out.printf( "%02d ? ", addr );
           else System.out.print( " ? " );
           
           if ( in.hasNextInt() ) {
              data = in.nextInt();
              if ( (data >= MINWVAL && data <= MAXWVAL) || data == EOINPUT )
                 done = true;
           }
           else {
              in.nextLine(); // eat up bad input on line
           }
           if ( !done ) 
              System.out.println("Invalid input. Try again.");
       }
       return data;
   }
   
   
   /* returns a dump of memory contents */
   public String toString() {
      String str = "\nMEMORY:\n";
      int row, col;
      
      for ( row = -1; row < SIZE/10; row++ ) {
          for ( col = -1; col < 10; col++ ) {
              if ( row == -1 ) {
                  if ( col == -1 ) str += ( "  " );
                  else str += String.format( "%7d", col );
              } else {
                  if ( col == -1 ) str += String.format( "%2d", row*10 );
                  else str += String.format( "  %+05d", memory[10*row + col] );
              }
          }
          str += ( "\n" );
      }
      
      return str;
   }
   
}
