using System;
using FastReport.Utils;

namespace FastReport.AdvMatrix
{
    /// <summary>
    /// Stores the TopN settings of the matrix header item.
    /// </summary>
    public class TopNInfo
    {
        /// <summary>
        /// Gets or sets the TopN count. 0 means no TopN grouping will be performed.
        /// </summary>
        public int Count { get; set; }
        
        /// <summary>
        /// Gets the properties of TopN total item.
        /// </summary>
        public ItemInfo Total { get; private set; }

        /// <summary>
        /// Gets the properties of Others item.
        /// </summary>
        public ItemInfo Others { get; private set; }

        /// <summary>
        /// Gets the properties of Others total item.
        /// </summary>
        public ItemInfo OthersTotal { get; private set; }


        internal void Serialize(FRWriter writer, string prefix, TopNInfo c)
        {
            if (Count != c.Count)
                writer.WriteInt(prefix + ".Count", Count);
            Total.Serialize(writer, prefix + ".Total", c.Total);
            Others.Serialize(writer, prefix + ".Others", c.Others);
            OthersTotal.Serialize(writer, prefix + ".OthersTotal", c.OthersTotal);
        }

        internal TopNInfo(HeaderDescriptor descr)
        {
            Total = new ItemInfo(descr) { Text = "Total" };
            Others = new ItemInfo(descr) { Visible = false };
            OthersTotal = new ItemInfo(descr) { Text = "Others" };
        }

        /// <summary>
        /// Stores the properties of TopN item.
        /// </summary>
        public class ItemInfo
        {
            private HeaderDescriptor descr;

            /// <summary>
            /// Gets or sets the Name of the header descriptor item.
            /// </summary>
            public string Name { get; set; }
            
            /// <summary>
            /// Gets or set the initial visibility of this item.
            /// </summary>
            public bool Visible { get; set; }
            
            /// <summary>
            /// Gets or set the text of this item. Applicable to "Total" items.
            /// </summary>
            public string Text { get; set; }

            internal HeaderDescriptor Descriptor
            {
                get
                {
                    HeaderDescriptor result = FindDescriptorInternal(descr.Parent);
                    if (result == null && descr.Parent != null)
                        result = FindDescriptorInternal(descr.Parent.Parent);
                    return result;
                }
            }

            private HeaderDescriptor FindDescriptorInternal(HeaderDescriptor root)
            {
                if (root == null || String.IsNullOrEmpty(Name))
                    return null;
                if (root.Name == Name)
                    return root;

                foreach (HeaderDescriptor d in root.Items)
                {
                    HeaderDescriptor result = FindDescriptorInternal(d);
                    if (result != null)
                        return result;
                }
                return null;
            }

            internal void Serialize(FRWriter writer, string prefix, ItemInfo c)
            {
                if (Name != c.Name)
                    writer.WriteStr(prefix + ".Name", Name);
                if (Visible != c.Visible)
                    writer.WriteBool(prefix + ".Visible", Visible);
                if (Text != c.Text)
                    writer.WriteStr(prefix + ".Text", Text);
            }

            internal ItemInfo(HeaderDescriptor descr)
            {
                this.descr = descr;
                Name = "";
                Visible = true;
                Text = "";
            }
        }
    }
}