using System;
using System.Collections.Generic;


namespace A1560ApiTestCsharpApp
{

    class MenuItem
    {
        public string Description;
        public char CharacterToInvoke;
        public Action Action;
    }

    class ProgramMenuLoop
    {
        public readonly object ConsoleLock = new object();
        private  List<MenuItem> _deviceCommands;
        private  List<MenuItem> _deviceParameters;

        public ProgramMenuLoop(List<MenuItem> deviceCommands, List<MenuItem> deviceParameters)
        {
            _deviceCommands = deviceCommands;
            _deviceParameters = deviceParameters;
            //Extend main menu with an option to display parameters menu 
            _deviceCommands.Add(new MenuItem{Description = "Set device parameters", Action = RunParameterMenuLoop, CharacterToInvoke = '6'});
        }
        

        public void RunMainMenuLoop()
        {
            MenuLoop(_deviceCommands);
        }

        private void RunParameterMenuLoop()
        {
            MenuLoop(_deviceParameters);
        }

        // the loop is: displaying list of possible actions -> waiting for user input -> performing the action selected by user (or leaving on ESC)
        private void MenuLoop(List<MenuItem> menuItems)
        {
            while (true)
            {
                
                lock (ConsoleLock)
                {
                    ShowMenuItems(menuItems);
                    Console.CursorTop = Console.WindowTop + Console.WindowHeight/2;
                    Console.CursorLeft = 0;
                    Console.WriteLine("Please select menu item (ESC to exit): ");
                }

                var userKey = Console.ReadKey();
                if (userKey.Key == ConsoleKey.Escape)
                {
                    Console.Clear();
                    break; //user wants to live current menu
                }
                foreach (var menuItem in menuItems)
                {
                    
                    if (userKey.KeyChar == menuItem.CharacterToInvoke)
                    {
                        PerformAction(menuItem);
                        break;
                    }
                }

            }
            
        }

        private void PerformAction(MenuItem menuItem)
        {

                try
                {
                    lock (ConsoleLock)
                    {
                        Console.Clear();
                        Console.Write($"{menuItem.Description}: ");
                    }

                    menuItem.Action();
                    lock (ConsoleLock)
                    {
                        Console.Write("OK");
                    }
                }
                catch (Exception ex)
                {
                    lock (ConsoleLock)
                    {
                        Console.WriteLine();
                        Console.WriteLine($"{ex.GetType()} exception: {ex.Message}");
                    }
                }

                lock (ConsoleLock)
                {
                    Console.CursorTop = Console.WindowTop + Console.WindowHeight / 2;
                    Console.CursorLeft = 0;
                    Console.WriteLine("Press any key");
                }


                Console.ReadKey();

        }

        private void ShowMenuItems(List<MenuItem> menuItems)
        {
            Console.Clear();
            {
                foreach (var menuItem in menuItems)
                {
                    Console.WriteLine($"{menuItem.CharacterToInvoke}: {menuItem.Description}" );
                }
            }

        }


 
    }
}