
/**
 * wavdump: a utility to parse and dump WAV audio files.
 * <br>© 2019 Ian Cameron Smith.  All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */


package org.hermit.wavdump;


import java.io.File;


/**
 * Command-line interface to WavDump.
 */
public class WavDump
{

	// ******************************************************************** //
	// Constructors.
	// ******************************************************************** //

	/**
	 * Non-instantiable.
	 */
	private WavDump() {}


	// ******************************************************************** //
	// Main.
	// ******************************************************************** //

	/**
	 * Command-line main function.
	 * 
	 * @param	args		The command-line arguments.
	 */
	public static final void main(String[] args) {
		int numFiles = 0;
		for (int i = 0; i < args.length; ++i) {
			// If this is a flag argument, deal with it and move on.
			if (args[i].startsWith("-")) {
				i += processFlag(args, i);
				continue;
			}
			
			// If this is an empty file name, complain and move on.
			if (args[i].length() == 0) {
				error("empty file name\n");
				continue;
			}
			
			File file = new File(args[i]);
			Dumper dumper = new Dumper(file, sampleMode, xmlMode);
			++numFiles;
			try {
				System.out.printf("%s:\n", args[i]);
				dumper.dump();
			} catch (Dumper.UserException e) {
				error("error in \"%s\": %s\n", args[i], e.getMessage());
			}
		}
		
		if (numFiles == 0)
			usage("require at least one WAV file argument\n");
	}
	
	
	/**
	 * Process a command-line flag.
	 * 
	 * @param	args		The command-line arguments.
	 * @param	i			The index of the argument to process.
	 * @return				The number of additional command-line words
	 * 						used up.  For a simple flag, this will be 0;
	 * 						if the flag takes one additional argument,
	 * 						it would be 1.
	 */
	private static int processFlag(String[] args, int i) {
		switch (args[i]) {
		case "-fullsamples":
			sampleMode = Dumper.DataMode.FULL;
			break;
		case "-shortsamples":
			sampleMode = Dumper.DataMode.SHORT;
			break;
		case "-nosamples":
			sampleMode = Dumper.DataMode.NONE;
			break;
		case "-fullxml":
			xmlMode = Dumper.DataMode.FULL;
			break;
		case "-shortxml":
			xmlMode = Dumper.DataMode.SHORT;
			break;
		case "-noxml":
			xmlMode = Dumper.DataMode.NONE;
			break;
		default:
			usage("invalid argument: \"%s\"", args[i]);
		}
		
		return 0;
	}
	

	/**
	 * Print a usage error message, display the correct command usage,
	 * and quit.
	 * 
	 * @param	fmt		Output format template.
	 * @param	args	Zero or more arguments to the template.
	 */
	private static void usage(String fmt, Object... args) {
		error(fmt, args);
		
		System.err.printf("Usage: wavdump [ flags ] wav-file ...\n");
		System.err.printf("Allowable flags:\n");
		System.err.printf("    -fullsamples   Display all audio samples\n");
		System.err.printf("    -shortsamples  Display a summary of audio samples\n");
		System.err.printf("    -nosamples     Don't display audio samples\n");
		System.err.printf("    -fullxml       Display all XML data\n");
		System.err.printf("    -shortxml      Display a summary of XML data\n");
		System.err.printf("    -noxml         Don't display XML data\n");

		System.exit(1);
	}


	/**
	 * Print an error message.
	 * 
	 * @param	fmt		Output format template.
	 * @param	args	Zero or more arguments to the template.
	 */
	private static void error(String fmt, Object... args) {
		System.out.flush();
		System.err.flush();

		System.err.printf("wavdump: ");
		System.err.printf(fmt, args);
	}
	
    
    // ******************************************************************** //
    // Private Data.
    // ******************************************************************** //

	// User-selected audio sample display mode.
	private static Dumper.DataMode sampleMode = Dumper.DataMode.SHORT;

	// User-selected XML display mode.
	private static Dumper.DataMode xmlMode = Dumper.DataMode.SHORT;
	
}

