using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace codelanguage
{
///
/// Enhanced debugger visualization with call stack, breakpoints, and variable inspection.
/// Provides interactive debugging UI with visual indicators for execution state.
///
public partial class DebuggerVisualization : UserControl
{
public ObservableCollection CallStackItems { get; } = new();
public ObservableCollection WatchItems { get; } = new();
public ObservableCollection BreakpointItems { get; } = new();
public ObservableCollection LocalVariables { get; } = new();
private DebuggerService _debugger;
private bool _isAttached = false;
public DebuggerVisualization()
{
InitializeComponent();
CallStackList.ItemsSource = CallStackItems;
WatchList.ItemsSource = WatchItems;
BreakpointsList.ItemsSource = BreakpointItems;
LocalsList.ItemsSource = LocalVariables;
UpdateUI();
}
public void AttachDebugger(DebuggerService debugger)
{
_debugger = debugger;
if (_debugger != null)
{
_debugger.BreakpointHit += Debugger_BreakpointHit;
_debugger.StateChanged += Debugger_StateChanged;
}
_isAttached = true;
UpdateUI();
}
public void DetachDebugger()
{
if (_debugger != null)
{
_debugger.BreakpointHit -= Debugger_BreakpointHit;
_debugger.StateChanged -= Debugger_StateChanged;
}
_isAttached = false;
UpdateUI();
}
private void Debugger_BreakpointHit(object? sender, int line)
{
UpdateUI();
}
private void Debugger_StateChanged(object? sender, DebuggerState state)
{
UpdateUI();
}
private void UpdateUI()
{
if (!_isAttached || _debugger == null)
{
DebuggerStatus.Text = "No debug session";
DebuggerStatus.Foreground = VisualThemeManager.GetBrush("TextMuted");
CallStackItems.Clear();
WatchItems.Clear();
LocalVariables.Clear();
BreakpointItems.Clear();
return;
}
// Update status
if (_debugger.IsAttached)
{
if (!_debugger.IsPaused)
{
DebuggerStatus.Text = "⏸ Running...";
DebuggerStatus.Foreground = VisualThemeManager.GetBrush("Warning");
}
else
{
DebuggerStatus.Text = "⏹ Paused";
DebuggerStatus.Foreground = VisualThemeManager.GetBrush("Success");
}
}
else
{
DebuggerStatus.Text = "⊗ Detached";
DebuggerStatus.Foreground = VisualThemeManager.GetBrush("Error");
}
// Update current file
DebuggerCurrentFile.Text = $"{_debugger.CurrentFile}:{_debugger.CurrentLine}";
// Update call stack
CallStackItems.Clear();
var callStack = _debugger.GetCallStack();
foreach (var frame in callStack)
{
CallStackItems.Add(new DebuggerFrameUI(frame));
}
// Update locals
LocalVariables.Clear();
var locals = _debugger.GetLocals();
foreach (var kvp in locals)
{
LocalVariables.Add(new LocalVariableUI(kvp.Key, kvp.Value));
}
// Update breakpoints
BreakpointItems.Clear();
foreach (var file in _debugger.Breakpoints)
{
foreach (var line in file.Value)
{
BreakpointItems.Add(new BreakpointItemUI($"{file.Key}:{line}", true));
}
}
}
private void ContinueButton_Click(object sender, RoutedEventArgs e)
{
_debugger?.Continue();
}
private void StepOverButton_Click(object sender, RoutedEventArgs e)
{
_debugger?.StepOver();
}
private void StepIntoButton_Click(object sender, RoutedEventArgs e)
{
_debugger?.StepInto();
}
private void StepOutButton_Click(object sender, RoutedEventArgs e)
{
_debugger?.StepOut();
}
private void AddWatchButton_Click(object sender, RoutedEventArgs e)
{
string varName = WatchInputBox.Text;
if (string.IsNullOrWhiteSpace(varName))
return;
WatchItems.Add(new WatchItemUI(varName));
WatchInputBox.Clear();
}
private void RemoveWatchButton_Click(object sender, RoutedEventArgs e)
{
if (WatchList.SelectedItem is WatchItemUI item)
WatchItems.Remove(item);
}
}
public class DebuggerFrameUI
{
public string ProcName { get; set; }
public string File { get; set; }
public int Line { get; set; }
public string DisplayText => $"{ProcName}() at {File}:{Line}";
public string Icon => "📍";
public DebuggerFrameUI(DebuggerFrame frame)
{
ProcName = frame.ProcName;
File = frame.File;
Line = frame.Line;
}
}
public class WatchItemUI
{
public string VariableName { get; set; }
public string DisplayText => $"Watch: {VariableName}";
public string Icon => "👁";
public WatchItemUI(string varName)
{
VariableName = varName;
}
}
public class BreakpointItemUI
{
public string Location { get; set; }
public bool IsEnabled { get; set; }
public string DisplayText => $"{Location} {(IsEnabled ? "✓" : "✗")}";
public string Icon => IsEnabled ? "🔴" : "⭕";
public BreakpointItemUI(string location, bool enabled)
{
Location = location;
IsEnabled = enabled;
}
}
public class LocalVariableUI
{
public string Name { get; set; }
public string Value { get; set; }
public string Type { get; set; }
public string DisplayText => $"{Name} = {Value}";
public string Icon => "🔤";
public LocalVariableUI(string name, CraftValue value)
{
Name = name;
Type = value.Type;
try
{
Value = value.Type switch
{
"num" => value.ToNumber().ToString(),
"text" => $"\"{value.ToText()}\"",
"list" => $"[{value.ListItems.Count} items]",
_ => value.ToText()
};
}
catch
{
Value = "";
}
}
}
}