Menu.cs 4.91 KB
Newer Older
Andres Käver's avatar
Andres Käver committed
1
2
using System;
using System.Collections.Generic;
Andres Käver's avatar
menu    
Andres Käver committed
3
using System.Linq;
Andres Käver's avatar
Andres Käver committed
4
5
6
7
8

namespace MenuSystem
{
    public class Menu
    {
Andres Käver's avatar
menu    
Andres Käver committed
9
10
11
        private readonly EMenuLevel _menuLevel;

        private readonly List<MenuItem> _menuItems = new List<MenuItem>();
Andres Käver's avatar
menu    
Andres Käver committed
12
13
14
        private readonly MenuItem _menuItemExit = new MenuItem("E", "Exit", null);
        private readonly MenuItem _menuItemReturn = new MenuItem("R", "Return", null);
        private readonly MenuItem _menuItemMain = new MenuItem("M", "Main", null);
Andres Käver's avatar
menu    
Andres Käver committed
15
16

        private readonly HashSet<string> _menuShortCuts = new HashSet<string>();
Andres Käver's avatar
menu    
Andres Käver committed
17
18
19
        private readonly HashSet<string> _menuSpecialShortCuts = new HashSet<string>();

        private readonly string _title;
Andres Käver's avatar
Andres Käver committed
20
21
22
23

        private readonly Func<string> _getHeaderInfoString;

        public Menu(Func<string> getHeaderInfoString, string title, EMenuLevel menuLevel)
Andres Käver's avatar
menu    
Andres Käver committed
24
        {
Andres Käver's avatar
Andres Käver committed
25
            _getHeaderInfoString = getHeaderInfoString;
Andres Käver's avatar
menu    
Andres Käver committed
26
            _title = title;
Andres Käver's avatar
menu    
Andres Käver committed
27
            _menuLevel = menuLevel;
Andres Käver's avatar
menu    
Andres Käver committed
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

            switch (_menuLevel)
            {
                case EMenuLevel.Root:
                    _menuSpecialShortCuts.Add(_menuItemExit.ShortCut.ToUpper());
                    break;
                case EMenuLevel.First:
                    _menuSpecialShortCuts.Add(_menuItemReturn.ShortCut.ToUpper());
                    _menuSpecialShortCuts.Add(_menuItemMain.ShortCut.ToUpper());
                    _menuSpecialShortCuts.Add(_menuItemExit.ShortCut.ToUpper());
                    break;
                case EMenuLevel.SecondOrMore:
                    _menuSpecialShortCuts.Add(_menuItemReturn.ShortCut.ToUpper());
                    _menuSpecialShortCuts.Add(_menuItemMain.ShortCut.ToUpper());
                    _menuSpecialShortCuts.Add(_menuItemExit.ShortCut.ToUpper());
                    break;
            }
Andres Käver's avatar
menu    
Andres Käver committed
45
46
47
48
        }

        public void AddMenuItem(MenuItem item, int position = -1)
        {
Andres Käver's avatar
menu    
Andres Käver committed
49
50
51
52
            if (_menuSpecialShortCuts.Add(item.ShortCut.ToUpper()) == false)
            {
                throw new ApplicationException($"Conflicting menu shortcut {item.ShortCut.ToUpper()}");
            }
Andres Käver's avatar
Andres Käver committed
53

Andres Käver's avatar
menu    
Andres Käver committed
54
55
56
57
58
            if (_menuShortCuts.Add(item.ShortCut.ToUpper()) == false)
            {
                throw new ApplicationException($"Conflicting menu shortcut {item.ShortCut.ToUpper()}");
            }

Andres Käver's avatar
menu    
Andres Käver committed
59

Andres Käver's avatar
menu    
Andres Käver committed
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
            if (position == -1)
            {
                _menuItems.Add(item);
            }
            else
            {
                _menuItems.Insert(position, item);
            }
        }

        public void DeleteMenuItem(int position = 0)
        {
            _menuItems.RemoveAt(position);
        }

        public void AddMenuItems(List<MenuItem> items)
        {
            foreach (var menuItem in items)
            {
                AddMenuItem(menuItem);
            }
        }
Andres Käver's avatar
Andres Käver committed
82
83
84

        public string Run()
        {
Andres Käver's avatar
menu    
Andres Käver committed
85
86
87
88
89
90
91
92
93
94
95
            var runDone = false;
            var input = "";
            do
            {
                OutputMenu();
                Console.Write("Your choice:");
                input = Console.ReadLine()?.Trim().ToUpper();
                var isInputValid = _menuShortCuts.Contains(input);
                if (isInputValid)
                {
                    var item = _menuItems.FirstOrDefault(t => t.ShortCut.ToUpper() == input);
Andres Käver's avatar
Andres Käver committed
96
                    input = item?.RunMethod == null ? input : item.RunMethod();
Andres Käver's avatar
menu    
Andres Käver committed
97
                }
Andres Käver's avatar
Andres Käver committed
98

Andres Käver's avatar
menu    
Andres Käver committed
99
                runDone = _menuSpecialShortCuts.Contains(input);
Andres Käver's avatar
Andres Käver committed
100

Andres Käver's avatar
menu    
Andres Käver committed
101
102
103
104
105
106
107
                if (!runDone && !isInputValid)
                {
                    Console.WriteLine($"Unknown shortcut '{input}'!");
                }
            } while (!runDone);

            if (input == _menuItemReturn.ShortCut.ToUpper()) return "";
Andres Käver's avatar
Andres Käver committed
108

Andres Käver's avatar
menu    
Andres Käver committed
109
            return input;
Andres Käver's avatar
Andres Käver committed
110
111
112
113
        }

        private void OutputMenu()
        {
Andres Käver's avatar
menu    
Andres Käver committed
114
            Console.WriteLine("====> " + _title + " <====");
Andres Käver's avatar
Andres Käver committed
115
116
117
118
119
120
121
122
123
124
            if (_getHeaderInfoString != null)
            {
                var headerInfo = _getHeaderInfoString();
                if (headerInfo != null)
                {
                    Console.WriteLine(headerInfo);
                }
            }


Andres Käver's avatar
menu    
Andres Käver committed
125
            Console.WriteLine("-------------------");
Andres Käver's avatar
Andres Käver committed
126

Andres Käver's avatar
menu    
Andres Käver committed
127
            foreach (var t in _menuItems)
Andres Käver's avatar
Andres Käver committed
128
129
130
131
132
            {
                Console.WriteLine(t);
            }

            Console.WriteLine("-------------------");
Andres Käver's avatar
menu    
Andres Käver committed
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

            switch (_menuLevel)
            {
                case EMenuLevel.Root:
                    Console.WriteLine(_menuItemExit);
                    break;
                case EMenuLevel.First:
                    Console.WriteLine(_menuItemReturn);
                    Console.WriteLine(_menuItemExit);
                    break;
                case EMenuLevel.SecondOrMore:
                    Console.WriteLine(_menuItemReturn);
                    Console.WriteLine(_menuItemMain);
                    Console.WriteLine(_menuItemExit);
                    break;
            }

Andres Käver's avatar
menu    
Andres Käver committed
150
            Console.WriteLine("=====================");
Andres Käver's avatar
Andres Käver committed
151
152
153
        }
    }
}