import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class CServe {
	private static final String PROGRAM_VERSION = "1.1";
    public CServe( File book, boolean addNicks ) throws IOException {
        FileInputStream in = new FileInputStream( book );
        File outFile = new File( "CServe.txt" );
        FileWriter out = new FileWriter( outFile );
        PrintWriter prn = new PrintWriter( out );
        int bytes, ch;
        int count = 0, entry, entries = 0;
        String buffer;
        String nick;
        StringBuffer buf = new StringBuffer( 256 );
        if( in.available() > 0 ) {
            bytes = in.read();
            entries = in.read() + 256 * in.read();
            System.out.println( "Exporting " + entries + " entries from address book " + book.getName() + "\nto " + outFile.getName() + " with" + (addNicks ? "" : "out") + " Polarbar nicknames." );
            prn.print( "Entry," );
            if( addNicks ) {
            	prn.print( "\"Nickname\"," );
            }
            prn.print( "\"Full Name\",\"Email Address\",\"Notes\",\n");
            while( in.available() > 0 ) {
                // Progress indicator.
                count++;
                if( count > 25 ) {
                    System.out.print( '.' );
                    count = 0;
                }
                // Read and write the address book entry number.
                entry = in.read() + 256 * in.read();
                prn.print( entry );
                prn.print( ',' );
                // Read the address book entry name.
                bytes = in.read();
                buf.setLength( 0 );
                while( bytes > 0 && in.available() > 0 ) {
                    buf.append( ( char ) in.read() );
                    bytes--;
                }
                // Remove leading and trailing spaces.
                buffer = buf.toString().trim();
                if( buffer.length() > 0 && buffer.charAt(0) != '"' ) {
                	// If the string doesn't already have quote marks, add them.
                    buffer = '"' + buffer.replace('"','\'') + '"';
                }
                // Optionally create and write a nickname.
                if( addNicks ) {
                	nick = buffer.toLowerCase().replace(' ','-').replace('@','-').replace(',','-').replace('<','-').replace('>','-');
                	prn.print( nick );
                	prn.print( ',' );
                }
                // Write the address book entry name.
                prn.print( buffer );
                prn.print( ',' );
                // Read and write the address book entry email address.
                bytes = in.read();
                buf.setLength( 0 );
                while( bytes > 0 && in.available() > 0 ) {
                    buf.append( ( char ) in.read() );
                    bytes--;
                }
                buffer = buf.toString();
                if( buffer.startsWith( "INTERNET:" ) ) {
                    buffer = buffer.substring( 9 );
                }
                else {
                    ch = buffer.indexOf( ',' );
                    if( ch >= 0 ) {
                        buffer = buffer.substring( 0, ch - 1 )
                        + '.' + buffer.substring( ch + 1 );
                    }
                    if( buffer.charAt( 0 ) == '[' ) {
                        buffer = buffer.substring( 1 );
                    }
                    if( buffer.charAt( buffer.length() - 1 ) == ']' ) {
                        buffer = buffer.substring( 0, buffer.length() - 1 );
                    }
                    buffer = buffer + "@compuserve.com";
                }
                prn.print( buffer );
                prn.print( ',' );
                // Read and write the address book entry notes.
                bytes = in.read();
                buf.setLength( 0 );
                while( bytes > 0 && in.available() > 0 ) {
                    buf.append( ( char ) in.read() );
                    bytes--;
                }
                // Remove leading and trailing spaces.
                buffer = buf.toString().trim();
                if( buffer.length() > 0 && buffer.charAt(0) != '"' ) {
                	// If the string doesn't already have quote marks, add them.
                    buffer = '"' + buffer.replace('"','\'') + '"';
                }
                prn.print( buffer );
                prn.print( ",\n" );
            }
            prn.close();
        }
    }

    public static void main( String args[] ) throws IOException {
        String book;
        String nick = null;

    	System.out.println( "Compuserve address book export utility, version " + PROGRAM_VERSION);
    	System.out.println();

        if( args.length > 0 ) {
            book = args[ 0 ];
            if( args.length > 1 ) {
            	nick = args[ 1 ];
            }
            new CServe( new File( book ), nick != null );
        }
        else {
            System.out.println( "Syntax: java CServe addressbook [add_nicks]" );
            System.out.println( "or: jre -cp . CServe addressbook [add_nicks]" );
            System.out.println();
            System.out.println( "which exports the specified Compuserve addressbook file to a comma-delimited" );
            System.out.println( "file named CServe.txt and displays a progress indicator every 25 addresses." );
            System.out.println( "Each record in the file consists of the Compuserve addressbook entry number," );
            System.out.println( "the adressbook entry name, the addressbook entry email address, and the address" );
            System.out.println( "book entry notes. The fields are comma separated and all fields but the entry" );
            System.out.println( "and email address are quote delimited. The first record is a field name header." );
            System.out.println();
            System.out.println( "If the optional add_nicks command line parameter is used, then the Compuserve" );
            System.out.println( "addressbook entry name is used to create a nickname that is inserted after the" );
            System.out.println( "entry number and ahead of the name. It does not matter what the add_nicks value" );
            System.out.println( "is, just that the extra parameter is present. Nicknames are created by forcing" );
            System.out.println( "the name to lower case and replacing all characters that are not valid nickname" );
            System.out.println( "characters with dashes." );
        }
    }
}
