using System;
using System.Diagnostics;
using System.IO;
using System.IO.Ports;
using System.Text;
using System.Timers;

namespace SSTServoPlayer
{
    public class Program
    {
        static INIFile Config;
        static string PathPrefix="/";
        static byte[] Signals;
        static SerialPort port = null;
        static System.Timers.Timer FrameTimer;
        static long index = 0;
        static int frameSkip = 6;

        static void Main(string[] args)
        {
            Config = INIFile.Load(args[0]);
            PathPrefix = Path.GetFullPath(args[0]).Replace("manifest.ini", "");
            Signals = File.ReadAllBytes(PathPrefix+Config.Data["data"]);
            port = new SerialPort(args[1], 9600, Parity.None, 8, StopBits.One);
            port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
            port.Open();
            FrameTimer = new System.Timers.Timer((1000d/double.Parse(Config.Data["frames-per-second"]))*frameSkip);
            FrameTimer.Elapsed += PlaySignal;
            FrameTimer.AutoReset = true;

            PlayAudio();
            FrameTimer.Start();
            Console.ReadLine();
            port.Close();
        }

        private static void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Console.Write(port.ReadExisting());
        }

        static void PlayAudio()
        {
            Process.Start("mpv", PathPrefix+Config.Data["audio"]);
        }

        static void PlaySignal(Object sender, ElapsedEventArgs e)
        {
            if (index == Signals.Length)
            {
                FrameTimer.Stop();
                Console.WriteLine("Complete!");
                return;
            }
            byte b = Signals[index];

            byte byte1 = (byte)(64 | ((b & 8) | (b & 4) | (b & 2) | (b & 1)));
            byte byte2 = (byte)(64 | (((b & 128) | (b & 64) | (b & 32) | (b & 16)) >> 4));
            port.Write(((char)byte1).ToString());
            port.Write(((char)byte2).ToString());
            //port.Write(((char)b).ToString());
            //Console.WriteLine(byte1.ToString("B8") + " " + byte2.ToString("B8"));
            index+=frameSkip;
        }
    }
}