public AutomataProcessor(AutomataDefinition definition, AutomataGrid grid)
        {
            _definition = definition;

            _currentGrid = new AutomataGrid(definition.Neighbourhood == Neighbourhood.Moore, definition.Wrap);
            _backbufferGrid = new AutomataGrid(definition.Neighbourhood == Neighbourhood.Moore, definition.Wrap);

            _currentGrid.Resize(grid.Width, grid.Height);
            _backbufferGrid.Resize(grid.Width, grid.Height);

            for (int idxX = 0; idxX < _currentGrid.Width; ++idxX)
            {
                for (int idxY = 0; idxY < _currentGrid.Height; ++idxY)
                {
                    _currentGrid[idxX, idxY] = grid[idxX, idxY];
                }
            }
        }
        public void Load()
        {
            string filePath = Platform.OpenFileDialog("Save as...", "Cellular Automata (*.ca)|*.ca|All files|*.*");

            string dump = string.Empty;

            if (filePath != null)
            {
                using (var stream = new FileStream(filePath, FileMode.Open))
                {
                    AutomataGrid grid;
                    string formula;
                    if(AutomataFile.Load(stream, out formula, out grid))
                    {
                        _currentGrid = grid;
                        Formula.StringValue = formula;
                        ProcessFormula();

                        DisplayGrid.Value = grid;
                    }
                }
            }

            UpdateWidthAndHeightStrings();
        }
        AutomataGrid SwapGrids()
        {
            AutomataGrid backBufferGrid = _currentGrid;

            _currentGrid = _backbufferGrid;
            _backbufferGrid = backBufferGrid;

            return _currentGrid;
        }
        public static void Save(Stream stream, string formula, AutomataGrid grid)
        {
            StreamWriter writer = new StreamWriter(stream);

            string[] formulaLines = formula.Split('|', '\n');

            foreach(var line in formulaLines)
            {
                writer.WriteLine(line);
            }
            writer.WriteLine();
            writer.Flush();

            for(int idxY = 0; idxY < grid.Height; ++idxY)
            {
                string row = string.Empty;

                for(int idxX = 0; idxX < grid.Width; ++idxX)
                {
                    row += string.Format("{0} ", grid[idxX, idxY]);
                }

                writer.WriteLine(row);
                writer.Flush();
            }
        }
        public static bool Load(Stream stream, out string formula, out AutomataGrid grid)
        {
            formula = string.Empty;
            grid = null;

            var reader = new StreamReader(stream);

            string line = reader.ReadLine();

            while(line != null)
            {
                if(string.IsNullOrWhiteSpace(line))
                {
                    break;
                }

                formula += line + "|";
                line = reader.ReadLine();
            }

            formula = formula.TrimEnd('|');

            var rows = new List<List<byte>>();

            int width = 0;
            int height = 0;

            line = reader.ReadLine();
            while (line != null)
            {
                if (string.IsNullOrWhiteSpace(line))
                {
                    break;
                }

                var row = new List<byte>();
                rows.Add(row);

                height++;

                string[] values = line.Split(' ', '\t');

                foreach(var value in values)
                {
                    if(string.IsNullOrWhiteSpace(value))
                    {
                        continue;
                    }

                    byte state;
                    byte.TryParse(value, out state);

                    row.Add(state);
                    width = Math.Max(width, row.Count);
                }

                line = reader.ReadLine();
            }

            grid = new AutomataGrid();

            if (width > 0 && height > 0)
            {
                grid.Resize(width, height);
            }

            for (int idxY = 0; idxY < rows.Count; ++idxY)
            {
                var row = rows[idxY];

                for (int idxX = 0; idxX < row.Count; ++idxX)
                {
                    byte state = row[idxX];
                    grid[idxX, idxY] = state;
                }
            }

            return true;
        }