using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Globalization;

namespace C1.Silverlight.FlexGridExcel
{
    /// <summary>
    /// Represents a MS Excel row.
    /// </summary>
    public class XLRow
    {
        //-------------------------------------------------------------------------
        #region ** fields

        int _cellCount;
        int _index;
        Dictionary<int, XLCell> _cells;

        #endregion

        //-------------------------------------------------------------------------
        #region ** ctors

        /// <summary>
        /// Initializes a new instance of an <see cref="XLRow"/> object.
        /// </summary>
        /// <param name="index">Index of the new row.</param>
        public XLRow(int index)
        {
            Element = new XElement(XLWorkbook.SheetNS + XLConstants.ROW);
            Element.SetAttributeValue(XLConstants.REFERENCE, index);
            _cells = new Dictionary<int, XLCell>();
            _index = index;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="XLRow"/> object from an xml element.
        /// </summary>
        /// <param name="element">The xml element to load the XLRow from.</param>
        public XLRow(XElement element)
        {
            Element = element ?? new XElement(XLWorkbook.SheetNS + XLConstants.ROW);
            if (Element.Attribute(XLConstants.REFERENCE) != null)
            {
                _index = int.Parse(Element.Attribute(XLConstants.REFERENCE).Value, CultureInfo.InvariantCulture);
            }
            _cells = new Dictionary<int, XLCell>();
            foreach (var cellElement in element.Descendants(XLWorkbook.SheetNS + XLConstants.CELL).ToList())
            {
                AddCell(cellElement);
            }
        }

        #endregion

        //-------------------------------------------------------------------------
        #region ** object model

        /// <summary>
        /// Gets the xml element that represents this row.
        /// </summary>
        public XElement Element { get; private set; }
        /// <summary>
        /// Gets or sets the outline level of the row (for grouped data).
        /// </summary>
        public int? OutlineLevel
        {
            get
            {
                if (Element.Attribute(XLConstants.OUTLINE_LEVEL) != null)
                {
                    return int.Parse(Element.Attribute(XLConstants.OUTLINE_LEVEL).Value, CultureInfo.InvariantCulture);
                }
                return null;
            }
            set
            {
                Element.SetAttributeValue(XLConstants.OUTLINE_LEVEL, value);
            }
        }
        /// <summary>
        /// Gets or sets the height of the row.
        /// </summary>
        /// <value>The height value.</value>
        public double? Height
        {
            get
            {
                if (Element.Attribute(XLConstants.HEIGHT) != null)
                {
                    return double.Parse(Element.Attribute(XLConstants.HEIGHT).Value, CultureInfo.InvariantCulture);
                }
                return null;
            }
            set
            {
                Element.SetAttributeValue(XLConstants.HEIGHT, value);
            }
        }
        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="XLRow"/> is hidden.
        /// </summary>
        /// <value><c>true</c> if hidden; otherwise, <c>false</c>.</value>
        public bool Hidden
        {
            get
            {
                if (Element.Attribute(XLConstants.HIDDEN) != null)
                {
                    return Element.Attribute(XLConstants.HIDDEN).Value.Equals("1");
                }
                return false;
            }
            set
            {
                Element.SetAttributeValue(XLConstants.HIDDEN, value ? 1 : 0);
            }
        }
        /// <summary>
        /// Gets the all the cells belonging to this row.
        /// </summary>
        /// <value>The cells.</value>
        public ICollection<XLCell> Cells
        {
            get
            {
                return _cells.Values;
            }
        }
        /// <summary>
        /// Creates a new cell and adds it to the current row.
        /// </summary>
        /// <returns>The new cell.</returns>
        public XLCell AddCell()
        {
            var newCell = new XLCell(_index, _cellCount);
            _cells[_cellCount++] = newCell;
            Element.Add(newCell.Element);
            return newCell;
        }
        /// <summary>
        /// Creates a new cell and adds it to the current row.
        /// </summary>
        /// <param name="element">The xml element to read the cell data from.</param>
        /// <returns>The new cell.</returns>
        public XLCell AddCell(XElement element)
        {
            XLCell newCell = new XLCell(element);
            _cells[_cellCount++] = newCell;
            Element.Add(newCell.Element);
            return newCell;
        }

        #endregion
    }
}
