using Agora.Rtc;
using Agora.Util;
using SC.XR.Unity;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;
using XRTool.Util;
using Logger = Agora.Util.Logger;

public class AgoraVideoAudioManager : SingletonMono<AgoraVideoAudioManager>
{
    [FormerlySerializedAs("appIdInput")]
    [SerializeField]
    private AppIdInput _appIdInput;

    [Header("_____________Basic Configuration_____________")]
    [FormerlySerializedAs("APP_ID")]
    [SerializeField]
    private string _appID = "";

    [FormerlySerializedAs("TOKEN")]
    [SerializeField]
    private string _token = "";

    [FormerlySerializedAs("CHANNEL_NAME")]
    [SerializeField]
    private string _channelName = "";

    internal IRtcEngine RtcEngine = null;

    internal Logger Log;

    private bool isAudio;
    private bool isVideo;

    //private static List<Agora.Rtc.UserInfo> list_UserInfo;
    private Dictionary<string, uint> dicPeeridAndUid;
    public Text LogText;

    private bool isRoom;
    private CustomPeer myPeer;
    public uint uid;
    public string userAccount;
  //  private Dictionary<string, RawImage> list_ShowView;
    
    public MenuIcon menuIcon;

    public bool isSwitchCamera;
    // Use this for initialization

    public List<CustomPeer> listCustomPeer;
    private void Start()
    {
        LoadAssetData();
        if (CheckAppId())
        {
            InitEngine();
            //SetChinnelName("0003003");
            //JoinChannel();
            //SetupUI();
        }
        //list_UserInfo = new List<Agora.Rtc.UserInfo>();
    //    list_ShowView = new Dictionary<string, RawImage>();
        dicPeeridAndUid = new Dictionary<string, uint>();
        isRoom = false;
        isSwitchCamera = false;
        listCustomPeer = new List<CustomPeer>();
    
}

    // Update is called once per frame
    private void Update()
    {
        PermissionHelper.RequestMicrophontPermission();
        PermissionHelper.RequestCameraPermission();
      
        //if(isRoom&&CommonMethod.MyPeer!=null&&list_ShowView.Count>0)
        //{
        //    if(myPeer==null)
        //    {
        //        myPeer = (CustomPeer)StudioRtc.Instance.customPeerList.getPeerName(CommonMethod.MyPeer.PeerId);
        //        Debug.Log(" Get  MyCustomPeer");
        //    }

        //    if (myPeer == null) return;

        //    if (isAudio != myPeer.isAudio)
        //    {
        //        isAudio = myPeer.isAudio;
        //        EnableLoacalAudio(isAudio);
        //    }
           
        //    if(isVideo!= myPeer.isVideo)
        //    {
        //        isVideo = myPeer.isVideo;
        //        EnableLocalVideo(isVideo);
        //    }
        //}

    }

    //Show data in AgoraBasicProfile
    [ContextMenu("ShowAgoraBasicProfileData")]
    private void LoadAssetData()
    {
        if (_appIdInput == null) return;
        _appID = _appIdInput.appID;
        _token = _appIdInput.token;
        _channelName = _appIdInput.channelName;
    }


    private bool CheckAppId()
    {
        Log = new Logger(LogText);
        return Log.DebugAssert(_appID.Length > 10, "Please fill in your appId in API-Example/profile/appIdInput.asset");
    }

    private void InitEngine()
    {
       
        RtcEngine = Agora.Rtc.RtcEngine.CreateAgoraRtcEngine();
       
        AgoraVideoManagerHandler handler = new AgoraVideoManagerHandler(this);
        RtcEngineContext context = new RtcEngineContext(_appID, 0,
                                    CHANNEL_PROFILE_TYPE.CHANNEL_PROFILE_COMMUNICATION,
                                    AUDIO_SCENARIO_TYPE.AUDIO_SCENARIO_DEFAULT);
        RtcEngine.Initialize(context);
        RtcEngine.InitEventHandler(handler);

        
    }

    public void RegisterLocalUserAccount(string peerId)
    {
        RtcEngine.RegisterLocalUserAccount(_appID, peerId);
    }

    public void SetChinnelName(string roomid)
    {
        _channelName = roomid;
    }

