/*Single/solo step conversion in Java, version 1.0
Simply takes steps (for only one difficulty) and chucks it into a separate file.
User can copy it into the same .sm file themselves for now.
Later versions will append to the same file.
Error checking will also be added later.
by Rhett Dobson, June 12 2008*/

import java.util.*;
import java.io.*;
import java.lang.*;

public class SMConvert1 {

	public static void main (String args[]) throws IOException {

		final int SIZE = 10; //just needs to be large enough for a single line of steps

		Scanner s = new Scanner(System.in); //user input

		System.out.println("Single/solo step converter, by Shiner");
		System.out.println("");

		System.out.print("Enter input file (.sm files only): ");
		String inf = s.nextLine();
		System.out.print("Enter output file: ");
		String outp = s.nextLine();

		if (outp.equals(inf)) outp = outp.concat("2"); //protection from overwriting your entire stepfile with an incomplete .sm file!!

		File inFile = new File(inf); //input file
		Scanner f = new Scanner(inFile); //file scanner

		FileWriter fw = new FileWriter(outp); //output file
		BufferedWriter bw = new BufferedWriter(fw); //file writer

		System.out.println("Specify conversion mode: ");
		System.out.println("1) Single to Solo");
		System.out.println("2) Solo to Single");
		int m = s.nextInt();
		boolean mode = true; //single->solo
		if (m == 2 ) mode = false; //solo->single
		/*POTENTIAL BUG:
		user could get an array out of bounds exception if they try to convert steps that actually
		already single to single*/

		System.out.println("");

		System.out.println("Specify difficulty: ");
		System.out.println("1) Beginner");
		System.out.println("2) Easy");
		System.out.println("3) Medium");
		System.out.println("4) Hard");
		System.out.println("5) Challenge");
		System.out.println("6) Edit");
		m = s.nextInt();

		String difficulty = "Challenge:"; //If there's going to be only one difficulty, usually people pick this one

		switch (m) {

			case 1:
				difficulty = "Beginner:";
				break;

			case 2:
				difficulty = "Easy:";
				break;

			case 3:
				difficulty = "Medium:";
				break;

			case 4:
				difficulty = "Hard:";
				break;

			case 5:
				difficulty = "Challenge:";
				break;

			case 6:
				difficulty = "Edit:";
				break;

		}

		String currentLine;
		char[] cArray = new char[SIZE];
		char[] trueArray = new char[6]; //large character array for single->solo
		char[] falseArray = new char[4]; //small array for solo->single
		String single = "dance-single";
		String solo = "dance-solo";
		String sMode = "";
		if (mode) sMode = solo;
		if (!mode) sMode = single;
		String header1 = "//---------------";
		String header2 = "----------------";

		//standard delimiter of whitespace is used for all File.next(); calls
		while (true) {
			currentLine = f.next(); //skip past all the junk at the start, it doesn't need to be copied
			if (currentLine.equals(difficulty)) break; //search until matching difficulty is found
		};

		//fabricate header. literal string is Description
		bw.write(header1 + sMode + " - Copied with SMConvert" + header2);
		bw.newLine();
		bw.write("#NOTES:");
		bw.newLine();
		bw.write("     " + sMode + ":");
		bw.newLine();
		bw.write("     Copied with SMConvert:"); //Description again
		bw.newLine();
		bw.write("     " + difficulty);
		bw.newLine();
		currentLine = f.next(); //now resume with file buffer
		bw.write("     " + currentLine); //numerical foot rating. 5 space indent needs to be re-added due to next()'s delimiter
		bw.newLine();

		currentLine = f.next();
		bw.write("     " + currentLine); //mysterious decimal numbers...may be durations of held notes
		bw.newLine();
		//now the rest is done algorithmically

	    currentLine = f.nextLine();
	    currentLine = currentLine.trim(); //needed for next if statement
	    if (currentLine.equals("// measure 1")) currentLine = f.nextLine();
	    //if measure numbers are intact (Stepmania 4.0 feature?) skip the first one. otherwise they are
	    //attached to the commas between measures which will be skipped anyway

		do {

			if (currentLine.length() > 3 && currentLine.length() < 7) { //if this line contains step data
				// (i.e. looks like "0100" or "10001M")
				// either a comma or a "// measure #" will be too long\
				// 'M' means there's a mine there so regexps would be tricky...
				/* would this work?
				 Pattern p = Pattern.compile("[\dM]");
				 Matcher m = p.matcher("[M0-4]");
 				 boolean b = m.matches();*/

				cArray = currentLine.toCharArray();

				if (mode) { //single->solo
					trueArray[0] = cArray[0]; //manually grab individual characters
					trueArray[1] = '0'; //empty hand step in the future solo steps
					trueArray[2] = cArray[1];
					trueArray[3] = cArray[2];
					trueArray[4] = '0'; //right hand
					trueArray[5] = cArray[3];
					bw.write(String.copyValueOf(trueArray)); //write a string made from the new array
					bw.newLine();
				}

				if (!mode) { //solo->single
					falseArray[0] = cArray[0];
					falseArray[1] = cArray[2]; //move around the hand sensor columns
					falseArray[2] = cArray[3];
					falseArray[3] = cArray[5];

					bw.write(String.copyValueOf(trueArray)); //write a string made from the new array
					bw.newLine();
				}

			} //else {
			if (currentLine.equals(",") || currentLine.length() > 6) {
				bw.write(","); //measure numbers can be added later
				bw.newLine();
			}

			currentLine = f.nextLine(); //proceed to next line

		} while (currentLine.equals(";") == false); //stepfiles end with a semicolon

		bw.write(";"); //end of stepfile
		bw.close();

		System.out.println("Done. Check " + outp + " and copy it to " + inf);

	}

}
