﻿using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// A console to display Unity’s debug logs in-game.
/// </summary>
public class ScreenLoger : MonoBehaviour
{
    struct Log
    {
        public string message;
        public string stackTrace;
        public LogType type;
    }

    public GameObject scrollView;
    public GameObject callbackView;
    public TMPro.TMP_Text logInfo;
    public GameObject scrollContent;

    #region Inspector Settings

    /// <summary>
    /// The hotkey to show and hide the console window.
    /// </summary>
    public KeyCode toggleKey = KeyCode.F1;

    /// <summary>
    /// Whether to open the window by shaking the device (mobile-only).
    /// </summary>
    public bool shakeToOpen = true;

    /// <summary>
    /// The (squared) acceleration above which the window should open.
    /// </summary>
    public float shakeAcceleration = 3f;

    /// <summary>
    /// Whether to only keep a certain number of logs.
    ///
    /// Setting this can be helpful if memory usage is a concern.
    /// </summary>
    public bool restrictLogCount = false;

    /// <summary>
    /// Number of logs to keep before removing old ones.
    /// </summary>
    public int maxLogs = 1000;
    #endregion
    readonly List<Log> logs = new List<Log>();
    Vector2 scrollPosition;
    bool visible;

    void Awake()
    {
        DontDestroyOnLoad(gameObject);
    }

    void OnEnable()
    {
#if UNITY_5
        Application.logMessageReceived += HandleLog;
#else
        Application.RegisterLogCallback(HandleLog);
#endif
    }

    void OnDisable()
    {
#if UNITY_5
        Application.logMessageReceived -= HandleLog;
#else
        Application.RegisterLogCallback(null);
#endif
    }

    public void showOrHide()
    {
        visible = !visible;
        scrollView.SetActive(visible);
        callbackView.SetActive(!visible);
    }

    public void clearLog()
    {
        logs.Clear();
        refreshOnTxt();
    }

    /// <summary>
    /// Records a log from the log callback.
    /// </summary>
    /// <param name="message">Message.</param>
    /// <param name="stackTrace">Trace of where the message came from.</param>
    /// <param name="type">Type of message (error, exception, warning, assert).</param>
    void HandleLog(string message, string stackTrace, LogType type)
    {
        //if (message == "DllNotFoundException: Microsoft_Xbox_Services_141_GDK_C_Thunks")
        //{
        //    return;
        //}
        logs.Add(new Log
        {
            message = message,
            stackTrace = stackTrace,
            type = type,
        });
        refreshOnTxt();
        TrimExcessLogs();
    }

    void refreshOnTxt()
    {
        string log = "";
        float infoMaxWidth = 1214f;
        float contentMaxWidth = 600;
        for (var i = 0; i < logs.Count; i++)
        {
            var loga = logs[i];
            if (loga.message.StartsWith("The character with Unicode value "))
            {
                continue;
            }
            log = log + loga.message + "\n";
            float curlength = loga.message.Length * 8.0f;
            if (curlength > infoMaxWidth)
            {
                infoMaxWidth = curlength;
            }
            float curCplength = loga.message.Length * 5.0f;
            if (curCplength > contentMaxWidth)
            {
                contentMaxWidth = curCplength;
            }
        }
        logInfo.text = log;
        var tr = scrollContent.GetComponent<RectTransform>();
        tr.sizeDelta = new Vector2(contentMaxWidth, logs.Count * 16.3f);
        var infotr = logInfo.GetComponent<RectTransform>();
        infotr.sizeDelta = new Vector2(infoMaxWidth, 571);


    }
    /// <summary>
    /// Removes old logs that exceed the maximum number allowed.
    /// </summary>
    void TrimExcessLogs()
    {
        var amountToRemove = Mathf.Max(logs.Count - maxLogs, 0);
        if (amountToRemove != 0)
        {
            Debug.Log("超了啊");
            logs.RemoveRange(0, amountToRemove);
        }
    }
}