private void DrawNetgraphBasicStrings(MyHudNetgraph netgraph, Vector2 initialPosition, Vector2 normalizedOffset)
        {
            StringBuilder sb = new StringBuilder();

            // Draw last received packet
            sb.Append("In: ").Append(netgraph.LastPacketBytesReceived);
            DrawNetgraphStringValue(initialPosition, sb);

            // Draw average in
            sb.Clear();
            sb.Append("Avg In: ").Append(netgraph.AverageIncomingKBytes.ToString("0.##")).Append(" kB/s");
            initialPosition.X += normalizedOffset.X;
            DrawNetgraphStringValue(initialPosition, sb);

            // Draw last sent packet
            sb.Clear();
            sb.Append("Out: ").Append(netgraph.LastPacketBytesSent);
            initialPosition.X -= normalizedOffset.X;
            initialPosition.Y += normalizedOffset.Y;
            DrawNetgraphStringValue(initialPosition, sb);

            // Draw average out
            sb.Clear();
            sb.Append("Avg Out: ").Append(netgraph.AverageOutgoingKBytes.ToString("0.##")).Append(" kB/s");
            initialPosition.X += normalizedOffset.X;
            DrawNetgraphStringValue(initialPosition, sb);

            // Draw updates per second
            sb.Clear();
            sb.Append("UPS: ").Append(netgraph.UpdatesPerSecond);
            initialPosition.X -= normalizedOffset.X;
            initialPosition.Y += normalizedOffset.Y;
            DrawNetgraphStringValue(initialPosition, sb);

            // Draw frames per second
            sb.Clear();
            sb.Append("FPS: ").Append(netgraph.FramesPerSecond);
            initialPosition.X += normalizedOffset.X;
            DrawNetgraphStringValue(initialPosition, sb);

            // Draw latency
            sb.Clear();
            sb.Append("Ping: ").Append(netgraph.Ping);
            initialPosition.X -= normalizedOffset.X;
            initialPosition.Y += normalizedOffset.Y;
            DrawNetgraphStringValue(initialPosition, sb);
        }
        private void DrawNetgraphBasicStrings(MyHudNetgraph netgraph, Vector2 initialPosition, Vector2 normalizedOffset)
        {
            StringBuilder sb = new StringBuilder();

            // Draw last received packet         
            sb.Append("In: ").Append(netgraph.LastPacketBytesReceived);
            DrawNetgraphStringValue(initialPosition, sb);

            // Draw average in
            sb.Clear();
            sb.Append("Avg In: ").Append(netgraph.AverageIncomingKBytes.ToString("0.##")).Append(" kB/s");
            initialPosition.X += normalizedOffset.X;
            DrawNetgraphStringValue(initialPosition, sb);

            // Draw last sent packet
            sb.Clear();
            sb.Append("Out: ").Append(netgraph.LastPacketBytesSent);
            initialPosition.X -= normalizedOffset.X;
            initialPosition.Y += normalizedOffset.Y;
            DrawNetgraphStringValue(initialPosition, sb);

            // Draw average out
            sb.Clear();
            sb.Append("Avg Out: ").Append(netgraph.AverageOutgoingKBytes.ToString("0.##")).Append(" kB/s");
            initialPosition.X += normalizedOffset.X;
            DrawNetgraphStringValue(initialPosition, sb);

            // Draw updates per second
            sb.Clear();
            sb.Append("UPS: ").Append(netgraph.UpdatesPerSecond);
            initialPosition.X -= normalizedOffset.X;
            initialPosition.Y += normalizedOffset.Y;
            DrawNetgraphStringValue(initialPosition, sb);

            // Draw frames per second
            sb.Clear();
            sb.Append("FPS: ").Append(netgraph.FramesPerSecond);
            initialPosition.X += normalizedOffset.X;
            DrawNetgraphStringValue(initialPosition, sb);

            // Draw latency
            sb.Clear();
            sb.Append("Ping: ").Append(netgraph.Ping);
            initialPosition.X -= normalizedOffset.X;
            initialPosition.Y += normalizedOffset.Y;
            DrawNetgraphStringValue(initialPosition, sb);
        }
        private void DrawNetgraphLine(MyHudNetgraph.NetgraphLineData lineData, ref Vector2 position, ref Vector2 size)
        {
            Vector2I offset = new Vector2I(0, 0);
            Vector2I positionI = new Vector2I((int)position.X, (int)position.Y);

            DrawNetgraphLineBar(positionI.X, ref positionI.Y, lineData.ByteCountReliableReceived, size.Y,
                MyGuiConstants.NETGRAPH_RELIABLE_PACKET_COLOR, MyGuiConstants.NETGRAPH_RELIABLE_PACKET_COLOR_TOP);

            DrawNetgraphLineBar(positionI.X, ref positionI.Y, lineData.ByteCountUnreliableReceived, size.Y,
                 MyGuiConstants.NETGRAPH_UNRELIABLE_PACKET_COLOR, MyGuiConstants.NETGRAPH_UNRELIABLE_PACKET_COLOR_TOP);

            DrawNetgraphLineBar(positionI.X, ref positionI.Y, lineData.ByteCountSent, size.Y,
                 MyGuiConstants.NETGRAPH_SENT_PACKET_COLOR, MyGuiConstants.NETGRAPH_SENT_PACKET_COLOR_TOP);
        }
        private void DrawNetgraph(MyHudNetgraph netgraph)
        {
            Vector2 bgPos = MyGuiConstants.NETGRAPH_INITIAL_POSITION;
            var texture = MyGuiConstants.NETGRAPH_BG_TEXTURE;
            Vector2 normBgPos = ConvertHudToNormalizedGuiPosition(ref bgPos);
            Vector2 normSizeBg = MyGuiManager.GetNormalizedSizeFromScreenSize(texture.SizePx);
            normSizeBg.Y = MyGuiConstants.NETGRAPH_BG_NORM_SIZE_Y;


            Vector2 screenOptimalBarSize = MyGuiManager.GetScreenSizeFromNormalizedSize(MyHudNetgraph.OPTIMAL_LENGTH_BAR_NORMALIZED);
            Vector2 screenOptimalBarSizeMulitplier = screenOptimalBarSize * netgraph.CurrentPacketScaleInvertedMaximumValue;
            float averageGraphSizeMultiplier = screenOptimalBarSize.Y * netgraph.CurrentAverageScaleInvertedMaximumValue;
            Vector2 scalePosition = normBgPos;
            scalePosition.X -= normSizeBg.X - 0.035f;
            scalePosition.Y -= normSizeBg.Y * (0.09f / MyGuiConstants.NETGRAPH_BG_NORM_SIZE_Y);

            ProfilerShort.Begin("Draw scales");
            // draw left scale (packet size)
            float maximumValue = netgraph.CurrentPacketScaleMaximumValue;
            StringBuilder unitForScale = new StringBuilder();
            netgraph.GetProperFormatAndValueForBytes(netgraph.CurrentPacketScaleMaximumValue, out maximumValue, unitForScale);
            DrawNetgraphScaleForPacketScale(scalePosition, (int)screenOptimalBarSize.Y,
                maximumValue, 5, unitForScale, true, true, 0.7f, MyFontEnum.White);

            // draw right scale (average)
            Vector2 averageScalePosition = scalePosition;
            averageScalePosition.X += (normSizeBg.X - 0.06f);
            unitForScale.Clear();
            netgraph.GetProperFormatAndValueForBytes(netgraph.CurrentAverageScaleMaximumValue, out maximumValue, unitForScale, true);
            DrawNetgraphScaleForPacketScale(averageScalePosition, (int)screenOptimalBarSize.Y,
                 maximumValue, 5, unitForScale, false, false, 0.7f, MyFontEnum.Red);

            ProfilerShort.End();

            Vector2 lineNormalizedPosition = scalePosition;
            lineNormalizedPosition.X += 0.014f;
            Vector2 linePosition = MyGuiManager.GetScreenCoordinateFromNormalizedCoordinate(lineNormalizedPosition);
            Vector2 cachedLinePosition = linePosition;

            ProfilerShort.Begin("Draw netgraph bars");
            // draw netgraph bars
            for (int i = netgraph.CurrentFirstIndex; i < MyHudNetgraph.NUMBER_OF_VISIBLE_PACKETS; i++)
            {
                DrawNetgraphLine(netgraph.GetNetgraphLineDataAtIndex(i), ref linePosition, ref screenOptimalBarSizeMulitplier);
                linePosition.X++;
            }
            for (int i = 0; i < netgraph.CurrentFirstIndex; i++)
            {
                DrawNetgraphLine(netgraph.GetNetgraphLineDataAtIndex(i), ref linePosition, ref screenOptimalBarSizeMulitplier);
                linePosition.X++;
            }
            ProfilerShort.End();

            ProfilerShort.Begin("Draw average line");
            // draw average line
            linePosition = cachedLinePosition;
            float averageOnFirstLine = netgraph.GetNetgraphLineDataAtIndex(netgraph.CurrentFirstIndex).AverageOnThisLine;
            linePosition.X++;
            for (int i = netgraph.CurrentFirstIndex + 1; i < MyHudNetgraph.NUMBER_OF_VISIBLE_PACKETS; i++)
            {
                float averageOnSecondLine = netgraph.GetNetgraphLineDataAtIndex(i).AverageOnThisLine;
                DrawNetgraphAverageLine(ref linePosition, averageOnFirstLine, averageOnSecondLine, averageGraphSizeMultiplier, Color.Red);
                linePosition.X++;
                averageOnFirstLine = averageOnSecondLine;
            }
            for (int i = 0; i < netgraph.CurrentFirstIndex; i++)
            {
                float averageOnSecondLine = netgraph.GetNetgraphLineDataAtIndex(i).AverageOnThisLine;
                DrawNetgraphAverageLine(ref linePosition, averageOnFirstLine, averageOnSecondLine, averageGraphSizeMultiplier, Color.Red);
                linePosition.X++;
                averageOnFirstLine = averageOnSecondLine;
            }
            ProfilerShort.End();
            // draw netgraph status data
            Vector2 textPosition = lineNormalizedPosition;
            textPosition.X = scalePosition.X - 0.02f;
            textPosition.Y += normSizeBg.Y * (0.012f / MyGuiConstants.NETGRAPH_BG_NORM_SIZE_Y); // 0.012f;
            DrawNetgraphBasicStrings(netgraph, textPosition, new Vector2(0.06f, 0.02f));

            // draw bars legend
            textPosition = scalePosition;
            textPosition.X -= 0.022f;
            textPosition.Y -= 0.2f;
            m_helperSB.Clear().Append("Reliable");
            Color tmp = MyGuiConstants.NETGRAPH_RELIABLE_PACKET_COLOR;
            tmp.A = 255;
            MyGuiManager.DrawString(MyFontEnum.White, m_helperSB, textPosition, 0.7f, tmp, MyGuiDrawAlignEnum.HORISONTAL_RIGHT_AND_VERTICAL_CENTER);
            textPosition.Y += 0.02f;
            m_helperSB.Clear().Append("Unreliable");
            tmp = MyGuiConstants.NETGRAPH_UNRELIABLE_PACKET_COLOR;
            tmp.A = 255;
            MyGuiManager.DrawString(MyFontEnum.White, m_helperSB, textPosition, 0.7f, tmp, MyGuiDrawAlignEnum.HORISONTAL_RIGHT_AND_VERTICAL_CENTER);
            textPosition.Y += 0.02f;
            m_helperSB.Clear().Append("Sent");
            tmp = MyGuiConstants.NETGRAPH_SENT_PACKET_COLOR;
            tmp.A = 255;
            MyGuiManager.DrawString(MyFontEnum.White, m_helperSB, textPosition, 0.7f, tmp, MyGuiDrawAlignEnum.HORISONTAL_RIGHT_AND_VERTICAL_CENTER);
        }
        private void DrawNetgraph(MyHudNetgraph netgraph)
        {
            Vector2 bgPos      = MyGuiConstants.NETGRAPH_INITIAL_POSITION;
            var     texture    = MyGuiConstants.NETGRAPH_BG_TEXTURE;
            Vector2 normBgPos  = ConvertHudToNormalizedGuiPosition(ref bgPos);
            Vector2 normSizeBg = MyGuiManager.GetNormalizedSizeFromScreenSize(texture.SizePx);

            normSizeBg.Y = MyGuiConstants.NETGRAPH_BG_NORM_SIZE_Y;


            Vector2 screenOptimalBarSize           = MyGuiManager.GetScreenSizeFromNormalizedSize(MyHudNetgraph.OPTIMAL_LENGTH_BAR_NORMALIZED);
            Vector2 screenOptimalBarSizeMulitplier = screenOptimalBarSize * netgraph.CurrentPacketScaleInvertedMaximumValue;
            float   averageGraphSizeMultiplier     = screenOptimalBarSize.Y * netgraph.CurrentAverageScaleInvertedMaximumValue;
            Vector2 scalePosition = normBgPos;

            scalePosition.X -= normSizeBg.X - 0.035f;
            scalePosition.Y -= normSizeBg.Y * (0.09f / MyGuiConstants.NETGRAPH_BG_NORM_SIZE_Y);

            ProfilerShort.Begin("Draw scales");
            // draw left scale (packet size)
            float         maximumValue = netgraph.CurrentPacketScaleMaximumValue;
            StringBuilder unitForScale = new StringBuilder();

            netgraph.GetProperFormatAndValueForBytes(netgraph.CurrentPacketScaleMaximumValue, out maximumValue, unitForScale);
            DrawNetgraphScaleForPacketScale(scalePosition, (int)screenOptimalBarSize.Y,
                                            maximumValue, 5, unitForScale, true, true, 0.7f, MyFontEnum.White);

            // draw right scale (average)
            Vector2 averageScalePosition = scalePosition;

            averageScalePosition.X += (normSizeBg.X - 0.06f);
            unitForScale.Clear();
            netgraph.GetProperFormatAndValueForBytes(netgraph.CurrentAverageScaleMaximumValue, out maximumValue, unitForScale, true);
            DrawNetgraphScaleForPacketScale(averageScalePosition, (int)screenOptimalBarSize.Y,
                                            maximumValue, 5, unitForScale, false, false, 0.7f, MyFontEnum.Red);

            ProfilerShort.End();

            Vector2 lineNormalizedPosition = scalePosition;

            lineNormalizedPosition.X += 0.014f;
            Vector2 linePosition       = MyGuiManager.GetScreenCoordinateFromNormalizedCoordinate(lineNormalizedPosition);
            Vector2 cachedLinePosition = linePosition;

            ProfilerShort.Begin("Draw netgraph bars");
            // draw netgraph bars
            for (int i = netgraph.CurrentFirstIndex; i < MyHudNetgraph.NUMBER_OF_VISIBLE_PACKETS; i++)
            {
                DrawNetgraphLine(netgraph.GetNetgraphLineDataAtIndex(i), ref linePosition, ref screenOptimalBarSizeMulitplier);
                linePosition.X++;
            }
            for (int i = 0; i < netgraph.CurrentFirstIndex; i++)
            {
                DrawNetgraphLine(netgraph.GetNetgraphLineDataAtIndex(i), ref linePosition, ref screenOptimalBarSizeMulitplier);
                linePosition.X++;
            }
            ProfilerShort.End();

            ProfilerShort.Begin("Draw average line");
            // draw average line
            linePosition = cachedLinePosition;
            float averageOnFirstLine = netgraph.GetNetgraphLineDataAtIndex(netgraph.CurrentFirstIndex).AverageOnThisLine;

            linePosition.X++;
            for (int i = netgraph.CurrentFirstIndex + 1; i < MyHudNetgraph.NUMBER_OF_VISIBLE_PACKETS; i++)
            {
                float averageOnSecondLine = netgraph.GetNetgraphLineDataAtIndex(i).AverageOnThisLine;
                DrawNetgraphAverageLine(ref linePosition, averageOnFirstLine, averageOnSecondLine, averageGraphSizeMultiplier, Color.Red);
                linePosition.X++;
                averageOnFirstLine = averageOnSecondLine;
            }
            for (int i = 0; i < netgraph.CurrentFirstIndex; i++)
            {
                float averageOnSecondLine = netgraph.GetNetgraphLineDataAtIndex(i).AverageOnThisLine;
                DrawNetgraphAverageLine(ref linePosition, averageOnFirstLine, averageOnSecondLine, averageGraphSizeMultiplier, Color.Red);
                linePosition.X++;
                averageOnFirstLine = averageOnSecondLine;
            }
            ProfilerShort.End();
            // draw netgraph status data
            Vector2 textPosition = lineNormalizedPosition;

            textPosition.X  = scalePosition.X - 0.02f;
            textPosition.Y += normSizeBg.Y * (0.012f / MyGuiConstants.NETGRAPH_BG_NORM_SIZE_Y); // 0.012f;
            DrawNetgraphBasicStrings(netgraph, textPosition, new Vector2(0.06f, 0.02f));

            // draw bars legend
            textPosition    = scalePosition;
            textPosition.X -= 0.022f;
            textPosition.Y -= 0.2f;
            m_helperSB.Clear().Append("Reliable");
            Color tmp = MyGuiConstants.NETGRAPH_RELIABLE_PACKET_COLOR;

            tmp.A = 255;
            MyGuiManager.DrawString(MyFontEnum.White, m_helperSB, textPosition, 0.7f, tmp, MyGuiDrawAlignEnum.HORISONTAL_RIGHT_AND_VERTICAL_CENTER);
            textPosition.Y += 0.02f;
            m_helperSB.Clear().Append("Unreliable");
            tmp   = MyGuiConstants.NETGRAPH_UNRELIABLE_PACKET_COLOR;
            tmp.A = 255;
            MyGuiManager.DrawString(MyFontEnum.White, m_helperSB, textPosition, 0.7f, tmp, MyGuiDrawAlignEnum.HORISONTAL_RIGHT_AND_VERTICAL_CENTER);
            textPosition.Y += 0.02f;
            m_helperSB.Clear().Append("Sent");
            tmp   = MyGuiConstants.NETGRAPH_SENT_PACKET_COLOR;
            tmp.A = 255;
            MyGuiManager.DrawString(MyFontEnum.White, m_helperSB, textPosition, 0.7f, tmp, MyGuiDrawAlignEnum.HORISONTAL_RIGHT_AND_VERTICAL_CENTER);
        }