    public void JoinChannel( )
    {
        Debug.Log("  JoinChannel  " + _channelName);
        RtcEngine.EnableAudio();
        RtcEngine.EnableVideo();

       // RtcEngine.DisableAudio();
       //  RtcEngine.DisableVideo();
        VideoEncoderConfiguration config = new VideoEncoderConfiguration();
        config.dimensions = new VideoDimensions(1280, 720);
        config.frameRate = 15;
        config.bitrate = 0;
        RtcEngine.SetVideoEncoderConfiguration(config);
        RtcEngine.SetChannelProfile(CHANNEL_PROFILE_TYPE.CHANNEL_PROFILE_COMMUNICATION);
        RtcEngine.SetClientRole(CLIENT_ROLE_TYPE.CLIENT_ROLE_BROADCASTER);
        // _channelName = roomid;
        
        RtcEngine.JoinChannel(_token, _channelName,"", uid);

        //RtcEngine.MuteLocalVideoStream(false);
        //RtcEngine.MuteLocalAudioStream(false);
        //RtcEngine.MuteAllRemoteAudioStreams(true);
        //RtcEngine.MuteAllRemoteVideoStreams(true);
        isRoom = true;

        //if(!isSwitchCamera)
        //{
        //    RtcEngine.SwitchCamera();
        //    isSwitchCamera = !isSwitchCamera;
        //}
      

        //if (_channelName== "0003003")
        //{
           
        //    StartCoroutine(CloseChannel(10f));
        //}
    }

    public void OpenAgoraAudio()
    {
        Debug.Log(" 打开   OpenAgoraAudio ");
       // RtcEngine.SwitchCamera();
        //RtcEngine.MuteAllRemoteAudioStreams(false);
        //RtcEngine.MuteAllRemoteVideoStreams(false);
        //   RtcEngine.EnableAudio();
    }

    private IEnumerator CloseChannel( float times)
    {
        yield return new WaitForSeconds(times);
        LeaveChannel();
    }

    public void LeaveChannel()
    {
        Debug.Log("LeaveChannel "  ); 
        int msg = RtcEngine.LeaveChannel();
        switch (msg)
        {
            case 0:
                LogText.text = "成功退出频道: " + _channelName;
                break;
            default:
                LogText.text = "退出频道失败: " + msg;
                break;
        }
        isRoom = false;
        myPeer = null;
        dicPeeridAndUid.Clear();
        dicPeeridAndUid = new Dictionary<string, uint>();
        //list_ShowView.Clear();
        //list_ShowView = new Dictionary<string, RawImage>();
        AgoraVideoAudioManager.Instance.listCustomPeer.Clear();
        AgoraVideoAudioManager.Instance.listCustomPeer = new List<CustomPeer>();
    }

    public void VuforiaLeaveChannel()
    {
        int msg = RtcEngine.LeaveChannel();
        switch (msg)
        {
            case 0:
                LogText.text = "成功退出频道: " + _channelName;
                break;
            default:
                LogText.text = "退出频道失败: " + msg;
                break;
        }
    }

    public void AddPeeridUid(string peerid, uint uid)
    {
        Debug.Log(" AddPeeridUid " + peerid + "   " + uid);

        if (dicPeeridAndUid.ContainsKey(peerid))
            return;
        dicPeeridAndUid.Add(peerid, uid);
    }

    public void RemAtPeeridUid(string peerid)
    {
        if (!dicPeeridAndUid.ContainsKey(peerid))
            return;
        Debug.Log(" RemAtPeeridUid " + peerid + "   " + dicPeeridAndUid[peerid]);
        dicPeeridAndUid.Remove(peerid);

        CloseAgoraMainImage(peerid, false);

        for (int i = 0; i < listCustomPeer.Count; i++)
        {
            if (listCustomPeer[i].peerId == peerid)
                listCustomPeer.RemoveAt(i);
        }

    }
    private void CloseAgoraMainImage(string peerid, bool isOpen)
    {
        //if (peerid == mainViewPeerId)
        //    RoomMain.Instance.agoraRawImage.gameObject.SetActive(isOpen);
    }
    //public void RemAtListShowView(string peerId)
    //{
    //    if (list_ShowView.ContainsKey(peerId))
    //        list_ShowView.Remove(peerId);
    //}

