using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Media; using SudokuWeek4.Models.Converters; using SudokuWeek4.Models; namespace SudokuWeek4.Models { public partial class LittleCell : UserControl, INotifyPropertyChanged { // Define a hashSet of the available options private readonly HashSet _options = new HashSet(); // Define a hashSet of the possible solutions private readonly HashSet _solutions = new HashSet(); // Define if the cell is selected private Boolean _selected; // This will hold the X and Y position of the cell public int X, Y; // Set the cell to be readOnly private Boolean _readOnly; // Set the cell fontColor private Color _fontColor; // Create a nullable int to check if the cell is already filled-in private int? _inputPlaced; // Create the OnPropertyChanged Event public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string name) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(name)); } // Create the constructor public LittleCell() { InitializeComponent(); // Set the color to the default color FontColor = Colors.Green; // Bind the currently selected cell Binding bind = new Binding("Selected"); bind.Source = this; bind.Converter = BorderValueConverter.Instance; smallBorder.SetBinding(Border.BorderBrushProperty, bind); // Bind the cell if there is a solution (possible) bind = new Binding("Solution"); bind.Source = this; bind.Converter = BackgroundValueConverter.Instance; this.SetBinding(BackgroundProperty, bind); // Set the columns and the rows of the Options to the size of the gameField optionsGrid.Columns = optionsGrid.Rows = BoardModel.GameFieldCount; for (int i = 1; i <= BoardModel.GameFieldSize; i++) { Grid child = new Grid(); child.Margin = new Thickness(2); optionsGrid.Children.Add(child); // Bind the available options to the cells (Cheat Mode) bind = new Binding("Options"); bind.Source = this; bind.Converter = OptionsValueConverter.Instance; bind.ConverterParameter = i; child.SetBinding(BackgroundProperty, bind); } // Bind if the grid was placed bind = new Binding("Determined"); bind.Source = this; bind.ConverterParameter = Constants.DefaultSmallCellFontColor; bind.Converter = Number2BrushValueConverter.Instance; inputGrid.SetBinding(BackgroundProperty, bind); // Bind if the inputGrid needs to be visible bind = new Binding("IsDetermined"); bind.Source = this; bind.Converter = VisibilityValueConverter.Instance; inputGrid.SetBinding(VisibilityProperty, bind); // Bind if the optionsGrid is determined bind = new Binding("IsDetermined"); bind.Source = this; bind.Converter = VisibilityValueConverter.Instance; bind.ConverterParameter = 0; optionsGrid.SetBinding(VisibilityProperty, bind); Clear(); } // This property will change the FontColor public Color FontColor { get { return _fontColor; } set { _fontColor = value; } } // This function will clear the cell public void Clear() { // Clear all the available options _options.Clear(); // Add all the available options to the optionsGrid for (int i = 1; i <= BoardModel.GameFieldSize; i++) _options.Add(i); _inputPlaced = null; _solutions.Clear(); Refresh(); } // Refresh all the bindings public void Refresh() { OnPropertyChanged(null); } // Create a property to get available Options (CheatMode) public HashSet Options { get { return _options; } } // Check if the cell can be set with a number public Boolean CanSet(int number) { if (BoardModel.CheatMode) return _options.Contains(number); else return true; } // Remove the number from the specified cell public void RemoveNumber(int number) { _inputPlaced = null; Refresh(); } // Add the option from the specified cell public void AddOption(int number) { _options.Add(number); Refresh(); } // Remove the option from the specified cell public void RemoveOption(int number) { _options.Remove(number); Refresh(); } // Create a property to check if the cell has a number public bool IsDetermined { get { return _inputPlaced.HasValue; } } // Create a property to get the current cellNumber public int Determined { get { return _inputPlaced.GetValueOrDefault(); } } // This method will make a decision on a specified cell public void MakeDecision(int number, Boolean hint = false, Boolean readOnly = false) { if (!_readOnly) { _inputPlaced = number; _readOnly = readOnly; if (readOnly || hint) { if (readOnly) { // Set the color of the font to the readOnly Font FontColor = Constants.DefaultSmallCellReadOnlyFontColor; } else if (hint) { // Set the color of the font to the hint Font FontColor = Constants.DefaultSmallCellHintFontColor; } // Rebind the cell (with the new color) Binding bind = new Binding("Determined"); bind.Source = this; bind.Converter = Number2BrushValueConverter.Instance; bind.ConverterParameter = FontColor; inputGrid.SetBinding(BackgroundProperty, bind); } Refresh(); } } // Create a property to check if the cell is readOnly public Boolean ReadOnly { get { return _readOnly; } } // Create a property to check if there is a solution public Boolean Solution { get { if (!BoardModel.CheatMode) return false; if (_inputPlaced.HasValue) return false; if (_solutions.Count > 1) return true; return _options.Count == 0; } } // Set the specified cell to a possible solution public void SetPossible(int cell) { _solutions.Add(cell); Refresh(); } // Create a property to check which cell is selected public Boolean Selected { get { return _selected; } set { if (value != _selected) { _selected = value; OnPropertyChanged("Selected"); } } } } }