/*
 * [TestConsole.java]
 *
 * Summary: Test how various characters display on the console.
 *
 * Copyright: (c) 2009-2017 Roedy Green, Canadian Mind Products, http://mindprod.com
 *
 * Licence: This software may be copied and used freely for any purpose but military.
 *          http://mindprod.com/contact/nonmil.html
 *
 * Requires: JDK 1.8+
 *
 * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/
 *
 * Version History:
 *  1.0 2011-01-15 initial version
 */
package com.mindprod.example;

import com.mindprod.common18.ST;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

import static java.lang.System.*;

/**
 * Test how various characters display on the console.
 *
 * @author Roedy Green, Canadian Mind Products
 * @version 1.0 2009-09-10 initial version
 * @since 2009-09-10
 */
public final class TestConsole
    {
    private static final String USAGE = "\nTestConsole need needs a filename and an encoding on the command line.\n" +
                                        "Either may be the word [default].";

    /**
     * table of descriptions of each character
     */
    private static final String[] descs = new String[ 256 ];

    static
        {
        buildDescs();
        }

    /**
     * build table of descriptions of characters 0..255
     */
    private static void buildDescs()
        {
        for ( int i = 0; i < 256; i++ )
            {
            descs[ i ] = "character";
            }
        for ( int i = 0; i <= 31; i++ )
            {
            descs[ i ] = "control char";
            }
        for ( int i = '0'; i <= '9'; i++ )
            {
            descs[ i ] = "digit " + String.valueOf( ( char ) i );
            }
        for ( int i = 'A'; i <= 'Z'; i++ )
            {
            descs[ i ] = "upper case letter " + String.valueOf( ( char ) i );
            }
        for ( int i = 'a'; i <= 'z'; i++ )
            {
            descs[ i ] = "lower case letter " + String.valueOf( ( char ) i );
            }
        descs[ 0x20 ] = "space";
        descs[ 0x21 ] = "! ordinary exclamation mark";
        descs[ 0x22 ] = "double quotation marks";
        descs[ 0x23 ] = "# sharp";
        descs[ 0x24 ] = "ordinary dollar sign";
        descs[ 0x25 ] = "percent";
        descs[ 0x26 ] = "ampersand";
        descs[ 0x27 ] = "apostrophe";
        descs[ 0x28 ] = "ordinary left parenthesis (";
        descs[ 0x29 ] = "ordinary right parenthesis )";
        descs[ 0x2a ] = "ordinary star";
        descs[ 0x2b ] = "ordinary plus";
        descs[ 0x2c ] = "ordinary comma";
        descs[ 0x2e ] = "ordinary period";
        descs[ 0x2f ] = "ordinary slash /";
        descs[ 0x3a ] = "ordinary colon";
        descs[ 0x3b ] = "ordinary semicolon";
        descs[ 0x3c ] = "less-than sign";
        descs[ 0x3d ] = "ordinary equal sign";
        descs[ 0x3e ] = "greater-than sign";
        descs[ 0x3f ] = "ordinary question mark";
        descs[ 0x40 ] = "at sign";
        descs[ 0x5b ] = "ordinary left bracket [";
        descs[ 0x5c ] = "ordinary backslash \\";
        descs[ 0x5d ] = "ordinary right bracket ]";
        descs[ 0x5e ] = "circumflex";
        descs[ 0x5f ] = "underscore";
        descs[ 0x60 ] = "grave";
        descs[ 0x7b ] = "ordinary left brace {";
        descs[ 0x7c ] = "ordinary vertical bar |";
        descs[ 0x7d ] = "ordinary right brace }";
        descs[ 0x7e ] = "tilde";
        descs[ 0xa0 ] = "non-breaking space";
        descs[ 0xa1 ] = "inverted exclamation mark";
        descs[ 0xa2 ] = "cent sign";
        descs[ 0xa3 ] = "pound sign";
        descs[ 0xa4 ] = "currency sign";
        descs[ 0xa5 ] = "yen sign";
        descs[ 0xa6 ] = "broken bar";
        descs[ 0xa7 ] = "section sign";
        descs[ 0xa8 ] = "diaeresis";
        descs[ 0xa8 ] = "umlaut";
        descs[ 0xa9 ] = "copyright sign circled c";
        descs[ 0xaa ] = "feminine ordinal indicator";
        descs[ 0xab ] = "left guillemot";
        descs[ 0xac ] = "not sign";
        descs[ 0xad ] = "soft hyphen";
        descs[ 0xae ] = "registered sign. circled R.";
        descs[ 0xaf ] = "macron";
        descs[ 0xb0 ] = "degree sign";
        descs[ 0xb1 ] = "plus-minus sign";
        descs[ 0xb2 ] = "superscript two";
        descs[ 0xb3 ] = "superscript three";
        descs[ 0xb4 ] = "acute accent";
        descs[ 0xb5 ] = "micro sign";
        descs[ 0xb6 ] = "pilcrow sign";
        descs[ 0xb7 ] = "middle dot";
        descs[ 0xb8 ] = "cedilla";
        descs[ 0xb9 ] = "superscript one";
        descs[ 0xba ] = "masculine ordinal indicator";
        descs[ 0xbb ] = "right guillemot";
        descs[ 0xbc ] = "vulgar fraction 1/4";
        descs[ 0xbd ] = "vulgar fraction 1/2";
        descs[ 0xbe ] = "vulgar fraction 3/4";
        descs[ 0xbf ] = "inverted question mark";
        descs[ 0xc0 ] = "Latin capital letter A with grave";
        descs[ 0xc1 ] = "Latin capital letter A with acute";
        descs[ 0xc2 ] = "Latin capital letter A with circumflex";
        descs[ 0xc3 ] = "Latin capital letter A with tilde";
        descs[ 0xc4 ] = "Latin capital letter A with diaeresis";
        descs[ 0xc5 ] = "Latin capital letter A with ring above";
        descs[ 0xc6 ] = "Latin capital letter AE";
        descs[ 0xc7 ] = "Latin capital letter C with cedilla";
        descs[ 0xc8 ] = "Latin capital letter E with grave";
        descs[ 0xc9 ] = "Latin capital letter E with acute";
        descs[ 0xca ] = "Latin capital letter E with circumflex";
        descs[ 0xcb ] = "Latin capital letter E with diaeresis";
        descs[ 0xcc ] = "Latin capital letter I with grave";
        descs[ 0xcd ] = "Latin capital letter I with acute";
        descs[ 0xce ] = "Latin capital letter I with circumflex";
        descs[ 0xcf ] = "Latin capital letter I with diaeresis";
        descs[ 0xd0 ] = "Latin capital letter Eth";
        descs[ 0xd1 ] = "Latin capital letter N with tilde";
        descs[ 0xd2 ] = "Latin capital letter O with grave";
        descs[ 0xd3 ] = "Latin capital letter O with acute";
        descs[ 0xd4 ] = "Latin capital letter O with circumflex";
        descs[ 0xd5 ] = "Latin capital letter O with tilde";
        descs[ 0xd6 ] = "Latin capital letter O with diaeresis";
        descs[ 0xd7 ] = "multiplication sign";
        descs[ 0xd8 ] = "Latin capital letter O with stroke";
        descs[ 0xd9 ] = "Latin capital letter U with grave";
        descs[ 0xda ] = "Latin capital letter U with acute";
        descs[ 0xdb ] = "Latin capital letter U with circumflex";
        descs[ 0xdc ] = "Latin capital letter U with diaeresis";
        descs[ 0xdd ] = "Latin capital letter Y with acute";
        descs[ 0xde ] = "Latin capital letter Thorn";
        descs[ 0xdf ] = "Latin small letter sharp s";
        descs[ 0xe0 ] = "Latin small letter a with grave";
        descs[ 0xe1 ] = "Latin small letter a with acute";
        descs[ 0xe2 ] = "Latin small letter a with circumflex";
        descs[ 0xe3 ] = "Latin small letter a with tilde";
        descs[ 0xe4 ] = "Latin small letter a with diaeresis";
        descs[ 0xe5 ] = "Latin small letter a with ring above";
        descs[ 0xe6 ] = "Latin lowercase ligature ae";
        descs[ 0xe7 ] = "Latin small letter c with cedilla";
        descs[ 0xe8 ] = "Latin small letter e with grave";
        descs[ 0xe9 ] = "Latin small letter e with acute";
        descs[ 0xea ] = "Latin small letter e with circumflex";
        descs[ 0xeb ] = "Latin small letter e with diaeresis";
        descs[ 0xec ] = "Latin small letter i with grave";
        descs[ 0xed ] = "Latin small letter i with acute";
        descs[ 0xee ] = "Latin small letter i with circumflex";
        descs[ 0xef ] = "Latin small letter i with diaeresis";
        descs[ 0xf0 ] = "Latin small letter eth";
        descs[ 0xf1 ] = "Latin small letter n with tilde";
        descs[ 0xf2 ] = "Latin small letter o with grave";
        descs[ 0xf3 ] = "Latin small letter o with acute";
        descs[ 0xf4 ] = "Latin small letter o with circumflex";
        descs[ 0xf5 ] = "Latin small letter o with tilde";
        descs[ 0xf6 ] = "Latin small letter o with diaeresis";
        descs[ 0xf7 ] = "division sign";
        descs[ 0xf8 ] = "Latin small letter o with stroke";
        descs[ 0xf9 ] = "Latin small letter u with grave";
        descs[ 0xfa ] = "Latin small letter u with acute";
        descs[ 0xfb ] = "Latin small letter u with circumflex";
        descs[ 0xfc ] = "Latin small letter u with diaeresis";
        descs[ 0xfd ] = "Latin small letter y with acute";
        descs[ 0xfe ] = "Latin small letter thorn";
        descs[ 0xff ] = "Latin small letter y with diaeresis";
        }

    /**
     * Test harness Run this file with various combination of encoding, file, out and look at the results
     * when view on the console, when copied to the console, or in an editor to understand the
     * way the Unicode characters in the program are transformed.
     *
     * @param args name of file, encoding.
     *
     * @throws java.io.FileNotFoundException        if can't write file
     * @throws java.io.UnsupportedEncodingException if you specify a non-supported exception
     */
    public static void main( String[] args ) throws IOException
        {
        if ( args.length != 2 )
            {
            throw new IllegalArgumentException( USAGE );
            }
        out.println( "default encoding: " + System.getProperty( "file.encoding" ) ); // usually Windows-1252
        String filename = args[ 0 ];
        String encoding = args[ 1 ];
        if ( encoding.equals( "default" ) )
            {
            encoding = System.getProperty( "file.encoding" );
            }
        // O P E N
        final OutputStreamWriter eosw;
        if ( filename.equals( "default" ) )
            {
            eosw = new OutputStreamWriter( out, encoding );
            }
        else
            {
            final FileOutputStream fos = new FileOutputStream( filename, false /* append */ );
            final BufferedOutputStream bos = new BufferedOutputStream( fos,
                    16 * 1024
                    /* 16K bytes, 25% of allocation is optimal */ );
            eosw = new OutputStreamWriter( bos, encoding );
            }
        for ( int i = 0; i <= 255; i++ )
            {
            // show char, hex, decimal, description
            eosw.write( ( char ) i + " " + ST.toLZHexString( i, 2 ) + " " + i + " " + descs[ i ] + "\n" );
            }
        eosw.close();
        }
    }