Respan Dataset Explorer

Select one behavior. Every returned turn has one binary label: Present or Absent. Source: final dense boolean release.

5,167,182physical rows
86shards
0.00%qualified row coverage
0.00%qualified cell coverage
Random row JSON API

turns-00061.parquet:26605

d54f08f80594697a85f358fc
turn 8/35gpt-4o-mini-2024-07-18EnglishRussia3670 words
degenerate_repetitionAbsentFinal dense release
USER
I need mediainfo code in code below:
```
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using LibVLCSharp.Shared;
using Microsoft.Win32;
using NeoSmart.PrettySize;
using RPA_Parser;

namespace RPA_Explorer
{
    public partial class RpaExplorer : Form
    {
        private RpaParser _rpaParser;
        private RpaParser _rpaParserBak;
        private Thread _operation;
        private bool _operationEnabled = true;
        private bool _archiveChanged;
        private bool _cancelAdd;
        private bool _archiveLoaded;
        private SortedDictionary<string, RpaParser.ArchiveIndex> _fileListBackup = new();
        private readonly Dictionary<string, long> _indexPathSize = new();
        private readonly List<string> _expandedList = new();
        private bool _switchTabs;
        private readonly LibVLC _libVlc; // https://code.videolan.org/mfkl/libvlcsharp-samples
        private MemoryStream _memoryStreamVlc;
        private StreamMediaInput _streamMediaInputVlc;
        private Media _mediaVlc;
        private int _searchStartIndex = 0;
        private static readonly FileInfo _appInfo = new(System.Reflection.Assembly.GetEntryAssembly()?.Location ?? throw new InvalidOperationException());
        private static readonly FileInfo _appName = new(System.Reflection.Assembly.GetEntryAssembly()?.GetName().Name ?? throw new InvalidOperationException());
        private readonly string settingsPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/" + _appName + @"/settings.ini";

        private static readonly System.ComponentModel.ComponentResourceManager Lang = new(typeof(Lang));

        private static Settings settings;

        public RpaExplorer()
        {
            // Form initiation
            InitializeComponent();

            Directory.CreateDirectory(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/" + _appName);

            settings = new Settings(settingsPath);

            // Language initiation
            foreach (Settings.Language lang in settings.LangList)
            {
                toolStripComboBox1.Items.Add(lang.Name);
            }

            toolStripComboBox1.SelectedItem = settings.GetLang().Name;

            LoadTexts();

            // LibVLC initiation
            Core.Initialize();
            _libVlc = new LibVLC("--input-repeat=9999999"); // --input-repeat=X : Loop X times
            videoView1.MediaPlayer = new MediaPlayer(_libVlc);
            videoView1.MediaPlayer.Volume = 50;
            videoView1.MediaPlayer.TimeChanged += videoView1_MediaPlayer_TimeChanged;
            videoView1.BackgroundImage = null;
            SetMediaTimeLabel(0, 0);

            // Initialize the seek bar
            seekBar.Maximum = 1000; // Set maximum value for smooth seeking
            seekBar.Scroll += SeekBar_Scroll; // Handle scroll events for seeking

            // Subscribe to the TabControl's SelectedIndexChanged event
            tabControl1.SelectedIndexChanged += TabControl1_SelectedIndexChanged;

            // Hide the seek bar initially
            seekBar.Visible = false;

            // TreeView styles initiation
            ImageList imageList = new ImageList();
            imageList.Images.Add(Resources.treeView1_Image_folder);
            imageList.Images.Add(Resources.treeView1_Image_file);
            imageList.Images.Add(Resources.treeView1_Image_fileChanged);
            treeView1.ImageList = imageList;

            // Arguments processing
            string[] args = Environment.GetCommandLineArgs();
            if (args.Length >= 2)
            {
                LoadArchive(args[1]);
            }
        }

        private void TabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Show the seek bar only on the Media tab (tabPage3)
            if (tabControl1.SelectedTab == tabPage3)
            {
                seekBar.Visible = true;
            }
            else
            {
                seekBar.Visible = false;
            }
        }

        // Event handler for the seek bar's Scroll event
        private void SeekBar_Scroll(object sender, EventArgs e)
        {
            if (videoView1.MediaPlayer?.Media != null)
            {
                long duration = videoView1.MediaPlayer.Media.Duration;
                if (duration > 0)
                {
                    // Calculate newTime based on SeekBar position
                    long newTime = (long)((seekBar.Value / (double)seekBar.Maximum) * duration);
                    newTime = Math.Min(newTime, duration - 1); // Ensure newTime does not exceed duration

                    // Update the label3 based on the new time, independent of playback state
                    SetMediaTimeLabel(duration, newTime);

                    // Seek the video. If you want to seek immediately when scrolling, uncomment the line below.
                    videoView1.MediaPlayer.Time = newTime;
                }
            }
        }

        private void videoView1_MediaPlayer_TimeChanged(object sender, MediaPlayerTimeChangedEventArgs e)
        {
            Task.Run(async () =>
            {
                if (videoView1.MediaPlayer?.Media != null)
                {
                    long duration = videoView1.MediaPlayer.Media.Duration;

                    // Retry fetching duration if it seems invalid
                    if (duration <= 0)
                    {
                        await Task.Delay(500);
                        duration = videoView1.MediaPlayer.Media.Duration;
                    }

                    if (duration > 0)
                    {
                        int progress = (int)((e.Time / (double)duration) * seekBar.Maximum);
                        progress = Math.Min(progress, seekBar.Maximum);

                        seekBar.PerformSafely(() => seekBar.Value = progress);
                        SetMediaTimeLabel(duration, e.Time);
                    }
                }
            });
        }

        // Reset the seek bar when a new video is loaded
        private void ResetPreviewFields()
        {
            pictureBox1.Image = null;
            textBox2.Text = String.Empty;
            if (_memoryStreamVlc != null)
            {
                _memoryStreamVlc.Dispose();
                _memoryStreamVlc = null;
            }
            if (_streamMediaInputVlc != null)
            {
                _streamMediaInputVlc.Dispose();
                _streamMediaInputVlc = null;
            }
            if (_mediaVlc != null)
            {
                _mediaVlc.Dispose();
                _mediaVlc = null;
            }
            if (videoView1.MediaPlayer is { IsPlaying: true })
            {
                videoView1.MediaPlayer.Play(null!);
            }
            SetMediaTimeLabel(0, 0);

            // Reset the seek bar
            seekBar.Value = 0;
        }

        private void LoadTexts()
        {
            Text = GetText("Explorer_title");
            toolStripTextBox1.Text = GetText("Language");
            button1.Text = GetText("Load_file");
            button2.Text = GetText("Export_checked");
            statusBar1.Text = GetText("Ready");
            button3.Text = GetText("Cancel_operation");
            tabPage0.Text = GetText("None");
            label2.Text = GetText("Usage_instructions_new");
            tabPage1.Text = GetText("Image");
            tabPage2.Text = GetText("Text");
            tabPage3.Text = GetText("Media");
            button4.Text = GetText("Pause");
            button5.Text = GetText("Create_new_archive");
            label4.Text = GetText("File_list");
            button6.Text = GetText("Remove_checked");
            button7.Text = GetText("Save_archive");
            button8.Text = GetText("Search_next");
            label5.Text = GetText("Search");
            optionsToolStripMenuItem.Text = GetText("Options");
            associateRPARPIExtensionsToolStripMenuItem.Text = GetText("File_association");
            aboutToolStripMenuItem.Text = GetText("About");

            GenerateArchiveInfo();
        }

        internal static string GetText(string name)
        {
            if (Lang.GetObject(settings.GetLang().Abbrev + "_" + name) != null)
            {
                return Lang.GetObject(settings.GetLang().Abbrev + "_" + name)?.ToString();
            }

            return " {!!! MISSING TRANSLATION !!!} ";
        }

        private void ExportFiles(List<string> exportFilesList, FolderBrowserDialog folderBrowserDialog)
        {
            int counter = 0;
            int jobSize = exportFilesList.Count;
            foreach (string file in exportFilesList)
            {
                counter++;
                int pctProcessed = (int)Math.Ceiling((double)counter / jobSize * 100);
                label1.PerformSafely(() => label1.Text = $@"{counter} / {jobSize}");
                progressBar1.PerformSafely(() => progressBar1.Value = pctProcessed);

                statusBar1.PerformSafely(() => statusBar1.Text = GetText("Exporting_file") + file);

                _rpaParser.Extract(file, folderBrowserDialog.SelectedPath);

                if (!_operationEnabled)
                {
                    break;
                }
            }

            button1.PerformSafely(() => button1.Enabled = true);
            button2.PerformSafely(() => button2.Enabled = true);
            button3.PerformSafely(() => button3.Enabled = false);
            progressBar1.PerformSafely(() => progressBar1.Value = 0);
            label1.PerformSafely(() => label1.Text = "");
            statusBar1.PerformSafely(() => statusBar1.Text = GetText("Ready"));

            _operationEnabled = true;
        }

        private void CreateNewArchive()
        {
            if (CheckIfChanged(GetText("Archive_modified_new")))
            {
                return;
            }

            _expandedList.Clear();
            _rpaParser = new RpaParser();

            GenerateTreeView();

            _switchTabs = true;
            tabControl1.SelectedTab = tabPage0;
            _switchTabs = false;
            label2.Text = GetText("Usage_instructions_loaded");

            ResetPreviewFields();

            treeView1.SelectedNode = null;

            button2.Enabled = true;
            button6.Enabled = true;
            button7.Enabled = true;

            statusBar1.Text = GetText("Ready");

            _archiveChanged = true;
        }

        private void SaveArchive()
        {
            if (_rpaParser.Index.Count == 0)
            {
                MessageBox.Show(GetText("Empty_archive_save"), GetText("Empty_archive"), MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            statusBar1.Text = GetText("Saving_archive");

            string initPath = _appInfo?.DirectoryName;
            if (_rpaParser.ArchiveInfo?.DirectoryName != null)
            {
                initPath = _rpaParser.ArchiveInfo.DirectoryName;
            }

            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Title = GetText("Save_RenPy_Archive");
            saveFileDialog.Filter = GetText("RPA_RPI_files") + @" (*.rpa,*.rpi)|*.rpa;*.rpi";
            saveFileDialog.InitialDirectory = initPath;
            saveFileDialog.CheckFileExists = false;
            saveFileDialog.CheckPathExists = true;

            ArchiveSave options = new ArchiveSave(_rpaParser);
            options.ShowDialog();

            if (!_rpaParser.OptionsConfirmed)
            {
                return;
            }

            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                _rpaParserBak = _rpaParser;
                try
                {
                    string saveName = _rpaParser.SaveArchive(saveFileDialog.FileName);
                    LoadArchive(saveName, true);
                }
                catch (Exception ex)
                {
                    _rpaParser = _rpaParserBak;
                    MessageBox.Show(
                        string.Format(GetText("Save_failed_reason"), ex.Message),
                        GetText("Save_failed"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                GenerateTreeView();

                statusBar1.Text = GetText("Ready");
            }
        }

        private void GenerateArchiveInfo()
        {
            string archiveInfo = String.Empty;

            if (_archiveLoaded)
            {
                string selectedPath = String.Empty;
                foreach (TreeNode node in treeView1.Nodes.All())
                {
                    if (node.IsSelected)
                    {
                        selectedPath = NormalizeTreePath(node.FullPath);
                    }
                }

                long selectedSize = -1;
                int unsavedCount = 0;
                foreach (KeyValuePair<string, RpaParser.ArchiveIndex> kvp in _rpaParser.Index)
                {
                    if (!kvp.Value.InArchive)
                    {
                        unsavedCount++;
                    }

                    if (selectedPath == kvp.Key)
                    {
                        selectedSize = kvp.Value.Length;
                    }
                }

                if (_indexPathSize.ContainsKey(selectedPath))
                {
                    selectedSize = _indexPathSize[selectedPath];
                }

                if (!_rpaParser.CheckVersion(_rpaParser.ArchiveVersion, RpaParser.Version.Unknown))
                {
                    archiveInfo += GetText("Archive_version") + _rpaParser.ArchiveVersion + Environment.NewLine;
                    archiveInfo += GetText("Archive_file_location") + _rpaParser.ArchiveInfo.FullName +
                                   Environment.NewLine;
                    archiveInfo += GetText("Archive_file_size") + PrettySize.Format(_rpaParser.ArchiveInfo.Length) +
                                   Environment.NewLine;
                    if (_rpaParser.IndexInfo != null)
                    {
                        archiveInfo += GetText("Index_file_location") + _rpaParser.IndexInfo.FullName +
                                       Environment.NewLine;
                        archiveInfo += GetText("Index_file_size") + PrettySize.Format(_rpaParser.IndexInfo.Length) +
                                       Environment.NewLine;
                    }
                }

                archiveInfo += GetText("Files_count") + _rpaParser.Index.Count + Environment.NewLine;
                archiveInfo += GetText("Unsaved_files_count") + unsavedCount + Environment.NewLine;

                if (selectedSize != -1)
                {
                    if (selectedPath == String.Empty)
                    {
                        selectedPath = "/";
                    }
                    archiveInfo += GetText("Selected_file_path") + selectedPath +
                                   Environment.NewLine;
                    archiveInfo += GetText("Selected_file_size") + PrettySize.Format(selectedSize) +
                                   Environment.NewLine;
                }
            }

            textBox1.Text = archiveInfo.Trim();
        }

        private void LoadArchive(string openFile, bool ignoreChanges = false)
        {
            if (!ignoreChanges)
            {
                if (CheckIfChanged(GetText("Archive_modified_load")))
                {
                    return;
                }
            }

            using OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Title = GetText("Load_RenPy_Archive");
            openFileDialog.Filter = GetText("RPA_RPI_files") + @" (*.rpa,*.rpi)|*.rpa;*.rpi";

            string archivePath = settings.GetArchive();
            if (!string.IsNullOrEmpty(archivePath))
            {
                FileInfo fi = new FileInfo(archivePath);
                openFileDialog.InitialDirectory = fi.DirectoryName;
            }

            DialogResult dialogResult = DialogResult.None;
            if (string.IsNullOrEmpty(openFile))
            {
                dialogResult = openFileDialog.ShowDialog();
            }
            else
            {
                if (openFile.EndsWith(".rpa") || openFile.EndsWith(".rpi"))
                {
                    dialogResult = DialogResult.OK;
                    openFileDialog.FileName = openFile;
                }
                else
                {
                    MessageBox.Show(
                        string.Format(GetText("Load_failed_reason"), GetText("Not_valid_archive_file")),
                        GetText("Load_failed"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                    statusBar1.Text = GetText("Ready");
                    return;
                }
            }

            if (dialogResult == DialogResult.OK)
            {
                if (openFileDialog.CheckFileExists)
                {
                    settings.SetArchive(openFileDialog.FileName);
                    statusBar1.Text = GetText("Loading_file") + openFileDialog.FileName;

                    try
                    {
                        _expandedList.Clear();
                        _rpaParser = new RpaParser();

                        string appFolder = Path.GetDirectoryName(Application.ExecutablePath);
                        _rpaParser.UnrpycLocation = Path.Combine(appFolder, "unrpyc.exe");

                        _rpaParser.LoadArchive(openFileDialog.FileName);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(
                            string.Format(GetText("Load_failed_reason"), ex.Message),
                            GetText("Load_failed"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                        statusBar1.Text = GetText("Ready");
                        return;
                    }

                    GenerateTreeView();

                    _switchTabs = true;
                    tabControl1.SelectedTab = tabPage0;
                    _switchTabs = false;
                    label2.Text = GetText("Usage_instructions_loaded");

                    ResetPreviewFields();

                    treeView1.SelectedNode = null;

                    button2.Enabled = true;
                    button6.Enabled = true;
                    button7.Enabled = true;

                    statusBar1.Text = GetText("Ready");
                }

                _archiveChanged = false;
            }
        }

        private void AddFilesToArchive(string[] pathList)
        {
            // TODO: prompt for path to inset files into? Default can be root or selected object?
            //       Or don't prompt and use selected object? Empty folders should be excluded.
            //string promptValue = Prompt.ShowDialog("Test", "123", "xx");

            _fileListBackup.Clear();
            _fileListBackup = _rpaParser.DeepCopyIndex(_rpaParser.Index);
            _cancelAdd = false;

            foreach (string path in pathList)
            {
                string originalPath = path;
                if (Directory.Exists(path))
                {
                    originalPath = new DirectoryInfo(path).Parent?.FullName;
                }
                if (File.Exists(path))
                {
                    originalPath = new FileInfo(path).DirectoryName;
                }
                AddPathToIndex(path, originalPath);
            }

            if (!_cancelAdd)
            {
                _rpaParser.Index = _rpaParser.DeepCopyIndex(_fileListBackup);
            }

            _fileListBackup.Clear();
            GenerateTreeView();
        }

        private void GenerateTreeView()
        {
            _indexPathSize.Clear();
            treeView1.Nodes.Clear();
            TreeNode root = new TreeNode();
            TreeNode node;
            root.Name = "";
            root.Text = @"/";
            root.BackColor = Color.SandyBrown;
            root.ImageIndex = 0;
            treeView1.Nodes.Add(root);
            _indexPathSize.Add("", 0);
            string pathBuild;

            // Folders first
            foreach (KeyValuePair<string, RpaParser.ArchiveIndex> kvp in _rpaParser.Index)
            {
                node = root;
                pathBuild = String.Empty;
                foreach (string pathBits in kvp.Key.Split('/'))
                {
                    if (pathBuild == String.Empty)
                    {
                        pathBuild = pathBits;
                    }
                    else
                    {
                        pathBuild += "/" + pathBits;
                    }

                    if (node.Nodes.ContainsKey(pathBits))
                    {
                        node = node.Nodes[pathBits];
                    }
                    else
                    {
                        if (pathBuild != kvp.Key)
                        {
                            node = node.Nodes.Add(pathBits, pathBits);
                        }
                    }
                }
            }

            // Files second
            foreach (KeyValuePair<string, RpaParser.ArchiveIndex> kvp in _rpaParser.Index)
            {
                node = root;
                pathBuild = String.Empty;
                foreach (string pathBits in kvp.Key.Split('/'))
                {
                    if (pathBuild == String.Empty)
                    {
                        pathBuild = pathBits;
                    }
                    else
                    {
                        pathBuild += "/" + pathBits;
                    }

                    node = node.Nodes.ContainsKey(pathBits) ? node.Nodes[pathBits] : node.Nodes.Add(pathBits, pathBits);

                    if (pathBuild != kvp.Key)
                    {
                        if (!_indexPathSize.ContainsKey(pathBuild))
                        {
                            _indexPathSize.Add(pathBuild, 0);
                        }

                        if (_rpaParser.Index.ContainsKey(kvp.Key))
                        {
                            _indexPathSize[pathBuild] += _rpaParser.Index[kvp.Key].Length;
                        }
                    }
                    else
                    {
                        _indexPathSize[""] += _rpaParser.Index[kvp.Key].Length;
                    }
                }
            }

            foreach (TreeNode nodeVisuals in treeView1.Nodes.All())
            {
                string nodeName = NormalizeTreePath(nodeVisuals.FullPath);

                if (nodeName != String.Empty)
                {
                    if (nodeVisuals.Nodes.Count > 0)
                    {
                        nodeVisuals.BackColor = Color.SandyBrown;
                        nodeVisuals.ImageIndex = 0;
                    }
                    else
                    {
                        nodeVisuals.BackColor = Color.Transparent;
                        nodeVisuals.ImageIndex = 1;
                    }
                }

                if (_rpaParser.Index.ContainsKey(nodeName))
                {
                    if (!_rpaParser.Index[nodeName].InArchive)
                    {
                        nodeVisuals.ForeColor = Color.Green;
                        nodeVisuals.ImageIndex = 2;

                        MarkChanged(nodeVisuals);
                    }
                }

                if (_expandedList.Contains(nodeVisuals.FullPath))
                {
                    nodeVisuals.Expand();
                }
            }

            root.Expand();
            _archiveLoaded = true;

            GenerateArchiveInfo();
        }

        private void MarkChanged(TreeNode node)
        {
            if (node.Parent != null)
            {
                node.Parent.ForeColor = Color.Green;
                MarkChanged(node.Parent);
            }
        }

        private void Search(TextBox tb, string pattern)
        {
            int index;

            tb.Focus();

            if ((index = tb.Text.IndexOf(pattern, _searchStartIndex, StringComparison.Ordinal)) != -1)
            {
                tb.Select(index, pattern.Length);
                _searchStartIndex = tb.SelectionStart + tb.SelectionLength;
            }
            else
            {
                _searchStartIndex = 0;
                if ((index = tb.Text.IndexOf(pattern, _searchStartIndex, StringComparison.Ordinal)) != -1)
                {
                    tb.Select(index, pattern.Length);
                    _searchStartIndex = tb.SelectionStart + tb.SelectionLength;
                }
                else
                {
                    tb.Select(0, 0);
                }
            }

            tb.ScrollToCaret();
        }

        private string NormalizeTreePath(string path)
        {
            return Regex.Replace(path, "^/+", "");
        }

        private async void PreviewSelectedItem()
        {
            TreeNode selectedNode = new TreeNode();
            bool unsupportedFile = true;
            pictureBox1.Image = null;

            foreach (TreeNode node in treeView1.Nodes.All())
            {
                // Reset fields
                ResetPreviewFields();

                if (node.IsSelected)
                {
                    selectedNode = node;
                }

                if (node.IsSelected && _rpaParser.Index.ContainsKey(NormalizeTreePath(node.FullPath)))
                {
                    KeyValuePair<string, object> data = new KeyValuePair<string, object>();
                    try
                    {
                        data = await Task.Run(() => _rpaParser.GetPreview(NormalizeTreePath(node.FullPath)));

                        if (data.Key == RpaParser.PreviewTypes.Image)
                        {
                            pictureBox1.Image = (Image)data.Value;
                            _switchTabs = true;
                            tabControl1.SelectedTab = tabPage1;
                            _switchTabs = false;
                            unsupportedFile = false;
                        }
                        else if (data.Key == RpaParser.PreviewTypes.Text)
                        {
                            _searchStartIndex = 0;
                            textBox2.Text = (string)data.Value;
                            _switchTabs = true;
                            tabControl1.SelectedTab = tabPage2;
                            _switchTabs = false;
                            unsupportedFile = false;
                        }
                        else if (data.Key == RpaParser.PreviewTypes.Audio || data.Key == RpaParser.PreviewTypes.Video)
                        {
                            _memoryStreamVlc = new MemoryStream((byte[])data.Value);
                            _streamMediaInputVlc = new StreamMediaInput(_memoryStreamVlc);
                            _mediaVlc = new Media(_libVlc, _streamMediaInputVlc);

                            // Ensure the media is stopped
                            await Task.Run(() =>
                            {
                                if (videoView1.MediaPlayer != null)
                                {
                                    videoView1.MediaPlayer.Stop();
                                }
                            });

                            // Playback the new media
                            videoView1.MediaPlayer.Play(_mediaVlc);
                            SetMediaTimeLabel(_mediaVlc.Duration, 0);
                            videoView1.BackgroundImage = data.Key == RpaParser.PreviewTypes.Audio ? Resources.videoView1_BackgroundImage : null;
                            _switchTabs = true;
                            tabControl1.SelectedTab = tabPage3;
                            _switchTabs = false;
                            unsupportedFile = false;

                            // Check playback state to update button text
                            button4.Text = "Pause"; // Assuming you want to start playing the new video.
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(string.Format(GetText("Preview_failed_reason"), ex.Message), GetText("Preview_failed"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }

                    break;
                }
            }

            if (unsupportedFile)
            {
                _switchTabs = true;
                tabControl1.SelectedTab = tabPage0;
                _switchTabs = false;
                label2.Text = GetText("Preview_is_not_supported");
            }

            treeView1.SelectedNode = selectedNode;
            treeView1.SelectedNode.SelectedImageIndex = selectedNode.ImageIndex;
            treeView1.SelectedNode.EnsureVisible();
            treeView1.Focus();
        }

        private void CheckAllChildNodes(TreeNode node, bool isChecked)
        {
            if (node.Nodes.Count == 0)
            {
                node.Checked = isChecked;
            }
            else
            {
                foreach (TreeNode childNode in node.Nodes)
                {
                    CheckAllChildNodes(childNode, isChecked);
                }
                node.Checked = isChecked;
            }
        }

        private void ParentCheckControl(TreeNode parentNode)
        {
            foreach (TreeNode node in parentNode.Nodes.All())
            {
                if (!node.Checked)
                {
                    parentNode.Checked = false;
                    break;
                }
                parentNode.Checked = true;
            }
            if (parentNode.Parent != null)
            {
                ParentCheckControl(parentNode.Parent);
            }
        }

        private void PlayPauseMedia()
        {
            if (videoView1.MediaPlayer is { IsPlaying: true })
            {
                videoView1.MediaPlayer?.Pause();
                button4.Text = GetText("Play");
            }
            else
            {
                videoView1.MediaPlayer?.Play();
                button4.Text = GetText("Pause");
            }
        }

        private void SetMediaTimeLabel(long totalTimeMillies, long currentTimeMillies)
        {
            TimeSpan totalTime = TimeSpan.FromMilliseconds(totalTimeMillies);
            TimeSpan currentTime = TimeSpan.FromMilliseconds(currentTimeMillies);
            TimeSpan remainingTime = totalTime - currentTime;

            string timeFormat = @"hh\:mm\:ss";
            string timeText = $"{currentTime.ToString(timeFormat)} / {totalTime.ToString(timeFormat)} (-{remainingTime.ToString(timeFormat)})";

            label3.PerformSafely(() => label3.Text = timeText);
        }

        private bool CheckIfChanged(string message)
        {
            if (message != String.Empty && _archiveChanged)
            {
                if (MessageBox.Show(message, GetText("Archive_modified"), MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No)
                {
                    return true;
                }

                return false;
            }

            return _archiveChanged;
        }

        private void AddPathToIndex(string path, string originalPath)
        {
            _archiveChanged = true;
            RpaParser.ArchiveIndex index = new RpaParser.ArchiveIndex
            {
                InArchive = false
            };

            if (Directory.Exists(path))
            {
                foreach (string pathFile in Directory.GetFiles(path))
                {
                    AddPathToIndex(pathFile, originalPath);
                }
                foreach (string pathDir in Directory.GetDirectories(path))
                {
                    AddPathToIndex(pathDir, originalPath);
                }
            }

            if (File.Exists(path) && !_cancelAdd)
            {
                index.FullPath = path.Replace(@"\", "/");
                index.TreePath = index.FullPath.Replace(originalPath.Replace(@"\", "/") + "/", String.Empty);
                index.ParentPath = Path.GetDirectoryName(index.TreePath);
                index.Length = new FileInfo(path).Length;
                index.InArchive = false;

                if (_fileListBackup.ContainsKey(index.TreePath))
                {
                    _fileListBackup.Remove(index.TreePath);
                }

                _fileListBackup.Add(index.TreePath, index);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            LoadArchive(String.Empty);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            using FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
            List<string> exportFilesList = new List<string>();
            foreach (TreeNode node in treeView1.Nodes.All())
            {
                if (node.Checked && _rpaParser.Index.ContainsKey(NormalizeTreePath(node.FullPath)))
                {
                    exportFilesList.Add(NormalizeTreePath(node.FullPath));
                }
            }

            if (exportFilesList.Count == 0)
            {
                return;
            }

            folderBrowserDialog.SelectedPath = _rpaParser.ArchiveInfo.DirectoryName;
            if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
            {
                button1.Enabled = false;
                button2.Enabled = false;
                button3.Enabled = true;
                progressBar1.Value = 0;
                label1.PerformSafely(() => label1.Text = "");

                _operation = new Thread(() => ExportFiles(exportFilesList, folderBrowserDialog));
                _operation.Start();
            }
        }

        public class FileAssociation
        {
            public string Extension { get; set; }
            public string ProgId { get; set; }
            public string FileTypeDescription { get; set; }
            public string ExecutableFilePath { get; set; }
        }

        public class FileAssociations
        {
            // needed so that Explorer windows get refreshed after the registry is updated
            [DllImport("Shell32.dll")]
            private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);

            private const int SHCNE_ASSOCCHANGED = 0x8000000;
            private const int SHCNF_FLUSH = 0x1000;


            public static void EnsureAssociationsSet(params FileAssociation[] associations)
            {
                bool madeChanges = false;
                foreach (FileAssociation association in associations)
                {
                    madeChanges |= SetAssociation(
                        association.Extension,
                        association.ProgId,
                        association.FileTypeDescription,
                        association.ExecutableFilePath);
                }

                if (madeChanges)
                {
                    SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero);
                }
            }

            private static bool SetAssociation(string extension, string progId, string fileTypeDescription, string applicationFilePath)
            {
                bool madeChanges = false;
                madeChanges |= SetKeyDefaultValue(@"Software\Classes\" + extension, progId);
                madeChanges |= SetKeyDefaultValue(@"Software\Classes\" + progId, fileTypeDescription);
                madeChanges |= SetKeyDefaultValue($@"Software\Classes\{progId}\shell\open\command", "\"" + applicationFilePath + "\" \"%1\"");
                return madeChanges;
            }

            private static bool SetKeyDefaultValue(string keyPath, string value)
            {
                using var key = Registry.CurrentUser.CreateSubKey(keyPath);
                if (key == null || key.GetValue(null) as string == value) return false;
                key.SetValue(null, value);
                return true;
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            _operationEnabled = false;
        }

        private void treeView1_AfterSelect(object sender, EventArgs e)
        {
            PreviewSelectedItem();
            GenerateArchiveInfo();
        }

        private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
        {
            if (e.Action != TreeViewAction.Unknown)
            {
                Task.Run(async () =>
                {
                    await Task.Delay(50); // Prevent rapid selection from missing updates
                    Application.DoEvents(); // Force UI refresh to process all pending events

                    // Ensure all children are updated
                    if (e.Node.Nodes.Count > 0)
                    {
                        CheckAllChildNodes(e.Node, e.Node.Checked);
                    }

                    // Ensure parents reflect the correct state
                    if (e.Node.Parent != null)
                    {
                        ParentCheckControl(e.Node.Parent);
                    }
                });
            }
        }

        private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e)
        {
            if (!_switchTabs)
            {
                e.Cancel = true;
            }
            _switchTabs = false;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            PlayPauseMedia();
        }

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            if (videoView1.MediaPlayer?.Media != null)
            {
                videoView1.MediaPlayer.Volume = trackBar1.Value;
            }
        }

        private void RpaExplorer_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (CheckIfChanged(GetText("Archive_modified_close")))
            {
                e.Cancel = true;
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            CreateNewArchive();
        }

        private string targetFoldername; // Class-level variable to store the folder name

        private void treeView1_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] droppedFiles = (string[])e.Data.GetData(DataFormats.FileDrop);

                // Initialize the targetFoldername variable
                targetFoldername = string.Empty; // Reset before each drop

                // Check if the first dropped item is a directory
                if (Directory.Exists(droppedFiles[0]))
                {
                    // If it's a folder, set targetFoldername to the name of that folder
                    targetFoldername = Path.GetFileName(droppedFiles[0]);
                }

                if (e.Data.GetDataPresent(DataFormats.FileDrop))
                {
                    AddFilesToArchive((string[])e.Data.GetData(DataFormats.FileDrop));
                }
            }
        }

        private void treeView1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop) && _archiveLoaded)
            {
                e.Effect = DragDropEffects.Copy;
                return;
            }
            e.Effect = DragDropEffects.None;
        }

        private void tabControl1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Copy;
                return;
            }
            e.Effect = DragDropEffects.None;
        }

        private void tabControl1_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                LoadArchive(((string[])e.Data.GetData(DataFormats.FileDrop))[0]);
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            bool changed = false;
            foreach (TreeNode node in treeView1.Nodes.All())
            {
                if (node.Checked && _rpaParser.Index.ContainsKey(NormalizeTreePath(node.FullPath)))
                {
                    _rpaParser.Index.Remove(NormalizeTreePath(node.FullPath));
                    changed = true;
                }
            }

            if (changed)
            {
                _archiveChanged = true;
                GenerateTreeView();
            }
        }

        private void button7_Click(object sender, EventArgs e)
        {
            SaveArchive();
        }

        private void treeView1_BeforeCollapse(object sender, TreeViewCancelEventArgs e)
        {
            if (_expandedList.Contains(e.Node.FullPath))
            {
                _expandedList.Remove(e.Node.FullPath);
            }
        }

        private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            _expandedList.Add(e.Node.FullPath);
        }

        private void toolStripComboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            settings.SetLang(toolStripComboBox1.SelectedItem.ToString());
            LoadTexts();
        }

        private void button8_Click(object sender, EventArgs e)
        {
            if (textBox3.Text.Trim() != String.Empty)
            {
                Search(textBox2, textBox3.Text.Trim());
            }
        }

        private void associateRPARPIExtensionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ProcessModule processModule = Process.GetCurrentProcess().MainModule;
            if (processModule != null)
            {
                string filePath = processModule.FileName;
                FileAssociations.EnsureAssociationsSet(
                    new FileAssociation
                    {
                        Extension = ".rpi",
                        ProgId = "RPA Explorer",
                        FileTypeDescription = "RenPy Index File",
                        ExecutableFilePath = filePath
                    },
                    new FileAssociation
                    {
                        Extension = ".rpa",
                        ProgId = "RPA Explorer",
                        FileTypeDescription = "RenPy Archive File",
                        ExecutableFilePath = filePath
                    });
            }
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new About().ShowDialog();
        }
    }

    public static class Prompt
    {
        public static string ShowDialog(string text, string caption, string defaultValue)
        {
            Form prompt = new Form
            {
                Width = 500,
                Height = 150,
                FormBorderStyle = FormBorderStyle.FixedDialog,
                Text = caption,
                StartPosition = FormStartPosition.CenterScreen,
                MaximizeBox = false,
                MinimizeBox = false,
                TopMost = true
            };
            Label textLabel = new Label { Left = 50, Top = 20, Text = text };
            TextBox textBox = new TextBox { Left = 50, Top = 50, Width = 400, Text = defaultValue };
            Button confirmation = new Button { Text = @"OK", Left = 350, Width = 101, Top = 70, DialogResult = DialogResult.OK };
            confirmation.Click += (sender, e) => { prompt.Close(); };
            prompt.Controls.Add(textBox);
            prompt.Controls.Add(confirmation);
            prompt.Controls.Add(textLabel);
            prompt.AcceptButton = confirmation;

            return prompt.ShowDialog() == DialogResult.OK ? textBox.Text : String.Empty;
        }
    }

    public static class CrossThreadExtensions
    {
        public static void PerformSafely(this Control target, Action action)
        {
            if (target.InvokeRequired)
            {
                target.Invoke(action);
            }
            else
            {
                action();
            }
        }

        public static void PerformSafely<T1>(this Control target, Action<T1> action, T1 parameter)
        {
            if (target.InvokeRequired)
            {
                target.Invoke(action, parameter);
            }
            else
            {
                action(parameter);
            }
        }

        public static void PerformSafely<T1, T2>(this Control target, Action<T1, T2> action, T1 p1, T2 p2)
        {
            if (target.InvokeRequired)
            {
                target.Invoke(action, p1, p2);
            }
            else
            {
                action(p1, p2);
            }
        }
    }


    public static class Extensions
    {
        public static IEnumerable<TreeNode> All(this TreeNodeCollection nodes)
        {
            foreach (TreeNode n in nodes)
            {
                yield return n;
                foreach (TreeNode child in n.Nodes.All())
                    yield return child;
            }
        }
    }
}
ASSISTANT
To integrate the `MediaInfo` functionality into the provided code for `RPA_Explorer`, you will first need to implement the `GetMediaInfo` method inside the `RpaExplorer` class. This will allow you to check the codec and resolution of media files when they are selected or previewed.

### Step 1: Install MediaInfo Library

If you haven't already done so, install the `MediaInfo.DotNetWrapper` NuGet package to your project. You can do this using the NuGet Package Manager with the following command:

```bash
Install-Package MediaInfo.DotNetWrapper
```

### Step 2: Add Using Directive

Add the necessary using directive at the top of your `RpaExplorer` file:

```csharp
using MediaInfoDotNet; // Import MediaInfo namespace
```

### Step 3: Implement GetMediaInfo Method

Add the `GetMediaInfo` method in the `RpaExplorer` class. This method will extract codec and resolution information from the selected media file:

```csharp
private string GetMediaInfo(string filePath)
{
    if (string.IsNullOrWhiteSpace(filePath) || !File.Exists(filePath))
    {
        return "Invalid file path or file does not exist.";
    }

    try
    {
        using var mediaInfo = new MediaInfo(filePath);
        
        string videoCodec = mediaInfo.Video.Count > 0 ? mediaInfo.Video[0].Format : "N/A";
        string imageCodec = mediaInfo.Image.Count > 0 ? mediaInfo.Image[0].Format : "N/A";

        string resolution = "N/A";
        if (mediaInfo.Video.Count > 0)
        {
            var width = mediaInfo.Video[0].Width;
            var height = mediaInfo.Video[0].Height;
            resolution = $"{width}x{height}";
        }
        else if (mediaInfo.Image.Count > 0)
        {
            var width = mediaInfo.Image[0].Width;
            var height = mediaInfo.Image[0].Height;
            resolution = $"{width}x{height}";
        }

        return $"Codec: {videoCodec}, Resolution: {resolution}";
    }
    catch (Exception ex)
    {
        return $"Error retrieving media information: {ex.Message}";
    }
}
```

### Step 4: Use GetMediaInfo in PreviewSelectedItem Method

In the `PreviewSelectedItem` method, obtain the file path of the selected item, then call the `GetMediaInfo` method and display its result. Modify the method as follows:

```csharp
private async void PreviewSelectedItem()
{
    TreeNode selectedNode = new TreeNode();
    bool unsupportedFile = true;
    pictureBox1.Image = null;

    foreach (TreeNode node in treeView1.Nodes.All())
    {
        // Reset fields
        ResetPreviewFields();

        if (node.IsSelected)
        {
            selectedNode = node;
        }

        if (node.IsSelected && _rpaParser.Index.ContainsKey(NormalizeTreePath(node.FullPath)))
        {
            KeyValuePair<string, object> data = new KeyValuePair<string, object>();
            try
            {
                data = await Task.Run(() => _rpaParser.GetPreview(NormalizeTreePath(node.FullPath)));

                if (data.Key == RpaParser.PreviewTypes.Image)
                {
                    pictureBox1.Image = (Image)data.Value;
                    _switchTabs = true;
                    tabControl1.SelectedTab = tabPage1;
                    _switchTabs = false;
                    unsupportedFile = false;
                }
                else if (data.Key == RpaParser.PreviewTypes.Text)
                {
                    _searchStartIndex = 0;
                    textBox2.Text = (string)data.Value;
                    _switchTabs = true;
                    tabControl1.SelectedTab = tabPage2;
                    _switchTabs = false;
                    unsupportedFile = false;
                }
                else if (data.Key == RpaParser.PreviewTypes.Audio || data.Key == RpaParser.PreviewTypes.Video)
                {
                    _memoryStreamVlc = new MemoryStream((byte[])data.Value);
                    _streamMediaInputVlc = new StreamMediaInput(_memoryStreamVlc);
                    _mediaVlc = new Media(_libVlc, _streamMediaInputVlc);

                    // Ensure the media is stopped
                    await Task.Run(() =>
                    {
                        if (videoView1.MediaPlayer != null)
                        {
                            videoView1.MediaPlayer.Stop();
                        }
                    });

                    // Playback the new media
                    videoView1.MediaPlayer.Play(_mediaVlc);
                    SetMediaTimeLabel(_mediaVlc.Duration, 0);
                    videoView1.BackgroundImage = data.Key == RpaParser.PreviewTypes.Audio ? Resources.videoView1_BackgroundImage : null;
                    _switchTabs = true;
                    tabControl1.SelectedTab = tabPage3;
                    _switchTabs = false;
                    unsupportedFile = false;

                    // Check playback state to update button text
                    button4.Text = "Pause"; // Assuming you want to start playing the new video.
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format(GetText("Preview_failed_reason"), ex.Message), GetText("Preview_failed"), MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            // Retrieve and display media info
            string mediaInfo = GetMediaInfo(NormalizeTreePath(node.FullPath));
            textBox1.AppendText(mediaInfo + Environment.NewLine); // Append media info to the textbox

            break;
        }
    }

    if (unsupportedFile)
    {
        _switchTabs = true;
        tabControl1.SelectedTab = tabPage0;
        _switchTabs = false;
        label2.Text = GetText("Preview_is_not_supported");
    }

    treeView1.SelectedNode = selectedNode;
    treeView1.SelectedNode.SelectedImageIndex = selectedNode.ImageIndex;
    treeView1.SelectedNode.EnsureVisible();
    treeView1.Focus();
}
```

### Summary of Changes Made:

1. **Added the `GetMediaInfo` Method**: This method retrieves codec and resolution details from the specified media file.
2. **Integrated the MediaInfo Call**: In the `PreviewSelectedItem` method, after fetching the preview of the selected item, the `GetMediaInfo` method is called to append its output to your `archiveInfo` display.
3. **Error Handling Applied**: Both the media information retrieval process and the preview selection process include try-catch blocks to handle any errors that could occur if the selected file is not a valid media file.

With these modifications, your application should effectively retrieve and display codec and resolution information for media files, handling unsupported files gracefully.

turns-00061.parquet:26606

835446f45db8fe87b185e7eb
turn 9/35gpt-4o-mini-2024-07-18EnglishRussia3825 words
degenerate_repetitionAbsentFinal dense release
USER
Не удалось найти тип или имя пространства имен "MediaInfoDotNet" (возможно, отсутствует директива using или ссылка на сборку).
"MediaInfo" является пространство имен, но используется как тип.
```
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using LibVLCSharp.Shared;
using Microsoft.Win32;
using NeoSmart.PrettySize;
using RPA_Parser;
using MediaInfoDotNet; // Import MediaInfo namespace

namespace RPA_Explorer
{
    public partial class RpaExplorer : Form
    {
        private RpaParser _rpaParser;
        private RpaParser _rpaParserBak;
        private Thread _operation;
        private bool _operationEnabled = true;
        private bool _archiveChanged;
        private bool _cancelAdd;
        private bool _archiveLoaded;
        private SortedDictionary<string, RpaParser.ArchiveIndex> _fileListBackup = new();
        private readonly Dictionary<string, long> _indexPathSize = new();
        private readonly List<string> _expandedList = new();
        private bool _switchTabs;
        private readonly LibVLC _libVlc; // https://code.videolan.org/mfkl/libvlcsharp-samples
        private MemoryStream _memoryStreamVlc;
        private StreamMediaInput _streamMediaInputVlc;
        private Media _mediaVlc;
        private int _searchStartIndex = 0;
        private static readonly FileInfo _appInfo = new(System.Reflection.Assembly.GetEntryAssembly()?.Location ?? throw new InvalidOperationException());
        private static readonly FileInfo _appName = new(System.Reflection.Assembly.GetEntryAssembly()?.GetName().Name ?? throw new InvalidOperationException());
        private readonly string settingsPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/" + _appName + @"/settings.ini";

        private static readonly System.ComponentModel.ComponentResourceManager Lang = new(typeof(Lang));

        private static Settings settings;

        public RpaExplorer()
        {
            // Form initiation
            InitializeComponent();

            Directory.CreateDirectory(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/" + _appName);

            settings = new Settings(settingsPath);

            // Language initiation
            foreach (Settings.Language lang in settings.LangList)
            {
                toolStripComboBox1.Items.Add(lang.Name);
            }

            toolStripComboBox1.SelectedItem = settings.GetLang().Name;

            LoadTexts();

            // LibVLC initiation
            Core.Initialize();
            _libVlc = new LibVLC("--input-repeat=9999999"); // --input-repeat=X : Loop X times
            videoView1.MediaPlayer = new MediaPlayer(_libVlc);
            videoView1.MediaPlayer.Volume = 50;
            videoView1.MediaPlayer.TimeChanged += videoView1_MediaPlayer_TimeChanged;
            videoView1.BackgroundImage = null;
            SetMediaTimeLabel(0, 0);

            // Initialize the seek bar
            seekBar.Maximum = 1000; // Set maximum value for smooth seeking
            seekBar.Scroll += SeekBar_Scroll; // Handle scroll events for seeking

            // Subscribe to the TabControl's SelectedIndexChanged event
            tabControl1.SelectedIndexChanged += TabControl1_SelectedIndexChanged;

            // Hide the seek bar initially
            seekBar.Visible = false;

            // TreeView styles initiation
            ImageList imageList = new ImageList();
            imageList.Images.Add(Resources.treeView1_Image_folder);
            imageList.Images.Add(Resources.treeView1_Image_file);
            imageList.Images.Add(Resources.treeView1_Image_fileChanged);
            treeView1.ImageList = imageList;

            // Arguments processing
            string[] args = Environment.GetCommandLineArgs();
            if (args.Length >= 2)
            {
                LoadArchive(args[1]);
            }
        }

        private void TabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Show the seek bar only on the Media tab (tabPage3)
            if (tabControl1.SelectedTab == tabPage3)
            {
                seekBar.Visible = true;
            }
            else
            {
                seekBar.Visible = false;
            }
        }

        // Event handler for the seek bar's Scroll event
        private void SeekBar_Scroll(object sender, EventArgs e)
        {
            if (videoView1.MediaPlayer?.Media != null)
            {
                long duration = videoView1.MediaPlayer.Media.Duration;
                if (duration > 0)
                {
                    // Calculate newTime based on SeekBar position
                    long newTime = (long)((seekBar.Value / (double)seekBar.Maximum) * duration);
                    newTime = Math.Min(newTime, duration - 1); // Ensure newTime does not exceed duration

                    // Update the label3 based on the new time, independent of playback state
                    SetMediaTimeLabel(duration, newTime);

                    // Seek the video. If you want to seek immediately when scrolling, uncomment the line below.
                    videoView1.MediaPlayer.Time = newTime;
                }
            }
        }

        private void videoView1_MediaPlayer_TimeChanged(object sender, MediaPlayerTimeChangedEventArgs e)
        {
            Task.Run(async () =>
            {
                if (videoView1.MediaPlayer?.Media != null)
                {
                    long duration = videoView1.MediaPlayer.Media.Duration;

                    // Retry fetching duration if it seems invalid
                    if (duration <= 0)
                    {
                        await Task.Delay(500);
                        duration = videoView1.MediaPlayer.Media.Duration;
                    }

                    if (duration > 0)
                    {
                        int progress = (int)((e.Time / (double)duration) * seekBar.Maximum);
                        progress = Math.Min(progress, seekBar.Maximum);

                        seekBar.PerformSafely(() => seekBar.Value = progress);
                        SetMediaTimeLabel(duration, e.Time);
                    }
                }
            });
        }

        // Reset the seek bar when a new video is loaded
        private void ResetPreviewFields()
        {
            pictureBox1.Image = null;
            textBox2.Text = String.Empty;
            if (_memoryStreamVlc != null)
            {
                _memoryStreamVlc.Dispose();
                _memoryStreamVlc = null;
            }
            if (_streamMediaInputVlc != null)
            {
                _streamMediaInputVlc.Dispose();
                _streamMediaInputVlc = null;
            }
            if (_mediaVlc != null)
            {
                _mediaVlc.Dispose();
                _mediaVlc = null;
            }
            if (videoView1.MediaPlayer is { IsPlaying: true })
            {
                videoView1.MediaPlayer.Play(null!);
            }
            SetMediaTimeLabel(0, 0);

            // Reset the seek bar
            seekBar.Value = 0;
        }

        private void LoadTexts()
        {
            Text = GetText("Explorer_title");
            toolStripTextBox1.Text = GetText("Language");
            button1.Text = GetText("Load_file");
            button2.Text = GetText("Export_checked");
            statusBar1.Text = GetText("Ready");
            button3.Text = GetText("Cancel_operation");
            tabPage0.Text = GetText("None");
            label2.Text = GetText("Usage_instructions_new");
            tabPage1.Text = GetText("Image");
            tabPage2.Text = GetText("Text");
            tabPage3.Text = GetText("Media");
            button4.Text = GetText("Pause");
            button5.Text = GetText("Create_new_archive");
            label4.Text = GetText("File_list");
            button6.Text = GetText("Remove_checked");
            button7.Text = GetText("Save_archive");
            button8.Text = GetText("Search_next");
            label5.Text = GetText("Search");
            optionsToolStripMenuItem.Text = GetText("Options");
            associateRPARPIExtensionsToolStripMenuItem.Text = GetText("File_association");
            aboutToolStripMenuItem.Text = GetText("About");

            GenerateArchiveInfo();
        }

        internal static string GetText(string name)
        {
            if (Lang.GetObject(settings.GetLang().Abbrev + "_" + name) != null)
            {
                return Lang.GetObject(settings.GetLang().Abbrev + "_" + name)?.ToString();
            }

            return " {!!! MISSING TRANSLATION !!!} ";
        }

        private void ExportFiles(List<string> exportFilesList, FolderBrowserDialog folderBrowserDialog)
        {
            int counter = 0;
            int jobSize = exportFilesList.Count;
            foreach (string file in exportFilesList)
            {
                counter++;
                int pctProcessed = (int)Math.Ceiling((double)counter / jobSize * 100);
                label1.PerformSafely(() => label1.Text = $@"{counter} / {jobSize}");
                progressBar1.PerformSafely(() => progressBar1.Value = pctProcessed);

                statusBar1.PerformSafely(() => statusBar1.Text = GetText("Exporting_file") + file);

                _rpaParser.Extract(file, folderBrowserDialog.SelectedPath);

                if (!_operationEnabled)
                {
                    break;
                }
            }

            button1.PerformSafely(() => button1.Enabled = true);
            button2.PerformSafely(() => button2.Enabled = true);
            button3.PerformSafely(() => button3.Enabled = false);
            progressBar1.PerformSafely(() => progressBar1.Value = 0);
            label1.PerformSafely(() => label1.Text = "");
            statusBar1.PerformSafely(() => statusBar1.Text = GetText("Ready"));

            _operationEnabled = true;
        }

        private void CreateNewArchive()
        {
            if (CheckIfChanged(GetText("Archive_modified_new")))
            {
                return;
            }

            _expandedList.Clear();
            _rpaParser = new RpaParser();

            GenerateTreeView();

            _switchTabs = true;
            tabControl1.SelectedTab = tabPage0;
            _switchTabs = false;
            label2.Text = GetText("Usage_instructions_loaded");

            ResetPreviewFields();

            treeView1.SelectedNode = null;

            button2.Enabled = true;
            button6.Enabled = true;
            button7.Enabled = true;

            statusBar1.Text = GetText("Ready");

            _archiveChanged = true;
        }

        private void SaveArchive()
        {
            if (_rpaParser.Index.Count == 0)
            {
                MessageBox.Show(GetText("Empty_archive_save"), GetText("Empty_archive"), MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            statusBar1.Text = GetText("Saving_archive");

            string initPath = _appInfo?.DirectoryName;
            if (_rpaParser.ArchiveInfo?.DirectoryName != null)
            {
                initPath = _rpaParser.ArchiveInfo.DirectoryName;
            }

            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Title = GetText("Save_RenPy_Archive");
            saveFileDialog.Filter = GetText("RPA_RPI_files") + @" (*.rpa,*.rpi)|*.rpa;*.rpi";
            saveFileDialog.InitialDirectory = initPath;
            saveFileDialog.CheckFileExists = false;
            saveFileDialog.CheckPathExists = true;

            ArchiveSave options = new ArchiveSave(_rpaParser);
            options.ShowDialog();

            if (!_rpaParser.OptionsConfirmed)
            {
                return;
            }

            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                _rpaParserBak = _rpaParser;
                try
                {
                    string saveName = _rpaParser.SaveArchive(saveFileDialog.FileName);
                    LoadArchive(saveName, true);
                }
                catch (Exception ex)
                {
                    _rpaParser = _rpaParserBak;
                    MessageBox.Show(
                        string.Format(GetText("Save_failed_reason"), ex.Message),
                        GetText("Save_failed"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                GenerateTreeView();

                statusBar1.Text = GetText("Ready");
            }
        }

        private string GetMediaInfo(string filePath)
        {
            if (string.IsNullOrWhiteSpace(filePath) || !File.Exists(filePath))
            {
                return "Invalid file path or file does not exist.";
            }

            try
            {
                using var mediaInfo = new MediaInfo(filePath);

                string videoCodec = mediaInfo.Video.Count > 0 ? mediaInfo.Video[0].Format : "N/A";
                string imageCodec = mediaInfo.Image.Count > 0 ? mediaInfo.Image[0].Format : "N/A";

                string resolution = "N/A";
                if (mediaInfo.Video.Count > 0)
                {
                    var width = mediaInfo.Video[0].Width;
                    var height = mediaInfo.Video[0].Height;
                    resolution = $"{width}x{height}";
                }
                else if (mediaInfo.Image.Count > 0)
                {
                    var width = mediaInfo.Image[0].Width;
                    var height = mediaInfo.Image[0].Height;
                    resolution = $"{width}x{height}";
                }

                return $"Codec: {videoCodec}, Resolution: {resolution}";
            }
            catch (Exception ex)
            {
                return $"Error retrieving media information: {ex.Message}";
            }
        }

        private void GenerateArchiveInfo()
        {
            string archiveInfo = String.Empty;

            if (_archiveLoaded)
            {
                string selectedPath = String.Empty;
                foreach (TreeNode node in treeView1.Nodes.All())
                {
                    if (node.IsSelected)
                    {
                        selectedPath = NormalizeTreePath(node.FullPath);
                    }
                }

                long selectedSize = -1;
                int unsavedCount = 0;
                foreach (KeyValuePair<string, RpaParser.ArchiveIndex> kvp in _rpaParser.Index)
                {
                    if (!kvp.Value.InArchive)
                    {
                        unsavedCount++;
                    }

                    if (selectedPath == kvp.Key)
                    {
                        selectedSize = kvp.Value.Length;
                    }
                }

                if (_indexPathSize.ContainsKey(selectedPath))
                {
                    selectedSize = _indexPathSize[selectedPath];
                }

                if (!_rpaParser.CheckVersion(_rpaParser.ArchiveVersion, RpaParser.Version.Unknown))
                {
                    archiveInfo += GetText("Archive_version") + _rpaParser.ArchiveVersion + Environment.NewLine;
                    archiveInfo += GetText("Archive_file_location") + _rpaParser.ArchiveInfo.FullName +
                                   Environment.NewLine;
                    archiveInfo += GetText("Archive_file_size") + PrettySize.Format(_rpaParser.ArchiveInfo.Length) +
                                   Environment.NewLine;
                    if (_rpaParser.IndexInfo != null)
                    {
                        archiveInfo += GetText("Index_file_location") + _rpaParser.IndexInfo.FullName +
                                       Environment.NewLine;
                        archiveInfo += GetText("Index_file_size") + PrettySize.Format(_rpaParser.IndexInfo.Length) +
                                       Environment.NewLine;
                    }
                }

                archiveInfo += GetText("Files_count") + _rpaParser.Index.Count + Environment.NewLine;
                archiveInfo += GetText("Unsaved_files_count") + unsavedCount + Environment.NewLine;

                if (selectedSize != -1)
                {
                    if (selectedPath == String.Empty)
                    {
                        selectedPath = "/";
                    }
                    archiveInfo += GetText("Selected_file_path") + selectedPath +
                                   Environment.NewLine;
                    archiveInfo += GetText("Selected_file_size") + PrettySize.Format(selectedSize) +
                                   Environment.NewLine;
                }
            }

            textBox1.Text = archiveInfo.Trim();
        }

        private void LoadArchive(string openFile, bool ignoreChanges = false)
        {
            if (!ignoreChanges)
            {
                if (CheckIfChanged(GetText("Archive_modified_load")))
                {
                    return;
                }
            }

            using OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Title = GetText("Load_RenPy_Archive");
            openFileDialog.Filter = GetText("RPA_RPI_files") + @" (*.rpa,*.rpi)|*.rpa;*.rpi";

            string archivePath = settings.GetArchive();
            if (!string.IsNullOrEmpty(archivePath))
            {
                FileInfo fi = new FileInfo(archivePath);
                openFileDialog.InitialDirectory = fi.DirectoryName;
            }

            DialogResult dialogResult = DialogResult.None;
            if (string.IsNullOrEmpty(openFile))
            {
                dialogResult = openFileDialog.ShowDialog();
            }
            else
            {
                if (openFile.EndsWith(".rpa") || openFile.EndsWith(".rpi"))
                {
                    dialogResult = DialogResult.OK;
                    openFileDialog.FileName = openFile;
                }
                else
                {
                    MessageBox.Show(
                        string.Format(GetText("Load_failed_reason"), GetText("Not_valid_archive_file")),
                        GetText("Load_failed"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                    statusBar1.Text = GetText("Ready");
                    return;
                }
            }

            if (dialogResult == DialogResult.OK)
            {
                if (openFileDialog.CheckFileExists)
                {
                    settings.SetArchive(openFileDialog.FileName);
                    statusBar1.Text = GetText("Loading_file") + openFileDialog.FileName;

                    try
                    {
                        _expandedList.Clear();
                        _rpaParser = new RpaParser();

                        string appFolder = Path.GetDirectoryName(Application.ExecutablePath);
                        _rpaParser.UnrpycLocation = Path.Combine(appFolder, "unrpyc.exe");

                        _rpaParser.LoadArchive(openFileDialog.FileName);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(
                            string.Format(GetText("Load_failed_reason"), ex.Message),
                            GetText("Load_failed"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                        statusBar1.Text = GetText("Ready");
                        return;
                    }

                    GenerateTreeView();

                    _switchTabs = true;
                    tabControl1.SelectedTab = tabPage0;
                    _switchTabs = false;
                    label2.Text = GetText("Usage_instructions_loaded");

                    ResetPreviewFields();

                    treeView1.SelectedNode = null;

                    button2.Enabled = true;
                    button6.Enabled = true;
                    button7.Enabled = true;

                    statusBar1.Text = GetText("Ready");
                }

                _archiveChanged = false;
            }
        }

        private void AddFilesToArchive(string[] pathList)
        {
            // TODO: prompt for path to inset files into? Default can be root or selected object?
            //       Or don't prompt and use selected object? Empty folders should be excluded.
            //string promptValue = Prompt.ShowDialog("Test", "123", "xx");

            _fileListBackup.Clear();
            _fileListBackup = _rpaParser.DeepCopyIndex(_rpaParser.Index);
            _cancelAdd = false;

            foreach (string path in pathList)
            {
                string originalPath = path;
                if (Directory.Exists(path))
                {
                    originalPath = new DirectoryInfo(path).Parent?.FullName;
                }
                if (File.Exists(path))
                {
                    originalPath = new FileInfo(path).DirectoryName;
                }
                AddPathToIndex(path, originalPath);
            }

            if (!_cancelAdd)
            {
                _rpaParser.Index = _rpaParser.DeepCopyIndex(_fileListBackup);
            }

            _fileListBackup.Clear();
            GenerateTreeView();
        }

        private void GenerateTreeView()
        {
            _indexPathSize.Clear();
            treeView1.Nodes.Clear();
            TreeNode root = new TreeNode();
            TreeNode node;
            root.Name = "";
            root.Text = @"/";
            root.BackColor = Color.SandyBrown;
            root.ImageIndex = 0;
            treeView1.Nodes.Add(root);
            _indexPathSize.Add("", 0);
            string pathBuild;

            // Folders first
            foreach (KeyValuePair<string, RpaParser.ArchiveIndex> kvp in _rpaParser.Index)
            {
                node = root;
                pathBuild = String.Empty;
                foreach (string pathBits in kvp.Key.Split('/'))
                {
                    if (pathBuild == String.Empty)
                    {
                        pathBuild = pathBits;
                    }
                    else
                    {
                        pathBuild += "/" + pathBits;
                    }

                    if (node.Nodes.ContainsKey(pathBits))
                    {
                        node = node.Nodes[pathBits];
                    }
                    else
                    {
                        if (pathBuild != kvp.Key)
                        {
                            node = node.Nodes.Add(pathBits, pathBits);
                        }
                    }
                }
            }

            // Files second
            foreach (KeyValuePair<string, RpaParser.ArchiveIndex> kvp in _rpaParser.Index)
            {
                node = root;
                pathBuild = String.Empty;
                foreach (string pathBits in kvp.Key.Split('/'))
                {
                    if (pathBuild == String.Empty)
                    {
                        pathBuild = pathBits;
                    }
                    else
                    {
                        pathBuild += "/" + pathBits;
                    }

                    node = node.Nodes.ContainsKey(pathBits) ? node.Nodes[pathBits] : node.Nodes.Add(pathBits, pathBits);

                    if (pathBuild != kvp.Key)
                    {
                        if (!_indexPathSize.ContainsKey(pathBuild))
                        {
                            _indexPathSize.Add(pathBuild, 0);
                        }

                        if (_rpaParser.Index.ContainsKey(kvp.Key))
                        {
                            _indexPathSize[pathBuild] += _rpaParser.Index[kvp.Key].Length;
                        }
                    }
                    else
                    {
                        _indexPathSize[""] += _rpaParser.Index[kvp.Key].Length;
                    }
                }
            }

            foreach (TreeNode nodeVisuals in treeView1.Nodes.All())
            {
                string nodeName = NormalizeTreePath(nodeVisuals.FullPath);

                if (nodeName != String.Empty)
                {
                    if (nodeVisuals.Nodes.Count > 0)
                    {
                        nodeVisuals.BackColor = Color.SandyBrown;
                        nodeVisuals.ImageIndex = 0;
                    }
                    else
                    {
                        nodeVisuals.BackColor = Color.Transparent;
                        nodeVisuals.ImageIndex = 1;
                    }
                }

                if (_rpaParser.Index.ContainsKey(nodeName))
                {
                    if (!_rpaParser.Index[nodeName].InArchive)
                    {
                        nodeVisuals.ForeColor = Color.Green;
                        nodeVisuals.ImageIndex = 2;

                        MarkChanged(nodeVisuals);
                    }
                }

                if (_expandedList.Contains(nodeVisuals.FullPath))
                {
                    nodeVisuals.Expand();
                }
            }

            root.Expand();
            _archiveLoaded = true;

            GenerateArchiveInfo();
        }

        private void MarkChanged(TreeNode node)
        {
            if (node.Parent != null)
            {
                node.Parent.ForeColor = Color.Green;
                MarkChanged(node.Parent);
            }
        }

        private void Search(TextBox tb, string pattern)
        {
            int index;

            tb.Focus();

            if ((index = tb.Text.IndexOf(pattern, _searchStartIndex, StringComparison.Ordinal)) != -1)
            {
                tb.Select(index, pattern.Length);
                _searchStartIndex = tb.SelectionStart + tb.SelectionLength;
            }
            else
            {
                _searchStartIndex = 0;
                if ((index = tb.Text.IndexOf(pattern, _searchStartIndex, StringComparison.Ordinal)) != -1)
                {
                    tb.Select(index, pattern.Length);
                    _searchStartIndex = tb.SelectionStart + tb.SelectionLength;
                }
                else
                {
                    tb.Select(0, 0);
                }
            }

            tb.ScrollToCaret();
        }

        private string NormalizeTreePath(string path)
        {
            return Regex.Replace(path, "^/+", "");
        }

        private async void PreviewSelectedItem()
        {
            TreeNode selectedNode = new TreeNode();
            bool unsupportedFile = true;
            pictureBox1.Image = null;

            foreach (TreeNode node in treeView1.Nodes.All())
            {
                // Reset fields
                ResetPreviewFields();

                if (node.IsSelected)
                {
                    selectedNode = node;
                }

                if (node.IsSelected && _rpaParser.Index.ContainsKey(NormalizeTreePath(node.FullPath)))
                {
                    KeyValuePair<string, object> data = new KeyValuePair<string, object>();
                    try
                    {
                        data = await Task.Run(() => _rpaParser.GetPreview(NormalizeTreePath(node.FullPath)));

                        if (data.Key == RpaParser.PreviewTypes.Image)
                        {
                            pictureBox1.Image = (Image)data.Value;
                            _switchTabs = true;
                            tabControl1.SelectedTab = tabPage1;
                            _switchTabs = false;
                            unsupportedFile = false;
                        }
                        else if (data.Key == RpaParser.PreviewTypes.Text)
                        {
                            _searchStartIndex = 0;
                            textBox2.Text = (string)data.Value;
                            _switchTabs = true;
                            tabControl1.SelectedTab = tabPage2;
                            _switchTabs = false;
                            unsupportedFile = false;
                        }
                        else if (data.Key == RpaParser.PreviewTypes.Audio || data.Key == RpaParser.PreviewTypes.Video)
                        {
                            _memoryStreamVlc = new MemoryStream((byte[])data.Value);
                            _streamMediaInputVlc = new StreamMediaInput(_memoryStreamVlc);
                            _mediaVlc = new Media(_libVlc, _streamMediaInputVlc);

                            // Ensure the media is stopped
                            await Task.Run(() =>
                            {
                                if (videoView1.MediaPlayer != null)
                                {
                                    videoView1.MediaPlayer.Stop();
                                }
                            });

                            // Playback the new media
                            videoView1.MediaPlayer.Play(_mediaVlc);
                            SetMediaTimeLabel(_mediaVlc.Duration, 0);
                            videoView1.BackgroundImage = data.Key == RpaParser.PreviewTypes.Audio ? Resources.videoView1_BackgroundImage : null;
                            _switchTabs = true;
                            tabControl1.SelectedTab = tabPage3;
                            _switchTabs = false;
                            unsupportedFile = false;

                            // Check playback state to update button text
                            button4.Text = "Pause"; // Assuming you want to start playing the new video.
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(string.Format(GetText("Preview_failed_reason"), ex.Message), GetText("Preview_failed"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }

                    break;
                }
            }

            if (unsupportedFile)
            {
                _switchTabs = true;
                tabControl1.SelectedTab = tabPage0;
                _switchTabs = false;
                label2.Text = GetText("Preview_is_not_supported");
            }

            treeView1.SelectedNode = selectedNode;
            treeView1.SelectedNode.SelectedImageIndex = selectedNode.ImageIndex;
            treeView1.SelectedNode.EnsureVisible();
            treeView1.Focus();
        }

        private void CheckAllChildNodes(TreeNode node, bool isChecked)
        {
            if (node.Nodes.Count == 0)
            {
                node.Checked = isChecked;
            }
            else
            {
                foreach (TreeNode childNode in node.Nodes)
                {
                    CheckAllChildNodes(childNode, isChecked);
                }
                node.Checked = isChecked;
            }
        }

        private void ParentCheckControl(TreeNode parentNode)
        {
            foreach (TreeNode node in parentNode.Nodes.All())
            {
                if (!node.Checked)
                {
                    parentNode.Checked = false;
                    break;
                }
                parentNode.Checked = true;
            }
            if (parentNode.Parent != null)
            {
                ParentCheckControl(parentNode.Parent);
            }
        }

        private void PlayPauseMedia()
        {
            if (videoView1.MediaPlayer is { IsPlaying: true })
            {
                videoView1.MediaPlayer?.Pause();
                button4.Text = GetText("Play");
            }
            else
            {
                videoView1.MediaPlayer?.Play();
                button4.Text = GetText("Pause");
            }
        }

        private void SetMediaTimeLabel(long totalTimeMillies, long currentTimeMillies)
        {
            TimeSpan totalTime = TimeSpan.FromMilliseconds(totalTimeMillies);
            TimeSpan currentTime = TimeSpan.FromMilliseconds(currentTimeMillies);
            TimeSpan remainingTime = totalTime - currentTime;

            string timeFormat = @"hh\:mm\:ss";
            string timeText = $"{currentTime.ToString(timeFormat)} / {totalTime.ToString(timeFormat)} (-{remainingTime.ToString(timeFormat)})";

            label3.PerformSafely(() => label3.Text = timeText);
        }

        private bool CheckIfChanged(string message)
        {
            if (message != String.Empty && _archiveChanged)
            {
                if (MessageBox.Show(message, GetText("Archive_modified"), MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No)
                {
                    return true;
                }

                return false;
            }

            return _archiveChanged;
        }

        private void AddPathToIndex(string path, string originalPath)
        {
            _archiveChanged = true;
            RpaParser.ArchiveIndex index = new RpaParser.ArchiveIndex
            {
                InArchive = false
            };

            if (Directory.Exists(path))
            {
                foreach (string pathFile in Directory.GetFiles(path))
                {
                    AddPathToIndex(pathFile, originalPath);
                }
                foreach (string pathDir in Directory.GetDirectories(path))
                {
                    AddPathToIndex(pathDir, originalPath);
                }
            }

            if (File.Exists(path) && !_cancelAdd)
            {
                index.FullPath = path.Replace(@"\", "/");
                index.TreePath = index.FullPath.Replace(originalPath.Replace(@"\", "/") + "/", String.Empty);
                index.ParentPath = Path.GetDirectoryName(index.TreePath);
                index.Length = new FileInfo(path).Length;
                index.InArchive = false;

                if (_fileListBackup.ContainsKey(index.TreePath))
                {
                    _fileListBackup.Remove(index.TreePath);
                }

                _fileListBackup.Add(index.TreePath, index);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            LoadArchive(String.Empty);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            using FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
            List<string> exportFilesList = new List<string>();
            foreach (TreeNode node in treeView1.Nodes.All())
            {
                if (node.Checked && _rpaParser.Index.ContainsKey(NormalizeTreePath(node.FullPath)))
                {
                    exportFilesList.Add(NormalizeTreePath(node.FullPath));
                }
            }

            if (exportFilesList.Count == 0)
            {
                return;
            }

            folderBrowserDialog.SelectedPath = _rpaParser.ArchiveInfo.DirectoryName;
            if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
            {
                button1.Enabled = false;
                button2.Enabled = false;
                button3.Enabled = true;
                progressBar1.Value = 0;
                label1.PerformSafely(() => label1.Text = "");

                _operation = new Thread(() => ExportFiles(exportFilesList, folderBrowserDialog));
                _operation.Start();
            }
        }

        public class FileAssociation
        {
            public string Extension { get; set; }
            public string ProgId { get; set; }
            public string FileTypeDescription { get; set; }
            public string ExecutableFilePath { get; set; }
        }

        public class FileAssociations
        {
            // needed so that Explorer windows get refreshed after the registry is updated
            [DllImport("Shell32.dll")]
            private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);

            private const int SHCNE_ASSOCCHANGED = 0x8000000;
            private const int SHCNF_FLUSH = 0x1000;


            public static void EnsureAssociationsSet(params FileAssociation[] associations)
            {
                bool madeChanges = false;
                foreach (FileAssociation association in associations)
                {
                    madeChanges |= SetAssociation(
                        association.Extension,
                        association.ProgId,
                        association.FileTypeDescription,
                        association.ExecutableFilePath);
                }

                if (madeChanges)
                {
                    SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero);
                }
            }

            private static bool SetAssociation(string extension, string progId, string fileTypeDescription, string applicationFilePath)
            {
                bool madeChanges = false;
                madeChanges |= SetKeyDefaultValue(@"Software\Classes\" + extension, progId);
                madeChanges |= SetKeyDefaultValue(@"Software\Classes\" + progId, fileTypeDescription);
                madeChanges |= SetKeyDefaultValue($@"Software\Classes\{progId}\shell\open\command", "\"" + applicationFilePath + "\" \"%1\"");
                return madeChanges;
            }

            private static bool SetKeyDefaultValue(string keyPath, string value)
            {
                using var key = Registry.CurrentUser.CreateSubKey(keyPath);
                if (key == null || key.GetValue(null) as string == value) return false;
                key.SetValue(null, value);
                return true;
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            _operationEnabled = false;
        }

        private void treeView1_AfterSelect(object sender, EventArgs e)
        {
            PreviewSelectedItem();
            GenerateArchiveInfo();
        }

        private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
        {
            if (e.Action != TreeViewAction.Unknown)
            {
                Task.Run(async () =>
                {
                    await Task.Delay(50); // Prevent rapid selection from missing updates
                    Application.DoEvents(); // Force UI refresh to process all pending events

                    // Ensure all children are updated
                    if (e.Node.Nodes.Count > 0)
                    {
                        CheckAllChildNodes(e.Node, e.Node.Checked);
                    }

                    // Ensure parents reflect the correct state
                    if (e.Node.Parent != null)
                    {
                        ParentCheckControl(e.Node.Parent);
                    }
                });
            }
        }

        private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e)
        {
            if (!_switchTabs)
            {
                e.Cancel = true;
            }
            _switchTabs = false;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            PlayPauseMedia();
        }

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            if (videoView1.MediaPlayer?.Media != null)
            {
                videoView1.MediaPlayer.Volume = trackBar1.Value;
            }
        }

        private void RpaExplorer_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (CheckIfChanged(GetText("Archive_modified_close")))
            {
                e.Cancel = true;
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            CreateNewArchive();
        }

        private string targetFoldername; // Class-level variable to store the folder name

        private void treeView1_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] droppedFiles = (string[])e.Data.GetData(DataFormats.FileDrop);

                // Initialize the targetFoldername variable
                targetFoldername = string.Empty; // Reset before each drop

                // Check if the first dropped item is a directory
                if (Directory.Exists(droppedFiles[0]))
                {
                    // If it's a folder, set targetFoldername to the name of that folder
                    targetFoldername = Path.GetFileName(droppedFiles[0]);
                }

                if (e.Data.GetDataPresent(DataFormats.FileDrop))
                {
                    AddFilesToArchive((string[])e.Data.GetData(DataFormats.FileDrop));
                }
            }
        }

        private void treeView1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop) && _archiveLoaded)
            {
                e.Effect = DragDropEffects.Copy;
                return;
            }
            e.Effect = DragDropEffects.None;
        }

        private void tabControl1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Copy;
                return;
            }
            e.Effect = DragDropEffects.None;
        }

        private void tabControl1_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                LoadArchive(((string[])e.Data.GetData(DataFormats.FileDrop))[0]);
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            bool changed = false;
            foreach (TreeNode node in treeView1.Nodes.All())
            {
                if (node.Checked && _rpaParser.Index.ContainsKey(NormalizeTreePath(node.FullPath)))
                {
                    _rpaParser.Index.Remove(NormalizeTreePath(node.FullPath));
                    changed = true;
                }
            }

            if (changed)
            {
                _archiveChanged = true;
                GenerateTreeView();
            }
        }

        private void button7_Click(object sender, EventArgs e)
        {
            SaveArchive();
        }

        private void treeView1_BeforeCollapse(object sender, TreeViewCancelEventArgs e)
        {
            if (_expandedList.Contains(e.Node.FullPath))
            {
                _expandedList.Remove(e.Node.FullPath);
            }
        }

        private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            _expandedList.Add(e.Node.FullPath);
        }

        private void toolStripComboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            settings.SetLang(toolStripComboBox1.SelectedItem.ToString());
            LoadTexts();
        }

        private void button8_Click(object sender, EventArgs e)
        {
            if (textBox3.Text.Trim() != String.Empty)
            {
                Search(textBox2, textBox3.Text.Trim());
            }
        }

        private void associateRPARPIExtensionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ProcessModule processModule = Process.GetCurrentProcess().MainModule;
            if (processModule != null)
            {
                string filePath = processModule.FileName;
                FileAssociations.EnsureAssociationsSet(
                    new FileAssociation
                    {
                        Extension = ".rpi",
                        ProgId = "RPA Explorer",
                        FileTypeDescription = "RenPy Index File",
                        ExecutableFilePath = filePath
                    },
                    new FileAssociation
                    {
                        Extension = ".rpa",
                        ProgId = "RPA Explorer",
                        FileTypeDescription = "RenPy Archive File",
                        ExecutableFilePath = filePath
                    });
            }
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new About().ShowDialog();
        }
    }

    public static class Prompt
    {
        public static string ShowDialog(string text, string caption, string defaultValue)
        {
            Form prompt = new Form
            {
                Width = 500,
                Height = 150,
                FormBorderStyle = FormBorderStyle.FixedDialog,
                Text = caption,
                StartPosition = FormStartPosition.CenterScreen,
                MaximizeBox = false,
                MinimizeBox = false,
                TopMost = true
            };
            Label textLabel = new Label { Left = 50, Top = 20, Text = text };
            TextBox textBox = new TextBox { Left = 50, Top = 50, Width = 400, Text = defaultValue };
            Button confirmation = new Button { Text = @"OK", Left = 350, Width = 101, Top = 70, DialogResult = DialogResult.OK };
            confirmation.Click += (sender, e) => { prompt.Close(); };
            prompt.Controls.Add(textBox);
            prompt.Controls.Add(confirmation);
            prompt.Controls.Add(textLabel);
            prompt.AcceptButton = confirmation;

            return prompt.ShowDialog() == DialogResult.OK ? textBox.Text : String.Empty;
        }
    }

    public static class CrossThreadExtensions
    {
        public static void PerformSafely(this Control target, Action action)
        {
            if (target.InvokeRequired)
            {
                target.Invoke(action);
            }
            else
            {
                action();
            }
        }

        public static void PerformSafely<T1>(this Control target, Action<T1> action, T1 parameter)
        {
            if (target.InvokeRequired)
            {
                target.Invoke(action, parameter);
            }
            else
            {
                action(parameter);
            }
        }

        public static void PerformSafely<T1, T2>(this Control target, Action<T1, T2> action, T1 p1, T2 p2)
        {
            if (target.InvokeRequired)
            {
                target.Invoke(action, p1, p2);
            }
            else
            {
                action(p1, p2);
            }
        }
    }


    public static class Extensions
    {
        public static IEnumerable<TreeNode> All(this TreeNodeCollection nodes)
        {
            foreach (TreeNode n in nodes)
            {
                yield return n;
                foreach (TreeNode child in n.Nodes.All())
                    yield return child;
            }
        }
    }
}
ASSISTANT
It looks like you're encountering issues with the `MediaInfoDotNet` namespace, which could be due to one of the following reasons:

1. **The library might not be installed correctly**.
2. **The correct namespace is being used**, but you're not using the classes and constructor correctly.

### Steps to Resolve the Issue

1. **Ensure MediaInfo is Installed**:
   Make sure that you have the `MediaInfo.DotNetWrapper` installed in your project. You can verify this in the `Solution Explorer` under the `Dependencies` or `References` section. If it's missing, install it using:
   ```bash
   Install-Package MediaInfo.DotNetWrapper
   ```

2. **Correct Namespace Usage**:
   The `MediaInfo.DotNetWrapper` should provide a `MediaInfo` class that you can use. Ensure you're using it correctly. The namespace might need to reflect the specific types it provides.

3. **Add the correct library reference**:
   If you see any errors like "The type or namespace name 'MediaInfoDotNet' does not exist," it suggests that your usings or references are not set up correctly. Make sure to follow these structured steps to implement it.

### Implementing MediaInfo

Given your existing code, let's incorporate the `GetMediaInfo` method correctly and ensure it checks for file types properly:

### Step 1: Declare the GetMediaInfo Method

Add the `GetMediaInfo` method inside the `RpaExplorer` class. This will retrieve the media information if the file exists and is a recognizable type.

```csharp
private string GetMediaInfo(string filePath)
{
    if (string.IsNullOrWhiteSpace(filePath) || !File.Exists(filePath))
    {
        return "Invalid file path or file does not exist.";
    }

    try
    {
        using var mediaInfo = new MediaInfo(filePath);

        // Extract video codec and resolution
        string videoCodec = mediaInfo.Video.Count > 0 ? mediaInfo.Video[0].Format : "N/A";
        string resolution = "N/A";
        if (mediaInfo.Video.Count > 0)
        {
            var width = mediaInfo.Video[0].Width;
            var height = mediaInfo.Video[0].Height;
            resolution = $"{width}x{height}";
        }

        return $"Codec: {videoCodec}, Resolution: {resolution}";
    }
    catch (Exception ex)
    {
        return $"Error retrieving media information: {ex.Message}";
    }
}
```

### Step 2: Integrate GetMediaInfo Functionality

Modify the `PreviewSelectedItem` method to include a call to `GetMediaInfo` when a media file is selected:

```csharp
private async void PreviewSelectedItem()
{
    TreeNode selectedNode = new TreeNode();
    bool unsupportedFile = true;
    pictureBox1.Image = null;

    foreach (TreeNode node in treeView1.Nodes.All())
    {
        // Reset fields
        ResetPreviewFields();

        if (node.IsSelected)
        {
            selectedNode = node;
        }

        if (node.IsSelected && _rpaParser.Index.ContainsKey(NormalizeTreePath(node.FullPath)))
        {
            KeyValuePair<string, object> data = new KeyValuePair<string, object>();
            try
            {
                data = await Task.Run(() => _rpaParser.GetPreview(NormalizeTreePath(node.FullPath)));

                // Handle image preview
                if (data.Key == RpaParser.PreviewTypes.Image)
                {
                    pictureBox1.Image = (Image)data.Value;
                    _switchTabs = true;
                    tabControl1.SelectedTab = tabPage1;
                    _switchTabs = false;
                    unsupportedFile = false;
                }
                // Handle text preview
                else if (data.Key == RpaParser.PreviewTypes.Text)
                {
                    textBox2.Text = (string)data.Value;
                    _switchTabs = true;
                    tabControl1.SelectedTab = tabPage2;
                    _switchTabs = false;
                    unsupportedFile = false;
                }
                // Handle media
                else if (data.Key == RpaParser.PreviewTypes.Audio || data.Key == RpaParser.PreviewTypes.Video)
                {
                    // Setting up media for playback
                    // (Assume you already have media handling here)
                    // ...

                    unsupportedFile = false;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format(GetText("Preview_failed_reason"), ex.Message), GetText("Preview_failed"), MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            // Retrieve media info for displayed media file
            string mediaInfo = GetMediaInfo(NormalizeTreePath(node.FullPath));
            // Display media info in a suitable control, e.g., in a TextBox
            textBox1.AppendText(mediaInfo + Environment.NewLine);

            break;
        }
    }

    if (unsupportedFile)
    {
        _switchTabs = true;
        tabControl1.SelectedTab = tabPage0;
        _switchTabs = false;
        label2.Text = GetText("Preview_is_not_supported");
    }

    treeView1.SelectedNode = selectedNode;
    treeView1.SelectedNode.SelectedImageIndex = selectedNode.ImageIndex;
    treeView1.SelectedNode.EnsureVisible();
    treeView1.Focus();
}
```

### Step 3: Ensure Correct Method Calls

1. Make sure any calls to `GetMediaInfo` are passing the correct file path based on how your file structure is organized in the TreeView.
2. When testing, ensure that you have files of different types in your `RPA_Parser` so that you can check both supported and unsupported media formats.

### Troubleshooting

- If you're seeing errors about the `MediaInfoDotNet` namespace, double-check the installation of the package, ensure your project's build system recognizes it, and confirm you're not using a version mismatch (like .NET Core vs. .NET Framework).
- Make sure to rebuild the solution after making these changes to clear out any lingering errors.

By structuring your code this way, you should be able to retrieve media information correctly while also managing unsupported file types gracefully.

turns-00061.parquet:26607

5e3e64def58a6515118c26ae
turn 10/35gpt-4o-mini-2024-07-18EnglishRussia3866 words
degenerate_repetitionAbsentFinal dense release
USER
I got errors:
"MediaInfoWrapper": тип, используемый в операторе using, должен реализовывать "System.IDisposable".
"MediaInfoWrapper" не содержит определения "Video", и не удалось найти доступный метод расширения "Video", принимающий тип "MediaInfoWrapper" в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку).
"MediaInfoWrapper" не содержит определения "Video", и не удалось найти доступный метод расширения "Video", принимающий тип "MediaInfoWrapper" в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку).
"MediaInfoWrapper" не содержит определения "Image", и не удалось найти доступный метод расширения "Image", принимающий тип "MediaInfoWrapper" в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку).
"MediaInfoWrapper" не содержит определения "Image", и не удалось найти доступный метод расширения "Image", принимающий тип "MediaInfoWrapper" в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку).
"MediaInfoWrapper" не содержит определения "Video", и не удалось найти доступный метод расширения "Video", принимающий тип "MediaInfoWrapper" в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку).
"MediaInfoWrapper" не содержит определения "Video", и не удалось найти доступный метод расширения "Video", принимающий тип "MediaInfoWrapper" в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку).
"MediaInfoWrapper" не содержит определения "Video", и не удалось найти доступный метод расширения "Video", принимающий тип "MediaInfoWrapper" в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку).
"MediaInfoWrapper" не содержит определения "Image", и не удалось найти доступный метод расширения "Image", принимающий тип "MediaInfoWrapper" в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку).
"MediaInfoWrapper" не содержит определения "Image", и не удалось найти доступный метод расширения "Image", принимающий тип "MediaInfoWrapper" в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку).
"MediaInfoWrapper" не содержит определения "Image", и не удалось найти доступный метод расширения "Image", принимающий тип "MediaInfoWrapper" в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку).
```
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using LibVLCSharp.Shared;
using Microsoft.Win32;
using NeoSmart.PrettySize;
using RPA_Parser;
using MediaInfo.DotNetWrapper; // Import MediaInfo namespace

namespace RPA_Explorer
{
    public partial class RpaExplorer : Form
    {
        private RpaParser _rpaParser;
        private RpaParser _rpaParserBak;
        private Thread _operation;
        private bool _operationEnabled = true;
        private bool _archiveChanged;
        private bool _cancelAdd;
        private bool _archiveLoaded;
        private SortedDictionary<string, RpaParser.ArchiveIndex> _fileListBackup = new();
        private readonly Dictionary<string, long> _indexPathSize = new();
        private readonly List<string> _expandedList = new();
        private bool _switchTabs;
        private readonly LibVLC _libVlc; // https://code.videolan.org/mfkl/libvlcsharp-samples
        private MemoryStream _memoryStreamVlc;
        private StreamMediaInput _streamMediaInputVlc;
        private Media _mediaVlc;
        private int _searchStartIndex = 0;
        private static readonly FileInfo _appInfo = new(System.Reflection.Assembly.GetEntryAssembly()?.Location ?? throw new InvalidOperationException());
        private static readonly FileInfo _appName = new(System.Reflection.Assembly.GetEntryAssembly()?.GetName().Name ?? throw new InvalidOperationException());
        private readonly string settingsPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/" + _appName + @"/settings.ini";

        private static readonly System.ComponentModel.ComponentResourceManager Lang = new(typeof(Lang));

        private static Settings settings;

        public RpaExplorer()
        {
            // Form initiation
            InitializeComponent();

            Directory.CreateDirectory(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/" + _appName);

            settings = new Settings(settingsPath);

            // Language initiation
            foreach (Settings.Language lang in settings.LangList)
            {
                toolStripComboBox1.Items.Add(lang.Name);
            }

            toolStripComboBox1.SelectedItem = settings.GetLang().Name;

            LoadTexts();

            // LibVLC initiation
            Core.Initialize();
            _libVlc = new LibVLC("--input-repeat=9999999"); // --input-repeat=X : Loop X times
            videoView1.MediaPlayer = new MediaPlayer(_libVlc);
            videoView1.MediaPlayer.Volume = 50;
            videoView1.MediaPlayer.TimeChanged += videoView1_MediaPlayer_TimeChanged;
            videoView1.BackgroundImage = null;
            SetMediaTimeLabel(0, 0);

            // Initialize the seek bar
            seekBar.Maximum = 1000; // Set maximum value for smooth seeking
            seekBar.Scroll += SeekBar_Scroll; // Handle scroll events for seeking

            // Subscribe to the TabControl's SelectedIndexChanged event
            tabControl1.SelectedIndexChanged += TabControl1_SelectedIndexChanged;

            // Hide the seek bar initially
            seekBar.Visible = false;

            // TreeView styles initiation
            ImageList imageList = new ImageList();
            imageList.Images.Add(Resources.treeView1_Image_folder);
            imageList.Images.Add(Resources.treeView1_Image_file);
            imageList.Images.Add(Resources.treeView1_Image_fileChanged);
            treeView1.ImageList = imageList;

            // Arguments processing
            string[] args = Environment.GetCommandLineArgs();
            if (args.Length >= 2)
            {
                LoadArchive(args[1]);
            }
        }

        private void TabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Show the seek bar only on the Media tab (tabPage3)
            if (tabControl1.SelectedTab == tabPage3)
            {
                seekBar.Visible = true;
            }
            else
            {
                seekBar.Visible = false;
            }
        }

        // Event handler for the seek bar's Scroll event
        private void SeekBar_Scroll(object sender, EventArgs e)
        {
            if (videoView1.MediaPlayer?.Media != null)
            {
                long duration = videoView1.MediaPlayer.Media.Duration;
                if (duration > 0)
                {
                    // Calculate newTime based on SeekBar position
                    long newTime = (long)((seekBar.Value / (double)seekBar.Maximum) * duration);
                    newTime = Math.Min(newTime, duration - 1); // Ensure newTime does not exceed duration

                    // Update the label3 based on the new time, independent of playback state
                    SetMediaTimeLabel(duration, newTime);

                    // Seek the video. If you want to seek immediately when scrolling, uncomment the line below.
                    videoView1.MediaPlayer.Time = newTime;
                }
            }
        }

        private void videoView1_MediaPlayer_TimeChanged(object sender, MediaPlayerTimeChangedEventArgs e)
        {
            Task.Run(async () =>
            {
                if (videoView1.MediaPlayer?.Media != null)
                {
                    long duration = videoView1.MediaPlayer.Media.Duration;

                    // Retry fetching duration if it seems invalid
                    if (duration <= 0)
                    {
                        await Task.Delay(500);
                        duration = videoView1.MediaPlayer.Media.Duration;
                    }

                    if (duration > 0)
                    {
                        int progress = (int)((e.Time / (double)duration) * seekBar.Maximum);
                        progress = Math.Min(progress, seekBar.Maximum);

                        seekBar.PerformSafely(() => seekBar.Value = progress);
                        SetMediaTimeLabel(duration, e.Time);
                    }
                }
            });
        }

        // Reset the seek bar when a new video is loaded
        private void ResetPreviewFields()
        {
            pictureBox1.Image = null;
            textBox2.Text = String.Empty;
            if (_memoryStreamVlc != null)
            {
                _memoryStreamVlc.Dispose();
                _memoryStreamVlc = null;
            }
            if (_streamMediaInputVlc != null)
            {
                _streamMediaInputVlc.Dispose();
                _streamMediaInputVlc = null;
            }
            if (_mediaVlc != null)
            {
                _mediaVlc.Dispose();
                _mediaVlc = null;
            }
            if (videoView1.MediaPlayer is { IsPlaying: true })
            {
                videoView1.MediaPlayer.Play(null!);
            }
            SetMediaTimeLabel(0, 0);

            // Reset the seek bar
            seekBar.Value = 0;
        }

        private void LoadTexts()
        {
            Text = GetText("Explorer_title");
            toolStripTextBox1.Text = GetText("Language");
            button1.Text = GetText("Load_file");
            button2.Text = GetText("Export_checked");
            statusBar1.Text = GetText("Ready");
            button3.Text = GetText("Cancel_operation");
            tabPage0.Text = GetText("None");
            label2.Text = GetText("Usage_instructions_new");
            tabPage1.Text = GetText("Image");
            tabPage2.Text = GetText("Text");
            tabPage3.Text = GetText("Media");
            button4.Text = GetText("Pause");
            button5.Text = GetText("Create_new_archive");
            label4.Text = GetText("File_list");
            button6.Text = GetText("Remove_checked");
            button7.Text = GetText("Save_archive");
            button8.Text = GetText("Search_next");
            label5.Text = GetText("Search");
            optionsToolStripMenuItem.Text = GetText("Options");
            associateRPARPIExtensionsToolStripMenuItem.Text = GetText("File_association");
            aboutToolStripMenuItem.Text = GetText("About");

            GenerateArchiveInfo();
        }

        internal static string GetText(string name)
        {
            if (Lang.GetObject(settings.GetLang().Abbrev + "_" + name) != null)
            {
                return Lang.GetObject(settings.GetLang().Abbrev + "_" + name)?.ToString();
            }

            return " {!!! MISSING TRANSLATION !!!} ";
        }

        private void ExportFiles(List<string> exportFilesList, FolderBrowserDialog folderBrowserDialog)
        {
            int counter = 0;
            int jobSize = exportFilesList.Count;
            foreach (string file in exportFilesList)
            {
                counter++;
                int pctProcessed = (int)Math.Ceiling((double)counter / jobSize * 100);
                label1.PerformSafely(() => label1.Text = $@"{counter} / {jobSize}");
                progressBar1.PerformSafely(() => progressBar1.Value = pctProcessed);

                statusBar1.PerformSafely(() => statusBar1.Text = GetText("Exporting_file") + file);

                _rpaParser.Extract(file, folderBrowserDialog.SelectedPath);

                if (!_operationEnabled)
                {
                    break;
                }
            }

            button1.PerformSafely(() => button1.Enabled = true);
            button2.PerformSafely(() => button2.Enabled = true);
            button3.PerformSafely(() => button3.Enabled = false);
            progressBar1.PerformSafely(() => progressBar1.Value = 0);
            label1.PerformSafely(() => label1.Text = "");
            statusBar1.PerformSafely(() => statusBar1.Text = GetText("Ready"));

            _operationEnabled = true;
        }

        private void CreateNewArchive()
        {
            if (CheckIfChanged(GetText("Archive_modified_new")))
            {
                return;
            }

            _expandedList.Clear();
            _rpaParser = new RpaParser();

            GenerateTreeView();

            _switchTabs = true;
            tabControl1.SelectedTab = tabPage0;
            _switchTabs = false;
            label2.Text = GetText("Usage_instructions_loaded");

            ResetPreviewFields();

            treeView1.SelectedNode = null;

            button2.Enabled = true;
            button6.Enabled = true;
            button7.Enabled = true;

            statusBar1.Text = GetText("Ready");

            _archiveChanged = true;
        }

        private void SaveArchive()
        {
            if (_rpaParser.Index.Count == 0)
            {
                MessageBox.Show(GetText("Empty_archive_save"), GetText("Empty_archive"), MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            statusBar1.Text = GetText("Saving_archive");

            string initPath = _appInfo?.DirectoryName;
            if (_rpaParser.ArchiveInfo?.DirectoryName != null)
            {
                initPath = _rpaParser.ArchiveInfo.DirectoryName;
            }

            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Title = GetText("Save_RenPy_Archive");
            saveFileDialog.Filter = GetText("RPA_RPI_files") + @" (*.rpa,*.rpi)|*.rpa;*.rpi";
            saveFileDialog.InitialDirectory = initPath;
            saveFileDialog.CheckFileExists = false;
            saveFileDialog.CheckPathExists = true;

            ArchiveSave options = new ArchiveSave(_rpaParser);
            options.ShowDialog();

            if (!_rpaParser.OptionsConfirmed)
            {
                return;
            }

            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                _rpaParserBak = _rpaParser;
                try
                {
                    string saveName = _rpaParser.SaveArchive(saveFileDialog.FileName);
                    LoadArchive(saveName, true);
                }
                catch (Exception ex)
                {
                    _rpaParser = _rpaParserBak;
                    MessageBox.Show(
                        string.Format(GetText("Save_failed_reason"), ex.Message),
                        GetText("Save_failed"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                GenerateTreeView();

                statusBar1.Text = GetText("Ready");
            }
        }

        private string GetMediaInfo(string filePath)
        {
            if (string.IsNullOrWhiteSpace(filePath) || !File.Exists(filePath))
            {
                return "Invalid file path or file does not exist.";
            }

            try
            {
                using var mediaInfo = new MediaInfoWrapper(filePath);

                string videoCodec = mediaInfo.Video.Count > 0 ? mediaInfo.Video[0].Format : "N/A";
                string imageCodec = mediaInfo.Image.Count > 0 ? mediaInfo.Image[0].Format : "N/A";

                string resolution = "N/A";
                if (mediaInfo.Video.Count > 0)
                {
                    var width = mediaInfo.Video[0].Width;
                    var height = mediaInfo.Video[0].Height;
                    resolution = $"{width}x{height}";
                }
                else if (mediaInfo.Image.Count > 0)
                {
                    var width = mediaInfo.Image[0].Width;
                    var height = mediaInfo.Image[0].Height;
                    resolution = $"{width}x{height}";
                }

                return $"Codec: {videoCodec}, Resolution: {resolution}";
            }
            catch (Exception ex)
            {
                return $"Error retrieving media information: {ex.Message}";
            }
        }

        private void GenerateArchiveInfo()
        {
            string archiveInfo = String.Empty;

            if (_archiveLoaded)
            {
                string selectedPath = String.Empty;
                foreach (TreeNode node in treeView1.Nodes.All())
                {
                    if (node.IsSelected)
                    {
                        selectedPath = NormalizeTreePath(node.FullPath);
                    }
                }

                long selectedSize = -1;
                int unsavedCount = 0;
                foreach (KeyValuePair<string, RpaParser.ArchiveIndex> kvp in _rpaParser.Index)
                {
                    if (!kvp.Value.InArchive)
                    {
                        unsavedCount++;
                    }

                    if (selectedPath == kvp.Key)
                    {
                        selectedSize = kvp.Value.Length;
                    }
                }

                if (_indexPathSize.ContainsKey(selectedPath))
                {
                    selectedSize = _indexPathSize[selectedPath];
                }

                if (!_rpaParser.CheckVersion(_rpaParser.ArchiveVersion, RpaParser.Version.Unknown))
                {
                    archiveInfo += GetText("Archive_version") + _rpaParser.ArchiveVersion + Environment.NewLine;
                    archiveInfo += GetText("Archive_file_location") + _rpaParser.ArchiveInfo.FullName +
                                   Environment.NewLine;
                    archiveInfo += GetText("Archive_file_size") + PrettySize.Format(_rpaParser.ArchiveInfo.Length) +
                                   Environment.NewLine;
                    if (_rpaParser.IndexInfo != null)
                    {
                        archiveInfo += GetText("Index_file_location") + _rpaParser.IndexInfo.FullName +
                                       Environment.NewLine;
                        archiveInfo += GetText("Index_file_size") + PrettySize.Format(_rpaParser.IndexInfo.Length) +
                                       Environment.NewLine;
                    }
                }

                archiveInfo += GetText("Files_count") + _rpaParser.Index.Count + Environment.NewLine;
                archiveInfo += GetText("Unsaved_files_count") + unsavedCount + Environment.NewLine;

                if (selectedSize != -1)
                {
                    if (selectedPath == String.Empty)
                    {
                        selectedPath = "/";
                    }
                    archiveInfo += GetText("Selected_file_path") + selectedPath +
                                   Environment.NewLine;
                    archiveInfo += GetText("Selected_file_size") + PrettySize.Format(selectedSize) +
                                   Environment.NewLine;
                }
            }

            textBox1.Text = archiveInfo.Trim();
        }

        private void LoadArchive(string openFile, bool ignoreChanges = false)
        {
            if (!ignoreChanges)
            {
                if (CheckIfChanged(GetText("Archive_modified_load")))
                {
                    return;
                }
            }

            using OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Title = GetText("Load_RenPy_Archive");
            openFileDialog.Filter = GetText("RPA_RPI_files") + @" (*.rpa,*.rpi)|*.rpa;*.rpi";

            string archivePath = settings.GetArchive();
            if (!string.IsNullOrEmpty(archivePath))
            {
                FileInfo fi = new FileInfo(archivePath);
                openFileDialog.InitialDirectory = fi.DirectoryName;
            }

            DialogResult dialogResult = DialogResult.None;
            if (string.IsNullOrEmpty(openFile))
            {
                dialogResult = openFileDialog.ShowDialog();
            }
            else
            {
                if (openFile.EndsWith(".rpa") || openFile.EndsWith(".rpi"))
                {
                    dialogResult = DialogResult.OK;
                    openFileDialog.FileName = openFile;
                }
                else
                {
                    MessageBox.Show(
                        string.Format(GetText("Load_failed_reason"), GetText("Not_valid_archive_file")),
                        GetText("Load_failed"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                    statusBar1.Text = GetText("Ready");
                    return;
                }
            }

            if (dialogResult == DialogResult.OK)
            {
                if (openFileDialog.CheckFileExists)
                {
                    settings.SetArchive(openFileDialog.FileName);
                    statusBar1.Text = GetText("Loading_file") + openFileDialog.FileName;

                    try
                    {
                        _expandedList.Clear();
                        _rpaParser = new RpaParser();

                        string appFolder = Path.GetDirectoryName(Application.ExecutablePath);
                        _rpaParser.UnrpycLocation = Path.Combine(appFolder, "unrpyc.exe");

                        _rpaParser.LoadArchive(openFileDialog.FileName);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(
                            string.Format(GetText("Load_failed_reason"), ex.Message),
                            GetText("Load_failed"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                        statusBar1.Text = GetText("Ready");
                        return;
                    }

                    GenerateTreeView();

                    _switchTabs = true;
                    tabControl1.SelectedTab = tabPage0;
                    _switchTabs = false;
                    label2.Text = GetText("Usage_instructions_loaded");

                    ResetPreviewFields();

                    treeView1.SelectedNode = null;

                    button2.Enabled = true;
                    button6.Enabled = true;
                    button7.Enabled = true;

                    statusBar1.Text = GetText("Ready");
                }

                _archiveChanged = false;
            }
        }

        private void AddFilesToArchive(string[] pathList)
        {
            // TODO: prompt for path to inset files into? Default can be root or selected object?
            //       Or don't prompt and use selected object? Empty folders should be excluded.
            //string promptValue = Prompt.ShowDialog("Test", "123", "xx");

            _fileListBackup.Clear();
            _fileListBackup = _rpaParser.DeepCopyIndex(_rpaParser.Index);
            _cancelAdd = false;

            foreach (string path in pathList)
            {
                string originalPath = path;
                if (Directory.Exists(path))
                {
                    originalPath = new DirectoryInfo(path).Parent?.FullName;
                }
                if (File.Exists(path))
                {
                    originalPath = new FileInfo(path).DirectoryName;
                }
                AddPathToIndex(path, originalPath);
            }

            if (!_cancelAdd)
            {
                _rpaParser.Index = _rpaParser.DeepCopyIndex(_fileListBackup);
            }

            _fileListBackup.Clear();
            GenerateTreeView();
        }

        private void GenerateTreeView()
        {
            _indexPathSize.Clear();
            treeView1.Nodes.Clear();
            TreeNode root = new TreeNode();
            TreeNode node;
            root.Name = "";
            root.Text = @"/";
            root.BackColor = Color.SandyBrown;
            root.ImageIndex = 0;
            treeView1.Nodes.Add(root);
            _indexPathSize.Add("", 0);
            string pathBuild;

            // Folders first
            foreach (KeyValuePair<string, RpaParser.ArchiveIndex> kvp in _rpaParser.Index)
            {
                node = root;
                pathBuild = String.Empty;
                foreach (string pathBits in kvp.Key.Split('/'))
                {
                    if (pathBuild == String.Empty)
                    {
                        pathBuild = pathBits;
                    }
                    else
                    {
                        pathBuild += "/" + pathBits;
                    }

                    if (node.Nodes.ContainsKey(pathBits))
                    {
                        node = node.Nodes[pathBits];
                    }
                    else
                    {
                        if (pathBuild != kvp.Key)
                        {
                            node = node.Nodes.Add(pathBits, pathBits);
                        }
                    }
                }
            }

            // Files second
            foreach (KeyValuePair<string, RpaParser.ArchiveIndex> kvp in _rpaParser.Index)
            {
                node = root;
                pathBuild = String.Empty;
                foreach (string pathBits in kvp.Key.Split('/'))
                {
                    if (pathBuild == String.Empty)
                    {
                        pathBuild = pathBits;
                    }
                    else
                    {
                        pathBuild += "/" + pathBits;
                    }

                    node = node.Nodes.ContainsKey(pathBits) ? node.Nodes[pathBits] : node.Nodes.Add(pathBits, pathBits);

                    if (pathBuild != kvp.Key)
                    {
                        if (!_indexPathSize.ContainsKey(pathBuild))
                        {
                            _indexPathSize.Add(pathBuild, 0);
                        }

                        if (_rpaParser.Index.ContainsKey(kvp.Key))
                        {
                            _indexPathSize[pathBuild] += _rpaParser.Index[kvp.Key].Length;
                        }
                    }
                    else
                    {
                        _indexPathSize[""] += _rpaParser.Index[kvp.Key].Length;
                    }
                }
            }

            foreach (TreeNode nodeVisuals in treeView1.Nodes.All())
            {
                string nodeName = NormalizeTreePath(nodeVisuals.FullPath);

                if (nodeName != String.Empty)
                {
                    if (nodeVisuals.Nodes.Count > 0)
                    {
                        nodeVisuals.BackColor = Color.SandyBrown;
                        nodeVisuals.ImageIndex = 0;
                    }
                    else
                    {
                        nodeVisuals.BackColor = Color.Transparent;
                        nodeVisuals.ImageIndex = 1;
                    }
                }

                if (_rpaParser.Index.ContainsKey(nodeName))
                {
                    if (!_rpaParser.Index[nodeName].InArchive)
                    {
                        nodeVisuals.ForeColor = Color.Green;
                        nodeVisuals.ImageIndex = 2;

                        MarkChanged(nodeVisuals);
                    }
                }

                if (_expandedList.Contains(nodeVisuals.FullPath))
                {
                    nodeVisuals.Expand();
                }
            }

            root.Expand();
            _archiveLoaded = true;

            GenerateArchiveInfo();
        }

        private void MarkChanged(TreeNode node)
        {
            if (node.Parent != null)
            {
                node.Parent.ForeColor = Color.Green;
                MarkChanged(node.Parent);
            }
        }

        private void Search(TextBox tb, string pattern)
        {
            int index;

            tb.Focus();

            if ((index = tb.Text.IndexOf(pattern, _searchStartIndex, StringComparison.Ordinal)) != -1)
            {
                tb.Select(index, pattern.Length);
                _searchStartIndex = tb.SelectionStart + tb.SelectionLength;
            }
            else
            {
                _searchStartIndex = 0;
                if ((index = tb.Text.IndexOf(pattern, _searchStartIndex, StringComparison.Ordinal)) != -1)
                {
                    tb.Select(index, pattern.Length);
                    _searchStartIndex = tb.SelectionStart + tb.SelectionLength;
                }
                else
                {
                    tb.Select(0, 0);
                }
            }

            tb.ScrollToCaret();
        }

        private string NormalizeTreePath(string path)
        {
            return Regex.Replace(path, "^/+", "");
        }

        private async void PreviewSelectedItem()
        {
            TreeNode selectedNode = new TreeNode();
            bool unsupportedFile = true;
            pictureBox1.Image = null;

            foreach (TreeNode node in treeView1.Nodes.All())
            {
                // Reset fields
                ResetPreviewFields();

                if (node.IsSelected)
                {
                    selectedNode = node;
                }

                if (node.IsSelected && _rpaParser.Index.ContainsKey(NormalizeTreePath(node.FullPath)))
                {
                    KeyValuePair<string, object> data = new KeyValuePair<string, object>();
                    try
                    {
                        data = await Task.Run(() => _rpaParser.GetPreview(NormalizeTreePath(node.FullPath)));

                        // Handle image preview
                        if (data.Key == RpaParser.PreviewTypes.Image)
                        {
                            pictureBox1.Image = (Image)data.Value;
                            _switchTabs = true;
                            tabControl1.SelectedTab = tabPage1;
                            _switchTabs = false;
                            unsupportedFile = false;
                        }
                        // Handle text preview
                        else if (data.Key == RpaParser.PreviewTypes.Text)
                        {
                            textBox2.Text = (string)data.Value;
                            _switchTabs = true;
                            tabControl1.SelectedTab = tabPage2;
                            _switchTabs = false;
                            unsupportedFile = false;
                        }
                        // Handle media
                        else if (data.Key == RpaParser.PreviewTypes.Audio || data.Key == RpaParser.PreviewTypes.Video)
                        {
                            // Setting up media for playback
                            // (Assume you already have media handling here)
                            // ...

                            unsupportedFile = false;
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(string.Format(GetText("Preview_failed_reason"), ex.Message), GetText("Preview_failed"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }

                    // Retrieve media info for displayed media file
                    string mediaInfo = GetMediaInfo(NormalizeTreePath(node.FullPath));
                    // Display media info in a suitable control, e.g., in a TextBox
                    textBox1.AppendText(mediaInfo + Environment.NewLine);

                    break;
                }
            }

            if (unsupportedFile)
            {
                _switchTabs = true;
                tabControl1.SelectedTab = tabPage0;
                _switchTabs = false;
                label2.Text = GetText("Preview_is_not_supported");
            }

            treeView1.SelectedNode = selectedNode;
            treeView1.SelectedNode.SelectedImageIndex = selectedNode.ImageIndex;
            treeView1.SelectedNode.EnsureVisible();
            treeView1.Focus();
        }

        private void CheckAllChildNodes(TreeNode node, bool isChecked)
        {
            if (node.Nodes.Count == 0)
            {
                node.Checked = isChecked;
            }
            else
            {
                foreach (TreeNode childNode in node.Nodes)
                {
                    CheckAllChildNodes(childNode, isChecked);
                }
                node.Checked = isChecked;
            }
        }

        private void ParentCheckControl(TreeNode parentNode)
        {
            foreach (TreeNode node in parentNode.Nodes.All())
            {
                if (!node.Checked)
                {
                    parentNode.Checked = false;
                    break;
                }
                parentNode.Checked = true;
            }
            if (parentNode.Parent != null)
            {
                ParentCheckControl(parentNode.Parent);
            }
        }

        private void PlayPauseMedia()
        {
            if (videoView1.MediaPlayer is { IsPlaying: true })
            {
                videoView1.MediaPlayer?.Pause();
                button4.Text = GetText("Play");
            }
            else
            {
                videoView1.MediaPlayer?.Play();
                button4.Text = GetText("Pause");
            }
        }

        private void SetMediaTimeLabel(long totalTimeMillies, long currentTimeMillies)
        {
            TimeSpan totalTime = TimeSpan.FromMilliseconds(totalTimeMillies);
            TimeSpan currentTime = TimeSpan.FromMilliseconds(currentTimeMillies);
            TimeSpan remainingTime = totalTime - currentTime;

            string timeFormat = @"hh\:mm\:ss";
            string timeText = $"{currentTime.ToString(timeFormat)} / {totalTime.ToString(timeFormat)} (-{remainingTime.ToString(timeFormat)})";

            label3.PerformSafely(() => label3.Text = timeText);
        }

        private bool CheckIfChanged(string message)
        {
            if (message != String.Empty && _archiveChanged)
            {
                if (MessageBox.Show(message, GetText("Archive_modified"), MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No)
                {
                    return true;
                }

                return false;
            }

            return _archiveChanged;
        }

        private void AddPathToIndex(string path, string originalPath)
        {
            _archiveChanged = true;
            RpaParser.ArchiveIndex index = new RpaParser.ArchiveIndex
            {
                InArchive = false
            };

            if (Directory.Exists(path))
            {
                foreach (string pathFile in Directory.GetFiles(path))
                {
                    AddPathToIndex(pathFile, originalPath);
                }
                foreach (string pathDir in Directory.GetDirectories(path))
                {
                    AddPathToIndex(pathDir, originalPath);
                }
            }

            if (File.Exists(path) && !_cancelAdd)
            {
                index.FullPath = path.Replace(@"\", "/");
                index.TreePath = index.FullPath.Replace(originalPath.Replace(@"\", "/") + "/", String.Empty);
                index.ParentPath = Path.GetDirectoryName(index.TreePath);
                index.Length = new FileInfo(path).Length;
                index.InArchive = false;

                if (_fileListBackup.ContainsKey(index.TreePath))
                {
                    _fileListBackup.Remove(index.TreePath);
                }

                _fileListBackup.Add(index.TreePath, index);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            LoadArchive(String.Empty);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            using FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
            List<string> exportFilesList = new List<string>();
            foreach (TreeNode node in treeView1.Nodes.All())
            {
                if (node.Checked && _rpaParser.Index.ContainsKey(NormalizeTreePath(node.FullPath)))
                {
                    exportFilesList.Add(NormalizeTreePath(node.FullPath));
                }
            }

            if (exportFilesList.Count == 0)
            {
                return;
            }

            folderBrowserDialog.SelectedPath = _rpaParser.ArchiveInfo.DirectoryName;
            if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
            {
                button1.Enabled = false;
                button2.Enabled = false;
                button3.Enabled = true;
                progressBar1.Value = 0;
                label1.PerformSafely(() => label1.Text = "");

                _operation = new Thread(() => ExportFiles(exportFilesList, folderBrowserDialog));
                _operation.Start();
            }
        }

        public class FileAssociation
        {
            public string Extension { get; set; }
            public string ProgId { get; set; }
            public string FileTypeDescription { get; set; }
            public string ExecutableFilePath { get; set; }
        }

        public class FileAssociations
        {
            // needed so that Explorer windows get refreshed after the registry is updated
            [DllImport("Shell32.dll")]
            private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);

            private const int SHCNE_ASSOCCHANGED = 0x8000000;
            private const int SHCNF_FLUSH = 0x1000;


            public static void EnsureAssociationsSet(params FileAssociation[] associations)
            {
                bool madeChanges = false;
                foreach (FileAssociation association in associations)
                {
                    madeChanges |= SetAssociation(
                        association.Extension,
                        association.ProgId,
                        association.FileTypeDescription,
                        association.ExecutableFilePath);
                }

                if (madeChanges)
                {
                    SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero);
                }
            }

            private static bool SetAssociation(string extension, string progId, string fileTypeDescription, string applicationFilePath)
            {
                bool madeChanges = false;
                madeChanges |= SetKeyDefaultValue(@"Software\Classes\" + extension, progId);
                madeChanges |= SetKeyDefaultValue(@"Software\Classes\" + progId, fileTypeDescription);
                madeChanges |= SetKeyDefaultValue($@"Software\Classes\{progId}\shell\open\command", "\"" + applicationFilePath + "\" \"%1\"");
                return madeChanges;
            }

            private static bool SetKeyDefaultValue(string keyPath, string value)
            {
                using var key = Registry.CurrentUser.CreateSubKey(keyPath);
                if (key == null || key.GetValue(null) as string == value) return false;
                key.SetValue(null, value);
                return true;
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            _operationEnabled = false;
        }

        private void treeView1_AfterSelect(object sender, EventArgs e)
        {
            PreviewSelectedItem();
            GenerateArchiveInfo();
        }

        private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
        {
            if (e.Action != TreeViewAction.Unknown)
            {
                Task.Run(async () =>
                {
                    await Task.Delay(50); // Prevent rapid selection from missing updates
                    Application.DoEvents(); // Force UI refresh to process all pending events

                    // Ensure all children are updated
                    if (e.Node.Nodes.Count > 0)
                    {
                        CheckAllChildNodes(e.Node, e.Node.Checked);
                    }

                    // Ensure parents reflect the correct state
                    if (e.Node.Parent != null)
                    {
                        ParentCheckControl(e.Node.Parent);
                    }
                });
            }
        }

        private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e)
        {
            if (!_switchTabs)
            {
                e.Cancel = true;
            }
            _switchTabs = false;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            PlayPauseMedia();
        }

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            if (videoView1.MediaPlayer?.Media != null)
            {
                videoView1.MediaPlayer.Volume = trackBar1.Value;
            }
        }

        private void RpaExplorer_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (CheckIfChanged(GetText("Archive_modified_close")))
            {
                e.Cancel = true;
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            CreateNewArchive();
        }

        private string targetFoldername; // Class-level variable to store the folder name

        private void treeView1_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] droppedFiles = (string[])e.Data.GetData(DataFormats.FileDrop);

                // Initialize the targetFoldername variable
                targetFoldername = string.Empty; // Reset before each drop

                // Check if the first dropped item is a directory
                if (Directory.Exists(droppedFiles[0]))
                {
                    // If it's a folder, set targetFoldername to the name of that folder
                    targetFoldername = Path.GetFileName(droppedFiles[0]);
                }

                if (e.Data.GetDataPresent(DataFormats.FileDrop))
                {
                    AddFilesToArchive((string[])e.Data.GetData(DataFormats.FileDrop));
                }
            }
        }

        private void treeView1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop) && _archiveLoaded)
            {
                e.Effect = DragDropEffects.Copy;
                return;
            }
            e.Effect = DragDropEffects.None;
        }

        private void tabControl1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Copy;
                return;
            }
            e.Effect = DragDropEffects.None;
        }

        private void tabControl1_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                LoadArchive(((string[])e.Data.GetData(DataFormats.FileDrop))[0]);
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            bool changed = false;
            foreach (TreeNode node in treeView1.Nodes.All())
            {
                if (node.Checked && _rpaParser.Index.ContainsKey(NormalizeTreePath(node.FullPath)))
                {
                    _rpaParser.Index.Remove(NormalizeTreePath(node.FullPath));
                    changed = true;
                }
            }

            if (changed)
            {
                _archiveChanged = true;
                GenerateTreeView();
            }
        }

        private void button7_Click(object sender, EventArgs e)
        {
            SaveArchive();
        }

        private void treeView1_BeforeCollapse(object sender, TreeViewCancelEventArgs e)
        {
            if (_expandedList.Contains(e.Node.FullPath))
            {
                _expandedList.Remove(e.Node.FullPath);
            }
        }

        private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            _expandedList.Add(e.Node.FullPath);
        }

        private void toolStripComboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            settings.SetLang(toolStripComboBox1.SelectedItem.ToString());
            LoadTexts();
        }

        private void button8_Click(object sender, EventArgs e)
        {
            if (textBox3.Text.Trim() != String.Empty)
            {
                Search(textBox2, textBox3.Text.Trim());
            }
        }

        private void associateRPARPIExtensionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ProcessModule processModule = Process.GetCurrentProcess().MainModule;
            if (processModule != null)
            {
                string filePath = processModule.FileName;
                FileAssociations.EnsureAssociationsSet(
                    new FileAssociation
                    {
                        Extension = ".rpi",
                        ProgId = "RPA Explorer",
                        FileTypeDescription = "RenPy Index File",
                        ExecutableFilePath = filePath
                    },
                    new FileAssociation
                    {
                        Extension = ".rpa",
                        ProgId = "RPA Explorer",
                        FileTypeDescription = "RenPy Archive File",
                        ExecutableFilePath = filePath
                    });
            }
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new About().ShowDialog();
        }
    }

    public static class Prompt
    {
        public static string ShowDialog(string text, string caption, string defaultValue)
        {
            Form prompt = new Form
            {
                Width = 500,
                Height = 150,
                FormBorderStyle = FormBorderStyle.FixedDialog,
                Text = caption,
                StartPosition = FormStartPosition.CenterScreen,
                MaximizeBox = false,
                MinimizeBox = false,
                TopMost = true
            };
            Label textLabel = new Label { Left = 50, Top = 20, Text = text };
            TextBox textBox = new TextBox { Left = 50, Top = 50, Width = 400, Text = defaultValue };
            Button confirmation = new Button { Text = @"OK", Left = 350, Width = 101, Top = 70, DialogResult = DialogResult.OK };
            confirmation.Click += (sender, e) => { prompt.Close(); };
            prompt.Controls.Add(textBox);
            prompt.Controls.Add(confirmation);
            prompt.Controls.Add(textLabel);
            prompt.AcceptButton = confirmation;

            return prompt.ShowDialog() == DialogResult.OK ? textBox.Text : String.Empty;
        }
    }

    public static class CrossThreadExtensions
    {
        public static void PerformSafely(this Control target, Action action)
        {
            if (target.InvokeRequired)
            {
                target.Invoke(action);
            }
            else
            {
                action();
            }
        }

        public static void PerformSafely<T1>(this Control target, Action<T1> action, T1 parameter)
        {
            if (target.InvokeRequired)
            {
                target.Invoke(action, parameter);
            }
            else
            {
                action(parameter);
            }
        }

        public static void PerformSafely<T1, T2>(this Control target, Action<T1, T2> action, T1 p1, T2 p2)
        {
            if (target.InvokeRequired)
            {
                target.Invoke(action, p1, p2);
            }
            else
            {
                action(p1, p2);
            }
        }
    }


    public static class Extensions
    {
        public static IEnumerable<TreeNode> All(this TreeNodeCollection nodes)
        {
            foreach (TreeNode n in nodes)
            {
                yield return n;
                foreach (TreeNode child in n.Nodes.All())
                    yield return child;
            }
        }
    }
}
ASSISTANT
The errors you are encountering indicate an issue with the MediaInfo library you are trying to use. It seems that you must use the correct classes and types from the `MediaInfo.DotNetWrapper` library.

### Steps for Resolution

1. **Correct Import Statement**: Ensure you are using the correct namespace for the MediaInfo wrapper. The correct namespace for the `MediaInfo` class from the `MediaInfo.DotNetWrapper` library is `MediaInfo`, not `MediaInfo.DotNetWrapper`.

2. **Use the Correct Object**: Make sure to check the documentation or the classes available in the `MediaInfo.DotNetWrapper` to see what types and properties are available. You may be trying to access properties (like `Video` and `Image`) which may not be present or named differently.

### Revised Code Example

Given your usage context, here is a proper example of how to integrate the MediaInfo functionality:

```csharp
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using LibVLCSharp.Shared;
using Microsoft.Win32;
using NeoSmart.PrettySize;
using RPA_Parser;
using MediaInfo; // Correct import for MediaInfo from MediaInfo.DotNetWrapper

