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

namespace C1.Silverlight.FlexGridExcel
{
    /// <summary>
    /// Represents the MS Excel shared strings table.
    /// </summary>
    public class XLSharedStrings
    {
        //-------------------------------------------------------------------------
        #region ** fields

        Dictionary<int, string> _strings;
        int _currentKey;

        #endregion

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

        /// <summary>
        /// Initializes a new instance of the <see cref="XLSharedStrings"/> class.
        /// </summary>
        /// <param name="document">The document to load the shared strings table from.</param>
        public XLSharedStrings(XDocument document)
        {
            if (document != null)
            {
                Document = document;
                _strings = new Dictionary<int, string>();
                _currentKey = 0;
                foreach (var element in document.Descendants(XLWorkbook.SheetNS + XLConstants.TEXT))
                {
                    _strings[_currentKey++] = element.Value;
                }
            }
        }

        #endregion

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

        /// <summary>
        /// Gets the xml document that represents this shared strings table.
        /// </summary>
        public XDocument Document { get; private set; }
        /// <summary>
        /// Gets the value associated with the specified key in the shared string table.
        /// </summary>
        /// <param name="key">The key of the value to get.</param>
        /// <param name="value">When this method returns, contains the value associated with the specified
        ///  key, if the key is found; otherwise, the default value for the type of the
        ///  value parameter. This parameter is passed uninitialized.</param>
        /// <returns>true if the table contains a string with the specified key; otherwise, false.</returns>
        public bool TryGetValue(int key, out string value)
        {
            return _strings.TryGetValue(key, out value);
        }
        /// <summary>
        /// Adds the specified string value to the table.
        /// </summary>
        /// <param name="value">The value to add.</param>
        /// <returns>The key of the added value.</returns>
        public int AddValue(string value)
        {
            if (_strings.ContainsValue(value))
            {
                foreach (var item in _strings)
                {
                    if (item.Value.Equals(value))
                    {
                        return item.Key;
                    }
                }
            }
            else
            {
                AddValueToModel(value);
                AddValueToDocument(value);
                return _currentKey++;
            }
            return -1;
        }

        #endregion

        //-------------------------------------------------------------------------
        #region ** implementation

        void AddValueToModel(string value)
        {
            _strings[_currentKey] = value;
        }

        void AddValueToDocument(string value)
        {
            XElement root = Document.Descendants(XLWorkbook.SheetNS + XLConstants.SHARED_STRING_TABLE).First();
            XElement sharedString = new XElement(XLConstants.STRING_ITEM, new XElement(XLConstants.TEXT, value));
            root.Add(sharedString);
        }

        #endregion
    }
}
