<commit_before>﻿using Microsoft.VisualStudio.Text;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using VsTeXCommentsExtension.Integration.Data;
using VsTeXCommentsExtension.Integration.View;

namespace VsTeXCommentsExtension.View
{
    /// <summary>
    /// Interaction logic for TexCommentAdornment.xaml
    /// </summary>
    internal partial class TeXCommentAdornment : UserControl, ITagAdornment
    {
        private const double RenderScale = 3;

        private readonly List<Span> spansOfChangesFromEditing = new List<Span>();
        private readonly Action<Span> refreshTags;
        private readonly Color foreground;
        private readonly Color background;
        private readonly System.Drawing.Font font;
        private readonly IRenderingManager renderingManager;

        private TeXCommentTag tag;
        private bool changeMadeWhileInEditMode;

        private bool isInEditMode;
        public bool IsInEditMode
        {
            get { return isInEditMode; }
            set
            {
                Debug.WriteLine($"Adornment {DebugIndex}: IsInEditMode={value}");
                isInEditMode = value;
                DisplayMode = isInEditMode ? IntraTextAdornmentTaggerDisplayMode.DoNotHideOriginalText : IntraTextAdornmentTaggerDisplayMode.HideOriginalText;
                if (isInEditMode) spansOfChangesFromEditing.Clear();
                changeMadeWhileInEditMode = false;
                SetUpControlsVisibility();

                if (spansOfChangesFromEditing.Count > 0)
                {
                    var resultSpan = spansOfChangesFromEditing[0];
                    for (int i = 1; i < spansOfChangesFromEditing.Count; i++)
                    {
                        var span = spansOfChangesFromEditing[i];
                        resultSpan = new Span(Math.Min(resultSpan.Start, span.Start), Math.Max(resultSpan.End, span.End));
                    }
                    refreshTags(resultSpan);
                }
                else refreshTags(tag.Span);
            }
        }

        public IntraTextAdornmentTaggerDisplayMode DisplayMode { get; private set; }

        private static int debugIndexer;
        public int DebugIndex { get; } = debugIndexer++;

        public LineSpan LineSpan { get; private set; }

        public TeXCommentAdornment(
            TeXCommentTag tag,
            Color foreground,
            Color background,
            System.Drawing.Font font,
            IRenderingManager renderingManager,
            LineSpan lineSpan,
            Action<Span> refreshTags,
            IntraTextAdornmentTaggerDisplayMode defaultDisplayMode)
        {
            this.tag = tag;
            this.refreshTags = refreshTags;
            this.foreground = foreground;
            this.background = background;
            this.font = font;
            this.renderingManager = renderingManager;

            LineSpan = lineSpan;
            DisplayMode = defaultDisplayMode;
            DataContext = this;

            InitializeComponent();

            var leftBorderPanelBrush = new SolidColorBrush(foreground);
            leftBorderPanelBrush.Freeze();
            leftBorderPanel1.Background = leftBorderPanelBrush;
            leftBorderPanel2.Background = leftBorderPanelBrush;

            isInEditMode = false;
            SetUpControlsVisibility();
            UpdateImageAsync();
        }

        public void Update(TeXCommentTag tag, LineSpan lineSpan)
        {
            bool changed = this.tag.Text != tag.Text;
            if (IsInEditMode)
            {
                changeMadeWhileInEditMode |= changed;
            }
            else if (changed)
            {
                this.tag = tag;
                LineSpan = lineSpan;
                UpdateImageAsync();
            }
        }

        public void HandleTextBufferChanged(object sender, TextContentChangedEventArgs args)
        {
            if (!IsInEditMode || args.Changes.Count == 0) return;

            var start = args.Changes[0].NewPosition;
            var end = args.Changes[args.Changes.Count - 1].NewEnd;

            spansOfChangesFromEditing.Add(new Span(start, end - start));
        }