namespace RPA_Explorer
{
    public partial class RpaExplorer : Form
    {
        // Your other fields and methods

        private string GetMediaInfo(string filePath)
        {
            if (string.IsNullOrWhiteSpace(filePath) || !File.Exists(filePath))
            {
                return "Invalid file path or file does not exist.";
            }

            try
            {
                // Use MediaInfo to gather media information
                var mediaInfo = new MediaInfo();
                mediaInfo.Open(filePath); // Open the file
                
                string videoCodec = mediaInfo.Get(StreamKind.Video, 0, "Format");
                string imageCodec = mediaInfo.Get(StreamKind.Image, 0, "Format");
                string resolution = mediaInfo.Get(StreamKind.Video, 0, "Width") + "x" + mediaInfo.Get(StreamKind.Video, 0, "Height");

                string codecInfo = string.IsNullOrEmpty(videoCodec) ? imageCodec : videoCodec;
                string formattedInfo = $"Codec: {codecInfo}, Resolution: {resolution}";

                mediaInfo.Close(); // Close the file media info

                return formattedInfo;
            }
            catch (Exception ex)
            {
                return $"Error retrieving media information: {ex.Message}";
            }
        }

        // The rest of your methods and code...
    }
}
```

### Key Changes

1. **Correct Namespace**: Ensured that the correct namespace `MediaInfo` is used for the MediaInfo class from the `MediaInfo.DotNetWrapper`.

2. **Using MediaInfo Methods**:
   - Open the media file using `mediaInfo.Open(filePath)`.
   - Retrieve codec and resolution information using `mediaInfo.Get()` method.
   - Close the media info instance with `mediaInfo.Close()`.

3. **Error Handling**: Proper error handling is included, ensuring that any exceptions when retrieving media information result in an appropriate message.

### Important Considerations

- **Documentation**: Always refer to the documentation of the library you are using to understand the properties and methods available.
- **Supported Types**: Make sure to check whether the file you are trying to analyze is supported by the `MediaInfo` library. If it isn’t, your code should handle that gracefully.
- **Testing**: After implementation, test it with different file types to ensure that it works as expected and handles errors appropriately.

This should resolve the compile-time errors and help you retrieve media codec and resolution information correctly using the `MediaInfo` library.

turns-00061.parquet:26608

bae2af33f793726c9a56ac89
turn 11/35gpt-4o-mini-2024-07-18EnglishRussia691 words
degenerate_repetitionAbsentFinal dense release
USER
now I got error:
"MediaInfo" является пространство имен, но используется как тип.
ASSISTANT
The error message you are encountering—**"MediaInfo" is a namespace, but is used as a type**—suggests that there's a conflict with the `MediaInfo` class name and the namespace you are using. Typically, this situation arises when both the namespace and class (or type) share the same name.

### Solution Steps

Here are steps to properly utilize the `MediaInfo` class from the `MediaInfo.DotNetWrapper`:

1. **Check Installed Assemblies**:
   Make sure you have installed `MediaInfo.DotNetWrapper` via NuGet package. Use the following command to ensure it is installed:
   ```sh
   Install-Package MediaInfo.DotNetWrapper
   ```

2. **Using the Correct Namespace**:
   Because you are experiencing naming conflicts, you might be importing the wrong namespace or using it incorrectly. The `MediaInfo` class should be instantiated from the `MediaInfo.DotNetWrapper` library. 

   You only need to import the base `MediaInfo.DotNetWrapper` namespace to access the types correctly.

3. **Update Your Code**:

   Here’s how you can modify your code to resolve the conflict:

```csharp
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using LibVLCSharp.Shared;
using Microsoft.Win32;
using NeoSmart.PrettySize;
using RPA_Parser;
// Remove or update the previously added import if creating conflicts
// using MediaInfo.DotNetWrapper; // You might replace this with just using MediaInfo;