    public void AddListShowView( string peerId, RawImage rawImage)
    {
        if (peerId == CommonMethod.MyPeer.PeerId)
        {
            rawImage.gameObject.SetActive(true);
            rawImage.rectTransform.localEulerAngles += new Vector3(0, 180, 180);
            MakeVideoView(0, rawImage);
        }
            

        if (peerId == CommonMethod.MyPeer.PeerId && !dicPeeridAndUid.ContainsKey(peerId))
            return;
         Debug.Log(" AddListShowView " + peerId);
      //  list_ShowView.Add(peerId, rawImage);
        rawImage.gameObject.SetActive(true);
        rawImage.rectTransform.localEulerAngles += new Vector3(0, 180, 180);

        MakeVideoView(dicPeeridAndUid[peerId], rawImage, this._channelName);
       
        //for (int i = 0; i < list_UserInfo.Count; i++)
        //{
        //    if(list_UserInfo[i].userAccount == peerId)
        //    {
        //        Debug.Log(" 查找到 ");
        //        MakeVideoView(list_UserInfo[i].uid,  rawImage,this._channelName );
        //        return;
        //    }
        //}
        //Debug.Log(" 未找到UID  ");

        //for (int i = 0; i < list_UserInfo.Count; i++)
        //{
        //    Debug.Log(list_UserInfo[i].uid + "   " + list_UserInfo[i].userAccount);
        //}
    }

    public void EnableLoacalAudio( bool isAudio)
    {
        int msg = RtcEngine.MuteLocalAudioStream(!isAudio);

      //  int msg = RtcEngine.EnableLocalAudio(isAudio);
        switch (msg)
        {
            case 0:
                Debug.Log( isAudio ? "打开本地音频成功" : "关闭本地音频成功 ");
                break;
            default:
                Debug.LogError("开关本地音频失败: " + msg);
                break;
        }
    }

    public void MuteRemoteAudioStream( string peerid , bool isAudio)
    {
        if (!dicPeeridAndUid.ContainsKey(peerid))
            return;
        int msg = RtcEngine.MuteRemoteAudioStream(dicPeeridAndUid[peerid], !isAudio);

        switch (msg)
        {
            case 0:
               Debug.Log( isAudio ? "订阅远端音频成功" : "取订远端音频成功 ");
                break;
            default:
                Debug.LogError( "开关本地音频失败: " + msg);
                break;
        }
    }
    public void MuteRemoteVideoStream(string peerid, bool isVideo)
    {
        if (!dicPeeridAndUid.ContainsKey(peerid))
            return;
        int msg = RtcEngine.MuteRemoteVideoStream(dicPeeridAndUid[peerid], !isVideo);

        switch (msg)
        {
            case 0:
                Debug.Log(isVideo ? "订阅远端视频成功" : "取订远端视频成功 ");
                break;
            default:
                Debug.LogError("开关本地音频失败: " + msg);
                break;
        }
    }
    public void EnableLocalVideo( bool isVideo)
    {
        //int msg = RtcEngine.MuteLocalVideoStream(!isVideo);
        //RtcEngine.EnableVideo();
        int msg = RtcEngine.EnableLocalVideo(isVideo);
        switch (msg)
        {
            case 0:
                Debug.Log( isVideo ? "打开本地视频成功 " : "关闭本地视频成功 ");
                break;
            default:
                Debug.LogError( "开关本地视频失败: " + msg);
                break;
        }
    }

    public void OnClickEnableLocalVideo( bool isVideo)
    {
        int msg = RtcEngine.EnableLocalVideo(isVideo);
        switch (msg)
        {
            case 0:
                LogText.text = isVideo ? "打开本地视频成功 " : "关闭本地视频成功 ";
                break;
            default:
                LogText.text = "开关本地视频失败: " + msg;
                break;
        }
    }

