using System;  
 | 
using System.Collections;  
 | 
using System.Collections.Generic;  
 | 
using System.Text.RegularExpressions;  
 | 
using UnityEngine;  
 | 
using UnityEngine.UI;  
 | 
using EnhancedUI.EnhancedScroller;  
 | 
namespace Snxxz.UI  
 | 
{  
 | 
    public class ChatContentBehaviour : MonoBehaviour  
 | 
    {  
 | 
        [SerializeField] ScrollerController m_ChatContentControl;  
 | 
        [SerializeField] RichText m_DestSysText;  
 | 
        [SerializeField] RichText m_DestTipText;  
 | 
        [SerializeField] RectTransform m_ContaienrNewInfo;  
 | 
        [SerializeField] Text m_NewInfoText;  
 | 
        [SerializeField] Button m_NewInfoBtn;  
 | 
        [SerializeField] Button m_LockAreaBtn;  
 | 
        [SerializeField] Image m_LockAreaCheck;  
 | 
        [SerializeField] RectTransform m_ContainerDisplay;  
 | 
        [SerializeField] RectTransform m_ContainerPrivateChatRemind;  
 | 
        [SerializeField] RectTransform m_Scroller;  
 | 
  
 | 
        [SerializeField, Header("锁定当前区域比例"), Range(0, 1)] float m_Percent = 0.3f;  
 | 
  
 | 
        [SerializeField] ChatPlayerMineCell m_ChatMineCell;  
 | 
        [SerializeField] ChatPlayerOtherCell m_ChatOtherCell;  
 | 
        [SerializeField] ChatMineVoiceCell m_ChatMineVoiceCell;  
 | 
        [SerializeField] ChatOtherVoiceCell m_ChatOtherVoiceCell;  
 | 
  
 | 
        private ChatInfoType m_ChatType = ChatInfoType.System;  
 | 
        public ChatInfoType chatType  
 | 
        {  
 | 
            get  
 | 
            {  
 | 
                return m_ChatType;  
 | 
            }  
 | 
            set  
 | 
            {  
 | 
                bool isChange = m_ChatType != value;  
 | 
                ResetNewInfo();  
 | 
                m_ChatType = value;  
 | 
                DisplayChatContent();  
 | 
                if (isChange)  
 | 
                {  
 | 
                    DisplayChatRemind();  
 | 
                }  
 | 
            }  
 | 
        }  
 | 
  
 | 
        public ScrollerController chatContentControl  
 | 
        {  
 | 
            get  
 | 
            {  
 | 
                return m_ChatContentControl;  
 | 
            }  
 | 
        }  
 | 
  
 | 
        private int cacheChatCount = 0;  
 | 
        private bool onCheckArea = false;  
 | 
  
 | 
        ChatCenter m_ChatCenter;  
 | 
        ChatCenter chatCenter  
 | 
        {  
 | 
            get  
 | 
            {  
 | 
                return m_ChatCenter ?? (m_ChatCenter = ModelCenter.Instance.GetModel<ChatCenter>());  
 | 
            }  
 | 
        }  
 | 
  
 | 
        FriendsModel friendModel  
 | 
        {  
 | 
            get { return ModelCenter.Instance.GetModel<FriendsModel>(); }  
 | 
        }  
 | 
  
 | 
        private void Awake()  
 | 
        {  
 | 
            m_ChatContentControl.OnGetDynamicSize += OnGetChatDynamicSize;  
 | 
            m_NewInfoBtn.onClick.AddListener(OnNewInfo);  
 | 
            m_LockAreaBtn.onClick.AddListener(OnLockAreaBtn);  
 | 
            m_ChatContentControl.mScrollRect.onValueChanged.AddListener(OnScrollValChange);  
 | 
  
 | 
            if (m_DestSysText.font == null)  
 | 
            {  
 | 
                m_DestSysText.font = FontUtility.preferred;  
 | 
            }  
 | 
            if (m_DestTipText.font == null)  
 | 
            {  
 | 
                m_DestTipText.font = FontUtility.preferred;  
 | 
            }  
 | 
        }  
 | 
  
 | 
        private void OnEnable()  
 | 
        {  
 | 
            DisplayChatContent();  
 | 
            DisplayChatRemind();  
 | 
            ChatCtrl.OnRefreshChat += OnRefreshChat;  
 | 
            ChatCtrl.OnRefreshPteChat += OnRefreshPteChat;  
 | 
            ChatCtrl.OnRefreshSelf += OnRefreshSelf;  
 | 
            ChatCtrl.Inst.OnPteChatChangeEvent += OnPteChatChangeEvent;  
 | 
            chatCenter.UpdateChatContent += UpdateChatContent;  
 | 
            PlayerDatas.Instance.playerDataRefreshEvent += PlayerDataRefreshInfoEvent;  
 | 
            friendModel.RefreshFriendCntEvent += RefreshFriendCntEvent;  
 | 
            friendModel.RefreshFriendModel += DisplayChatRemind;  
 | 
            ResetNewInfo();  
 | 
            UpdateChatContent();  
 | 
            if (m_ChatType == ChatInfoType.Friend)  
 | 
            {  
 | 
                DisplayChatContent();  
 | 
                JumpPteChatBottom();  
 | 
            }  
 | 
        }  
 | 
  
 | 
        private void OnPteChatChangeEvent()  
 | 
        {  
 | 
            if (m_ChatType == ChatInfoType.Friend)  
 | 
            {  
 | 
                DisplayChatContent();  
 | 
                DisplayChatRemind();  
 | 
                JumpPteChatBottom();  
 | 
            }  
 | 
        }  
 | 
  
 | 
        private void OnRefreshSelf(ChatData data)  
 | 
        {  
 | 
            chatCenter.ChangeChatValue(string.Empty, false, false);  
 | 
            ChatCtrl.Inst.itemPlaceList.Clear();  
 | 
            if (m_ChatType == ChatInfoType.Friend)  
 | 
            {  
 | 
                JumpPteChatBottom();  
 | 
            }  
 | 
            else  
 | 
            {  
 | 
                ChatCtrl.Inst.lockUpdate = false;  
 | 
            }  
 | 
            UpdateChatContent();  
 | 
        }  
 | 
  
 | 
        private void OnRefreshPteChat(ChatFriendData data)  
 | 
        {  
 | 
            if (data == null)  
 | 
            {  
 | 
                return;  
 | 
            }  
 | 
            if (data.toPlayer != ChatCtrl.Inst.PteChatID && data.player != ChatCtrl.Inst.PteChatID)  
 | 
            {  
 | 
                return;  
 | 
            }  
 | 
            DisplayChatContent(true);  
 | 
            float _displaySize = 0;  
 | 
            if (m_ChatContentControl.mScrollRect != null)  
 | 
            {  
 | 
                _displaySize = m_ChatContentControl.mScrollRect.content.sizeDelta.y;  
 | 
            }  
 | 
            if (data.player == PlayerDatas.Instance.baseData.PlayerID)  
 | 
            {  
 | 
                OnRefreshSelf(data);  
 | 
            }  
 | 
            else if (ChatCtrl.Inst.lockUpdate && _displaySize > m_ChatContentControl.m_Scorller.ScrollRectSize)  
 | 
            {  
 | 
                cacheChatCount++;  
 | 
                cacheChatCount = Mathf.Min(cacheChatCount, 999);  
 | 
                m_NewInfoText.text = Language.Get("ChatNewWord", cacheChatCount);  
 | 
                m_ContaienrNewInfo.SetActive(true);  
 | 
            }  
 | 
        }  
 | 
  
 | 
        private void OnScrollValChange(Vector2 _pos)  
 | 
        {  
 | 
            if (m_ChatContentControl.mScrollRect.verticalNormalizedPosition < 0.1f && m_ChatType == ChatInfoType.Friend)  
 | 
            {  
 | 
                ResetNewInfo();  
 | 
            }  
 | 
            if (m_ChatContentControl.m_Scorller._ScrollSize <= 0 || m_ChatType == ChatInfoType.Friend)  
 | 
            {  
 | 
                return;  
 | 
            }  
 | 
            float _value = m_Percent / m_ChatContentControl.m_Scorller._ScrollSize * m_ChatContentControl.m_Scorller.ScrollRectSize;  
 | 
            if (_pos.y <= _value)  
 | 
            {  
 | 
                if (ChatCtrl.Inst.lockUpdate && !onCheckArea)  
 | 
                {  
 | 
                    ChatCtrl.Inst.lockUpdate = false;  
 | 
                    UpdateLockAreaState();  
 | 
                    ResetNewInfo();  
 | 
                }  
 | 
                onCheckArea = true;  
 | 
            }  
 | 
            else  
 | 
            {  
 | 
                if (!ChatCtrl.Inst.lockUpdate)  
 | 
                {  
 | 
                    ChatCtrl.Inst.lockUpdate = true;  
 | 
                    UpdateChatContent();  
 | 
                }  
 | 
                onCheckArea = false;  
 | 
            }  
 | 
        }  
 | 
  
 | 
        private void OnLockAreaBtn()  
 | 
        {  
 | 
            ChatCtrl.Inst.lockUpdate = !ChatCtrl.Inst.lockUpdate;  
 | 
            UpdateChatContent();  
 | 
        }  
 | 
  
 | 
        private void OnRefreshChat(ChatInfoType _type)  
 | 
        {  
 | 
            if (_type == m_ChatType)  
 | 
            {  
 | 
                DisplayChatContent(true);  
 | 
                float _displaySize = 0;  
 | 
                if (m_ChatContentControl.mScrollRect != null)  
 | 
                {  
 | 
                    _displaySize = m_ChatContentControl.mScrollRect.content.sizeDelta.y;  
 | 
                }  
 | 
                if (ChatCtrl.Inst.lockUpdate && _displaySize > m_ChatContentControl.m_Scorller.ScrollRectSize)  
 | 
                {  
 | 
                    cacheChatCount++;  
 | 
                    cacheChatCount = Mathf.Min(cacheChatCount, 999);  
 | 
                    m_NewInfoText.text = Language.Get("ChatNewWord", cacheChatCount);  
 | 
                    m_ContaienrNewInfo.SetActive(true);  
 | 
                }  
 | 
            }  
 | 
        }  
 | 
  
 | 
        private void ResetNewInfo()  
 | 
        {  
 | 
            cacheChatCount = 0;  
 | 
            if (m_ContaienrNewInfo.gameObject.activeSelf)  
 | 
            {  
 | 
                m_ContaienrNewInfo.SetActive(false);  
 | 
            }  
 | 
        }  
 | 
  
 | 
        private void DisplayChatContent(bool _keep = false)  
 | 
        {  
 | 
            float _offset = KeepArea();  
 | 
  
 | 
            m_ChatContentControl.Refresh();  
 | 
  
 | 
            if (m_ChatType != ChatInfoType.Friend)  
 | 
            {  
 | 
                List<ChatData> _list = ChatCtrl.Inst.GetChatInfo(m_ChatType);  
 | 
                if (_list != null)  
 | 
                {  
 | 
                    for (int i = 0; i < _list.Count; i++)  
 | 
                    {  
 | 
                        switch (_list[i].type)  
 | 
                        {  
 | 
                            case ChatInfoType.World:  
 | 
                            case ChatInfoType.Area:  
 | 
                            case ChatInfoType.CrossServer:  
 | 
                            case ChatInfoType.Team:  
 | 
                            case ChatInfoType.Trumpet:  
 | 
                            case ChatInfoType.Fairy:  
 | 
                                ChatUeseData data = _list[i] as ChatUeseData;  
 | 
                                if (data.detailType == ChatInfoType.FairyQuestion  
 | 
                                    || data.detailType == ChatInfoType.FairyTip  
 | 
                                    || data.detailType == ChatInfoType.TeamTip)  
 | 
                                {  
 | 
                                    m_ChatContentControl.AddCell(ScrollerDataType.Extra1, i);  
 | 
                                }  
 | 
                                else  
 | 
                                {  
 | 
                                    if (data.IsSound)  
 | 
                                    {  
 | 
                                        m_ChatContentControl.AddCell(data.player == PlayerDatas.Instance.PlayerId ?  
 | 
                                            ScrollerDataType.Extra2 : ScrollerDataType.Extra3, i);  
 | 
                                        break;  
 | 
                                    }  
 | 
                                    if (data.player == PlayerDatas.Instance.baseData.PlayerID)  
 | 
                                    {  
 | 
                                        m_ChatContentControl.AddCell(ScrollerDataType.Header, i);  
 | 
                                    }  
 | 
                                    else  
 | 
                                    {  
 | 
                                        m_ChatContentControl.AddCell(ScrollerDataType.Normal, i);  
 | 
                                    }  
 | 
                                }  
 | 
                                break;  
 | 
                            case ChatInfoType.Invite:  
 | 
                            case ChatInfoType.System:  
 | 
                                {  
 | 
                                    m_ChatContentControl.AddCell(ScrollerDataType.Tail, i);  
 | 
                                }  
 | 
                                break;  
 | 
                        }  
 | 
                    }  
 | 
                }  
 | 
            }  
 | 
            else  
 | 
            {  
 | 
                List<ChatFriendData> _list = ChatCtrl.Inst.GetChatInfo(ChatCtrl.Inst.PteChatID);  
 | 
                if (_list != null)  
 | 
                {  
 | 
                    for (int i = 0; i < _list.Count; i++)  
 | 
                    {  
 | 
                        if (_list[i].IsSound)  
 | 
                        {  
 | 
                            m_ChatContentControl.AddCell(_list[i].player == PlayerDatas.Instance.PlayerId ?  
 | 
                                            ScrollerDataType.Extra2 : ScrollerDataType.Extra3, i);  
 | 
                            continue;  
 | 
                        }  
 | 
                        if (Regex.IsMatch(_list[i].content, ChatCtrl.KILL_IDENTIFY))  
 | 
                        {  
 | 
                            m_ChatContentControl.AddCell(ScrollerDataType.Tail, i);  
 | 
                            continue;  
 | 
                        }  
 | 
                        if (_list[i].player == PlayerDatas.Instance.baseData.PlayerID)  
 | 
                        {  
 | 
                            m_ChatContentControl.AddCell(ScrollerDataType.Header, i);  
 | 
                        }  
 | 
                        else  
 | 
                        {  
 | 
                            m_ChatContentControl.AddCell(ScrollerDataType.Normal, i);  
 | 
                        }  
 | 
                    }  
 | 
                }  
 | 
            }  
 | 
  
 | 
            m_ChatContentControl.Restart();  
 | 
  
 | 
            if (_keep && ChatCtrl.Inst.lockUpdate)  
 | 
            {  
 | 
                m_ChatContentControl.JumpIndex(-_offset, 0, EnhancedUI.EnhancedScroller.EnhancedScroller.TweenType.immediate);  
 | 
            }  
 | 
  
 | 
            m_LockAreaBtn.SetActive(m_ChatType != ChatInfoType.Friend);  
 | 
        }  
 | 
  
 | 
        private void DisplayChatRemind()  
 | 
        {  
 | 
            if (m_ContainerPrivateChatRemind != null)  
 | 
            {  
 | 
                bool requireRemind = false;  
 | 
                var _dict = friendModel.GetFriendInfoDict((byte)GroupType.RecentContact);  
 | 
                if (m_ChatType == ChatInfoType.Friend)  
 | 
                {  
 | 
                    if (WindowCenter.Instance.IsOpen<ChatWin>())  
 | 
                    {  
 | 
                        if (((_dict != null && _dict.Count > 0) ||  
 | 
                        friendModel.tempFriendData != null) && ChatCtrl.Inst.PteChatID > 0)  
 | 
                        {  
 | 
                            requireRemind = true;  
 | 
                        }  
 | 
                    }  
 | 
                    else  
 | 
                    {  
 | 
                        requireRemind = true;  
 | 
                    }  
 | 
                }  
 | 
                var displayAreaHeight = m_ContainerDisplay.rect.height;  
 | 
                m_ContainerPrivateChatRemind.SetActive(requireRemind);  
 | 
                if (requireRemind)  
 | 
                {  
 | 
                    displayAreaHeight = m_ContainerDisplay.rect.height - m_ContainerPrivateChatRemind.rect.height;  
 | 
                }  
 | 
                m_Scroller.sizeDelta = m_Scroller.sizeDelta.SetY(displayAreaHeight);  
 | 
            }  
 | 
        }  
 | 
  
 | 
        float KeepArea()  
 | 
        {  
 | 
            if (m_ChatContentControl.GetNumberOfCells(m_ChatContentControl.m_Scorller) == ChatCtrl.Inst.CHAT_INFO_CNT)  
 | 
            {  
 | 
                var count = 0;  
 | 
                if (m_ChatType == ChatInfoType.Friend)  
 | 
                {  
 | 
                    var list = ChatCtrl.Inst.GetChatInfo(ChatCtrl.Inst.PteChatID);  
 | 
                    count = list == null ? 0 : list.Count;  
 | 
                }  
 | 
                else  
 | 
                {  
 | 
                    var list = ChatCtrl.Inst.GetChatInfo(m_ChatType);  
 | 
                    count = list == null ? 0 : list.Count;  
 | 
                }  
 | 
                if (count == ChatCtrl.Inst.CHAT_INFO_CNT)  
 | 
                {  
 | 
                    var first_size = m_ChatContentControl.GetCellSize(0);  
 | 
                    return first_size;  
 | 
                }  
 | 
            }  
 | 
            return 0;  
 | 
        }  
 | 
  
 | 
        private void SoundReceiveEvent(ChatInfoType _type, int _index)  
 | 
        {  
 | 
            if (m_ChatType != _type)  
 | 
            {  
 | 
                return;  
 | 
            }  
 | 
            m_ChatContentControl.RefreshSingleCellView(_index);  
 | 
        }  
 | 
  
 | 
        private bool OnGetChatDynamicSize(ScrollerDataType _type, int _index, out float _height)  
 | 
        {  
 | 
            _height = 0;  
 | 
            ChatData chat = null;  
 | 
            if (m_ChatType == ChatInfoType.Friend)  
 | 
            {  
 | 
                var _list = ChatCtrl.Inst.GetChatInfo(ChatCtrl.Inst.PteChatID);  
 | 
                if (_list == null || _index >= _list.Count)  
 | 
                {  
 | 
                    return false;  
 | 
                }  
 | 
                chat = _list[_index];  
 | 
            }  
 | 
            else  
 | 
            {  
 | 
                List<ChatData> _list = ChatCtrl.Inst.GetChatInfo(m_ChatType);  
 | 
                if (_list == null || _index >= _list.Count)  
 | 
                {  
 | 
                    return false;  
 | 
                }  
 | 
                chat = _list[_index];  
 | 
            }  
 | 
            if (chat == null)  
 | 
            {  
 | 
                return false;  
 | 
            }  
 | 
            switch (_type)  
 | 
            {  
 | 
                case ScrollerDataType.Header:  
 | 
                    _height = m_ChatMineCell.GetHeight(chat.content, chat.infoList);  
 | 
                    return true;  
 | 
                case ScrollerDataType.Normal:  
 | 
                    _height = m_ChatOtherCell.GetHeight(chat.content, chat.infoList);  
 | 
                    return true;  
 | 
                case ScrollerDataType.Extra1:  
 | 
                case ScrollerDataType.Tail:  
 | 
                    _height = 30;  
 | 
                    break;  
 | 
                case ScrollerDataType.Extra2:  
 | 
                    _height = m_ChatMineVoiceCell.GetHeight(chat.content, chat.infoList);  
 | 
                    return true;  
 | 
                case ScrollerDataType.Extra3:  
 | 
                    _height = m_ChatOtherVoiceCell.GetHeight(chat.content, chat.infoList);  
 | 
                    return true;  
 | 
            }  
 | 
            OnGetChatDynamicHeight(chat.content, ref _height, _type, chat.infoList);  
 | 
            return true;  
 | 
        }  
 | 
  
 | 
        private void OnGetChatDynamicHeight(string _content, ref float _height, ScrollerDataType _type, ArrayList _infoList)  
 | 
        {  
 | 
            float _textHeight = 0;  
 | 
            if (_type == ScrollerDataType.Tail)  
 | 
            {  
 | 
                m_DestSysText.SetExtenalData(_infoList);  
 | 
                m_DestSysText.text = _content;  
 | 
                _textHeight = Mathf.Max(m_DestSysText.preferredHeight, m_DestSysText.fontSize);  
 | 
                _height += Mathf.Max(0, _textHeight - 23);  
 | 
            }  
 | 
            else if (_type == ScrollerDataType.Extra1)  
 | 
            {  
 | 
                m_DestTipText.SetExtenalData(_infoList);  
 | 
                m_DestTipText.text = _content;  
 | 
                _textHeight = Mathf.Max(m_DestTipText.preferredHeight, m_DestTipText.fontSize);  
 | 
                _height += Mathf.Max(0, _textHeight - 23);  
 | 
            }  
 | 
        }  
 | 
  
 | 
        private void UpdateChatContent()  
 | 
        {  
 | 
            UpdateLockAreaState();  
 | 
            if (!ChatCtrl.Inst.lockUpdate)  
 | 
            {  
 | 
                chatContentControl.ResetScrollPos();  
 | 
                ResetNewInfo();  
 | 
            }  
 | 
        }  
 | 
  
 | 
        private void UpdateLockAreaState()  
 | 
        {  
 | 
            chatContentControl.lockType = ChatCtrl.Inst.lockUpdate ? EnhanceLockType.KeepVertical : EnhanceLockType.LockVerticalBottom;  
 | 
            m_LockAreaCheck.SetActive(ChatCtrl.Inst.lockUpdate);  
 | 
        }  
 | 
  
 | 
        private void OnNewInfo()  
 | 
        {  
 | 
            if (m_ChatType != ChatInfoType.Friend)  
 | 
            {  
 | 
                ChatCtrl.Inst.lockUpdate = false;  
 | 
            }  
 | 
            else  
 | 
            {  
 | 
                JumpPteChatBottom();  
 | 
            }  
 | 
            UpdateChatContent();  
 | 
        }  
 | 
  
 | 
        private void JumpPteChatBottom()  
 | 
        {  
 | 
            ChatCtrl.Inst.lockUpdate = true;  
 | 
            chatContentControl.lockType = EnhanceLockType.LockVerticalBottom;  
 | 
            chatContentControl.ResetScrollPos();  
 | 
            ResetNewInfo();  
 | 
            chatContentControl.lockType = EnhanceLockType.KeepVertical;  
 | 
        }  
 | 
  
 | 
        private void OnDisable()  
 | 
        {  
 | 
            ChatCtrl.OnRefreshChat -= OnRefreshChat;  
 | 
            ChatCtrl.OnRefreshPteChat -= OnRefreshPteChat;  
 | 
            ChatCtrl.OnRefreshSelf -= OnRefreshSelf;  
 | 
            chatCenter.UpdateChatContent -= UpdateChatContent;  
 | 
            ChatCtrl.Inst.OnPteChatChangeEvent -= OnPteChatChangeEvent;  
 | 
            PlayerDatas.Instance.playerDataRefreshEvent -= PlayerDataRefreshInfoEvent;  
 | 
            friendModel.RefreshFriendCntEvent -= RefreshFriendCntEvent;  
 | 
            friendModel.RefreshFriendModel -= DisplayChatRemind;  
 | 
        }  
 | 
  
 | 
        private void RefreshFriendCntEvent(GroupType type, bool arg2)  
 | 
        {  
 | 
            if (type == GroupType.RecentContact && m_ChatType == ChatInfoType.Friend)  
 | 
            {  
 | 
                DisplayChatRemind();  
 | 
                if (WindowCenter.Instance.IsOpen<ChatWin>())  
 | 
                {  
 | 
                    var _dict = friendModel.GetFriendInfoDict((byte)GroupType.RecentContact);  
 | 
                    if (!_dict.ContainsKey((uint)ChatCtrl.Inst.PteChatID))  
 | 
                    {  
 | 
                        ChatCtrl.Inst.PteChatID = 0;  
 | 
                    }  
 | 
                }  
 | 
            }  
 | 
        }  
 | 
  
 | 
        private void PlayerDataRefreshInfoEvent(PlayerDataType refreshType)  
 | 
        {  
 | 
            if (refreshType == PlayerDataType.ExAttr10)  
 | 
            {  
 | 
                m_ChatContentControl.m_Scorller.RefreshActiveCellViews();  
 | 
            }  
 | 
        }  
 | 
    }  
 | 
}  
 | 
  
 |