namespace RPA_Explorer
{
    public partial class RpaExplorer : Form
    {
        private RpaParser _rpaParser;
        private RpaParser _rpaParserBak;
        private Thread _operation;
        private bool _operationEnabled = true;
        private bool _archiveChanged;
        private bool _cancelAdd;
        private bool _archiveLoaded;
        private SortedDictionary<string, RpaParser.ArchiveIndex> _fileListBackup = new();
        private readonly Dictionary<string, long> _indexPathSize = new();
        private readonly List<string> _expandedList = new();
        private bool _switchTabs;
        private readonly LibVLC _libVlc;
        private MemoryStream _memoryStreamVlc;
        private StreamMediaInput _streamMediaInputVlc;
        private Media _mediaVlc;
        private int _searchStartIndex = 0;
        private static readonly FileInfo _appInfo = new(System.Reflection.Assembly.GetEntryAssembly()?.Location ?? throw new InvalidOperationException());
        private static readonly FileInfo _appName = new(System.Reflection.Assembly.GetEntryAssembly()?.GetName().Name ?? throw new InvalidOperationException());
        private readonly string settingsPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/" + _appName + @"/settings.ini";

        private static readonly System.ComponentModel.ComponentResourceManager Lang = new(typeof(Lang));

        private static Settings settings;

