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

using System;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using CommunityServer.Components;

namespace CommunityServer.Controls {

	/// <summary>
	/// Provides the ability to toggle the visibility of another serverside control.
	/// </summary>
	public class ExpanderPanel : WebControl, INamingContainer {

		CSContext csContext = CSContext.Current;

		/// <exclude />
		protected override HtmlTextWriterTag TagKey {
			get {
				return HtmlTextWriterTag.Div;
			}
		}

		
		#region CompositeControl Pattern

		/// <exclude />
		public override ControlCollection Controls {
			get {
				this.EnsureChildControls();
				return base.Controls;
			}
		}


		#endregion

		#region Properties

		#region Button

		/// <summary>
		/// Gets or sets the url of the image shown in the toggle button when the target control is in view.
		/// </summary>
		[
		System.ComponentModel.Editor("System.Web.UI.Design.ImageUrlEditor, System.Design", typeof(System.Drawing.Design.UITypeEditor)),
		System.ComponentModel.Description( "Collapse link image URL" ),
		System.ComponentModel.DefaultValue( "" ),
		]
		public virtual String ButtonImage {
			get {
				Object state = ViewState["ButtonImage"];
				if ( state != null ) {
					return (String)state;
				}
				return "";
			}
			set {
				ViewState["ButtonImage"] = value;
			}
		}

		/// <summary>
		/// Gets or sets the url of the image shown in the toggle button when the target control is hidden.
		/// </summary>
		[
		System.ComponentModel.Editor("System.Web.UI.Design.ImageUrlEditor, System.Design", typeof(System.Drawing.Design.UITypeEditor)),
		System.ComponentModel.Description( "Collapse link image URL" ),
		System.ComponentModel.DefaultValue( "" ),
		]
		public virtual String ButtonImageCollapsed {
			get {
				Object state = ViewState["ButtonImageCollapsed"];
				if ( state != null ) {
					return (String)state;
				}
				return "";
			}
			set {
				ViewState["ButtonImageCollapsed"] = value;
			}
		}

		/// <summary>
		/// Gets or sets the css class of the toggle button
		/// </summary>
		[
		System.ComponentModel.DefaultValue( "" ),
		]
		public virtual String ButtonCssClass {
			get {
				Object state = ViewState["ButtonCssClass"];
				if ( state != null ) {
					return (String)state;
				}
				return "";
			}
			set {
				ViewState["ButtonCssClass"] = value;
			}
		}

		#endregion

		#region Text

		/// <summary>
		/// Gets or sets the text shown next to the toggle button
		/// </summary>
		[
		System.ComponentModel.DefaultValue( "Caption" ),
		]
		public virtual String Text {
			get {

                if(ResourceName != null)
                    return CommunityServer.Components.ResourceManager.GetString(ResourceName);

				Object state = ViewState["Text"];
				if ( state != null ) {
					return (String)state;
				}
				return "Caption";
			}
			set {
				ViewState["Text"] = value;
			}
		}

        public virtual String ResourceName 
        {
            get 
            {
               return ViewState["ResourceName"] as string;
            }
            set 
            {
                ViewState["ResourceName"] = value;
            }
        }



		/// <summary>
		/// Gets or sets the css class of the text next to the toggle button
		/// </summary>
		[
		System.ComponentModel.DefaultValue( "" ),
		]
		public virtual String TextCssClass {
			get {
				Object state = ViewState["TextCssClass"];
				if ( state != null ) {
					return (String)state;
				}
				return "";
			}
			set {
				ViewState["TextCssClass"] = value;
			}
		}

		#endregion

		/// <summary>
		/// Gets or sets the ID of the control which is the target of the visibility-toggling behavior.
		/// </summary>
		[
		Description("Gets or sets the ID of the control which is the target of the visibility-toggling behavior."),
		Category("Behavior"),
		DefaultValue(""),
		]
		public virtual String ControlToToggle {
			get {
				object savedState = this.ViewState["ControlToToggle"];
				if ( savedState != null ) {
					return (String)savedState; 
				}
				return "";
			}
			set {
				this.ViewState["ControlToToggle"] = value;
				this.cachedTargetControl = null;
			}
		}


		/// <summary>
		/// Gets or sets whether the target control is visible or not
		/// </summary>
		[
		System.ComponentModel.DefaultValue( false ),
		]
		public virtual Boolean Collapsed {
			get {
				Object state = ViewState["Collapsed"];
				if ( state != null ) {
					return (Boolean)state;
				}
				return false;
			}
			set {
				ViewState["Collapsed"] = value;
			}
		}


