using UnityEngine;
using System.Collections;
using System.IO.Ports;
/// <summary>
/// This is a very basic interface to the Arduino controller, make sure that you set API compatibility level
/// to ".Net 2.0", otherwise you cannot use the SerialPort class. The script takes values from the sliders and
/// propagats them to the controller, the port has to be specified manually. Actually, the .Net API provides
/// methods to search the ports for devices, however, the respective methods are not part of the Mono framework.
/// </summary>
[RequireComponent (typeof (SliderGUI))]
public class ArduinoConnector : MonoBehaviour
{
    // the port the Arduino controller is connected to
    public string Port;
    // the serial port instance we use to send data
    private static SerialPort serialPort;
    // user input is collected by this script
    private SliderGUI userInterface;
    // the actual values that we want to send
    private int value1 = -1;
    private int value2 = -1;
    private int value3 = -1;
    private int value4 = -1;
    private int value5 = -1;
    // initialization is done here: the port is set up and the connection is opened
    void Start()
    {
        // create the port with a baudrate of 9600
        ArduinoConnector.serialPort = new SerialPort(Port, 9600);
        // open up the actual connection
        this.OpenConnection();
        // to get the values, we obtain the GUI script, which is hopefully attached to the same game object
        this.userInterface = this.GetComponent<SliderGUI>();
    }

    void Update()
    {
        // the update method is called in every frame, that is, depending on your framerate every 16 ms;
        // here we send data in each frame, which is pretty ineffective. In a more complex application, you
        // only want to send data, if the values are changing
        this.sendData();
    }
    // opens the connection to the serial port
    public void OpenConnection()
    {
        if (ArduinoConnector.serialPort != null)
        {
            if (ArduinoConnector.serialPort.IsOpen)
            {
                ArduinoConnector.serialPort.Close();
                UnityEngine.Debug.Log("closing port, because it was already open...");
            }
            else
            {
                ArduinoConnector.serialPort.Open();
                ArduinoConnector.serialPort.ReadTimeout = 16;
                UnityEngine.Debug.Log("port opened...");
            }
        }
        else
        {
            if (ArduinoConnector.serialPort.IsOpen)
            {
                UnityEngine.Debug.Log("port is already open...");
            }
            else
            {
                UnityEngine.Debug.Log("port is null...");
            }
        }
    }
    // when terminating the application, we deactivate all motors
    void OnApplicationQuit()
    {
        string output = "0,0,0,0,0\n";
        ArduinoConnector.serialPort.Write(output);
        ArduinoConnector.serialPort.Close();
    }
    // we send the data, that is the slider values from the UI
    public void sendData()
    {
        int newVal1 = (int)this.userInterface.vSliderValue1;
        int newVal2 = (int)this.userInterface.vSliderValue2;
        int newVal3 = (int)this.userInterface.vSliderValue3;
        int newVal4 = (int)this.userInterface.vSliderValue4;
        int newVal5 = (int)this.userInterface.vSliderValue5;
		// only send when values actually change
        if (value1 != newVal1 || value2 != newVal2 || value3 != newVal3 || value4 != newVal4 || value5 != newVal5)
        {
            this.value1 = newVal1;
            this.value2 = newVal2;
            this.value3 = newVal3;
            this.value4 = newVal4;
            this.value5 = newVal5;
            string output = this.value1.ToString() + "," + this.value2.ToString() + "," + this.value3.ToString() + "," + this.value4.ToString() + "," + this.value5.ToString() + "\n";
            UnityEngine.Debug.Log("change motor activation to: " + this.value2.ToString() + "," + this.value3.ToString() + "," + this.value4.ToString() + "," + this.value5.ToString() + "...");
            ArduinoConnector.serialPort.Write(output);
        }
    }

}