        public RpaExplorer()
        {
            // Form initiation
            InitializeComponent();

            Directory.CreateDirectory(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/" + _appName);

            settings = new Settings(settingsPath);

            // Language initiation
            foreach (Settings.Language lang in settings.LangList)
            {
                toolStripComboBox1.Items.Add(lang.Name);
            }

            toolStripComboBox1.SelectedItem = settings.GetLang().Name;

            LoadTexts();

            // LibVLC initiation
            Core.Initialize();
            _libVlc = new LibVLC("--input-repeat=9999999"); // --input-repeat=X : Loop X times
            videoView1.MediaPlayer = new MediaPlayer(_libVlc);
            videoView1.MediaPlayer.Volume = 50;
            videoView1.MediaPlayer.TimeChanged += videoView1_MediaPlayer_TimeChanged;
            videoView1.BackgroundImage = null;
            SetMediaTimeLabel(0, 0);

            // Initialize the seek bar
            seekBar.Maximum = 1000; // Set maximum value for smooth seeking
            seekBar.Scroll += SeekBar_Scroll; // Handle scroll events for seeking

            // Subscribe to the TabControl's SelectedIndexChanged event
            tabControl1.SelectedIndexChanged += TabControl1_SelectedIndexChanged;

            // Hide the seek bar initially
            seekBar.Visible = false;

            // TreeView styles initiation
            ImageList imageList = new ImageList();
            imageList.Images.Add(Resources.treeView1_Image_folder);
            imageList.Images.Add(Resources.treeView1_Image_file);
            imageList.Images.Add(Resources.treeView1_Image_fileChanged);
            treeView1.ImageList = imageList;

            // Arguments processing
            string[] args = Environment.GetCommandLineArgs();
            if (args.Length >= 2)
            {
                LoadArchive(args[1]);
            }
        }

        // Method to retrieve media information
        private string GetMediaInfo(string filePath)
        {
            if (string.IsNullOrWhiteSpace(filePath) || !File.Exists(filePath))
            {
                return "Invalid file path or file does not exist.";
            }

            try
            {
                using var mediaInfo = new MediaInfoWrapper(filePath); // Correctly use MediaInfoWrapper
 
                string videoCodec = mediaInfo.Video.Count > 0 ? mediaInfo.Video[0].Format : "N/A";
                string resolution = "N/A";
                if (mediaInfo.Video.Count > 0)
                {
                    var width = mediaInfo.Video[0].Width;
                    var height = mediaInfo.Video[0].Height;
                    resolution = $"{width}x{height}";
                }

                return $"Codec: {videoCodec}, Resolution: {resolution}";
            }
            catch (Exception ex)
            {
                return $"Error retrieving media information: {ex.Message}";
            }
        }

        // The rest of your existing methods go here...
    }

