//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System;
using CommunityServer.Controls;
using System.Collections;
using System.ComponentModel;
using CommunityServer.Components;
using CA = ComponentArt.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI;

namespace CommunityServer.Blogs.Controls
{
	public interface INavigationBarItem
	{
		void Process(NavigationBar nb, CA.BaseMenuItem bmi, bool isSelected);
	}

	/// <summary>
	/// Enables CS to use TabStrip, Menu, and NavBar objects in a generic way
	/// </summary>
	public abstract class NavigationBar : WeblogThemedControl
	{
		//Menu "holder"
		protected Control theMenu = null;

		#region Skin Wireup
		protected override void AttachChildControls()
		{
			theMenu = FindControl("Menu");
			BindData();
		}
		#endregion

		#region Abstracts
		public abstract CA.BaseMenuItem CreateMenuItem { get;}
		protected abstract void SetSelected(CA.BaseMenuItem bmi);
		public abstract void AddMenuItem(CA.BaseMenuItem parent, CA.BaseMenuItem child);
		public abstract void AddMenuItem(CA.BaseMenuItem bmi);
		#endregion

		#region Data
		void BindData()
		{
			string cacheKey = "MainNavigationUrls-";
			string roleKey = CSContext.Current.RolesCacheKey;
			ArrayList links;

			// If no roleKey, then set it to "Everyone";
			if(roleKey == null)
				roleKey = "Everyone";

			// See if there is anything cached
			links = CSCache.Get(cacheKey+roleKey) as ArrayList;

			// If not, then calculate it and cache it
			if(links == null)
			{
				#region Determine and cache tab information

				links = new ArrayList();
				ArrayList tabUrls = Globals.GetSiteUrls().MainNavigationLinks;
				string[] roles = roleKey.ToLower().Split(',');

				if(ReverseItems)
				{
					links = links.Clone() as ArrayList;
					links.Reverse();
				}

				// Loop through the links to get the ones they are authorized for
				foreach(CSLink link in tabUrls)
				{
					bool authorized = false;

					// See if they are authorized for this link
					foreach(string role in roles)
					{
						if(link.Roles.ToLower().IndexOf(role.Trim()) != -1)
						{
							authorized = true;
							break;
						}
					}

					// Continue if they're not authorized
					if(authorized == false)
						continue;

					// Otherwise, add it to their links
					links.Add(link);
				}

				// Cache it
				CSCache.Insert(cacheKey+roleKey, links, CSCache.MinuteFactor * 15);

				#endregion
			}

			CA.BaseMenuItem bmi = null;
			foreach (CSLink link in links)
			{
				bmi = this.CreateMenuItem;
				bmi.NavigateUrl = link.NavigateUrl;
				bmi.Text = link.Text;

				this.AddMenuItem(bmi);
				bool isSelected = false;
				
				if (String.Compare(link.Name, this.SelectedItem, true) == 0)
				{
					this.SetSelected(bmi);
					isSelected = true;
				}
				INavigationBarItem inbi = link.NavigationItem as INavigationBarItem;
				if(inbi != null)
				{
					inbi.Process(this, bmi, isSelected);
				}
			}
			
		}
		#endregion

		#region Properties
		[
		Bindable(true),
		Category("Behavior"),
		Description("Gets or sets the selected item."),
		DefaultValue(""),
		]
		public string SelectedItem
		{
			get
			{
				Object state = ViewState["SelectedItem"];
				if(state == null)
					state = Context.Items["SelectedNavigation"];

				if(state == null)
					state = CSContext.Current.ApplicationType.ToString().ToLower() ; 
					
				return state == null ? "" : (string) state;
			}
			set
			{
				ViewState["SelectedItem"] = value;
			}
		}

		/// <summary>
		/// Gets or sets whether the top-level items should be in reverse order
		/// </summary>
		[
		Bindable(true),
		Category("Behavior"),
		Description("Gets or sets whether top-level items should be in reverse order"),
		DefaultValue(false),
		]
		public bool ReverseItems
		{
			get
			{
				Object state = ViewState["ReverseItems"];
				if ( state != null ) 
				{
					return (bool)state;
				}
				return false;
			}
			set 
			{
				ViewState["ReverseItems"] = value;
			}
		}
		#endregion
	}

	#region TabBar Implementation
	/// <summary>
	/// TabStrip implementation of NavigationBar
	/// </summary>
	public class TabBar : NavigationBar
	{
		private CA.TabStrip _ts;

