/// <summary>Handles the SpeechRecognized event of the engine control.</summary>
void engine_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
	if (e.Result.Text == "regarde a gauche")
	{
		TrySetTarget("00074672", 0, 1000 * 4);  
		TrySetTarget("00074672", 1, 1000 * 4);  
		Synth.SpeakAsync("Je regarde a gauche");
	}
	if (e.Result.Text == "regarde a droite")
	{
		TrySetTarget("00074672", 0, 1600 * 4); 
		TrySetTarget("00074672", 1, 1600 * 4);
		Synth.SpeakAsync("Je regarde a droite");
	}
	if (e.Result.Text == "regarde en fasse")
	{
		TrySetTarget("00074672", 0, 1300 * 4);
		TrySetTarget("00074672", 1, 1300 * 4);
		Synth.SpeakAsync("Je regarde en fasse");
	}
	if (e.Result.Text == "louche comme un homme")
	{
		TrySetTarget("00074672", 0, 1000 * 4);
		TrySetTarget("00074672", 1, 1600 * 4);
		Synth.SpeakAsync("Je louche comme un homme");
	}
	if (e.Result.Text == "louche comme un extraterrestre")
	{
		TrySetTarget("00074672", 0, 1600 * 4);
		TrySetTarget("00074672", 1, 1000 * 4);
		Synth.SpeakAsync("Je louche comme un extraterrestre");
	}
}

/// <summary>
/// Handles the AudioLevelUpdated event of the engine control.
/// </summary>
void engine_AudioLevelUpdated(object sender, AudioLevelUpdatedEventArgs e)
{
    prgLevel.Value = e.AudioLevel;
}

/// <summary>
/// Loads the grammar and commands.
/// </summary>
private void loadGrammarAndCommands()
{
    try
    {
        Choices texts = new Choices();
        string[] lines = File.ReadAllLines(Environment.CurrentDirectory + 
			"\\example.txt");
        foreach (string line in lines)
        {
            // skip commentblocks and empty lines..
            if (line.StartsWith("--") || line == String.Empty) continue;

            // split the line
            var parts = line.Split(new char[] { '|' });

// add commandItem to the list for later lookup or execution
words.Add(new Word() { 
Text = parts[0], AttachedText = parts[1], IsShellCommand = (parts[2] == "true") 
});

            // add the text to the known choices of speechengine
            texts.Add(parts[0]);
        }
        Grammar wordsList = new Grammar(new GrammarBuilder(texts));
        speechRecognitionEngine.LoadGrammar(wordsList);
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

/// <summary>Attempts to set the target of a channel.</summary>
/// <param name="channel">Channel number from 0 to 23.<param>
/// <param name="target">
///   Target, in units of quarter microseconds.  For typical servos,
///   6000 is neutral and the acceptable range is 4000-8000.
/// </param>
void TrySetTarget(string DeviceId, Byte channel, UInt16 target)
{
    try
    {
		// Find a device and temporarily connect.
        using (Usc device = connectToDevice(DeviceId))  
        {
            device.setTarget(channel, target);

            // device.Dispose() is called automatically 
			// when the "using" block ends, allowing 
			//other functions and processes to use the device.
        }
    }
	// Handle exceptions by displaying them to the user.
    catch (Exception exception)  
    {
        displayException(exception);
    }
}

void TrySetSpeedAndTarget(string DeviceId, 
	Byte channel, 
	UInt16 speed, 
	UInt16 target)
{
    try
    {
        using (Usc device = connectToDevice(DeviceId))
        {
            device.setSpeed(channel, speed);
            device.setTarget(channel, target);
        }
    }
	// Handle exceptions by displaying them to the user.
    catch (Exception exception)  
    {
        displayException(exception);
    }
}

/// <summary>
/// Connects to a Maestro using native USB and returns the Usc object
/// representing that connection.  When you are done with the
/// connection, you should close it using the Dispose() method so that
/// other processes or functions can connect to the device later.  The
/// "using" statement can do this automatically for you.
/// </summary>
Usc connectToDevice(string DeviceId)
{
    // Get a list of all connected devices of this type.
    List<DeviceListItem> connectedDevices = Usc.getConnectedDevices();

    foreach (DeviceListItem dli in connectedDevices)
    {
        // If you have multiple devices connected and want to select a particular
        // device by serial number, you could simply add a line like this:
        if (dli.serialNumber == DeviceId)
        {
            Usc device = new Usc(dli); // Connect to the device.
            return device;             // Return the device.
        }

        if (dli.serialNumber == DeviceId)
        {
            Usc device = new Usc(dli); // Connect to the device.
            return device;             // Return the device.
        }

    }
    throw new Exception("Could not find device. " +
			"Make sure it is plugged in to USB " +
			"and check your Device Manager (Windows) " +
			"or run lsusb (Linux).");
}

/// <summary>
/// Displays an exception to the user by popping up a message box.
/// </summary>
void displayException(Exception exception)
{
    StringBuilder stringBuilder = new StringBuilder();
    do
    {
        stringBuilder.Append(exception.Message + "  ");
        if (exception is Win32Exception)
        {
        stringBuilder.Append("Error code 0x" +
		((Win32Exception)exception).NativeErrorCode.ToString("x") + ".  ");
        }
        exception = exception.InnerException;
    }
    while (exception != null);
    MessageBox.Show(
		stringBuilder.ToString(), 
		this.Text, 
		MessageBoxButtons.OK, 
		MessageBoxIcon.Error
	);
}