using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Web.Mvc.Navigation
{
///
/// This represents our navigation stack - used for allowing us to navigate backwards
/// through our web app.
///
public class NavigationManager
{
private const string sessionKey = "NAVIGATION__STACK";
public Stack NavigationItems { get; private set; }
// We store the stack in session - if it exists, we'll retrieve it, if it doesn't then
// we create an instance and add it to session
public NavigationManager()
{
if (HttpContext.Current.Session[sessionKey] != null)
{
NavigationItems = HttpContext.Current.Session[sessionKey] as Stack;
}
else
{
NavigationItems = new Stack();
Save();
}
}
public void Push(NavigationItem navigationItem, bool onlyComparePath)
{
// IF the item is already in the list - remove all items up to that point
if (NavigationItems.Any() && NavigationItems.Contains(navigationItem))
{
var matches = false;
while (matches == false)
{
if (NavigationItems.Peek().Equals(navigationItem))
{
matches = true;
break;
}
NavigationItems.Pop();
}
}
// If the item on the top matches the item being passed in, then pop it off,
// and replace it with the new one - as we're not interested in navigating
// back to the same page that we're already on! In addition, if we add a page
// and it then fails model validation, when we resubmit, it would get added
// again, if we didn't perform this logic.
if (onlyComparePath)
{
if (NavigationItems.Any() && NavigationItems.Peek().Path == navigationItem.Path)
{
NavigationItems.Pop();
}
}
else
{
if (NavigationItems.Any() && NavigationItems.Peek().Equals(navigationItem))
{
NavigationItems.Pop();
}
}
NavigationItems.Push(navigationItem);
Save();
}
public NavigationItem Pop()
{
if (!NavigationItems.Any()) return null;
if ((HttpContext.Current.Request.UrlReferrer != null)
&& (HttpContext.Current.Request.UrlReferrer.PathAndQuery == NavigationItems.Peek().Url)
&& (NavigationItems.Count() > 1))
{
NavigationItems.Pop();
}
if (!NavigationItems.Any()) return null;
var navigationItem = NavigationItems.Pop();
Save();
return navigationItem;
}
public void Clear()
{
NavigationItems.Clear();
Save();
}
private void Save()
{
HttpContext.Current.Session[sessionKey] = NavigationItems;
}
}
}