using System;
using System.Collections.Generic;
using System.Text;

namespace FastReport.Export.Dbf
{
    /// <summary>
    /// Represents the record.
    /// </summary>
    public class Record
    {
        /// <summary>
        /// Types of fields.
        /// </summary>
        public enum FieldType
        {
            /// <summary>
            /// Boolean type in DBF equal Logical marked 'L'.
            /// </summary>
            Boolean = 'L',

            /// <summary
            /// DataTime type in DBF equal DataTime marked 'T'.
            /// </summary>
            DataTime = 'T',

            /// <summary>
            /// String type in DBF equal Character marked 'C'.
            /// </summary>
            String = 'C',

            /// <summary>
            /// Decimal type in DBF equal Numeric marked 'N'.
            /// </summary>
            Decimal = 'N',

            /// <summary>
            /// Currency type 'Y'
            /// </summary>
            Currency = 'Y',

            /// <summary>
            /// Integer type in DBF equal Integer marked 'I'.
            /// </summary>
            Integer = 'I',
        }
        #region Constants

        private const int MAX_RECORD_CHARS = 4000;
        private const int MAX_RECORD_FIELDS = 255;
        internal const int MAX_FIELD_CHARS = 254;
        internal const int MAX_FIELD_NAME_CHARS = 10;

        #endregion // Constants

        #region Fields

        private List<Field> fields;

        #endregion // Fields

        #region Properties

        /// <summary>
        /// Gets or sets the field with a specified index.
        /// </summary>
        public Field this[int index]
        {
            get { return fields[index]; }
            set { fields[index] = value; }
        }

        /// <summary>
        /// Gets the count of a fields.
        /// </summary>
        public int Count
        {
            get { return fields.Count; }
        }

        /// <summary>
        /// Gets the size of a fields.
        /// </summary>
        public int Size
        {
            get { return GetSize(); }
        }

        #endregion // Properties

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="Record"/> class.
        /// </summary>
        public Record()
        {
            fields = new List<Field>();
        }

        #endregion // Constructors

        #region Private Methods

        private int GetSize()
        {
            int size = 0;
            foreach (Field field in fields)
            {
                size += field.Data.Length;
            }
            return size;
        }

        #endregion // Private Methods

        #region Public Methods

        /// <summary>
        /// Adds the new item into a list of fields.
        /// </summary>
        public void Add(StringBuilder item, FieldType type)
        {
            if (Count < MAX_RECORD_FIELDS)
            {
                if (item.Length > MAX_FIELD_CHARS)
                {
                    item.Remove(MAX_FIELD_CHARS, item.Length - MAX_FIELD_CHARS);
                }
                if (Size + item.Length > MAX_RECORD_CHARS)
                {
                    item.Remove(MAX_RECORD_CHARS - Size, item.Length - (MAX_RECORD_CHARS - Size));
                }

                fields.Add( new Field() { Data = item, Type = type});
            }
        }

        /// <summary>
        /// Clears the list of fields.
        /// </summary>
        public void Clear()
        {
            fields.Clear();
        }

        /// <summary>
        ///  Represents the field.
        /// </summary>
        public class Field
        {
            /// <summary>
            /// Gets or sets data in field
            /// </summary>
            public StringBuilder Data { get; set; }

            /// <summary>
            /// Gets or sets type of field
            /// </summary>
            public FieldType Type { get; set; }
        }

        #endregion // Public Methods
    }
}