    public void RemoteVideoStateChanged(uint uid, REMOTE_VIDEO_STATE state, REMOTE_VIDEO_STATE_REASON
      reason)
    {
        Debug.Log("RemoteVideoStateChanged   " + uid);
        //if (!dicPeeridAndUid.ContainsValue(uid))
        //    return;
        for (int i = 0; i < listCustomPeer.Count; i++)
        {

            if (dicPeeridAndUid.ContainsKey(listCustomPeer[i].name) && dicPeeridAndUid[listCustomPeer[i].name] == uid)
            {
                Debug.Log("RemoteVideoStateChanged   " + 2);

                switch (state)
                {
                    case REMOTE_VIDEO_STATE.REMOTE_VIDEO_STATE_STOPPED:
                        break;
                    case REMOTE_VIDEO_STATE.REMOTE_VIDEO_STATE_STARTING:
                        listCustomPeer[i].isVideo = true;
                        break;
                    case REMOTE_VIDEO_STATE.REMOTE_VIDEO_STATE_DECODING:
                        break;
                    case REMOTE_VIDEO_STATE.REMOTE_VIDEO_STATE_FROZEN:
                        break;
                    case REMOTE_VIDEO_STATE.REMOTE_VIDEO_STATE_FAILED:
                        break;
                    default:
                        break;
                }

                switch (reason)
                {
                    case REMOTE_VIDEO_STATE_REASON.REMOTE_VIDEO_STATE_REASON_INTERNAL:
                        break;
                    case REMOTE_VIDEO_STATE_REASON.REMOTE_VIDEO_STATE_REASON_NETWORK_CONGESTION://网络阻塞。

                        //  listCustomPeer[i].isVideo = false;
                        break;
                    case REMOTE_VIDEO_STATE_REASON.REMOTE_VIDEO_STATE_REASON_NETWORK_RECOVERY:// 网络恢复正常。

                        //  listCustomPeer[i].isVideo = true;
                        break;
                    case REMOTE_VIDEO_STATE_REASON.REMOTE_VIDEO_STATE_REASON_LOCAL_MUTED://本地用户停止接收远端视频流或本地用户禁用视频模块

                        listCustomPeer[i].isCloseVideo = true;
                        break;
                    case REMOTE_VIDEO_STATE_REASON.REMOTE_VIDEO_STATE_REASON_LOCAL_UNMUTED://本地用户恢复接收远端视频流或本地用户启动视频模块

                        listCustomPeer[i].isCloseVideo = false;
                        break;
                    case REMOTE_VIDEO_STATE_REASON.REMOTE_VIDEO_STATE_REASON_REMOTE_MUTED://远端用户停止发送视频流或远端用户禁用视频模块。

                        listCustomPeer[i].isVideo = false;

                        break;
                    case REMOTE_VIDEO_STATE_REASON.REMOTE_VIDEO_STATE_REASON_REMOTE_UNMUTED://远端用户恢复发送视频流或远端用户启用视频模块。

                        listCustomPeer[i].isVideo = true;

                        break;
                    case REMOTE_VIDEO_STATE_REASON.REMOTE_VIDEO_STATE_REASON_REMOTE_OFFLINE: //远端用户离开频道。

                        listCustomPeer[i].isVideo = false;
                        break;
                    case REMOTE_VIDEO_STATE_REASON.REMOTE_VIDEO_STATE_REASON_AUDIO_FALLBACK:
                        break;
                    case REMOTE_VIDEO_STATE_REASON.REMOTE_VIDEO_STATE_REASON_AUDIO_FALLBACK_RECOVERY:
                        break;
                    case REMOTE_VIDEO_STATE_REASON.REMOTE_VIDEO_STATE_REASON_VIDEO_STREAM_TYPE_CHANGE_TO_LOW:
                        break;
                    case REMOTE_VIDEO_STATE_REASON.REMOTE_VIDEO_STATE_REASON_VIDEO_STREAM_TYPE_CHANGE_TO_HIGH:
                        break;
                    default:
                        break;
                }
                break;
            }
        }





    }

