using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

using Vrh.XmlProcessing;

namespace Vrh.iScheduler
{
    /// <summary>
    /// A "Manager" elem leképezése.
    /// </summary>
    public class ManagerElement : XmlLinqBase
    {
        #region Built'in classes

        #region ElementNames class
        /// <summary>
        /// Az XML fájlban ilyen elem nevek találhatóak egy "Button" elemben.
        /// </summary>
        public new class ElementNames : XmlLinqBase.ElementNames
        {
            /// <summary>
            /// 'Button' elem név.
            /// </summary>
            public const string BUTTON = "Button";

            /// <summary>
            /// 'Buttons' elem név.
            /// </summary>
            public const string BUTTONS = "Buttons";
            
            /// <summary>
            /// 'Options' elem név.
            /// </summary>
            public const string OPTIONS = "Options";
        }
        #endregion ElementNames class

        #region AttributeNames static class
        /// <summary>
        /// Az XML fájlban ilyen attribútum nevek találhatóak egy 'Button' elemben.
        /// </summary>
        public static class AttributeNames
        {
            /// <summary>
            /// 'DefaultDisplayMode' attribútum név.
            /// </summary>
            public const string DEFAULTDISPLAYMODE = "DefaultDisplayMode";
        }
        #endregion AttributeNames static class

        #endregion Built'in classes

        #region Properties

        /// <summary>
        /// A kezelőgombok elhelyezéséhez hány sor fog kelleni.
        /// </summary>
        public int ButtonRows { get; set; } = 0;

        /// <summary>
        /// A kezelőgombok elhelyezéséhez hány oszlop fog kelleni.
        /// </summary>
        public int ButtonCols { get; set; } = 0;

        /// <summary>
        /// Kezelő gombok listája. 
        /// </summary>
        public List<ButtonElement> Buttons { get; set; }

        /// <summary>
        /// Alapértelmezett nézet.
        /// </summary>
        public DisplayMode DefaultDisplayMode { get; set; }

        #endregion Properties

        #region Constructors
        /// <summary>
        /// Példányosítás egy 'Manager' XElement alapján.
        /// </summary>
        /// <param name="xelement">A 'Manager' elem XElement objektuma.</param>
        /// <param name="lcid">A környezetben érvényes nyelvi kód.</param>
        /// <param name="wordCodePrefix">
        /// A gomboknál lévő szókód lesz hozzáfűzve. 
        /// Így alkotják a gomb megjelenő nevének szókódját.
        /// </param>
        //public ManagerElement(XElement xelement, string lcid, string wordCodePrefix)
		public ManagerElement(XElement xelement, string lcid)
		{
            if (xelement != null)
            {
                #region DefaultDisplayMode beállítása
                XAttribute xa = xelement.Element(ElementNames.OPTIONS)?.Attribute(AttributeNames.DEFAULTDISPLAYMODE);
                if (xa == null)
                {
                    this.DefaultDisplayMode = DisplayMode.List;
                }
                else
                {
                    this.DefaultDisplayMode = GetEnumValue(xa, DisplayMode.List);
                }
                #endregion DefaultDisplayMode beállítása

                #region Buttons beállítása
                XElement xe = xelement.Element(ElementNames.BUTTONS);
                if (xe != null)
                {
                    IEnumerable<XElement> buttonsXE = xe.Elements(ElementNames.BUTTON);
                    if (buttonsXE != null && buttonsXE.Any())
                    {
                        this.Buttons = new List<ButtonElement>();
                        foreach (var buttonXE in buttonsXE)
                        {
							//using (var newbttn = new ButtonElement(buttonXE, lcid, wordCodePrefix))
							using (var newbttn = new ButtonElement(buttonXE, lcid))
							{
                                if (this.Buttons.Any(x => x.Name == newbttn.Name))
                                {
                                    throw new ApplicationException(string.Format(
                                        "The 'Button.Name' attribute is not unique in the buttons! Name={0}", newbttn.Name
                                    ));
                                }
                                if (this.Buttons.Any(x => x.Row == newbttn.Row && x.Col == newbttn.Col))
                                {
                                    throw new ApplicationException(string.Format(
                                        "The 'Row' and 'Col' attribute is not unique in the buttons! Name='{0}', Row={1}, Col={2}", newbttn.Name, newbttn.Row, newbttn.Col
                                    ));
                                }
                                this.ButtonRows = this.ButtonRows < (newbttn.Row + newbttn.RowSpan - 1) ? (newbttn.Row + newbttn.RowSpan - 1) : this.ButtonRows;
                                this.ButtonCols = this.ButtonCols < (newbttn.Col + newbttn.ColSpan - 1) ? (newbttn.Col + newbttn.ColSpan - 1) : this.ButtonCols;
                                this.Buttons.Add(newbttn);
                            }
                        }
                    }
                }
                #endregion Buttons beállítása
            }
        }
        #endregion Constructors
    }
}
