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

using System;
using System.Collections;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using CommunityServer.Controls;

namespace CommunityServer.Galleries.Controls
{
	/// <summary>
	/// Summary description for PagingControl.
	/// </summary>
	public class PagingControl : GalleryThemedControl
	{

		#region Child Controls

		private IText prefix;
		private IButton prevButton;
		private Repeater pageRepeater;
		private IButton nextButton;
		private IText truncateOf;
		private IButton totalButton;

		#endregion

		#region Public Properties

		[DefaultValue( "" )]
		public virtual string QueryName
		{
			get
			{
				Object state = ViewState["QueryName"];
				if(state != null)
					return (string)state;
				return string.Empty;
			}
			set { ViewState["QueryName"] = value; }
		}

		[DefaultValue( "" )]
		public virtual string NavigateUrl
		{
			get
			{
				Object state = ViewState["NavigateUrl"];
				if(state != null)
					return (string)state;
				return string.Empty;
			}
			set { ViewState["NavigateUrl"] = value; }
		}

		[DefaultValue( "" )]
		protected virtual string BaseUrl
		{
			get
			{
				Object state = ViewState["BaseUrl"];
				if(state != null)
					return (string)state;
				return string.Empty;
			}
			set { ViewState["BaseUrl"] = value; }
		}

		[DefaultValue( "" )]
		public virtual string PrefixText
		{
			get
			{
				Object state = ViewState["PrefixText"];
				if(state != null)
					return (string)state;
				return string.Empty;
			}
			set { ViewState["PrefixText"] = value; }
		}

		[DefaultValue( false )]
		public virtual bool UseClickEvent
		{
			get
			{
				Object state = ViewState["UseClickEvent"];
				if(state != null)
					return (bool)state;
				return false;
			}
			set { ViewState["UseClickEvent"] = value; }
		}

		[DefaultValue( false )]
		public virtual bool VisibleOnOnePage
		{
			get
			{
				Object state = ViewState["VisibleOnOnePage"];
				if(state != null)
					return (bool)state;
				return false;
			}
			set { ViewState["VisibleOnOnePage"] = value; }
		}

		[DefaultValue( true )]
		public virtual bool TruncatePages
		{
			get
			{
				Object state = ViewState["TruncatePages"];
				if(state != null)
					return (bool)state;
				return true;
			}
			set { ViewState["TruncatePages"] = value; }
		}

		[DefaultValue( 5 )]
		public virtual int TruncateCount
		{
			get
			{
				Object state = ViewState["TruncateCount"];
				if(state != null)
					return (int)state;
				return 5;
			}
			set { ViewState["TruncateCount"] = value; }
		}

		[DefaultValue( 1 )]
		public virtual int CurrentPage
		{
			get
			{
				Object state = ViewState["CurrentPage"];
				if(state != null)
					return (int)state;
				return 1;
			}
			set
			{
				ViewState["CurrentPage"] = value;
				SelectedPage = value;
			}
		}

		[DefaultValue( 1 )]
		public virtual int TotalPages
		{
			get
			{
				Object state = ViewState["TotalPages"];
				if(state != null)
					return (int)state;
				return 1;
			}
			set { ViewState["TotalPages"] = value; }
		}

		[DefaultValue( 1 )]
		public virtual int SelectedPage
		{
			get
			{
				Object state = ViewState["SelectedPage"];
				if(state != null)
					return (int)state;
				return 1;
			}
			set { ViewState["SelectedPage"] = value; }
		}

		#endregion

		#region Skin

		protected override void AttachChildControls()
		{
			prefix = FindText( "Prefix" );
			prevButton = FindButton( "PrevButton" );
			pageRepeater = (Repeater)FindControl( "PageRepeater" );
			nextButton = FindButton( "NextButton" );
			truncateOf = FindText( "TruncateOf" );
			totalButton = FindButton( "TotalButton" );

			pageRepeater.ItemDataBound += new RepeaterItemEventHandler(pageRepeater_ItemDataBound);
			pageRepeater.ItemCommand += new RepeaterCommandEventHandler(pageRepeater_ItemCommand);
			prevButton.Click += new EventHandler(page_Click);
			nextButton.Click += new EventHandler(page_Click);
			totalButton.Click += new EventHandler(page_Click);
		}

		#endregion

		#region Event Overrides

		protected override void OnLoad(System.EventArgs e)
		{
			base.OnLoad(e);
			if(!Page.IsPostBack)
				DataBind();
		}
		
		public override void DataBind()
		{
			base.DataBind();
			BindData();
		}

		#endregion

