// File: Java_ACM_io.java
//
// Author: Robert W. Lindeman, with help from Rahul Simha.
// Created: 11/08/2001
//
// A package of useful I/O functions for the ACM.
// See the main function below for examples of use.

import java.io.*;
import java.util.*;
import java.text.*;
import java.lang.Math.*;

public class Acm_io {
    // Class data for screen input.
    // Instance data:
    private int in_source = 0; // 0 = stdin, 1 = filename.

    // For line/string processing.
    private String line;
    private StringTokenizer lt;
    private String delim = " \t\r\n";

    // When reading from stdin.
    private InputStreamReader isr;

    // When reading from a file.
    private FileReader fr;
    private String filename = "";

    // Used by both files and the screen.
    private LineNumberReader lr;

    // Constructor for reading from stdin.
    public Acm_io( ) {
	isr = new InputStreamReader( System.in );
	lr = new LineNumberReader( isr );
	in_source = 0;
    }

    // Constructor for reading from a file.
    public Acm_io( String fname ) {
	filename = fname;
	try {
	    fr = new FileReader( filename );
	}
	catch( FileNotFoundException e ) {
	    System.out.println( "ERR: Acm_io.Acm_io: file <" +
				filename + "> not found.\n" );
	    System.exit( 0 );
	}
	lr = new LineNumberReader( fr );
	in_source = 1;
    }

    // Instance methods:
    public String getLine( ) {
	try {
	    String s = lr.readLine( );
	    line = s;
	    lt = new StringTokenizer( line );
	    return( line );
	}
	catch( NullPointerException e ) {
	    line = "";
	    lt = new StringTokenizer( line );
	    return( null );
	}
	catch( IOException e ) {
	    line = "";
	    lt = new StringTokenizer( line );
	    return( null );
	}
    }

    public String getToken( ) {
	try {
	    String tok = lt.nextToken( delim );
	    tok = tok.trim( );
	    return( tok );
	}
	catch( NoSuchElementException e ) {
	    return( null );
	}
        catch( NullPointerException e ) {
	    return( null );
	}

    }

    static final int INT    = 0;
    static final int LONG   = 1;
    static final int STRING = 2;
    static final int FLOAT  = 3;
    static final int CHAR   = 4;

    public Object getObj( int type ) {
	String tok = getToken( );
	Object buf = null;
	if( tok == null ) {
	    return( null );
	}
	switch( type ) {
	case INT   : buf = Integer.valueOf( tok ); break;
	case LONG  : buf = Long.valueOf( tok ); break;
	case STRING:
	    if( tok.length( ) > 0 ) {
		buf = tok;
	    }
	    break;
	case FLOAT : buf = Float.valueOf( tok ); break;
	case CHAR  :
	    if( tok.length( ) == 1 ) {
		buf = new Character( tok.charAt( 0 ) );
	    }
	    break;
	}

	return( buf );
    }

    /////////////////////////////////////////////////////////
    // Formatting output:
    // Pad blanks as required (for both int's and double's).
    static String padBlanks( String s, int target_len, boolean is_int ) {
	int slen = s.length( );

	// No decimal point to worry about with int's.
	if( is_int ) {
	    if( slen >= target_len ) {
		return( s );
	    }
	    // Otherwise we pad from front
	    for( int i = 0; i < target_len-slen; i++ ) {
		s = ' ' + s;
	    }
	    return( s );
	}

	// Otherwise check up to decimal point
	int i = s.indexOf( '.' );
	if( ( i < 0 ) || ( i >= slen ) ) {
	    System.out.println( "ERR: padBlanks: no decimal point." );
	    System.exit( 1 );
	}
	if( i >= target_len ) {
	    return( s );
	}

	// Otherwise, pad with blanks
	for( int j = 0; j < target_len - i; j++ ) {
	    s = ' ' + s;
	}
	return( s );
    }

    // Format integers.
    public static String format( long i, int width ) {
	DecimalFormat df_i = new DecimalFormat( "#" );
	String s_i = df_i.format( i );
	s_i = padBlanks( s_i, width, true );
	return s_i;
    }

    // Format double's.
    public static String format( double d, int before_dec_pt,
				 int after_dec_pt ) {
	// Use '#' symbols before decimal point.
	String s = "";
	for( int i = 0; i < before_dec_pt; i++ ) {
	    s = s + '#';
	}

	// Force a zero for numbers less than 1.0
	s = s + "0.";

	// Include zeroes as specified by width.
	for( int i = 0; i < after_dec_pt; i++ ) {
	    s = s + '0';
	}

	DecimalFormat df_d = new DecimalFormat( s );
	String s_d = df_d.format( d );

	// Pad blanks.
	s_d = padBlanks( s_d, before_dec_pt, false );
	return s_d;
    }

    /////////////////////////////////////////////////////////
    // Test routine.

    public static void main( String[] argv ) {
	String line = "";
	String stationName = "";
	Integer stations = new Integer( 0 ),
                x = new Integer( 0 ), y = new Integer( 0 );
	Integer startStation = new Integer( 0 );
	Character stationLetter = new Character( 'A' );
	Float dist = new Float( 0 );

	// Create instances of a screen reader and a file reader.
	Acm_io my_io = new Acm_io( );
	//    Acm_io my_io = new Acm_io( "input.in" );

	System.out.print( "Parsing input file...\n" );
	line = my_io.getLine( );
	stations = ( Integer )my_io.getObj( INT );
	for( int i = 0; i < stations.intValue( ); i++ ) {
	    line = my_io.getLine( );
	    stationName = ( String )my_io.getObj( STRING );
	    stationLetter = ( Character )my_io.getObj( CHAR );
	    x = ( Integer )my_io.getObj( INT );
	    y = ( Integer )my_io.getObj( INT );
	    dist = ( Float )my_io.getObj( FLOAT );
	    System.out.print( "Case " + i + ": " +
                        stationName + " " +
                        stationLetter + " " +
                        x + " " +
                        y + " " +
			      dist );
	    if( ( startStation = ( Integer )my_io.getObj( INT ) ) != null ) {
		System.out.print( " (Start)" );
	    }
	    System.out.println( );
	}

	System.out.println( "<" + Acm_io.format( 10, 3 ) +
                            "> <" + Acm_io.format( .01, 4, 4 ) + ">" );

    }
} // End of class "Acm_io"


