namespace SMFD_Paragon_DisallowRussianChars
{
    #region Using
    using System;
    using Forms = System.Windows.Forms;

    using System.Text.RegularExpressions;
    using Aveva.ApplicationFramework;
    using Aveva.ApplicationFramework.Presentation;
    using Aveva.Pdms.Database;
    using Aveva.Pdms.Geometry;
    using Aveva.Pdms.Shared;
    #endregion

    /// <summary>
    /// Сервис отслеживания букв русского алфавита
    /// </summary>
    public class RussianCharsService
    {
        #region Свойства
        private DbElement elem;
        private string oldElemName;
        /// <summary>
        /// Регулярное выражение для поиска букв русского алфавита
        /// </summary>
        private Regex regex;
        private static RussianCharsService instance;
        #endregion

        #region Конструктор
        /// <summary>
        /// Конструктор
        /// </summary>
        private RussianCharsService()
        {
            this.regex = new Regex(@"[а-я]{1,}", RegexOptions.IgnoreCase | RegexOptions.Compiled);
        }
        #endregion

        #region Методы
        /// <summary>
        /// Проверяет и переименовывает подчинённые элементы
        /// </summary>
        /// <param name="dbEle">Элемент</param>
        private void CheckMembers(DbElement dbEle)
        {
            foreach (DbElement mem in dbEle.Members())
            {
                string oldElemName = mem.GetString(DbAttributeInstance.NAME);

                if (!oldElemName.StartsWith("=") && regex.Match(oldElemName).Success)
                {
                    string newElemName = regex.Replace(oldElemName, string.Empty);

                    if (!string.IsNullOrEmpty(newElemName))
                        mem.SetAttribute(DbAttributeInstance.NAME, newElemName);
                    else
                        mem.SetAttribute(DbAttributeInstance.NAME, string.Empty);

                    this.CheckMembers(mem);
                }
            }
        }

        /// <summary>
        /// Удаляет дочерние элементы
        /// </summary>
        /// <param name="dbEle">Элемент</param>
        private void DeleteChildren(DbElement dbEle)
        {
            foreach (DbElement ele in dbEle.Members())
            {
                this.DeleteChildren(ele);

                if (!ele.IsDeleted)
                    ele.Delete();
            }
        }
        #endregion

        #region Общие свойства
        /// <summary>
        /// Текущий элемент, за которым ведётся наблюдение
        /// </summary>
        public DbElement Elem
        {
            get { return this.elem; }
            set
            {
                if (this.elem != null && !this.elem.IsDeleted && !this.elem.Db.IsReadOnly && (this.elem.Db.Type == DbType.Catalog || this.elem.Db.Type == DbType.Property))
                {
                    string newElemName = this.elem.GetString(DbAttributeInstance.NAME);

                    if (!newElemName.StartsWith("="))
                    {
                        if (regex.Match(newElemName).Success)
                        {
                            string message =
                                string.Format(
                                "Имя элемента не может содержать символы русского алфавита.{0}Атрибут NAME элемента будет изменён на предыдущее значение:{0} с\t{1}{0} на\t{2}",
                                Environment.NewLine,
                                newElemName,
                                string.IsNullOrEmpty(this.oldElemName) ? "значение по умолчанию" : this.oldElemName);

                            Forms.MessageBox.Show(
                                message,
                                "Ошибка: русские буквы в атрибуте NAME",
                                Forms.MessageBoxButtons.OK,
                                Forms.MessageBoxIcon.Error,
                                Forms.MessageBoxDefaultButton.Button1);

                            if (!this.oldElemName.StartsWith("="))
                                this.elem.SetAttribute(DbAttributeInstance.NAME, this.oldElemName);
                            else
                                this.elem.SetAttribute(DbAttributeInstance.NAME, string.Empty);

                            this.CheckMembers(this.elem);

                            CurrentElement.Element = this.elem;
                        }
                    }
                }

                this.elem = value;
                this.oldElemName = this.elem.GetString(DbAttributeInstance.NAME);

                if (!this.oldElemName.StartsWith("=") && regex.Match(this.oldElemName).Success && !this.elem.Db.IsReadOnly && (this.elem.Db.Type == DbType.Catalog || this.elem.Db.Type == DbType.Property))
                {
                    // Проверяем был ли элемент создан или просто выбран в дереве элементов
                    bool isCreated;
                    elem.HasElementBeenCreatedSince(elem.Db.CurrentSession, out isCreated);

                    if (isCreated)
                    {
                        string message =
                            string.Format(
                            "Имя элемента не может содержать символы русского алфавита.{0}Элемент {1} не будет создан!",
                            Environment.NewLine,
                            this.oldElemName);

                        Forms.MessageBox.Show(
                            message,
                            "Ошибка: русские буквы в атрибуте NAME",
                            Forms.MessageBoxButtons.OK,
                            Forms.MessageBoxIcon.Error,
                            Forms.MessageBoxDefaultButton.Button1);

                        this.DeleteChildren(this.elem);

                        DbElement owner = this.elem.Owner;

                        this.elem.Delete();

                        CurrentElement.Element = owner;
                    }
                    else
                    {
                        string newElemName = regex.Replace(this.oldElemName, string.Empty);

                        string message =
                            string.Format(
                            "Имя элемента не может содержать символы русского алфавита.{0}Из атрибута NAME элемента будут убраны все русские буквы.{0}Атрибут NAME будет изменён:{0} с\t{1}{0} на\t{2}",
                            Environment.NewLine,
                            this.oldElemName,
                            string.IsNullOrEmpty(newElemName) ? "значение по умолчанию" : newElemName);

                        Forms.MessageBox.Show(
                            message,
                            "Ошибка: русские буквы в атрибуте NAME",
                            Forms.MessageBoxButtons.OK,
                            Forms.MessageBoxIcon.Error,
                            Forms.MessageBoxDefaultButton.Button1);

                        if (!string.IsNullOrEmpty(newElemName))
                            this.elem.SetAttribute(DbAttributeInstance.NAME, newElemName);
                        else
                            this.elem.SetAttribute(DbAttributeInstance.NAME, string.Empty);

                        this.CheckMembers(this.elem);

                        CurrentElement.Element = this.elem;
                    }
                }
            }
        }

        /// <summary>
        /// RussianCharsService Instance
        /// </summary>
        public static RussianCharsService Instance
        {
            get
            {
                if (instance == null)
                    instance = new RussianCharsService();

                return instance;
            }
        }
        #endregion
    }
}