		public void BindData()
		{
			// If we only have one page, we might not need to show this control
			if((TotalPages <= 1) && !VisibleOnOnePage)
				this.Visible = false;
			else
				this.Visible = true;

			// Configure the Url
			BaseUrl = NavigateUrl;
			if(BaseUrl.IndexOf("?") != -1)
			{
				bool hasPart = false;
				string queryString = BaseUrl.Substring( BaseUrl.IndexOf("?") + 1 );
				string[] parts = queryString.Split('&');
				for(int i = 0 ; i < parts.Length ; i++)
				{
					if(parts[i].StartsWith(QueryName))
					{
						parts[i] = QueryName + "={0}";
						hasPart = true;
					}
				}
				if(hasPart == true)
					BaseUrl = BaseUrl.Replace(queryString, string.Join("&", parts));
				else
					BaseUrl = BaseUrl.Replace(queryString, string.Join("&", parts) + "&" + QueryName + "={0}");
			}
			else
				BaseUrl = BaseUrl + "?" + QueryName + "={0}";

			// Variables
			int startPage = 1;
			int endPage = TotalPages;
			bool doTruncating = false;

			if((TruncatePages) && (TotalPages > TruncateCount))
			{
				doTruncating = true;

				// Find the start page
				if((CurrentPage - (TruncateCount / 2)) <= 1)
					startPage = 1;
				else
					startPage = CurrentPage - (TruncateCount / 2);

				// Find the end page
				if((startPage + TruncateCount) <= TotalPages)
					endPage = startPage + TruncateCount - 1;
				else
					startPage = TotalPages - TruncateCount + 1;
			}

			// Add the prefix
			if(prefix != null)
				prefix.Text = PrefixText;

			// Add the Prev link
			if(prevButton != null)
			{
				if(CurrentPage > 1)
				{
					prevButton.Text = "&lt;&lt;";
					prevButton.CommandArgument = (CurrentPage - 1).ToString();
					prevButton.Visible = true;
					prevButton.CausesValidation = false;
				}
				else
					prevButton.Visible = false;
			}
			// Loop through and add the pages
			ArrayList pages = new ArrayList();
			for(int i = startPage ; i <= endPage ; i++)
				pages.Add(i.ToString());
			pageRepeater.DataSource = pages;
			pageRepeater.DataBind();

			// Add the Next link
			if(nextButton != null)
			{
				if(CurrentPage < TotalPages)
				{
					nextButton.Text = "&gt;&gt;";
					nextButton.CommandArgument = (CurrentPage + 1).ToString();
					nextButton.Visible = true;
					nextButton.CausesValidation = false;
				}
				else
					nextButton.Visible = false;
			}
			// Add the "of x" text
			if(totalButton != null)
			{
				if(doTruncating)
				{
					totalButton.Text = TotalPages.ToString();
					totalButton.CommandArgument = TotalPages.ToString();
					totalButton.Visible = true;
					totalButton.CausesValidation = false;
					if(truncateOf != null)
						truncateOf.Visible = true;
				}
				else
				{
					totalButton.Visible = false;
					if(truncateOf != null)
						truncateOf.Visible = false;
				}
			}
		}

		private void pageRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
		{
			string page = e.Item.DataItem as string;

			switch(e.Item.ItemType)
			{
				case ListItemType.Item:
				case ListItemType.AlternatingItem:

					if(CurrentPage.ToString() != page)
					{
						LinkButton pageButton = (LinkButton)e.Item.FindControl( "PageButton" );
						if( pageButton != null)
						{
							pageButton.Text = page;
							pageButton.CommandArgument = page;
							pageButton.CausesValidation = false;
							pageButton.Click += new EventHandler(page_Click);
						}
					}
					else
					{
						e.Item.Controls.Clear();
						e.Item.Controls.Add( new LiteralControl( "<span class=\"currentPage\">" + page + "</span>" ) );
					}

					break;
			}
		}

		private void pageRepeater_ItemCommand(object source, RepeaterCommandEventArgs e)
		{
			int page = int.Parse((string)e.CommandArgument);

			if(UseClickEvent)
			{
				if(SelectedPage != page)
				{
					SelectedPage = page;
					OnPageChange(e);
				}
			}
			else
			{
				string url = string.Format(BaseUrl, page);
				Page.Response.Redirect( url, true );
			}
		}

		private void page_Click(object sender, EventArgs e)
		{
			LinkButton button = (LinkButton)sender;
			int page = int.Parse(button.CommandArgument);

			if(UseClickEvent)
			{
				if(SelectedPage != page)
				{
					SelectedPage = page;
					OnPageChange(e);
				}
			}
			else
				Page.Response.Redirect( string.Format(BaseUrl, page), true );
		}

		public event EventHandler PageChanged;

		protected void OnPageChange(EventArgs e)
		{
			if(PageChanged != null)
				PageChanged(this, e);
		}

	}
}
