private static void DrawGraphAttribute(KeyValuePair <string, VarTracerGraphItData> kv)
        {
            GUILayout.Label("Graph:" + kv.Key, NameLabel);
            int colorIndex = kv.Value.mData.Count;

            foreach (var varBodyName in GetAllVariableBodyFromChannel(kv.Key))
            {
                NameLabel.normal.textColor = Color.white;

                GUILayout.Label("LogicName:" + varBodyName, NameLabel);

                foreach (var entry in kv.Value.mData)
                {
                    var variable            = VarTracer.GetGraphItVariableByVariableName(entry.Key);
                    VarTracerDataInternal g = entry.Value;
                    if (variable.VarBodyName.Equals(varBodyName))
                    {
                        if (kv.Value.mData.Count >= 1)
                        {
                            NameLabel.normal.textColor = g.mColor;
                        }
                        GUILayout.Label("     [Variable]   " + entry.Key + ":" + g.mCurrentValue.ToString(VarTracerConst.NUM_FORMAT_2), NameLabel);
                    }
                }

                var varBody = VarTracer.Instance.groups[varBodyName];

                foreach (var eventName in varBody.EventInfos.Keys)
                {
                    colorIndex++;
                    NameLabel.normal.textColor = VarTracerUtils.GetColorByIndex(colorIndex);
                    GUILayout.BeginHorizontal();

                    Color saveColor = GUI.backgroundColor;
                    GUI.backgroundColor = NameLabel.normal.textColor;
                    GUILayout.Button("", EventButtonStyle, GUILayout.Width(10));
                    GUI.backgroundColor = saveColor;
                    var flag = EditorGUILayout.Toggle(varBody.EventInfos[eventName].IsCutFlag, GUILayout.Width(10));
                    if (flag != varBody.EventInfos[eventName].IsCutFlag)
                    {
                        varBody.EventInfos[eventName].IsCutFlag = flag;
                        if (flag)
                        {
                            varBody.EventInfos[eventName].TimeStamp = VarTracerUtils.GetTimeStamp();
                        }
                    }
                    GUILayout.Label("     <Event>    " + eventName, NameLabel);
                    GUILayout.EndHorizontal();
                }
            }

            if (kv.Value.mData.Count >= 1)
            {
                HoverText.normal.textColor = Color.white;
                GUILayout.Label("duration:" + (mWidth / kv.Value.XStep / VarTracerConst.FPS).ToString(VarTracerConst.NUM_FORMAT_3) + "(s)", HoverText, GUILayout.Width(140));
                kv.Value.XStep = GUILayout.HorizontalSlider(kv.Value.XStep, 0.1f, 15, GUILayout.Width(160));
            }
        }
        private static void ShowVariableCombine()
        {
            var targetGraphName = (mMouseSelectedGraphNum - 1).ToString();

            VarTracer.ClearGraph(targetGraphName);
            foreach (var varName in VarTracer.Instance.Graphs[targetGraphName].VariableCombineList)
            {
                VarTracer.AttachVariable(varName, targetGraphName);
            }
        }
        void OnEnable()
        {
            Application.runInBackground = true;
            EditorApplication.update   += Update;
            if (VarTracer.Instance != null)
            {
                if (VarTracer.Instance.Graphs.Count == 0)
                {
                    VarTracer.AddChannel();
                }

                bool constainsCamera = VarTracer.Instance.groups.ContainsKey("Camera");
                if (!constainsCamera || VarTracer.Instance.groups["Camera"].VariableDict.Count == 0)
                {
                    //VarTracerHandler.DefineVariable("CameraV_X", "Camera");
                    //VarTracerHandler.DefineVariable("CameraV_Y", "Camera");
                    //VarTracerHandler.DefineVariable("CameraV_Z", "Camera");
                    //VarTracerHandler.DefineVariable("CameraV_T", "Camera");

                    VarTracerHandler.DefineVariable("PlayerV_X", "Player");
                    VarTracerHandler.DefineVariable("PlayerV_Y", "Player");
                    VarTracerHandler.DefineVariable("PlayerV_Z", "Player");
                    VarTracerHandler.DefineVariable("CameraV_T", "Camera");

                    VarTracerHandler.DefineVariable("FPS", "System");

                    VarTracerHandler.DefineEvent("JUMP", "Camera");
                    VarTracerHandler.DefineEvent("ATTACK", "Camera");

                    //VarTracerHandler.DefineVariable("NpcV_X", "Npc");
                    //VarTracerHandler.DefineVariable("NpcV_Y", "Npc");
                    //VarTracerHandler.DefineVariable("NpcV_Z", "Npc");
                    //VarTracerHandler.DefineVariable("NpcV_T", "Npc");
                }
            }
            VarTracer.AddChannel();
        }
        public static void DrawGraphs(Rect rect, EditorWindow window)
        {
            if (VarTracer.Instance)
            {
                CreateLineMaterial();

                mLineMaterial.SetPass(0);

                int graph_index = 0;

                //use this to get the starting y position for the GL rendering
                Rect find_y = EditorGUILayout.BeginVertical(GUIStyle.none);
                EditorGUILayout.EndVertical();

                int currentFrameIndex = VarTracerNet.Instance.GetCurrentFrameFromTimestamp(VarTracerUtils.GetTimeStamp());
                if (m_isPaused)
                {
                    currentFrameIndex = VarTracerNet.Instance.GetCurrentFrameFromTimestamp(VarTracerUtils.StopTimeStamp);
                }

                float scrolled_y_pos = y_offset - mGraphViewScrollPos.y;
                if (Event.current.type == EventType.Repaint)
                {
                    GL.PushMatrix();
                    float start_y = find_y.y;
                    GL.Viewport(new Rect(0, 0, rect.width, rect.height - start_y));
                    GL.LoadPixelMatrix(0, rect.width, rect.height - start_y, 0);

                    //Draw grey BG
                    GL.Begin(GL.QUADS);
                    GL.Color(new Color(0.2f, 0.2f, 0.2f));

                    foreach (KeyValuePair <string, VarTracerGraphItData> kv in VarTracer.Instance.Graphs)
                    {
                        float height = kv.Value.GetHeight();

                        GL.Vertex3(x_offset, scrolled_y_pos, 0);
                        GL.Vertex3(x_offset + mWidth, scrolled_y_pos, 0);
                        GL.Vertex3(x_offset + mWidth, scrolled_y_pos + height, 0);
                        GL.Vertex3(x_offset, scrolled_y_pos + height, 0);

                        scrolled_y_pos += (height + y_gap);
                    }
                    GL.End();

                    scrolled_y_pos = y_offset - mGraphViewScrollPos.y;
                    //Draw Lines
                    GL.Begin(GL.LINES);

                    foreach (KeyValuePair <string, VarTracerGraphItData> kv in VarTracer.Instance.Graphs)
                    {
                        graph_index++;
                        float height = kv.Value.GetHeight();
                        DrawGraphGridLines(scrolled_y_pos, mWidth, height, graph_index == mMouseSelectedGraphNum);

                        foreach (KeyValuePair <string, VarTracerDataInternal> entry in kv.Value.mData)
                        {
                            VarTracerDataInternal g = entry.Value;

                            float y_min   = kv.Value.GetMin(entry.Key);
                            float y_max   = kv.Value.GetMax(entry.Key);
                            float y_range = Mathf.Max(y_max - y_min, 0.00001f);

                            //draw the 0 line
                            if (y_min != 0.0f)
                            {
                                GL.Color(Color.white);
                                float y = scrolled_y_pos + height * (1 - (0.0f - y_min) / y_range);
                                Plot(x_offset, y, x_offset + mWidth, y);
                            }

                            GL.Color(g.mColor);

                            float previous_value = 0, value = 0;
                            int   dataInfoIndex = 0, frameIndex = 0;
                            for (int i = 0; i <= currentFrameIndex; i++)
                            {
                                int dataCount = g.mDataInfos.Count;
                                if (dataCount != 0)
                                {
                                    int   lastFrame = g.mDataInfos[dataCount - 1].FrameIndex;
                                    float lastValue = g.mDataInfos[dataCount - 1].Value;
                                    frameIndex = g.mDataInfos[dataInfoIndex].FrameIndex;

                                    if (dataInfoIndex >= 1)
                                    {
                                        value = g.mDataInfos[dataInfoIndex - 1].Value;
                                    }

                                    if (dataInfoIndex == 0 && i < frameIndex)
                                    {
                                        value = 0;
                                    }

                                    if (i >= frameIndex)
                                    {
                                        while (g.mDataInfos[dataInfoIndex].FrameIndex == frameIndex && dataInfoIndex < dataCount - 1)
                                        {
                                            dataInfoIndex++;
                                        }
                                    }

                                    if (i > lastFrame)
                                    {
                                        value = lastValue;
                                    }
                                }
                                else
                                {
                                    value = 0;
                                }

                                if (i >= 1)
                                {
                                    float x0 = x_offset + (i - 1) * kv.Value.XStep - kv.Value.ScrollPos.x;
                                    if (x0 <= x_offset - kv.Value.XStep)
                                    {
                                        continue;
                                    }
                                    if (x0 >= mWidth + x_offset)
                                    {
                                        break;
                                    }
                                    float y0 = scrolled_y_pos + height * (1 - (previous_value - y_min) / y_range);

                                    if (i == 1)
                                    {
                                        x0 = x_offset;
                                        y0 = scrolled_y_pos + height;
                                    }

                                    float x1 = x_offset + i * kv.Value.XStep - kv.Value.ScrollPos.x;
                                    float y1 = scrolled_y_pos + height * (1 - (value - y_min) / y_range);

                                    if (m_isDrawLine)
                                    {
                                        Plot(x0, y0, x1, y1);
                                    }
                                    else
                                    {
                                        Plot(x0, y0, x0 + 1, y0 + 1);
                                    }
                                }
                                previous_value = value;
                            }
                        }
                        scrolled_y_pos += (height + y_gap);
                    }
                    GL.End();

                    scrolled_y_pos = y_offset - mGraphViewScrollPos.y;
                    scrolled_y_pos = ShowEventLabel(scrolled_y_pos);
                    GL.PopMatrix();

                    GL.Viewport(new Rect(0, 0, rect.width, rect.height));
                    GL.LoadPixelMatrix(0, rect.width, rect.height, 0);
                }

                float allGraphHieght = (VarTracerConst.DefaultChannelHieght + y_gap) * VarTracer.Instance.Graphs.Count - y_gap - mGraphViewScrollPos.y;
                Rect  rec            = new Rect(10, allGraphHieght, 100, 1000);
                GUILayout.BeginArea(rec);
                GUILayout.BeginHorizontal();
                if (GUILayout.Button("+", GUILayout.Width(20), GUILayout.Height(20)))
                {
                    VarTracer.AddChannel();
                }

                if (GUILayout.Button("-", GUILayout.Width(20), GUILayout.Height(20)))
                {
                    VarTracer.RemoveChannel();
                }

                GUILayout.EndHorizontal();
                GUILayout.EndArea();

                mGraphViewScrollPos = EditorGUILayout.BeginScrollView(mGraphViewScrollPos, GUIStyle.none);
                GUILayout.Label("", GUILayout.Height((VarTracerConst.DefaultChannelHieght + y_gap) * VarTracer.Instance.Graphs.Count + y_offset + m_controlScreenHeight));
                graph_index = 0;
                mWidth      = window.position.width - VarTracerConst.NavigationAreaRWidth;
                foreach (KeyValuePair <string, VarTracerGraphItData> kv in VarTracer.Instance.Graphs)
                {
                    graph_index++;
                    float height = kv.Value.GetHeight();
                    float width  = currentFrameIndex * kv.Value.XStep;
                    if (width < mWidth)
                    {
                        width = mWidth - x_offset;
                    }
                    else
                    {
                        if (!m_isPaused)
                        {
                            kv.Value.ScrollPos = new Vector2(width - mWidth, kv.Value.ScrollPos.y);
                        }
                    }

                    GUIStyle s = new GUIStyle();
                    s.fixedHeight  = height + y_gap;
                    s.stretchWidth = true;
                    Rect r = EditorGUILayout.BeginVertical(s);

                    //skip subgraph title if only one, and it's the same.
                    NameLabel.normal.textColor = Color.white;

                    r.height = height + 50;
                    r.width  = width;
                    r.x      = x_offset - 35;
                    r.y      = (height + y_gap) * (graph_index - 1) - 10;

                    if (kv.Value.mData.Count > 0)
                    {
                        GUILayout.BeginArea(r);
                        GUILayout.BeginVertical();
                        for (int i = 0; i < VarTracerConst.Graph_Grid_Row_Num + 1; i++)
                        {
                            GUILayout.Space(6);
                            EditorGUILayout.LabelField("");
                        }
                        GUILayout.BeginHorizontal();
                        kv.Value.ScrollPos = GUILayout.BeginScrollView(kv.Value.ScrollPos, GUILayout.Width(mWidth), GUILayout.Height(0));
                        GUILayout.Label("", GUILayout.Width(width), GUILayout.Height(0));
                        GUILayout.EndScrollView();
                        GUILayout.EndHorizontal();
                        GUILayout.EndVertical();
                        GUILayout.EndArea();
                    }

                    r.width = mWidth + 35;
                    ////Respond to mouse input!
                    if (Event.current.type == EventType.MouseDrag && r.Contains(Event.current.mousePosition - Event.current.delta))
                    {
                        if (Event.current.button == 0)
                        {
                            kv.Value.ScrollPos = new Vector2(kv.Value.ScrollPos.x + Event.current.delta.x, kv.Value.ScrollPos.y);
                        }
                        window.Repaint();
                    }
                    else if (Event.current.type == EventType.MouseDown && r.Contains(Event.current.mousePosition))
                    {
                        mMouseSelectedGraphNum = graph_index;
                    }

                    EditorGUILayout.EndVertical();
                }
                EditorGUILayout.EndScrollView();
            }
        }
        void DrawVariableBar()
        {
            GUILayout.BeginVertical();
            GUILayout.BeginHorizontal();
            GUILayout.Space(10);

            var variableCombineList = VarTracer.Instance.Graphs[(mMouseSelectedGraphNum - 1).ToString()].VariableCombineList;

            for (int i = 0; i < variableCombineList.Count; i++)
            {
                if (GUILayout.Button(variableCombineList[i], VarSelectedBtnStyle, GUILayout.Width(90)))
                {
                    variableCombineList.Remove(variableCombineList[i]);
                    ShowVariableCombine();
                }
            }
            GUILayout.Space(20);

            if (GUILayout.Button("Clear", EditorStyles.toolbarButton, GUILayout.Width(50), GUILayout.Height(25)))
            {
                variableCombineList.Clear();
                ShowVariableCombine();
            }

            if (GUILayout.Button("Clear All", EditorStyles.toolbarButton, GUILayout.Width(100)))
            {
                VarTracer.ClearAll();
            }

            GUI.SetNextControlName("LoginIPTextField");
            var currentStr = GUILayout.TextField(_IPField, GUILayout.Width(120));

            if (!_IPField.Equals(currentStr))
            {
                _IPField = currentStr;
            }

            if (GUI.GetNameOfFocusedControl().Equals("LoginIPTextField") && _IPField.Equals(VarTracerConst.RemoteIPDefaultText))
            {
                _IPField = "";
            }

            bool savedState = GUI.enabled;

            bool connected = NetManager.Instance != null && NetManager.Instance.IsConnected;

            GUI.enabled = !connected;
            if (GUILayout.Button("Connect", EditorStyles.toolbarButton, GUILayout.Width(80)))
            {
                _connectPressed = true;
            }
            GUI.enabled = connected;
            GUI.enabled = savedState;

            string buttonName;

            if (m_isDrawLine)
            {
                buttonName = "Draw Point";
            }
            else
            {
                buttonName = "Draw Line";
            }
            if (GUILayout.Button(buttonName, EditorStyles.toolbarButton, GUILayout.Width(100)))
            {
                m_isDrawLine = !m_isDrawLine;
            }

            if (m_isPaused)
            {
                buttonName = "Resume";
            }
            else
            {
                buttonName = "Pause";
            }
            if (GUILayout.Button(buttonName, EditorStyles.toolbarButton, GUILayout.Width(100)))
            {
                m_isPaused = !m_isPaused;
                if (m_isPaused)
                {
                    StopVarTracer();
                }
                else
                {
                    StartVarTracer();
                }
            }
            GUILayout.EndHorizontal();

            var lineNum = CalculateVariableLineNum();
            var varList = GetVariableList();

            for (int i = 0; i < lineNum; i++)
            {
                GUILayout.BeginHorizontal();
                GUILayout.Space(10);
                for (int j = 0; j < variableNumPerLine; j++)
                {
                    if (j + i * variableNumPerLine >= varList.Count)
                    {
                        continue;
                    }
                    var var       = varList[j + i * variableNumPerLine];
                    var saveColor = GUI.color;
                    if (VarTracer.IsVariableOnShow(var.VarName))
                    {
                        GUI.color = Color.white;
                    }

                    if (GUILayout.Button(var.VarName, EditorStyles.toolbarButton, GUILayout.Width(100)))
                    {
                        if (!variableCombineList.Contains(var.VarName))
                        {
                            variableCombineList.Add(var.VarName);
                            ShowVariableCombine();
                        }
                        else
                        {
                            variableCombineList.Remove(variableCombineList[i]);
                            ShowVariableCombine();
                        }
                    }

                    GUI.color = saveColor;
                }
                GUILayout.EndHorizontal();
            }

            GUILayout.EndVertical();
        }