    public void RemoteAudioStateChanged(uint uid, REMOTE_AUDIO_STATE state, REMOTE_AUDIO_STATE_REASON reason)
    {
        Debug.Log("RemoteAudioStateChanged   " + uid);

        for (int i = 0; i < listCustomPeer.Count; i++)
        {

            if (dicPeeridAndUid.ContainsKey(listCustomPeer[i].name) && dicPeeridAndUid[listCustomPeer[i].name] == uid)
            {
                Debug.Log("RemoteAudioStateChanged   " + 2);

                switch (state)
                {
                    case REMOTE_AUDIO_STATE.REMOTE_AUDIO_STATE_STOPPED:
                        break;
                    case REMOTE_AUDIO_STATE.REMOTE_AUDIO_STATE_STARTING:
                        listCustomPeer[i].isAudio = true;
                        break;
                    case REMOTE_AUDIO_STATE.REMOTE_AUDIO_STATE_DECODING:
                        break;
                    case REMOTE_AUDIO_STATE.REMOTE_AUDIO_STATE_FROZEN:
                        break;
                    case REMOTE_AUDIO_STATE.REMOTE_AUDIO_STATE_FAILED:
                        break;
                    default:
                        break;
                }
                switch (reason)
                {
                    case REMOTE_AUDIO_STATE_REASON.REMOTE_AUDIO_REASON_INTERNAL:
                        break;
                    case REMOTE_AUDIO_STATE_REASON.REMOTE_AUDIO_REASON_NETWORK_CONGESTION:
                        //  listCustomPeer[i].isAudio = false;
                        break;
                    case REMOTE_AUDIO_STATE_REASON.REMOTE_AUDIO_REASON_NETWORK_RECOVERY:
                        //  listCustomPeer[i].isAudio = true;
                        break;
                    case REMOTE_AUDIO_STATE_REASON.REMOTE_AUDIO_REASON_LOCAL_MUTED:
                        listCustomPeer[i].isCloseAudio = true;
                        break;
                    case REMOTE_AUDIO_STATE_REASON.REMOTE_AUDIO_REASON_LOCAL_UNMUTED:
                        listCustomPeer[i].isCloseAudio = false;
                        break;
                    case REMOTE_AUDIO_STATE_REASON.REMOTE_AUDIO_REASON_REMOTE_MUTED:
                        listCustomPeer[i].isAudio = false;
                        break;
                    case REMOTE_AUDIO_STATE_REASON.REMOTE_AUDIO_REASON_REMOTE_UNMUTED:
                        listCustomPeer[i].isAudio = true;
                        break;
                    case REMOTE_AUDIO_STATE_REASON.REMOTE_AUDIO_REASON_REMOTE_OFFLINE:
                        listCustomPeer[i].isAudio = false;
                        break;
                    default:
                        break;
                }
                break;
            }
        }





    }

    private void StopPublish()
    {
        var options = new ChannelMediaOptions();
        options.publishMicrophoneTrack.SetValue(false);
        options.publishCameraTrack.SetValue(false);
        var nRet = RtcEngine.UpdateChannelMediaOptions(options);
        this.Log.UpdateLog("UpdateChannelMediaOptions: " + nRet);  
    }

    private void StartPublish()
    {
        var options = new ChannelMediaOptions();
        options.publishMicrophoneTrack.SetValue(true);
        options.publishCameraTrack.SetValue(true);
        var nRet = RtcEngine.UpdateChannelMediaOptions(options);
        this.Log.UpdateLog("UpdateChannelMediaOptions: " + nRet); 
    }

    private void OnDestroy()
    {
        Debug.Log("OnDestroy");
        if (RtcEngine == null) return;
        RtcEngine.InitEventHandler(null);
        RtcEngine.LeaveChannel();
        RtcEngine.Dispose();
    }

    internal static void MakeVideoView(uint uid, RawImage rawImage, string channelId = "")
    {
        Debug.Log("MakeVideoView   " + uid);
        //var go = GameObject.Find(uid.ToString());
        //if (!ReferenceEquals(go, null))
        //{
        //    return; // reuse
        //}

        // create a GameObject and assign to this new user
          var videoSurface = MakeImageSurface(rawImage);
       // var videoSurface = MakePlaneSurface(uid.ToString());
        if (ReferenceEquals(videoSurface, null)) return;
        // configure videoSurface
        if (uid == 0)
        {
            videoSurface.SetForUser(uid, channelId);
        }
        else
        {
            videoSurface.SetForUser(uid, channelId, VIDEO_SOURCE_TYPE.VIDEO_SOURCE_REMOTE);
        }

        //videoSurface.OnTextureSizeModify += (int width, int height) =>
        //{
        //    float scale = (float)height / (float)width;
        //    videoSurface.transform.localScale = new Vector3(-5, 5 * scale, 1);
        //    Debug.Log("OnTextureSizeModify: " + width + "  " + height);
        //};

        videoSurface.SetEnable(true);
    }

