using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Chernobyl.DesignPatterns.Command
{
///
/// An that implements the composite design pattern
/// (see http://en.wikipedia.org/wiki/Composite_pattern) for
/// objects. This type takes in several
/// objects. When is called
/// on this class, it goes through it's list of objects
/// and invokes on them in FIFO (first in, first out)
/// order. When is called on this class, it goes through
/// it's list of objects and invokes
/// on them in LIFO (last in, first out) order. Note that
/// is only called if the instance supports undo.
///
public class CommandCollection : ICommand, ICollection
{
///
/// Initializes a new instance of the
/// class that uses an for implementing it's
/// collection.
///
public CommandCollection() : this(new List())
{ }
///
/// Initializes a new instance of the class.
///
/// The to use when
/// storing objects.
public CommandCollection(ICollection collection)
{
Collection = collection;
}
///
/// Calls on all of the
/// instances contained within this in
/// FIFO (first in, first out) order.
///
public void Execute()
{
foreach (ICommand command in Collection)
command.Execute();
}
///
/// Calls on all of the
/// instances contained within this in
/// LIFO (last in, first out) order. Note that this method will skip
/// s that do not support undo (i.e.,
/// is set to false).
///
/// Thrown if any
/// in this does not
/// support undo (i.e., is false).
public void Undo()
{
foreach (ICommand command in Collection.Where(comm => comm.CanUndo).Reverse())
command.Undo();
}
///
/// Adds an item to the .
///
/// The object to add to the
/// .
///
/// The is read-only.
///
public void Add(ICommand item)
{
Collection.Add(item);
}
///
/// Removes all items from the .
///
///
/// The is read-only.
///
public void Clear()
{
Collection.Clear();
}
///
/// Determines whether the contains a
/// specific value.
///
/// The object to locate in the
/// .
///
/// true if is found in the
/// ; otherwise, false.
///
public bool Contains(ICommand item)
{
return Collection.Contains(item);
}
///
/// Copies the elements of the to an
/// , starting at a particular
/// index.
///
/// The one-dimensional that is
/// the destination of the elements copied from .
/// The must have zero-based indexing.
/// The zero-based index in
/// at which copying begins.
/// is
/// null.
///
/// is less than 0.
/// is
/// multidimensional, is equal to or
/// greater than the length of , or the number of
/// elements in the source is greater than
/// the available space from to the end of
/// the destination .
///
public void CopyTo(ICommand[] array, int arrayIndex)
{
Collection.CopyTo(array, arrayIndex);
}
///
/// Removes the first occurrence of a specific object from the
/// .
///
/// The object to remove from the
/// .
///
/// true if was successfully removed from the
/// ; otherwise, false. This method also
/// returns false if is not found in the original
/// .
///
/// The
/// is read-only.
public bool Remove(ICommand item)
{
return Collection.Remove(item);
}
///
/// Returns an enumerator that iterates through the collection.
///
///
/// A that can be used to iterate through
/// the collection.
///
public IEnumerator GetEnumerator()
{
return Collection.GetEnumerator();
}
///
/// Returns an enumerator that iterates through a collection.
///
///
/// An object that can be used to iterate
/// through the collection.
///
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
///
/// True if at least one of the instances within
/// this can be reverted after a call to
/// , false if otherwise.
///
public bool CanUndo
{
get { return Collection.Any(comm => comm.CanUndo); }
}
///
/// Gets the number of elements contained in the .
///
///
///
/// The number of elements contained in the .
///
public int Count
{
get { return Collection.Count; }
}
///
/// Gets a value indicating whether the is
/// read-only.
///
///
/// true if the is read-only;
/// otherwise, false.
///
public bool IsReadOnly
{
get { return Collection.IsReadOnly; }
}
///
/// The collection of objects.
///
ICollection Collection { get; set; }
}
}