using System;
using System.Collections.Generic;
 
namespace DoFactory.GangOfFour.Strategy.RealWorld
{
  /// 
  /// MainApp startup class for Real-World 
  /// Strategy Design Pattern.
  /// 
  class MainApp
  {
    /// 
    /// Entry point into console application.
    /// 
    static void Main()
    {
      // Two contexts following different strategies
      SortedList studentRecords = new SortedList();
 
      studentRecords.Add("Samual");
      studentRecords.Add("Jimmy");
      studentRecords.Add("Sandra");
      studentRecords.Add("Vivek");
      studentRecords.Add("Anna");
 
      studentRecords.SetSortStrategy(new QuickSort());
      studentRecords.Sort();
 
      studentRecords.SetSortStrategy(new ShellSort());
      studentRecords.Sort();
 
      studentRecords.SetSortStrategy(new MergeSort());
      studentRecords.Sort();
 
      // Wait for user
      Console.ReadKey();
    }
  }
 
  /// 
  /// The 'Strategy' abstract class
  /// 
  abstract class SortStrategy
  {
    public abstract void Sort(List list);
  }
 
  /// 
  /// A 'ConcreteStrategy' class
  /// 
  class QuickSort : SortStrategy
  {
    public override void Sort(List list)
    {
      list.Sort(); // Default is Quicksort
      Console.WriteLine("QuickSorted list ");
    }
  }
 
  /// 
  /// A 'ConcreteStrategy' class
  /// 
  class ShellSort : SortStrategy
  {
    public override void Sort(List list)
    {
      //list.ShellSort(); not-implemented
      Console.WriteLine("ShellSorted list ");
    }
  }
 
  /// 
  /// A 'ConcreteStrategy' class
  /// 
  class MergeSort : SortStrategy
  {
    public override void Sort(List list)
    {
      //list.MergeSort(); not-implemented
      Console.WriteLine("MergeSorted list ");
    }
  }
 
  /// 
  /// The 'Context' class
  /// 
  class SortedList
  {
    private List _list = new List();
    private SortStrategy _sortstrategy;
 
    public void SetSortStrategy(SortStrategy sortstrategy)
    {
      this._sortstrategy = sortstrategy;
    }
 
    public void Add(string name)
    {
      _list.Add(name);
    }
 
    public void Sort()
    {
      _sortstrategy.Sort(_list);
 
      // Iterate over list and display results
      foreach (string name in _list)
      {
        Console.WriteLine(" " + name);
      }
      Console.WriteLine();
    }
  }
}