    //internal static void OnUserInfoUpdated(uint uid, Agora.Rtc.UserInfo info)
    //{
    //    Debug.Log(info.uid);
    //    disUserPeer_Uid.Add("", info);
    //}

    internal static void OnUserJoined(uint uid)
    {
       // _videoSample.Log.UpdateLog(string.Format("OnUserJoined uid: ${0} elapsed: ${1}", uid, elapsed));
       // Debug.Log(string.Format("OnUserJoined uid: ${0} elapsed: ${1}", uid, elapsed))
        Agora.Rtc.UserInfo userInfo = new Agora.Rtc.UserInfo();
        AgoraVideoAudioManager.Instance.RtcEngine.GetUserInfoByUid(uid, ref userInfo);
        
    }
    #region -- Video Render UI Logic ---

    // VIDEO TYPE 1: 3D Object
    private static VideoSurface MakePlaneSurface(string goName)
    {
        var go = GameObject.CreatePrimitive(PrimitiveType.Quad);

        //for (int i = 0; i < list_UserInfo.Count; i++)
        //{
        //    if (list_UserInfo[i].uid.ToString() == goName)
        //    {
        //        string userAccount = list_UserInfo[i].userAccount;
        //        if (AgoraVideoAudioManager.Instance.list_ShowView.ContainsKey(list_UserInfo[i].userAccount))
        //        {
        //            go = AgoraVideoAudioManager.Instance.list_ShowView[list_UserInfo[i].userAccount].gameObject;
        //        }
        //        else
        //            Debug.LogError("  Agora ShowView is NULL ");
        //    }
        //}

        if (go == null)
        {
            go = GameObject.CreatePrimitive(PrimitiveType.Plane);
            return null;
        }

        go.name = goName;
        // set up transform
        go.transform.Rotate(-90.0f, 0.0f, 0.0f);
        var yPos = Random.Range(3.0f, 5.0f);
        var xPos = Random.Range(-2.0f, 2.0f);
        go.transform.position = Vector3.zero;
        go.transform.localScale = new Vector3(0.25f, 0.5f, 0.5f);

        // configure videoSurface
        var videoSurface = go.AddComponent<VideoSurface>();
        return videoSurface;
    }

    // Video TYPE 2: RawImage
    private static VideoSurface MakeImageSurface(RawImage rawImage)
    {
        
        rawImage.gameObject.AddComponent<UIElementDrag>();   
        var videoSurface = rawImage.gameObject.AddComponent<VideoSurface>();
        return videoSurface;
    }

    internal static void DestroyVideoView(uint uid)
    {
        var go = GameObject.Find(uid.ToString());
        if (!ReferenceEquals(go, null))
        {
            Destroy(go);
        }
    }

   

    internal static void OnUserInfoUpdated(uint uid, Agora.Rtc.UserInfo info)
    {
        Debug.Log(uid.ToString() + "  " + info.uid + "  " + info.userAccount);
     //   list_UserInfo.Add(info);
        
    }

    internal static void  OnLocalUserRegistered(uint uid, string userAccount)
    {
        //AgoraVideoAudioManager.Instance.uid = uid;
        //AgoraVideoAudioManager.Instance.userAccount = userAccount;
    }
    internal static void OnRemoteVideoStateChanged(uint uid, REMOTE_VIDEO_STATE state, REMOTE_VIDEO_STATE_REASON
     reason)
    {
        AgoraVideoAudioManager.Instance.RemoteVideoStateChanged(uid, state, reason);
    }
    internal static void OnRemoteAudioStateChanged(uint uid, REMOTE_AUDIO_STATE state, REMOTE_AUDIO_STATE_REASON reason)
    {
        AgoraVideoAudioManager.Instance.RemoteAudioStateChanged(uid, state, reason);
    }
    #endregion
}

#region -- Agora Event ---

