using System.Globalization;
using System.Xml.Schema;
using Turing.Model;

class Program
{
    private static void wyświetlProgram(Turing.Model.Program program)
    {
        Console.WriteLine("Program:");
        foreach(var czwórka in program.Czwórki)
            Console.WriteLine(czwórka.ToString());
    }

    private static void wyświetlStanMaszyny(StanMaszyny stanMaszyny, bool uproszczone = false)
    {
        Console.WriteLine($"Taśma: {stanMaszyny.ToString()}");
        if (!uproszczone)
        {
            Console.WriteLine($"Stan głowicy: {stanMaszyny.StanGłowicy}");
            Console.WriteLine($"Indeks głowicy: {stanMaszyny.IndeksGłowicy}");
        }
    }

    public static bool analizujArgumentyLiniiKomend(out string ścieżkaPlikuMaszyny, out string ścieżkaPlikuProgramu)
    {
        Console.WriteLine("Linia polecenia: " + Environment.CommandLine);
        string[] argumentyLiniiKomend = Environment.GetCommandLineArgs();

        if (argumentyLiniiKomend.Length < 3)
        {
            Console.Error.WriteLine("Nieodpowiednia liczba argumentów");
            ścieżkaPlikuMaszyny = null;
            ścieżkaPlikuProgramu = null;
            return false;
        }

        foreach (string argument in argumentyLiniiKomend)
            Console.WriteLine(argument);
        ścieżkaPlikuMaszyny = argumentyLiniiKomend[1];
        ścieżkaPlikuProgramu = argumentyLiniiKomend[2];
        return true;
    }


    //private static void Main(string[] args)
    private static void Main()
    {
        Console.WriteLine("Turing");

        string ścieżkaPlikuMaszyny, ścieżkaPlikuProgramu;
        bool powodzenie = analizujArgumentyLiniiKomend(out ścieżkaPlikuMaszyny, out ścieżkaPlikuProgramu);
        if (!powodzenie) Environment.Exit(1);

        Turing.Model.Turing maszynaTuringa = null;
        try
        {
            //maszynaTuringa = new Turing.Model.Turing("taśma.txt", "program.txt");
            maszynaTuringa = new Turing.Model.Turing(ścieżkaPlikuMaszyny, ścieżkaPlikuProgramu);
            wyświetlStanMaszyny(maszynaTuringa.StanMaszyny);
            wyświetlProgram(maszynaTuringa.Program);
        }
        catch (TuringException exc) 
        {
            Console.Error.WriteLine("Błąd przy próbie inicjacji maszyny Turinga: " + exc.Message);                        
        }
        catch(Exception exc)
        {
            Console.Error.WriteLine("Nierozpoznany typ błędu: " + exc.Message);            
        }

        if (maszynaTuringa == null)
        {
            Console.Error.WriteLine("Nie udało się zainicjować maszyny Turinga");
            Environment.Exit(1);
        }

        //zdarzenie
        maszynaTuringa.InstrukcjaWykonana +=
            (object _sender, Turing.Model.Turing.DaneInstrukcjiEventArgs _e) =>
            {
                Console.WriteLine(_e.WykonywanaInstrukcja.ToString());
                wyświetlStanMaszyny(maszynaTuringa.StanMaszyny, true);
            };

        //wykonywanie programu
        Console.WriteLine("\nUruchamiam program...");
        maszynaTuringa.Uruchom();
        wyświetlStanMaszyny(maszynaTuringa.StanMaszyny);
        Console.WriteLine("Zakończono wykonywanie programu");
    }
}
