using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEngine.UI;

using com.badam.support;

namespace com.badam.ui
{
    public class ExtText : Text
    {
        private readonly UIVertex[] _realTextVerts = new UIVertex[4];

        float _temp = 0f;
        string _text = "";
        TextGenerator _cached;
        float _lastPositionX = 0f;

        [SerializeField]
        private bool _rtl = false;

        protected override void OnPopulateMesh(VertexHelper toFill)
        {
            if (this.font == null)
            {
                return;
            }
            this.m_DisableFontTextureRebuiltCallback = true;
            Vector2 size = base.rectTransform.rect.size;
            TextGenerationSettings generationSettings = this.GetGenerationSettings(size);

            //
            if (this.rtl)
            {
                char[] cs = WeiYuSupport.ResetTags(this.text).ToCharArray();
                Array.Reverse(cs);

                //ıʾʱ(Ϊַַ࣬ʹ)
                _cached = new TextGenerator(this.text.Length);
                TextGenerationSettings _generationSettings = this.GetGenerationSettings(size);
                _generationSettings.horizontalOverflow = HorizontalWrapMode.Overflow;
                _cached.Populate(this.text, _generationSettings);

                //ʾ
                this.cachedTextGenerator.Populate(new string(cs), generationSettings);
            } else {
                this.cachedTextGenerator.Populate(this.text, generationSettings);
            }
            
            Rect rect = base.rectTransform.rect;
            Vector2 textAnchorPivot = Text.GetTextAnchorPivot(this.alignment);
            Vector2 zero = Vector2.zero;
            zero.x = Mathf.Lerp(rect.xMin, rect.xMax, textAnchorPivot.x);
            zero.y = Mathf.Lerp(rect.yMin, rect.yMax, textAnchorPivot.y);
            Vector2 vector = base.PixelAdjustPoint(zero) - zero;

            IList<UIVertex> verts = this.cachedTextGenerator.verts;
            float num = 1f / this.pixelsPerUnit;
            int num2 = verts.Count - 4;
            toFill.Clear();

            float _space = 0f;

            List<ChatSpace> _list = getSourceTextVerts(vector);
            ChatSpace _cs;
            _lastPositionX = 0f;


            int _tmp = 0;
            int _charIndex = 0;
            for (int j = 0; j < num2; j++)
            {
                _tmp = j & 3;
                this._realTextVerts[_tmp] = verts[j];
                this._realTextVerts[_tmp].position = this._realTextVerts[_tmp].position * num;
                this._realTextVerts[_tmp].position.x += vector.x;
                this._realTextVerts[_tmp].position.y += vector.y;
                if (this.rtl)
                {
                    this._realTextVerts[_tmp].position.x *= -1;
                }
                

                //Debug.LogError(this._realTextVerts[_tmp]);
                if (_tmp == 3)
                {
                    if (this.rtl)
                    {
                        _temp = this._realTextVerts[0].position.x;
                        this._realTextVerts[0].position.x = this._realTextVerts[1].position.x;
                        this._realTextVerts[3].position.x = this._realTextVerts[2].position.x;

                        this._realTextVerts[1].position.x = _temp;
                        this._realTextVerts[2].position.x = _temp;
                        //UnityEngine.Debug.LogError(_lastPositionX);
                        //Debug.LogError(this._realTextVerts[0].position);
                    }

                    if (this.rtl && null != _list && _list.Count > 0)
                    {
                        _cs = _list[0];
                        _list.RemoveAt(0);

                        if (IsNextLine(_charIndex))
                        {
                            if (this.alignment == TextAnchor.LowerLeft || this.alignment == TextAnchor.MiddleLeft || this.alignment == TextAnchor.UpperLeft)
                            {
                                _space = 3f;
                            }
                            else
                            {
                                _space = 0;
                            }
                        }
                        else {
                            _space += _cs.space + (this._realTextVerts[1].position.x - _lastPositionX);
                        }
                        _lastPositionX = this._realTextVerts[0].position.x;

                        for (int k = 0; k < 4; k++)
                        {
                            this._realTextVerts[k].position.x -= _space;
                        }
                        _charIndex++;
                    }

                    toFill.AddUIVertexQuad(this._realTextVerts);
                }
            }
            this.m_DisableFontTextureRebuiltCallback = false;
            _cached = null;
            _list = null;
        }

        bool IsNextLine(int index)
        {
            bool flag = false;
            UILineInfo[] lines = this.cachedTextGenerator.GetLinesArray();
            for (int i = 0; i < lines.Length; i++)
            {
                if (index == lines[i].startCharIdx)
                {

                    flag = true;
                    break;
                }
            }
            return flag;
        }

        List<ChatSpace> getSourceTextVerts(Vector2 vector)
        {
            if (!this.rtl && _cached == null)
            {
                return null;
            }
            IList<UIVertex> verts = _cached.verts;
            float num = 1f / this.pixelsPerUnit;
            int num2 = verts.Count - 4;
            UIVertex[] _tempVerts = new UIVertex[4];
            List<ChatSpace> list = new List<ChatSpace>();
            ChatSpace cs;
            //Debug.LogError("--------------------");
            for (int j = 0; j < num2; j++)
            {
                int num4 = j & 3;
                _tempVerts[num4] = verts[j];
                _tempVerts[num4].position = _tempVerts[num4].position * num;

                if (num4 == 3)
                {
                    if (list.Count > 0)
                    {
                        cs = list[list.Count - 1];
                        //Debug.LogError(_tempVerts[0].position.x - cs.x);
                        list.Add(new ChatSpace(_tempVerts[0].position.x - cs.x, _tempVerts[1].position.x));
                    }
                    else
                    {
                        list.Add(new ChatSpace(0, _tempVerts[1].position.x));
                    }
                }
            }

            if (list.Count > 0)
            {
                ChatSpace[] css = list.ToArray();
                Array.Reverse(css);
                list.Clear();
                list.AddRange(css);

                int _c = list.Count;
                list.Insert(0, new ChatSpace(0, 0));
                list.RemoveAt(list.Count - 1);
            }

            return list;
        }

        public bool rtl
        {
            get
            {
                return this._rtl;
            }
            set
            {
                if (this._rtl == value)
                {
                    return;
                }
                this._rtl = value;
                this.SetVerticesDirty();
                this.SetLayoutDirty();
            }
        }

        struct ChatSpace
        {
            public float space;
            public float x;

            public ChatSpace(float s, float lastX)
            {
                this.space = s;
                this.x = lastX;
            }
        }

    }

}