public class AgoraVideoManagerHandler : IRtcEngineEventHandler
{
    private readonly AgoraVideoAudioManager _videoSample;

    internal AgoraVideoManagerHandler(AgoraVideoAudioManager videoSample)
    {
        _videoSample = videoSample;
    }

    public override void OnError(int err, string msg)
    {
        _videoSample.Log.UpdateLog(string.Format("OnError err: {0}, msg: {1}", err, msg));
    }

    public override void OnJoinChannelSuccess(RtcConnection connection, int elapsed)
    {
        int build = 0;
        Debug.Log("Agora: OnJoinChannelSuccess ");
        _videoSample.Log.UpdateLog(string.Format("sdk version: ${0}",
            _videoSample.RtcEngine.GetVersion(ref build)));
        _videoSample.Log.UpdateLog(string.Format("sdk build: ${0}",
          build));
        _videoSample.Log.UpdateLog(
            string.Format("OnJoinChannelSuccess channelName: {0}, uid: {1}, elapsed: {2}",
                            connection.channelId, connection.localUid, elapsed));

      //  _videoSample.ClickSelf();
       // AgoraVideoAudioManager.MakeVideoView(0);

    }

    public override void OnRejoinChannelSuccess(RtcConnection connection, int elapsed)
    {
        _videoSample.Log.UpdateLog("OnRejoinChannelSuccess");
    }

    public override void OnLeaveChannel(RtcConnection connection, RtcStats stats)
    {
        _videoSample.Log.UpdateLog("OnLeaveChannel");
        AgoraVideoAudioManager.DestroyVideoView(0);
    }

    public override void OnClientRoleChanged(RtcConnection connection, CLIENT_ROLE_TYPE oldRole, CLIENT_ROLE_TYPE newRole)
    {
        _videoSample.Log.UpdateLog("OnClientRoleChanged");
    }

    public override void OnUserJoined(RtcConnection connection, uint uid, int elapsed)
    {
        Debug.Log(string.Format("OnUserJoined uid: ${0} elapsed: ${1}", uid, elapsed));
        _videoSample.Log.UpdateLog(string.Format("OnUserJoined uid: ${0} elapsed: ${1}", uid, elapsed));
        AgoraVideoAudioManager.OnUserJoined(uid);
     //   AgoraVideoAudioManager.MakeVideoView(uid, _videoSample.GetChannelName());
    }

    public override void OnUserOffline(RtcConnection connection, uint uid, USER_OFFLINE_REASON_TYPE reason)
    {
        _videoSample.Log.UpdateLog(string.Format("OnUserOffLine uid: ${0}, reason: ${1}", uid,
            (int)reason));
        AgoraVideoAudioManager.DestroyVideoView(uid);
    }

    public override void OnUserInfoUpdated(uint uid, Agora.Rtc.UserInfo info)
    {
        _videoSample.Log.UpdateLog(string.Format(" 用户 :${0}  加入房间", uid));

        AgoraVideoAudioManager.OnUserInfoUpdated(uid, info);
    }


    public override void OnUplinkNetworkInfoUpdated(UplinkNetworkInfo info)
    {
        _videoSample.Log.UpdateLog("OnUplinkNetworkInfoUpdated");
    }

    public override void OnDownlinkNetworkInfoUpdated(DownlinkNetworkInfo info)
    {
        _videoSample.Log.UpdateLog("OnDownlinkNetworkInfoUpdated");
    }

    public override void OnLocalUserRegistered(uint uid, string userAccount)
    {
        AgoraVideoAudioManager.OnLocalUserRegistered(uid, userAccount);
    }

    public override void OnRemoteVideoStateChanged(RtcConnection connection, uint remoteUid, REMOTE_VIDEO_STATE state, REMOTE_VIDEO_STATE_REASON reason, int elapsed)
    {
        AgoraVideoAudioManager.OnRemoteVideoStateChanged(remoteUid, state, reason);
    }

    public override void OnRemoteAudioStateChanged(RtcConnection connection, uint remoteUid, REMOTE_AUDIO_STATE state, REMOTE_AUDIO_STATE_REASON reason, int elapsed)
    {
        AgoraVideoAudioManager.OnRemoteAudioStateChanged(remoteUid, state, reason);
    }
}

#endregion