		/// <summary>
		/// Gets or sets the order of the button and text
		/// </summary>
		[
		System.ComponentModel.DefaultValue( System.Web.UI.WebControls.TextAlign.Left ),
		]
		public virtual System.Web.UI.WebControls.TextAlign TextAlign {
			get {
				Object state = ViewState["TextAlign"];
				if ( state != null ) {
					return (System.Web.UI.WebControls.TextAlign)state;
				}
				return System.Web.UI.WebControls.TextAlign.Left;
			}
			set {
				ViewState["TextAlign"] = value;
			}
		}


		#endregion

		#region Lifecycle

		/// <exclude />
		protected override void CreateChildControls() {

			Controls.Clear();

			tracker = new HtmlInputHidden();
			tracker.Name = "tracker";
			tracker.ID = "tracker";
			tracker.ServerChange += new EventHandler( this.ClientExpanedStateChanged );
			Controls.Add(tracker);

			headerLabel = new Label();
			headerLabel.ID = "label";
			Controls.Add( headerLabel );

			button = new ImageButton();
			button.CausesValidation = false;
			button.ID = "clicker";
			button.Click += new System.Web.UI.ImageClickEventHandler( this.button_Click );
			this.Controls.Add(button);

		}

		/// <exclude />
		protected override void OnPreRender(EventArgs e) {
			this.EnsureChildControls();

			base.OnPreRender (e);

			if (!csContext.User.EnableCollapsingPanels)
				Collapsed = false;

			if ( !Page.IsClientScriptBlockRegistered( scriptKey ) ) {
				this.Page.RegisterClientScriptBlock( scriptKey, String.Format( "<script type='text/javascript' language='javascript' src='{0}'></script>", Page.ResolveUrl( "~/Utility/ExpanderPanelScript.js" ) ) );
			}

			this.tracker.Value = this.Collapsed.ToString();
			
			if ( this.Collapsed ) {
				this.targetStyle["display"] = "none";
			} else {
				if ( this.targetStyle["display"] != null ) {
					this.targetStyle.Remove("display");
				}
			}
		}

		/// <exclude />
		protected override void Render( HtmlTextWriter writer ) {

			if ( this.Page != null ) {
				this.Page.VerifyRenderingInServerForm( this );
			}

			ApplyPropertiesToChildren();

			base.Render( writer );
		}

		private void ApplyPropertiesToChildren() {
			this.EnsureChildControls();

			if ( this.TextAlign == TextAlign.Right ) {
				this.Controls.Remove( headerLabel );
				this.Controls.Add( headerLabel );
			}

			this.button.Attributes[ "onclick" ] =
				String.Format(
					"return ExpanderPanel_Toggle('{0}','{1}','{2}','{3}','{4}');", 
					this.targetControl.ClientID,
					this.button.ClientID, 
					this.tracker.ClientID,
					this.ResolveUrl( this.ButtonImage ), 
					this.ResolveUrl( this.ButtonImageCollapsed )
				);

			this.button.CssClass = this.ButtonCssClass;

			this.headerLabel.Text = this.Text;
			this.headerLabel.CssClass = this.TextCssClass;

			if ( this.Collapsed ) {
				this.button.ImageUrl = this.ButtonImage;
			} else {
				this.button.ImageUrl = this.ButtonImageCollapsed;
			}

		}

		#endregion

		#region Event Handlers

		private void ClientExpanedStateChanged( Object sender, EventArgs e ) {
			try {
				Boolean clientExpanedValue = Boolean.Parse( tracker.Value );
				this.Collapsed = clientExpanedValue;
			} catch {}
		}

		private void button_Click(Object sender, ImageClickEventArgs e) {
			this.Collapsed = !this.Collapsed;
		}

		#endregion

		#region Target Control

		private Control targetControl {
			get {
				if ( cachedTargetControl == null ) {
					this.cachedTargetControl = this.NamingContainer.FindControl(this.ControlToToggle);
				}
				return this.cachedTargetControl;
			}
		}
		private Control cachedTargetControl = null;

		private System.Web.UI.CssStyleCollection targetStyle {
			get {
				WebControl targetWebControl = this.targetControl as WebControl;
				if ( targetWebControl != null ) {
					return targetWebControl.Style;
				}
				System.Web.UI.HtmlControls.HtmlControl targetHtmlControl = this.targetControl as System.Web.UI.HtmlControls.HtmlControl;
				if ( targetHtmlControl != null ) {
					return targetHtmlControl.Style;
				}
				return null;
			}
		}

		#endregion


		private static readonly String scriptKey = "CommunityServer.Controls.ExpanderPanel";

		private HtmlInputHidden tracker;
		private Label headerLabel;
		private ImageButton button;

	}
}