        private void UpdateImageAsync()
        {
            imageControl.Source = null;

            var template = new TeXCommentHtmlTemplate()
            {
                BackgroundColor = background,<commit_msg>Changes tracking while in edit mode bug fix.<commit_after>﻿using Microsoft.VisualStudio.Text;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using VsTeXCommentsExtension.Integration.Data;
using VsTeXCommentsExtension.Integration.View;

namespace VsTeXCommentsExtension.View
{
    /// <summary>
    /// Interaction logic for TexCommentAdornment.xaml
    /// </summary>
    internal partial class TeXCommentAdornment : UserControl, ITagAdornment
    {
        private const double RenderScale = 3;

        private readonly List<Span> spansOfChangesFromEditing = new List<Span>();
        private readonly Action<Span> refreshTags;
        private readonly Color foreground;
        private readonly Color background;
        private readonly System.Drawing.Font font;
        private readonly IRenderingManager renderingManager;

        private TeXCommentTag tag;
        private bool changeMadeWhileInEditMode;

        private bool isInEditMode;
        public bool IsInEditMode
        {
            get { return isInEditMode; }
            set
            {
                Debug.WriteLine($"Adornment {DebugIndex}: IsInEditMode={value}");
                isInEditMode = value;
                DisplayMode = isInEditMode ? IntraTextAdornmentTaggerDisplayMode.DoNotHideOriginalText : IntraTextAdornmentTaggerDisplayMode.HideOriginalText;
                if (isInEditMode) spansOfChangesFromEditing.Clear();
                changeMadeWhileInEditMode = false;
                SetUpControlsVisibility();

                if (spansOfChangesFromEditing.Count > 0)
                {
                    var resultSpan = spansOfChangesFromEditing[0];
                    for (int i = 1; i < spansOfChangesFromEditing.Count; i++)
                    {
                        var span = spansOfChangesFromEditing[i];
                        resultSpan = new Span(Math.Min(resultSpan.Start, span.Start), Math.Max(resultSpan.End, span.End));
                    }
                    refreshTags(resultSpan);
                }
                else refreshTags(tag.Span);
            }
        }

        public IntraTextAdornmentTaggerDisplayMode DisplayMode { get; private set; }

        private static int debugIndexer;
        public int DebugIndex { get; } = debugIndexer++;

        public LineSpan LineSpan { get; private set; }

        public TeXCommentAdornment(
            TeXCommentTag tag,
            Color foreground,
            Color background,
            System.Drawing.Font font,
            IRenderingManager renderingManager,
            LineSpan lineSpan,
            Action<Span> refreshTags,
            IntraTextAdornmentTaggerDisplayMode defaultDisplayMode)
        {
            this.tag = tag;
            this.refreshTags = refreshTags;
            this.foreground = foreground;
            this.background = background;
            this.font = font;
            this.renderingManager = renderingManager;

            LineSpan = lineSpan;
            DisplayMode = defaultDisplayMode;
            DataContext = this;

            InitializeComponent();

            var leftBorderPanelBrush = new SolidColorBrush(foreground);
            leftBorderPanelBrush.Freeze();
            leftBorderPanel1.Background = leftBorderPanelBrush;
            leftBorderPanel2.Background = leftBorderPanelBrush;

            isInEditMode = false;
            SetUpControlsVisibility();
            UpdateImageAsync();
        }

        public void Update(TeXCommentTag tag, LineSpan lineSpan)
        {
            bool changed = this.tag.Text != tag.Text;
            if (IsInEditMode)
            {
                changeMadeWhileInEditMode = changed;
            }
            else if (changed)
            {
                this.tag = tag;
                LineSpan = lineSpan;
                UpdateImageAsync();
            }
        }

        public void HandleTextBufferChanged(object sender, TextContentChangedEventArgs args)
        {
            if (!IsInEditMode || args.Changes.Count == 0) return;

            var start = args.Changes[0].NewPosition;
            var end = args.Changes[args.Changes.Count - 1].NewEnd;

            spansOfChangesFromEditing.Add(new Span(start, end - start));
        }

        private void UpdateImageAsync()
        {
            imageControl.Source = null;

            var template = new TeXCommentHtmlTemplate()
            {
                BackgroundColor = background,
{'fraction_non_alphanumeric': 0.0705676090291475, 'fraction_numerical': 0.0019723865877712033, 'mean_word_length': 1.9187719859290053, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4888617', 'n_tokens_mistral': 2302, 'n_tokens_neox': 2157, 'n_words': 500}