    // The rest of your classes and methods...
}
```

### Notes:

- **Using the Class**: The `MediaInfoWrapper` class is likely the class you should instantiate instead of `MediaInfo`, depending on the specific implementation of the `MediaInfo.DotNetWrapper`.
- **Check Class and Method Names**: Make sure to check the documentation of the `MediaInfo.DotNetWrapper` for the exact class and method names, as they can vary slightly sometimes.
- **Namespace Conflicts**: If there are still conflicts, it may be helpful to fully qualify the class when using it, e.g., `MediaInfo.DotNetWrapper.MediaInfoWrapper` if you have to.

By making these adjustments, you should eliminate the errors you are currently experiencing when working with the MediaInfo library in your `RPA_Explorer` application. Make sure to test the functionality after these changes to ensure everything works as expected.

turns-00061.parquet:26609

dff13f5f0b2bec5ec47f0fa8
turn 12/35gpt-4o-mini-2024-07-18EnglishRussia717 words
degenerate_repetitionAbsentFinal dense release
USER
"MediaInfoWrapper": тип, используемый в операторе using, должен реализовывать "System.IDisposable".
"MediaInfoWrapper" не содержит определения "Video", и не удалось найти доступный метод расширения "Video", принимающий тип "MediaInfoWrapper" в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку).
"MediaInfoWrapper" не содержит определения "Video", и не удалось найти доступный метод расширения "Video", принимающий тип "MediaInfoWrapper" в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку).
"MediaInfoWrapper" не содержит определения "Image", и не удалось найти доступный метод расширения "Image", принимающий тип "MediaInfoWrapper" в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку).
"MediaInfoWrapper" не содержит определения "Image", и не удалось найти доступный метод расширения "Image", принимающий тип "MediaInfoWrapper" в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку).
"MediaInfoWrapper" не содержит определения "Video", и не удалось найти доступный метод расширения "Video", принимающий тип "MediaInfoWrapper" в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку).
"MediaInfoWrapper" не содержит определения "Video", и не удалось найти доступный метод расширения "Video", принимающий тип "MediaInfoWrapper" в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку).
"MediaInfoWrapper" не содержит определения "Video", и не удалось найти доступный метод расширения "Video", принимающий тип "MediaInfoWrapper" в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку).
"MediaInfoWrapper" не содержит определения "Image", и не удалось найти доступный метод расширения "Image", принимающий тип "MediaInfoWrapper" в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку).
"MediaInfoWrapper" не содержит определения "Image", и не удалось найти доступный метод расширения "Image", принимающий тип "MediaInfoWrapper" в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку).
"MediaInfoWrapper" не содержит определения "Image", и не удалось найти доступный метод расширения "Image", принимающий тип "MediaInfoWrapper" в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку).
code below is wrong, rewrite it:
```
                using var mediaInfo = new MediaInfoWrapper(filePath);

