using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using Telerik.Web.UI;
using System.ComponentModel;

namespace Telerik.Web.UI
{
    /// <summary>
    /// Extends RadGrid's scroll behavior by showing a customizable tooltip
    /// with the top item scrolled into view
    /// </summary>
    [TargetControlType(typeof(RadGrid))]
    public class GridScrollTooltipExtender : ExtenderControl
    {
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            if (!String.IsNullOrEmpty(this.TargetControlID))
            {
                this._targetGrid = Page.FindControl(this.TargetControlID) as RadGrid;
                if (this._targetGrid != null)
                {
                    this._targetGrid.ColumnCreated += new GridColumnCreatedEventHandler(TargetGrid_ColumnCreated);
                }
            }
        }

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

            this._targetGrid.MasterTableView.NestedViewTemplate = this.ToolTipTemplate;
            this._targetGrid.MasterTableView.HierarchyLoadMode = GridChildLoadMode.Client;
        }

        private void TargetGrid_ColumnCreated(object sender, GridColumnCreatedEventArgs e)
        {
            if (e.Column is GridExpandColumn && e.Column.Owner == this._targetGrid.MasterTableView)
            {
                e.Column.Visible = false;
            }
        }

        /// Gets or sets the tooltip template rendered in the RadGrid slider.
        /// </summary>
        [Browsable(false), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty),
        Description("Gets or sets the tooltip template rendered in the RadGrid slider.")]
        public ITemplate ToolTipTemplate
        {
            get { return this._toolTipTemplate; }
            set { this._toolTipTemplate = value; }
        }

        /// <summary>
        /// Gets the left position of the tooltip relative to the grid element.
        /// </summary>
        [DefaultValue(0), Bindable(true),
        Description("Gets the left location of the tooltip relative to the grid element.")]
        public int Left
        {
            get { return (int)(this.ViewState["Left"] ?? 0); }
            set { this.ViewState["Left"] = value; }
        }

        /// <summary>
        /// Gets the right position of the tooltip relative to the grid element.
        /// </summary>
        [DefaultValue(0), Bindable(true),
        Description("Gets the right location of the tooltip relative to the grid element.")]
        public int Right
        {
            get { return (int)(this.ViewState["Right"] ?? 0); }
            set { this.ViewState["Right"] = value; }
        }

        /// <summary>
        /// Gets the top position of the tooltip relative to the grid element.
        /// </summary>
        [DefaultValue(0), Bindable(true),
        Description("Gets the top location of the tooltip relative to the grid element.")]
        public int Top
        {
            get { return (int)(this.ViewState["Top"] ?? 0); }
            set { this.ViewState["Top"] = value; }
        }

        /// <summary>
        /// Gets the bottom position of the tooltip relative to the grid element.
        /// </summary>
        [DefaultValue(0), Bindable(true),
        Description("Gets the bottom location of the tooltip relative to the grid element.")]
        public int Bottom
        {
            get { return (int)(this.ViewState["Bottom"] ?? 0); }
            set { this.ViewState["Bottom"] = value; }
        }

        /// <summary>
        /// Gets or sets the delay (in milliseconds) before the tooltip
        /// is hidden after scroll.
        /// </summary>
        [DefaultValue(400), Bindable(true),
        Description("Gets or sets the delay (in milliseconds) before the tooltip is hidden after scroll.")]
        public int HideDelay
        {
            get { return (int)(this.ViewState["HideDelay"] ?? 400); }
            set { this.ViewState["HideDelay"] = value; }
        }

        /// <summary>
        /// Gets or sets the client name of a client event handler
        /// that is fired before the tooltip is shown.
        /// </summary>
        [DefaultValue(""),
        Description("Gets or sets the client name of a client event handler that is fired before the tooltip is shown.")]
        public string OnClientBeforeShow
        {
            get { return (string)(this.ViewState["OnClientBeforeShow"] ?? String.Empty);}
            set { this.ViewState["OnClientBeforeShow"] = value; }
        }

        /// <summary>
        /// Gets or sets the client name of a client event handler
        /// that is fired after the tooltip is shown.
        /// </summary>
        [DefaultValue(""),
        Description("Gets or sets the client name of a client event handler that is fired before the tooltip is shown.")]
        public string OnClientShow
        {
            get { return (string)(this.ViewState["OnClientShow"] ?? String.Empty); }
            set { this.ViewState["OnClientShow"] = value; }
        }

        private RadGrid _targetGrid;
        private ITemplate _toolTipTemplate;

        protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors(Control targetControl)
        {
            ScriptBehaviorDescriptor descriptor = new ScriptBehaviorDescriptor("Telerik.Web.UI.GridScrollTooltipExtender", targetControl.ClientID);

            if (this.Left > 0) descriptor.AddProperty("left", this.Left);
            if (this.Right > 0) descriptor.AddProperty("right", this.Right);
            if (this.Top > 0) descriptor.AddProperty("top", this.Top);
            if (this.Bottom > 0) descriptor.AddProperty("botton", this.Bottom);
            if (this.HideDelay > 400) descriptor.AddProperty("hideDelay", this.HideDelay);

            if (!String.IsNullOrEmpty(this.OnClientBeforeShow))
            {
                descriptor.AddEvent("beforeShow", this.OnClientBeforeShow);
            }

            if (!String.IsNullOrEmpty(this.OnClientShow))
            {
                descriptor.AddEvent("show", this.OnClientShow);
            }

            yield return descriptor;
        }

        protected override IEnumerable<ScriptReference> GetScriptReferences()
        {
            ScriptReference reference = new ScriptReference(this.ResolveClientUrl("GridScrollTooltipExtender.js"));
            yield return reference;
        }
    }
}