		protected CA.TabStrip GetTabStrip
		{
			get
			{
				if(_ts == null)
					_ts = theMenu as CA.TabStrip;

				return _ts;
			}
		}

		public override CA.BaseMenuItem CreateMenuItem
		{
			get
			{
				return new CA.TabStripTab();
			}
		}

		public override void AddMenuItem(CA.BaseMenuItem bmi)
		{
			CA.TabStripTab tab = bmi as CA.TabStripTab;
			if(tab != null)
			{
				if(!Globals.IsNullorEmpty(tab.NavigateUrl) && tab.Text.IndexOf(tab.NavigateUrl)  == -1)
					tab.Text = GetText(tab.Text, tab.NavigateUrl);

				GetTabStrip.Tabs.Add(tab);
			}
		}


		public override void AddMenuItem(CA.BaseMenuItem parent, CA.BaseMenuItem child)
		{
			CA.TabStripTab tab = parent as CA.TabStripTab;
			if(tab != null)
			{
				CA.TabStripTab t2 = child as CA.TabStripTab;
				tab.Tabs.Add(t2);
			}
		}

		protected override void SetSelected(CA.BaseMenuItem bmi)
		{
			GetTabStrip.SelectedTab = (bmi as CA.TabStripTab);
		}

		protected string GetText(string t, string url)
		{
			return String.Format(@"<a href=""{0}"" onclick=""event.cancelBubble=true;"">{1}</a>",url, t);
		}

	}
	#endregion

	#region MenuBar Imeplementation
	/// <summary>
	/// Menu implementation of NavigationBar
	/// </summary>
	public class MenuBar : NavigationBar
	{
		private CA.Menu _menu;

		protected CA.Menu GetMenu
		{
			get
			{
				if(_menu == null)
					_menu = theMenu as CA.Menu;

				return _menu;
			}
		}

		public override CA.BaseMenuItem CreateMenuItem
		{
			get { return new CA.MenuItem(); }
		}

		protected override void SetSelected(CA.BaseMenuItem bmi)
		{
			GetMenu.SelectedItem = (bmi as CA.MenuItem);
		}

		public override void AddMenuItem(CA.BaseMenuItem parent, CA.BaseMenuItem child)
		{
			CA.MenuItem mi = parent as CA.MenuItem;
			if(mi != null)
			{
				CA.MenuItem mi2 = child as CA.MenuItem;
				if(mi2 != null)
					mi.Items.Add(mi2);
			}
		}

		public override void AddMenuItem(CA.BaseMenuItem bmi)
		{
			CA.MenuItem mi = bmi as CA.MenuItem;
			GetMenu.Items.Add(mi);
		}
	}
	#endregion

	#region RepeaterBar Implementation
	/// <summary>
	/// TabStrip implementation of NavigationBar
	/// </summary>
	public class RepeaterBar : NavigationBar
	{
		private ArrayList _data = new ArrayList();
		private Repeater _repeater;

		protected Repeater Repeater
		{
			get
			{
				if(_repeater == null)
					_repeater = theMenu as Repeater;

				return _repeater;
			}
		}

		public override CA.BaseMenuItem CreateMenuItem
		{
			get
			{
				return new RepeaterMenuBarItem();
			}
		}

		public override void AddMenuItem(CA.BaseMenuItem bmi)
		{
			RepeaterMenuBarItem item = bmi as RepeaterMenuBarItem;
			if(item != null)
			{
				_data.Add(item);
			}
		}

		public override void AddMenuItem(CA.BaseMenuItem parent, CA.BaseMenuItem child)
		{
			// not supported, ignore
		}

		protected override void SetSelected(CA.BaseMenuItem bmi)
		{
			RepeaterMenuBarItem item = bmi as RepeaterMenuBarItem;
			if (item != null)
				item.IsSelected = true;
		}

		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad (e);
			this.DataBind();
		}

		public override void DataBind()
		{
			EnsureChildControls();
			base.DataBind ();

			if (Repeater != null)
			{
				Repeater.DataSource = _data;
				Repeater.DataBind();
			}
		}

	}

	public class RepeaterMenuBarItem : CA.BaseMenuItem
	{
		private bool _isSelected = false;
		public new bool IsSelected
		{
			get
			{
				return _isSelected;
			}
			set
			{
				_isSelected = value;
			}
		}

		public RepeaterMenuBarItem() : base()
		{
		}
	}

	#endregion
}
