using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.IO;
using System.Linq;
using Vanara.Collections;
using Vanara.Extensions;
using static Vanara.PInvoke.Shell32;
namespace Vanara.Windows.Shell
{
/// The navigation log is a history of the locations visited by a shell view object.
public class ShellNavigationHistory : IHistory
{
private readonly History pidls = new();
/// Initializes a new instance of the class.
public ShellNavigationHistory()
{
pidls.CollectionChanged += (s, e) => CollectionChanged?.Invoke(this, e);
pidls.PropertyChanged += (s, e) => PropertyChanged?.Invoke(this, e);
}
/// Occurs when an item is added, removed, changed, moved, or the entire list is refreshed.
public event NotifyCollectionChangedEventHandler CollectionChanged;
/// Occurs when a property value changes.
public event PropertyChangedEventHandler PropertyChanged;
/// Indicates the presence of items in the history that can be reached by calling .
/// if this instance can seek backward; otherwise, .
public bool CanSeekBackward => pidls.CanSeekBackward;
/// Indicates the presence of items in the history that can be reached by calling .
/// if this instance can seek forward; otherwise, .
public bool CanSeekForward => pidls.CanSeekForward;
/// Gets the items in the history.
/// The number of items.
public int Count => pidls.Count;
/// Gets the shell object in the Locations collection pointed to by CurrentLocationIndex.
public ShellItem Current => new(pidls.Current);
///
/// Adds the specified item as the last history entry and sets the property to
/// it's value.
///
/// The item to add to the history.
public void Add(ShellItem item) => pidls.Add(item.PIDL, true);
/// Clears the history of all items.
public void Clear() => pidls.Clear();
/// Returns an enumerator that iterates through the collection.
/// A that can be used to iterate through the collection.
public IEnumerator GetEnumerator() => pidls.Select(p => new ShellItem(p)).GetEnumerator();
/// Gets a specified number of items starting at a location within the history.
/// The maximum number of items to retrieve. The actual number of items returned may be less if not avaialable.
/// The reference point within the history at which to start fetching items.
/// A read-only list of items.
public IReadOnlyList GetItems(int count, SeekOrigin origin) => (IReadOnlyList)new List(pidls.GetItems(count, origin).Select(ShIFromPIDL));
///
/// Seeks through the history a given number of items starting at a known location within the history. This updates the property.
///
/// The number of items to move. This value can be negative to search backwards or positive to search forwards.
/// The reference point within the history at which to start seeking.
/// The value at the new current pointer position.
public ShellItem Seek(int count, SeekOrigin origin) => ShIFromPIDL(pidls.Seek(count, origin));
/// Seeks one position backwards.
/// The value at the new current pointer position.
public ShellItem SeekBackward() => ShIFromPIDL(pidls.SeekBackward());
/// Seeks one position forwards.
/// The value at the new current pointer position.
public ShellItem SeekForward() => ShIFromPIDL(pidls.SeekForward());
///
/// Adds the specified item as the last history entry and sets the property to
/// it's value.
///
/// The item to add to the history.
///
/// indicates to remove all items forward of the current pointer; leaves the history intact.
///
void IHistory.Add(ShellItem item, bool removeForwardItems) => pidls.Add(item?.PIDL, removeForwardItems);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
internal void Add(PIDL pidl) => pidls.Add(pidl, true);
private static ShellItem ShIFromPIDL(PIDL pidl) => pidl is null ? null : new ShellItem(pidl);
}
}