namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter12.Listing12_02
{
    using System;
    using System.Collections.Generic;

    public class Program
    {
        public static void Main()
        {
            Program p;

            p = new Program();
            p.Sketch();
        }

        public void Sketch()
        {

            Stack<Cell> path = new Stack<Cell>();
            Cell currentPosition;
            ConsoleKeyInfo key;  // Typ dodany w wersji C# 2.0.

            Console.WriteLine("Używaj strzałek do rysowania. X zamyka program.");
            for(int i = 2; i < Console.WindowHeight; i++)
            {
                Console.WriteLine();
            }

            currentPosition = new Cell(Console.WindowWidth / 2, Console.WindowHeight / 2);
            path.Push(currentPosition);
            FillCell(currentPosition);

            do
            {
                // Rysowanie kreski w kierunku określonym przez
                // strzałkę wciśniętą przez użytkownika.
                key = Move();

                switch(key.Key)
                {
                    case ConsoleKey.Z:
                        // Wymazanie ostatnio narysowanego elementu.
                        if (path.Count >= 1)
                        {
                            currentPosition = (Cell)path.Pop();
                            Console.SetCursorPosition(
                                currentPosition.X, currentPosition.Y);
                            FillCell(currentPosition, ConsoleColor.Black);
                            Undo();
                        }
                        break;
                    case ConsoleKey.DownArrow:
                        if(Console.CursorTop < Console.WindowHeight - 2)
                        {
                            currentPosition = new Cell(
                                Console.CursorLeft, Console.CursorTop + 1);
                        }
                        path.Push(currentPosition);
                        FillCell(currentPosition);
                        break;
                    case ConsoleKey.UpArrow:
                        if(Console.CursorTop > 1)
                        {
                            currentPosition = new Cell(
                                Console.CursorLeft, Console.CursorTop - 1);
                        }
                        path.Push(currentPosition);
                        FillCell(currentPosition);
                        break;
                    case ConsoleKey.LeftArrow:
                        if(Console.CursorLeft > 1)
                        {
                            currentPosition = new Cell(
                                Console.CursorLeft - 1, Console.CursorTop);
                        }
                        path.Push(currentPosition);
                        FillCell(currentPosition);
                        break;
                    case ConsoleKey.RightArrow:
                        // SaveState()
                        if(Console.CursorLeft < Console.WindowWidth - 2)
                        {
                            currentPosition = new Cell(
                                Console.CursorLeft + 1, Console.CursorTop);
                        }
                        path.Push(currentPosition);
                        FillCell(currentPosition);
                        break;

                    default:
                        Console.Beep();  // Dodane w wersji C# 2.0.
                        break;
                }

            }
            while(key.Key != ConsoleKey.X);  // Klawisz X pozwala zamknąć program.
        }

        private static ConsoleKeyInfo Move()
        {
            return Console.ReadKey(true);
        }

        private static void Undo()
        {
            // Namiastka
        }

        private static void FillCell(Cell cell)
        {
            FillCell(cell, ConsoleColor.White);
        }

        private static void FillCell(Cell cell, ConsoleColor color)
        {
            Console.SetCursorPosition(cell.X, cell.Y);
            Console.BackgroundColor = color;
            Console.Write(' ');
            Console.SetCursorPosition(cell.X, cell.Y);
            Console.BackgroundColor = ConsoleColor.Black;
        }
    }

    public struct Cell
    {
        // W wersjach starszych niż C# 6.0 należy użyć pola tylko do odczytu.
        public int X { get; }
        public int Y { get; }

        public Cell(int x, int y)
        {
            X = x;
            Y = y;
        }
    }
}