                string videoCodec = mediaInfo.Video.Count > 0 ? mediaInfo.Video[0].Format : "N/A";
                string imageCodec = mediaInfo.Image.Count > 0 ? mediaInfo.Image[0].Format : "N/A";

                string resolution = "N/A";
                if (mediaInfo.Video.Count > 0)
                {
                    var width = mediaInfo.Video[0].Width;
                    var height = mediaInfo.Video[0].Height;
                    resolution = $"{width}x{height}";
                }
                else if (mediaInfo.Image.Count > 0)
                {
                    var width = mediaInfo.Image[0].Width;
                    var height = mediaInfo.Image[0].Height;
                    resolution = $"{width}x{height}";
                }
ASSISTANT
It seems that there is some confusion regarding the classes and properties you are working with in `MediaInfo.DotNetWrapper`. Based on the error messages, it looks like the `MediaInfoWrapper` class does not have properties like `Video` and `Image` directly accessible. Instead, it may provide methods to retrieve video and image information in a different way. 

### Correct Usage of MediaInfo

To properly implement the `GetMediaInfo` method using `MediaInfo.DotNetWrapper`, you may want to structure it like this:

```csharp
private string GetMediaInfo(string filePath)
{
    if (string.IsNullOrWhiteSpace(filePath) || !File.Exists(filePath))
    {
        return "Invalid file path or file does not exist.";
    }

    // Initialize MediaInfo
    var mediaInfo = new MediaInfo();
    mediaInfo.Open(filePath);

    try
    {
        // Retrieve codec information
        string videoCodec = mediaInfo.Get(StreamKind.Video, 0, "Format");
        string imageCodec = mediaInfo.Get(StreamKind.Image, 0, "Format");

        // Retrieve resolution information
        string width = mediaInfo.Get(StreamKind.Video, 0, "Width");
        string height = mediaInfo.Get(StreamKind.Video, 0, "Height");
        string resolution = string.IsNullOrEmpty(width) || string.IsNullOrEmpty(height) ? "N/A" : $"{width}x{height}";

        // If no video codec found, check for image codec
        string codecInfo = !string.IsNullOrEmpty(videoCodec) ? videoCodec : imageCodec;
        
        return $"Codec: {codecInfo ?? "N/A"}, Resolution: {resolution}";
    }
    catch (Exception ex)
    {
        return $"Error retrieving media information: {ex.Message}";
    }
    finally
    {
        mediaInfo.Close(); // Close the media info object
    }
}
```

### Breakdown of Changes:

1. **Initialization**: Use `var mediaInfo = new MediaInfo();` to create an instance of `MediaInfo`.

2. **Open the File**: Call `mediaInfo.Open(filePath);` to prepare to extract media information.

3. **Retrieve Information**:
   - Use `mediaInfo.Get(StreamKind.Video, 0, "Format");` to get the video codec.
   - Use `mediaInfo.Get(StreamKind.Video, 0, "Width");` and `mediaInfo.Get(StreamKind.Video, 0, "Height");` to extract width and height.

4. **Handle Resolution**: Only construct the resolution string if both width and height are available.

5. **Error Handling**: The method includes robust error handling with a try-catch-finally block to manage errors while retrieving information and ensure that resources are cleaned up properly.

### Integration with Your Existing Code

You can integrate this `GetMediaInfo` method as described earlier in the `RpaExplorer` class and call it when appropriate during media file previews. This updated implementation should resolve the errors regarding accessibility and provide the correct codec and resolution information as intended. Make sure to test this with valid media files to ensure functionality.

turns-00061.parquet:26610

42a72c0015a9da1ac167eadb
turn 13/35gpt-4o-mini-2024-07-18EnglishRussia519 words
degenerate_repetitionAbsentFinal dense release
USER
no, wrong again, use readme file below to make correct code:
Usage
Add to usings:

using MediaInfo;
Instantiate an object of class MediaInfoWrapper, providing the full path to the media file and logger instance if it is required.

var media = new MediaInfoWrapper(mediaFileLocation);
Check successfully parsing of the parameters of the media file.

if (media.Success)
{
    ...
}
Retrieve technical and tag data from the video or audio file:

var containerFormat = media.Format;
var mediaHasVideo = media.HasVideo;
var videoBitRate = media.VideoRate;
foreach (var stream in media.AudioStreams)
{
    var codec = stream.Codec;
}
ASSISTANT
Thank you for providing the details from the README file. Based on this information, I will adjust the implementation of the `GetMediaInfo` method accordingly, using the correct initialization and properties of the `MediaInfoWrapper` class as specified.

### Updated GetMediaInfo Method

Here's the correctly revised version of the `GetMediaInfo` method based on the provided usage instructions from the README:

```csharp
using MediaInfo; // Make sure this is included at the top

private string GetMediaInfo(string filePath)
{
    if (string.IsNullOrWhiteSpace(filePath) || !File.Exists(filePath))
    {
        return "Invalid file path or file does not exist.";
    }

    try
    {
        // Instantiate MediaInfoWrapper with the file path
        var media = new MediaInfoWrapper(filePath);

        // Check if media information was successfully parsed
        if (!media.Success)
        {
            return "Failed to retrieve media information.";
        }

        // Retrieve codec and resolution information
        var codec = media.Format; // Container format or codec of the media
        var resolution = (media.HasVideo) ? $"{media.VideoWidth}x{media.VideoHeight}" : "N/A";

        // Optionally retrieve audio stream information if needed
        string audioInfo = "";
        foreach (var stream in media.AudioStreams)
        {
            audioInfo += $"{stream.Codec} - ";
        }

        // Return formatted information
        return $"Codec: {codec}, Resolution: {resolution}, Audio: {audioInfo.TrimEnd(' ', '-')}"; // Remove trailing spaces and dash
    }
    catch (Exception ex)
    {
        return $"Error retrieving media information: {ex.Message}";
    }
}
```

### Explanation of Key Changes

1. **Initialization**: The `MediaInfoWrapper` is instantiated directly with the file path. 

2. **Success Check**: The method checks if parsing was successful using `media.Success`.

3. **Retrieving Information**:
   - The container format or codec of the media can be fetched using `media.Format`.
   - For resolution, it retrieves the width and height only if the media has video using `media.VideoWidth` and `media.VideoHeight`.
   - The method also includes a loop to gather information about audio streams if they exist. Audio codecs are collected from `media.AudioStreams`.

4. **Formatting the Result**: The returned string formats codec, resolution, and audio stream information neatly.

### Integration

You can integrate this method within the `RpaExplorer` class as previously described, specifically in the part of the code where it previews selected media files. 

The call to `GetMediaInfo` should remain as before, allowing you to retrieve the codec, resolution, and audio which you can then display in your application's UI.

### Example Call Location

Here’s how you might use this `GetMediaInfo` method particularly in the `PreviewSelectedItem()` function:

```csharp
// Retrieve media info for the displayed media file
string mediaInfo = GetMediaInfo(NormalizeTreePath(node.FullPath));
// Display media info in a suitable control, e.g., in a TextBox
textBox1.AppendText(mediaInfo + Environment.NewLine); 
```

Ensure that this updated `GetMediaInfo` method is tested against various media files to verify that it works correctly in all cases.

turns-00061.parquet:26611

d1ca3c4ea94baa2482cd3228
turn 14/35gpt-4o-mini-2024-07-18EnglishRussia1307 words
degenerate_repetitionAbsentFinal dense release
USER
still don't work below is working code example:
```
#region Copyright (C) 2017-2022 Yaroslav Tatarenko

// Copyright (C) 2017-2022 Yaroslav Tatarenko
// This product uses MediaInfo library, Copyright (c) 2002-2021 MediaArea.net SARL. 
// https://mediaarea.net

#endregion

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text.Json.Serialization;

namespace ApiSample.Models;

/// <summary>
/// Information about media.
/// </summary>
[DataContract]
public class MediaInfo
{
    /// <summary>
    /// A value indicating whether this media has video.
    /// </summary>
    [DataMember(Name = "video")]
    [JsonPropertyName("video")]
    public bool HasVideo { get; set; }

    /// <summary>
    /// A value indicating whether media is 3D.
    /// </summary>
    [DataMember(Name = "3d")]
    [JsonPropertyName("3d")]
    public bool Is3D { get; set; }

    /// <summary>
    /// A value indicating whether this media is HDR video.
    /// </summary>
    [DataMember(Name = "hdr")]
    [JsonPropertyName("hdr")]
    public bool IsHdr { get; set; }

    /// <summary>
    /// A video streams.
    /// </summary>
    [DataMember(Name = "videos")]
    [JsonPropertyName("videos")]
    public IList<VideoStream> VideoStreams { get; set; }

    /// <summary>
    /// A video codec.
    /// </summary>
    [DataMember(Name = "videoCodec")]
    [JsonPropertyName("videoCodec")]
    public string VideoCodec { get; set; }

    /// <summary>
    /// A video frame rate.
    /// </summary>
    [DataMember(Name = "framerate")]
    [JsonPropertyName("framerate")]
    public double Framerate { get; set; }

    /// <summary>
    /// A video picture width.
    /// </summary>
    [DataMember(Name = "width")]
    [JsonPropertyName("width")]
    public int Width { get; set; }

    /// <summary>
    /// A video picture height.
    /// </summary>
    [DataMember(Name = "height")]
    [JsonPropertyName("height")]
    public int Height { get; set; }

    /// <summary>
    /// A video aspect ratio.
    /// </summary>
    [DataMember(Name = "aspectRatio")]
    [JsonPropertyName("aspectRatio")]
    public string AspectRatio { get; set; }

    /// <summary>
    /// A type of the scan.
    /// </summary>
    [DataMember(Name = "scanType")]
    [JsonPropertyName("scanType")]
    public string ScanType { get; set; }

    /// <summary>
    /// A value indicating whether this video is interlaced.
    /// </summary>
    [DataMember(Name = "interlaced")]
    [JsonPropertyName("interlaced")]
    public bool IsInterlaced { get; set; }

    /// <summary>
    /// A video resolution.
    /// </summary>
    [DataMember(Name = "videoResolution")]
    [JsonPropertyName("videoResolution")]
    public string VideoResolution { get; set; }

    /// <summary>
    /// A video rate.
    /// </summary>
    [DataMember(Name = "videoRate")]
    [JsonPropertyName("videoRate")]
    public int VideoRate { get; set; }

    /// <summary>
    /// The audio streams.
    /// </summary>
    [DataMember(Name = "audios")]
    [JsonPropertyName("audios")]
    public IList<AudioStream> AudioStreams { get; set; }

    /// <summary>
    /// An audio codec.
    /// </summary>
    [DataMember(Name = "audioCodec")]
    [JsonPropertyName("audioCodec")]
    public string AudioCodec { get; set; }

    /// <summary>
    /// An audio rate.
    /// </summary>
    [DataMember(Name = "audioRate")]
    [JsonPropertyName("audioRate")]
    public int AudioRate { get; set; }

    /// <summary>
    /// An audio sample rate.
    /// </summary>
    [DataMember(Name = "audioSampleRate")]
    [JsonPropertyName("audioSampleRate")]
    public int AudioSampleRate { get; set; }

    /// <summary>
    /// An audio channels friendly.
    /// </summary>
    [DataMember(Name = "audioChannelsFriendly")]
    [JsonPropertyName("audioChannelsFriendly")]
    public string AudioChannelsFriendly { get; set; }

    /// <summary>
    /// The subtitle streams.
    /// </summary>
    [DataMember(Name = "subtitles")]
    [JsonPropertyName("subtitles")]
    public IList<SubtitleStream> Subtitles { get; set; }

    /// <summary>
    /// A value indicating whether this video has external subtitles.
    /// </summary>
    [DataMember(Name = "externalSubtitles")]
    [JsonPropertyName("externalSubtitles")]
    public bool HasExternalSubtitles { get; set; }

    /// <summary>
    /// The chapter streams.
    /// </summary>
    [DataMember(Name = "chapters")]
    [JsonPropertyName("chapters")]
    public IList<ChapterStream> Chapters { get; set; }

    /// <summary>
    /// The menu streams.
    /// </summary>
    [DataMember(Name = "menus")]
    [JsonPropertyName("menus")]
    public IList<MenuStream> MenuStreams { get; set; }

    /// <summary>
    /// A value indicating whether this video is DVD format.
    /// </summary>
    [DataMember(Name = "dvd")]
    [JsonPropertyName("dvd")]
    public bool IsDvd { get; set; }

    /// <summary>
    /// A media format.
    /// </summary>
    [DataMember(Name = "format")]
    [JsonPropertyName("format")]
    public string Format { get; set; }

    /// <summary>
    /// A value indicating whether this media is streamable.
    /// </summary>
    [DataMember(Name = "streamable")]
    [JsonPropertyName("streamable")]
    public bool IsStreamable { get; set; }

    /// <summary>
    /// A writing media application.
    /// </summary>
    [DataMember(Name = "writingApplication")]
    [JsonPropertyName("writingApplication")]
    public string WritingApplication { get; set; }

    /// <summary>
    /// A writing media library.
    /// </summary>
    [DataMember(Name = "writingLibrary")]
    [JsonPropertyName("writingLibrary")]
    public string WritingLibrary { get; set; }

    /// <summary>
    /// The media attachments.
    /// </summary>
    [DataMember(Name = "attachments")]
    [JsonPropertyName("attachments")]
    public string Attachments { get; set; }

    /// <summary>
    /// A media format version.
    /// </summary>
    [DataMember(Name = "formatVersion")]
    [JsonPropertyName("formatVersion")]
    public string FormatVersion { get; set; }

    /// <summary>
    /// A media profile.
    /// </summary>
    [DataMember(Name = "profile")]
    [JsonPropertyName("profile")]
    public string Profile { get; set; }

    /// <summary>
    /// A media codec.
    /// </summary>
    [DataMember(Name = "codec")]
    [JsonPropertyName("codec")]
    public string Codec { get; set; }

    /// <summary>
    /// A value indicating whether this media is Blu-Ray.
    /// </summary>
    [DataMember(Name = "bluRay")]
    [JsonPropertyName("bluRay")]
    public bool IsBluRay { get; set; }

    /// <summary>
    /// A media duration.
    /// </summary>
    [DataMember(Name = "duration")]
    [JsonPropertyName("duration")]
    public TimeSpan Duration { get; set; }

    /// <summary>
    /// A media size.
    /// </summary>
    [DataMember(Name = "size")]
    [JsonPropertyName("size")]
    public long Size { get; set; }
}
ASSISTANT
Thank you for providing the working code example that defines the `MediaInfo` class. Let's rewrite your `GetMediaInfo` method using this example and the `MediaInfo` class correctly. I understand now that you are using a custom `MediaInfo` class to retrieve media information, which includes video, audio, and subtitle streams, along with other relevant data.

### Implementation of GetMediaInfo Method

We will integrate the functionality into your existing `RpaExplorer` class that retrieves media information based on the outlined properties in the `MediaInfo` class.

Here’s how to correctly implement the `GetMediaInfo` method for your application:

```csharp
// Ensure the correct using statement is added.
using MediaInfo;  // Make sure this is correctly referencing your MediaInfo library

private string GetMediaInfo(string filePath)
{
    if (string.IsNullOrWhiteSpace(filePath) || !File.Exists(filePath))
    {
        return "Invalid file path or file does not exist.";
    }

    try
    {
        // Instantiate MediaInfoWrapper with the file path.
        var media = new MediaInfoWrapper(filePath);

        // Check if media information was successfully parsed.
        if (!media.Success)
        {
            return "Failed to retrieve media information.";
        }

        // Retrieve codec and resolution information
        string codec = media.VideoCodec ?? "N/A";
        string resolution = media.HasVideo ? $"{media.Width}x{media.Height}" : "N/A";

        // Construct the return string
        return $"Codec: {codec}, Resolution: {resolution}, Duration: {media.Duration}";
    }
    catch (Exception ex)
    {
        return $"Error retrieving media information: {ex.Message}";
    }
}
```

### Explanation of the Code

1. **Input Validation**: The method first checks if the provided `filePath` is valid and if the file exists. If either check fails, it returns an appropriate message.

2. **Using MediaInfoWrapper**:
    - Here, we create an instance of `MediaInfoWrapper`, passing in the `filePath`.
    - The `.Success` property checks if media parsing succeeded.

3. **Retrieve Information**:
   - The codec is fetched using `media.VideoCodec` and defaults to "N/A" if it's not available.
   - The resolution is formed using the properties `media.Width` and `media.Height`, or it can return "N/A" if no video exists.
   - Optionally, I included the media duration in the output string that can be fetched from `media.Duration`.

4. **Error Handling**: Catch any exceptions that might occur during this process and provide a meaningful message.

### How to Use It

You can call this method where appropriate within your application, particularly in scenarios where you want to display information about the media file selected in the `TreeView`. 

For example, modify the `PreviewSelectedItem` method to append media information to a text box:

```csharp
private async void PreviewSelectedItem()
{
    TreeNode selectedNode = new TreeNode();
    bool unsupportedFile = true;
    pictureBox1.Image = null;

    foreach (TreeNode node in treeView1.Nodes.All())
    {
        // Reset fields
        ResetPreviewFields();

        if (node.IsSelected)
        {
            selectedNode = node;
        }

        if (node.IsSelected && _rpaParser.Index.ContainsKey(NormalizeTreePath(node.FullPath)))
        {
            KeyValuePair<string, object> data = new KeyValuePair<string, object>();
            try
            {
                data = await Task.Run(() => _rpaParser.GetPreview(NormalizeTreePath(node.FullPath)));

                // Existing preview logic goes here...

                // Now get the media info
                string mediaInfo = GetMediaInfo(NormalizeTreePath(node.FullPath)); // Get media info based on selected file
                textBox1.AppendText(mediaInfo + Environment.NewLine); // Display in your textbox
                break; // Break after processing the selected node
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format(GetText("Preview_failed_reason"), ex.Message), GetText("Preview_failed"), MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }

    // Handle unsupported file as before...
}
```

### Conclusion

With this revised `GetMediaInfo` method, your application should now correctly fetch and display the codec, resolution, and any other information you want about media files while handling edge cases and errors gracefully. Be sure to test the implementation with various media formats to ensure robust performance.

turns-00061.parquet:26612

e8d7eda6a96c11d7033bceda
turn 15/35gpt-4o-mini-2024-07-18EnglishRussia645 words
degenerate_repetitionAbsentFinal dense release
USER
It still don't shows mediainfo, I see image in preview but in info window I got this:
Archive version: 3
Archive location: D:\Games\DP-4.6-pc\game\archive.rpa
Archive size: 851 MiB
Files count: 6902
Unsaved files count: 0
Selected file path: images/Anissa/Avatars/anissa hap 0.png
Selected file size: 103 KiBInvalid file path or file does not exist.
ASSISTANT
The issue you’re experiencing—where the **MediaInfo** does not retrieve data but instead returns "Invalid file path or file does not exist"—suggests that the `GetMediaInfo` method is being called with a file path that is not being resolved correctly or does not point to a valid media file.

Let's debug and refine this:

1. **Ensure Correct Path Resolution**: Double-check how you're constructing the path when invoking `GetMediaInfo`. You need to make sure that the path passed to `GetMediaInfo` points to the actual file on disk correctly. When using **RPA_Parser** to get preview data, ensure that `NormalizeTreePath(node.FullPath)` returns a valid path.

2. **Use Absolute Path**: When selecting a file for media information, it's better to convert the normalized path into an absolute path. Here's how to do it:

### Revised Code Example

Here's an updated version of the `PreviewSelectedItem` and `GetMediaInfo` methods to ensure paths are resolved correctly:

**GetMediaInfo Method:**
```csharp
private string GetMediaInfo(string filePath)
{
    // Check if the filePath is valid and exists
    if (string.IsNullOrWhiteSpace(filePath) || !File.Exists(filePath))
    {
        return "Invalid file path or file does not exist.";
    }

    try
    {
        // Instantiate MediaInfoWrapper with the file path
        using var media = new MediaInfoWrapper(filePath);

        // Check if media information was successfully parsed
        if (!media.Success)
        {
            return "Failed to retrieve media information.";
        }

        // Retrieve codec and resolution information
        string codec = media.VideoCodec ?? "N/A";
        string resolution = media.HasVideo ? $"{media.Width}x{media.Height}" : "N/A";

        return $"Codec: {codec}, Resolution: {resolution}, Duration: {media.Duration}";
    }
    catch (Exception ex)
    {
        return $"Error retrieving media information: {ex.Message}";
    }
}
```

**PreviewSelectedItem Method:**
```csharp
private async void PreviewSelectedItem()
{
    TreeNode selectedNode = new TreeNode();
    bool unsupportedFile = true;
    pictureBox1.Image = null;

    foreach (TreeNode node in treeView1.Nodes.All())
    {
        // Reset fields
        ResetPreviewFields();

        if (node.IsSelected)
        {
            selectedNode = node;
        }

        if (node.IsSelected && _rpaParser.Index.ContainsKey(NormalizeTreePath(node.FullPath)))
        {
            KeyValuePair<string, object> data = new KeyValuePair<string, object>();
            try
            {
                // Retrieve preview data
                data = await Task.Run(() => _rpaParser.GetPreview(NormalizeTreePath(node.FullPath)));

                // Handle preview logic
                if (data.Key == RpaParser.PreviewTypes.Image)
                {
                    pictureBox1.Image = (Image)data.Value;
                    _switchTabs = true;
                    tabControl1.SelectedTab = tabPage1;
                    _switchTabs = false;
                    unsupportedFile = false;
                }
                else if (data.Key == RpaParser.PreviewTypes.Audio || data.Key == RpaParser.PreviewTypes.Video)
                {
                    // Existing media playback logic...

                    unsupportedFile = false;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format(GetText("Preview_failed_reason"), ex.Message), GetText("Preview_failed"), MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            // Generate the absolute path from the selected node full path
            string absolutePath = Path.Combine(_rpaParser.ArchiveInfo.DirectoryName, NormalizeTreePath(node.FullPath));

            // Now get the media info
            string mediaInfo = GetMediaInfo(absolutePath); // Use the absolute path for MediaInfo
            textBox1.AppendText(mediaInfo + Environment.NewLine); // Display in your text box

            break; // Break after processing selected node
        }
    }

    if (unsupportedFile)
    {
        _switchTabs = true;
        tabControl1.SelectedTab = tabPage0;
        _switchTabs = false;
        label2.Text = GetText("Preview_is_not_supported");
    }

    treeView1.SelectedNode = selectedNode;
    treeView1.SelectedNode.SelectedImageIndex = selectedNode.ImageIndex;
    treeView1.SelectedNode.EnsureVisible();
    treeView1.Focus();
}
```

### Key Changes Made

1. **Absolute Path Construction**: Used the `Path.Combine` method to construct the absolute path to the selected media file within the archive directory. This is crucial because the `NormalizeTreePath(node.FullPath)` may not return a correct file system path if the node is part of a hierarchical structure.

2. **Using the Correct Path in `GetMediaInfo`**: Instead of passing a potentially incorrect path to the `GetMediaInfo` method, we ensure to use a fully constructed file path pointing to the actual location of the media file.

### Conclusion

This should resolve the issue of not being able to retrieve media information. If the problem persists, ensure that the media files you are testing with are valid and check input paths being generated step by step in the debugging process.

Make sure to test this implementation with different files to ensure that it works reliably for the intended media types.

turns-00061.parquet:26613

90a2439805f3a260245421e9
turn 16/35gpt-4o-mini-2024-07-18EnglishRussia506 words
degenerate_repetitionAbsentFinal dense release
USER
rewrite code using example below:
```
                    string absolutePath = Path.Combine(_rpaParser.ArchiveInfo.DirectoryName, NormalizeTreePath(node.FullPath));
                    if (File.Exists(absolutePath))
                    {
                        var media = new MediaInfoWrapper(absolutePath);
                        if (media.Success)
                        {
                            string format = media.Format;
                            string videoCodec = media.HasVideo ? media.VideoStreams[0].Codec.ToString() : "";
                            string width = media.HasVideo ? media.VideoStreams[0].Width.ToString() : "";
                            string height = media.HasVideo ? media.VideoStreams[0].Height.ToString() : "";

                            if (!string.IsNullOrEmpty(videoCodec) && !string.IsNullOrEmpty(width) && !string.IsNullOrEmpty(height))
                            {
                                archiveInfo += "\n" + GetText("Media_Info") + videoCodec + " (" + width + "x" + height + ")";
                            }
                        }
                    }
ASSISTANT
Sure! I’ll rewrite the `GetMediaInfo` method using the structure and approach you provided in your example. This includes initializing the `MediaInfoWrapper` with the absolute path, checking for its success, and retrieving relevant media information like format, codec, and resolution.

### Updated `GetMediaInfo` Method

Here’s how you can rewrite your `GetMediaInfo` method accordingly:

```csharp
private string GetMediaInfo(string filePath)
{
    if (string.IsNullOrWhiteSpace(filePath) || !File.Exists(filePath))
    {
        return "Invalid file path or file does not exist.";
    }

    try
    {
        // Create the MediaInfoWrapper for the specified file path
        var media = new MediaInfoWrapper(filePath);
        
        // Check if the media info was successfully retrieved
        if (!media.Success)
        {
            return "Failed to retrieve media information.";
        }

        // Retrieve media data
        string format = media.Format;
        string videoCodec = media.HasVideo ? media.VideoStreams[0].Codec.ToString() : "N/A";
        string width = media.HasVideo ? media.VideoStreams[0].Width.ToString() : "N/A";
        string height = media.HasVideo ? media.VideoStreams[0].Height.ToString() : "N/A";

        // Prepare the info string
        string mediaInfo = $"{GetText("Media_Info")}: {videoCodec} ({width}x{height})";

        return mediaInfo;
    }
    catch (Exception ex)
    {
        return $"Error retrieving media information: {ex.Message}";
    }
}
```

### Use in PreviewSelectedItem Method

You can call this method in your `PreviewSelectedItem` method as previously explained. Here’s how it fits into your existing method logic:

```csharp
private async void PreviewSelectedItem()
{
    TreeNode selectedNode = new TreeNode();
    bool unsupportedFile = true;
    pictureBox1.Image = null;

    foreach (TreeNode node in treeView1.Nodes.All())
    {
        // Reset fields
        ResetPreviewFields();

        if (node.IsSelected)
        {
            selectedNode = node;
        }

        if (node.IsSelected && _rpaParser.Index.ContainsKey(NormalizeTreePath(node.FullPath)))
        {
            KeyValuePair<string, object> data = new KeyValuePair<string, object>();
            try
            {
                data = await Task.Run(() => _rpaParser.GetPreview(NormalizeTreePath(node.FullPath)));

                // Handle Image and Text preview logic

            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format(GetText("Preview_failed_reason"), ex.Message), GetText("Preview_failed"), MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            // Construct the absolute path to the media file
            string absolutePath = Path.Combine(_rpaParser.ArchiveInfo.DirectoryName, NormalizeTreePath(node.FullPath));

            // Call GetMediaInfo and display results
            string mediaInfo = GetMediaInfo(absolutePath);
            textBox1.AppendText(mediaInfo + Environment.NewLine); // Displaying mediaInfo

            break; // Process the selected node and exit
        }
    }

    if (unsupportedFile)
    {
        _switchTabs = true;
        tabControl1.SelectedTab = tabPage0;
        _switchTabs = false;
        label2.Text = GetText("Preview_is_not_supported");
    }

    treeView1.SelectedNode = selectedNode;
    treeView1.SelectedNode.SelectedImageIndex = selectedNode.ImageIndex;
    treeView1.SelectedNode.EnsureVisible();
    treeView1.Focus();
}
```

### Summary of Changes

- The `GetMediaInfo` method now uses the provided pattern from your example to correctly instantiate `MediaInfoWrapper`.
- It checks for success and retrieves the required codec and resolution data.
- The method can now be easily executed by passing the correct absolute path derived from your selected media in the TreeView.

With these adjustments, your application will retrieve and display media information properly in the designated text box while also adhering to the structure you provided. Be sure to test it with valid media files to check that it behaves as intended.

turns-00061.parquet:26614

a2908eff0fb47ebcd2633515
turn 17/35gpt-4o-mini-2024-07-18EnglishRussia780 words
degenerate_repetitionAbsentFinal dense release
USER
below is original function so add there needed code but keep all logic intact:
```
        private async void PreviewSelectedItem()
        {
            TreeNode selectedNode = new TreeNode();
            bool unsupportedFile = true;
            pictureBox1.Image = null;

            foreach (TreeNode node in treeView1.Nodes.All())
            {
                // Reset fields
                ResetPreviewFields();

                if (node.IsSelected)
                {
                    selectedNode = node;
                }

                if (node.IsSelected && _rpaParser.Index.ContainsKey(NormalizeTreePath(node.FullPath)))
                {
                    KeyValuePair<string, object> data = new KeyValuePair<string, object>();
                    try
                    {
                        data = await Task.Run(() => _rpaParser.GetPreview(NormalizeTreePath(node.FullPath)));

                        if (data.Key == RpaParser.PreviewTypes.Image)
                        {
                            pictureBox1.Image = (Image)data.Value;
                            _switchTabs = true;
                            tabControl1.SelectedTab = tabPage1;
                            _switchTabs = false;
                            unsupportedFile = false;
                        }
                        else if (data.Key == RpaParser.PreviewTypes.Text)
                        {
                            _searchStartIndex = 0;
                            textBox2.Text = (string)data.Value;
                            _switchTabs = true;
                            tabControl1.SelectedTab = tabPage2;
                            _switchTabs = false;
                            unsupportedFile = false;
                        }
                        else if (data.Key == RpaParser.PreviewTypes.Audio || data.Key == RpaParser.PreviewTypes.Video)
                        {
                            _memoryStreamVlc = new MemoryStream((byte[])data.Value);
                            _streamMediaInputVlc = new StreamMediaInput(_memoryStreamVlc);
                            _mediaVlc = new Media(_libVlc, _streamMediaInputVlc);

                            // Ensure the media is stopped
                            await Task.Run(() =>
                            {
                                if (videoView1.MediaPlayer != null)
                                {
                                    videoView1.MediaPlayer.Stop();
                                }
                            });

                            // Playback the new media
                            videoView1.MediaPlayer.Play(_mediaVlc);
                            SetMediaTimeLabel(_mediaVlc.Duration, 0);
                            videoView1.BackgroundImage = data.Key == RpaParser.PreviewTypes.Audio ? Resources.videoView1_BackgroundImage : null;
                            _switchTabs = true;
                            tabControl1.SelectedTab = tabPage3;
                            _switchTabs = false;
                            unsupportedFile = false;

                            // Check playback state to update button text
                            button4.Text = "Pause"; // Assuming you want to start playing the new video.
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(string.Format(GetText("Preview_failed_reason"), ex.Message), GetText("Preview_failed"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }

                    break;
                }
            }

            if (unsupportedFile)
            {
                _switchTabs = true;
                tabControl1.SelectedTab = tabPage0;
                _switchTabs = false;
                label2.Text = GetText("Preview_is_not_supported");
            }

            treeView1.SelectedNode = selectedNode;
            treeView1.SelectedNode.SelectedImageIndex = selectedNode.ImageIndex;
            treeView1.SelectedNode.EnsureVisible();
            treeView1.Focus();
        }
ASSISTANT
Certainly! Below is your original `PreviewSelectedItem` method with the `MediaInfo` functionality added while keeping the rest of the logic intact. This implementation retrieves codec and resolution information for audio and video files after extracting the preview data. 

### Updated `PreviewSelectedItem` Function

```csharp
private async void PreviewSelectedItem()
{
    TreeNode selectedNode = new TreeNode();
    bool unsupportedFile = true;
    pictureBox1.Image = null;

    foreach (TreeNode node in treeView1.Nodes.All())
    {
        // Reset fields
        ResetPreviewFields();

        if (node.IsSelected)
        {
            selectedNode = node;
        }

        if (node.IsSelected && _rpaParser.Index.ContainsKey(NormalizeTreePath(node.FullPath)))
        {
            KeyValuePair<string, object> data = new KeyValuePair<string, object>();
            try
            {
                data = await Task.Run(() => _rpaParser.GetPreview(NormalizeTreePath(node.FullPath)));

                if (data.Key == RpaParser.PreviewTypes.Image)
                {
                    pictureBox1.Image = (Image)data.Value;
                    _switchTabs = true;
                    tabControl1.SelectedTab = tabPage1;
                    _switchTabs = false;
                    unsupportedFile = false;
                }
                else if (data.Key == RpaParser.PreviewTypes.Text)
                {
                    _searchStartIndex = 0;
                    textBox2.Text = (string)data.Value;
                    _switchTabs = true;
                    tabControl1.SelectedTab = tabPage2;
                    _switchTabs = false;
                    unsupportedFile = false;
                }
                else if (data.Key == RpaParser.PreviewTypes.Audio || data.Key == RpaParser.PreviewTypes.Video)
                {
                    // Process media streams and display them
                    _memoryStreamVlc = new MemoryStream((byte[])data.Value);
                    _streamMediaInputVlc = new StreamMediaInput(_memoryStreamVlc);
                    _mediaVlc = new Media(_libVlc, _streamMediaInputVlc);

                    // Ensure the media is stopped
                    await Task.Run(() =>
                    {
                        if (videoView1.MediaPlayer != null)
                        {
                            videoView1.MediaPlayer.Stop();
                        }
                    });

                    // Playback the new media
                    videoView1.MediaPlayer.Play(_mediaVlc);
                    SetMediaTimeLabel(_mediaVlc.Duration, 0);
                    videoView1.BackgroundImage = data.Key == RpaParser.PreviewTypes.Audio ? Resources.videoView1_BackgroundImage : null;
                    _switchTabs = true;
                    tabControl1.SelectedTab = tabPage3;
                    _switchTabs = false;
                    unsupportedFile = false;

                    // Check playback state to update button text
                    button4.Text = "Pause"; // Assuming you want to start playing the new video.

                    // Construct the absolute path to the media file
                    string absolutePath = Path.Combine(_rpaParser.ArchiveInfo.DirectoryName, NormalizeTreePath(node.FullPath));

                    // Now get the media info
                    if (File.Exists(absolutePath))
                    {
                        var media = new MediaInfoWrapper(absolutePath); // Correctly use MediaInfoWrapper

                        if (media.Success)
                        {
                            string format = media.Format; // Retrieve media format
                            string videoCodec = media.HasVideo ? media.VideoStreams[0].Codec.ToString() : "N/A"; // Video codec
                            string width = media.HasVideo ? media.VideoStreams[0].Width.ToString() : "N/A"; // Video width
                            string height = media.HasVideo ? media.VideoStreams[0].Height.ToString() : "N/A"; // Video height
                            
                            // Display media info in archiveInfo or textBox
                            string mediaInfo = $"Media Info: {videoCodec} ({width}x{height}, Format: {format})";
                            textBox1.AppendText(mediaInfo + Environment.NewLine); // Appending to some output textbox
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format(GetText("Preview_failed_reason"), ex.Message), GetText("Preview_failed"), MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            break; // Exit after previewing the selected item
        }
    }

    if (unsupportedFile)
    {
        _switchTabs = true;
        tabControl1.SelectedTab = tabPage0;
        _switchTabs = false;
        label2.Text = GetText("Preview_is_not_supported");
    }

    treeView1.SelectedNode = selectedNode;
    treeView1.SelectedNode.SelectedImageIndex = selectedNode.ImageIndex;
    treeView1.SelectedNode.EnsureVisible();
    treeView1.Focus();
}
```

### Changes Made
1. **Construct Absolute Path**: The absolute path for the media file is constructed before you call the `MediaInfoWrapper`.
   
2. **Use `MediaInfoWrapper`**: The path is passed to `MediaInfoWrapper`, which directly checks if the information could be successfully retrieved.

3. **Retrieve and Display Media Info**:
   - Retrieve the media format, codec, width, and height using available properties of `MediaInfoWrapper`.
   - The media information is formatted and appended to the `textBox1` for display.

4. **Maintain Original Logic**: The original logic and flow of the method are preserved, making sure all other preview functionalities remain unaffected.

### Conclusion
This adjustment ensures that when previewing selected media files, the relevant information about video and audio streams is correctly retrieved and displayed in your user interface, alongside the existing functionalities. Be sure to test this implementation with various media files to ensure it works reliably.