// Window1.xaml.cs
using System;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Diagnostics;
using System.Collections;
using System.Data;
using System.Data.OleDb;
using System.ComponentModel;
using System.Xml;

namespace XmlBinding {

  public partial class Window1 : Window {

    // the family XML document
    XmlDocument doc;

    public Window1() {
      InitializeComponent();

      this.birthdayButton.Click += birthdayButton_Click;
      this.backButton.Click += backButton_Click;
      this.forwardButton.Click += forwardButton_Click;
      this.addButton.Click += addButton_Click;
      this.sortButton.Click += sortButton_Click;
      this.filterButton.Click += filterButton_Click;
      this.groupButton.Click += groupButton_Click;

      LoadFamilyXml();
    }

    void LoadFamilyXml() {
      // Load the XML using an XmlDocument
      doc = new XmlDocument();
      doc.Load("family.xml");

      // Make the namespace prefix mappings available for use in binding
      XmlNamespaceManager manager = new XmlNamespaceManager(doc.NameTable);
      manager.AddNamespace("sb", "http://sellsbrothers.com");
      Binding.SetXmlNamespaceManager(grid, manager);

      // Make the XML available for data binding. We use a binding here
      // because it will detect when the source document changes so it can
      // refresh the set of nodes returned by the XPath query
      Binding b = new Binding();
      b.XPath = "/sb:Family/sb:Person";
      b.Source = doc;
      grid.SetBinding(Grid.DataContextProperty, b);
    }

    ICollectionView GetFamilyView() {
      // The default view comes directly from the data
      return CollectionViewSource.GetDefaultView(grid.DataContext);
    }

    void birthdayButton_Click(object sender, RoutedEventArgs e) {
      ICollectionView view = GetFamilyView();

      // Each "person" is an XmlElement and data
      // values come from an string-based indexer
      XmlElement person = (XmlElement)view.CurrentItem;
      person.SetAttribute("Age",
        (int.Parse(person.Attributes["Age"].Value) + 1).ToString());
      MessageBox.Show(
        string.Format(
          "Happy Birthday, {0}, age {1}!",
          person.Attributes["Name"].Value,
          person.Attributes["Age"].Value),
        "Birthday");
    }

    void backButton_Click(object sender, RoutedEventArgs e) {
      ICollectionView view = GetFamilyView();
      view.MoveCurrentToPrevious();
      if( view.IsCurrentBeforeFirst ) {
        view.MoveCurrentToFirst();
      }
    }

    void forwardButton_Click(object sender, RoutedEventArgs e) {
      ICollectionView view = GetFamilyView();
      view.MoveCurrentToNext();
      if( view.IsCurrentAfterLast ) {
        view.MoveCurrentToLast();
      }
    }

    void addButton_Click(object sender, RoutedEventArgs e) {
      // Creating a new XmlElement
      XmlElement person = doc.CreateElement("Person", "http://sellsbrothers.com");
      person.SetAttribute("Name", "Chris");
      person.SetAttribute("Age", "37");
      doc.DocumentElement.AppendChild(person);
    }

    void sortButton_Click(object sender, RoutedEventArgs e) {
      ICollectionView view = GetFamilyView();
      if( view.SortDescriptions.Count == 0 ) {
        view.SortDescriptions.Add(
          new SortDescription("@Name", ListSortDirection.Ascending));
        view.SortDescriptions.Add(
          new SortDescription("@Age", ListSortDirection.Descending));
      }
      else {
        view.SortDescriptions.Clear();
      }
    }

    void filterButton_Click(object sender, RoutedEventArgs e) {
      ICollectionView view = GetFamilyView();

      if( view.Filter == null ) {
        view.Filter = delegate(object item) {
          return
            int.Parse(((XmlElement)item).Attributes["Age"].Value) > 25;
        };
      }
      else {
        view.Filter = null;
      }
    }

    void groupButton_Click(object sender, RoutedEventArgs e) {
      ICollectionView view = GetFamilyView();
      if( view.GroupDescriptions.Count == 0 ) {
        // Group by age
        view.GroupDescriptions.Add(new PropertyGroupDescription("@Age"));
      }
      else {
        view.GroupDescriptions.Clear();
      }
    }

  }

  public class AgeToForegroundConverter : IValueConverter {
    // Called when converting the Age to a Foreground brush
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
      Debug.Assert(targetType == typeof(Brush));

      // DANGER! After 25, it's all down hill...
      int age = int.Parse(value.ToString());
      return (age > 25 ? Brushes.Red : Brushes.Black);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
      // should not be called in our example
      throw new NotImplementedException();
    }
  }

}
