package vermilion;

//TODO: columns are storing the cues, need to ensure synchro
//
//TODO: Try to write an audio processing plugin or 'machine'. Any mathematical
//equation is an audio effect that someone will find useful one day. Look at the
//examples in the Extensions directory and just copy and modify an existing
//machine. (Trivial, fun)
//
//TODO: Write help on the above experiences in the instructions.txt file and the
//program's main help to help non-programmers create unique machines. (Docs)
//
//TODO: Make the selection of a soundcard easier, both as a default setting during
//the first run and as a user preference that can later be modified. Consider
//using a Java library that uses ASIO or some other high performance multi
//channel audio API. (Specialised)
//
//TODO: Look at the loop delay machine and try to work out how to make its delay
//correct under any scenario. (This is a buffering/concurrency thought experiment,
//contact me).
//
//TODO: Improve the mechanism for registering serialisable data types in the composition,
//including deregistration of types. (Simple code work)
//
//TODO: Improve the help viewer to allow the help file to be broken into separate files
//(by handling hyperlink clicks). (Hobby)
//
//TODO: Implement one or more of the three remaining required parameter types: Switches,
//Commands, and (musical) Notes. (API work, good on resume)
//
//TODO: Implement keyboard mappings (including for different locales) when programming
//musical notes in the tracker interface. (I8LN. "I Hate LaNguages"  :-P )
//
//TODO: Add a 'Blurb' tab to the program as a system component that loads text notes
//from a composition, displays them on loading a new composition and allows editing
//by the composer. (Fun)
//
//TODO: Make the help viewer have word wrap either by replacing the JLabel control or
//manually wrapping the text. (A fun self-contained problem).
//
//TODO: Optimise the audio routines in the audio thread and simple wire classes. Loop
//unrolling, SIMD, etc. (Java Guru)
//
//TODO: Add a mechanism and controls to show a hint for the currently selected column
//and cursor position in the tracker. (Miroslav?)
//
//TODO: Create a mechanism for showing message dialogs and filerequesters in the same
//font that the main window is currently using. (Swing)
//
//TODO: Improve the mechanism for registering event and audio providers, adding the
//ability to have multiples of each. (Hard)
//
//TODO: Implement global and track parameters for machine plugins, including the
//interface in the router and the composer. (Fun)
//
//TODO: Create the program's sample bank, with the ability to hold audio, envelopes,
//waveforms and other things as defined by registerable classes. (Good major
//project if you are ambitious).
//
//TODO: Implement the loading and saving of things in the sample bank, both as part
//of a composition and as external files, including (load only) support for things
//like MP3 files. (Library work, good on resume)
//
//TODO: Create the supporting routines/classes for the sample bank allowing easy use
//of sampled audio, waveforms or envelopes by machine plugin developers. (Write your
//own API, with my guidance)
//
//TODO: Implement basic locking of data between the main (GUI) thread and the audio
//thread (and any parameter window threads). (Learn parallel programming).
//
//TODO: Generalise the audio processing routines so that we can add wavelet audio to
//Vermilion. (Hard).
//
//TODO: Generalise the main event driving mechanisms to allow e.g. a video thread, video
//providers etc. (Harder).
//
//TODO: Examine the life cycle of ALL composition and runtime data for concurrency and
//locking problems. (Got parallel skills?)
//
//TODO: Try to understand the philosophy of Vermilion, and give me feedback on what you
//find confusing or what you would change. Note that there's little chance getting
//me to change my mind and rewrite things at this point, but I'll take any comments
//on board.

import java.util.ArrayList;

/**
 * Represents a wire in the document, by storing all relevant information
 * about the wire. The class extends UsefulFileObject so it can be written to
 * the document.
 */
public class WireNode extends UsefulFileObject
{
    /**
     * The name of the machine the wire we are representing 'reads from'.
     */
    public String input;

    /**
     * The name of the machine the wire we are representing 'writes to'.
     */
    public String output;

    /**
     * The channel selection of the wire we are representing.
     */
    public int channel = 0;

    /**
     * The left volume of the wire we are representing.
     */
    public float amplitudeL = 1.0f;

    /**
     * The right volume of the wire we are representing.
     */
    public float amplitudeR = 1.0f;

    /**
     * Constructs a new node representing the given wire.
     * @param w The wire we wish to represent in the document.
     */
    public WireNode(SimpleWire w)
    {
        if (w == null) return;

        // 'Serialise'
        input = w.input.machineID;
        output = w.output.machineID;
        channel = w.channel;
        amplitudeL = w.amplitudeL;
        amplitudeR = w.amplitudeR;
    }

    /**
     * The serialisation type for this object is 'WIRE'.
     */
    @Override
    public String getType() { return "WIRE"; }

    /**
     * The current serialisation version for this object is 1.
     * @return
     */
    @Override
    public int getVersion() { return 1; }

    /**
     * Loads a WireNode from the document.
     */
    @Override
    public UsefulFileObject loadImpl(String str, int version)
    {
        WireNode node = new WireNode(null);

        if (version == 1)
        {
            ArrayList<String> data = stringToList(str);

            if (data.size() >= 5)
            {
                node.input = data.get(0);
                node.output = data.get(1);
                node.amplitudeL = Float.parseFloat(data.get(2));
                node.amplitudeR = Float.parseFloat(data.get(3));
                node.channel = Integer.parseInt(data.get((4)));
            }
        }

        return node;
    }

    /**
     * Saves a WireNode to the document.
     */
    @Override
    public String saveImpl()
    {
        ArrayList<String> strs = new ArrayList<String>();

        strs.add(input);
        strs.add(output);
        strs.add(String.valueOf(amplitudeL));
        strs.add(String.valueOf(amplitudeR));
        strs.add(String.valueOf(channel));

        return listToString(strs);
    }
}
