using Microsoft.VisualBasic;
using Microsoft.VisualBasic.FileIO;
using Newtonsoft.Json.Linq;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Security.Policy;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Timers;
using WinFormsApp1;

namespace DragonVideoPlayer
{
   
    
    public class MainForm : Form
    {    //↓ミニプレイヤーをマウスで動かすのに使う
        [DllImport("user32.dll")]
        private static extern bool ReleaseCapture();

        [DllImport("user32.dll")]
        private static extern IntPtr SendMessage(
            IntPtr hWnd,
            int Msg,
            int wParam,
            int lParam);

        private const int WM_NCLBUTTONDOWN = 0xA1;
        private const int HTCAPTION = 0x2;
        private bool _isMiniPlayer = false;

        private bool _isVr360Mode = false;
        private int fov_360 = 90;
        private bool vr360Dirty = false;
        private System.Windows.Forms.Timer vr360Timer;
        private int roll_360 = 0;
        private int yaw_360 = 0;
        private int pitch_360 = 0;
        private int step_360 = 5; // 1回の移動量（調整可）

        private double _currentSubDelay = 0;
        // mini化前のフォーム状態を保存
        private Rectangle _prevMiniBounds;
        private FormBorderStyle _prevMiniBorderStyle;
        private FormWindowState _prevMiniWindowState;


        bool _mute_bool = false;

        private NotifyIcon trayIcon;
        private ContextMenuStrip trayMenu;

        private MenuStrip capter_menuStrip;
        private ToolStripMenuItem menuChapters;
        //public PictureBox loadingGif;

        private double audio_delay = 0;
        private int list_type = 0;
        private double _currentSpeed = 1.0;
        private double _subsize = 1.0;
        private int _sub_pos_y = 100;
        private System.Windows.Forms.Timer _a_b_loopTimer;
        private double _a_maker;
        private double _b_maker;
        private String _title = "";
        private int _volume = 100;
        bool _a_b_isLooping = false;
        ToolStripMenuItem menuAudio;
        ToolStripMenuItem menuSub;
        private int cap_size = 0;
        private int cap_position = 0;
        private bool youtube_playlist_bool = false;

        private double nokori_jikan;
        internal Panel videoPanel;
        internal TrackBar PositionSlider;
        internal TrackBar volume_Slider;
        internal TrackBar ListSlider;
        internal TrackBar Speed_Slider;
        internal Label lblTime;
        internal Label lblResolution;
        internal Label lblFilesize;
        internal Label lbl_Listsize;
        internal Label lbl_title;
        internal Label lbl_list_name;
        internal Label volume_label;
        internal Label speed_label;
        private System.Windows.Forms.Timer _frameStepTimer;
        private System.Windows.Forms.Timer _frameBackStepTimer;

        private MenuBuilder _menuBuilder;

        private bool _isFullScreen = false;

        internal FormWindowState _prevWindowState;
        internal FormBorderStyle _prevBorderStyle;


        private bool _list_slidr_isDragging = false;
        private bool _pos_slidr_isDragging = false;

        private string argument;



        private double _duration = 0;


        private ToolStripTextBox searchBox;
        private ToolStripButton searchButton;
        private ToolStripMenuItem resultMenu;

        private string currentFilePath = "";


        private double _videoWidth;
        private double _videoHeight;
        private double _filesize;


        // IPC用

        private Thread _readThread;

        private double _timePos = 0;

        internal Panel BottomControlPanel;


        private VideoState _videoState = new VideoState();
        //グローバル変数
        private List<String> folder_movie_lists;
        private List<String> main_video_lists;
        private List<String> abema_stream_lists;

        private List<String> search_lists;

        private List<String> OverClocked_remix_lists;

        private List<String> primehome_lists;
        private List<String> mov3_lists;
        private List<String> utako_moe_lists;
        private List<String> rakuten_lists;
        private List<String> youtube_play_lists_url;

        private List<String> arva_lists;

        private List<String> youtube_play_lists_title;

        private List<String> db_all_video_lists;
        private int main_video_count;
        
        internal System.Windows.Forms.Timer _seekTimer;
        internal System.Windows.Forms.Timer _prevseekTimer;
        internal System.Windows.Forms.Timer _next_movie_Timer;
        internal System.Windows.Forms.Timer _prev_movie_Timer;
        internal System.Windows.Forms.Timer _speed_up_Timer;
        internal System.Windows.Forms.Timer _speed_down_Timer;
        internal System.Windows.Forms.Timer _flame_step_Timer;
        internal System.Windows.Forms.Timer _flame_back_step_Timer;

        internal System.Windows.Forms.Timer _cap_next_Timer;
        internal System.Windows.Forms.Timer _cap_back_Timer;


        private MpvPlayer _myplayer;





        internal TableLayoutPanel _mainLayout;
        internal MenuStrip TopMenuPanel;
        public MainForm()
        {
            Directory.SetCurrentDirectory(AppContext.BaseDirectory);
            OverClocked_remix_lists =new List<string>();
               folder_movie_lists = new List<string>();
        main_video_lists = new List<string>();
       abema_stream_lists = new List<string>();

        search_lists = new List<string>();

         OverClocked_remix_lists = new List<string>();

        primehome_lists = new List<string>();
        mov3_lists = new List<string>();
         utako_moe_lists = new List<string>();
            arva_lists = new List<string>();
            rakuten_lists = new List<string>();
        youtube_play_lists_url = new List<string>();

      youtube_play_lists_title = new List<string>();

            db_all_video_lists = new List<string>();
            _a_b_loopTimer = new System.Windows.Forms.Timer();
            _a_b_loopTimer.Interval = 100; // 0.1秒ごとチェック
            _a_b_loopTimer.Tick += a_b_LoopTimer_Tick;
            list_type = 0;
            nokori_jikan = 1;
            this.Icon = new Icon("icon.ico");
            this.AllowDrop = true;
            this.Text = "Dragon Video Player";
            int this_Width = 800;
            int this_Height = 600;
            this.MinimumSize = new Size(200, 100);
            if (config_class.config_int_read("起動時のウインドウサイズ") == 1)
            {
                try
                {
                    if (!string.IsNullOrWhiteSpace(config_class.config_text_read("起動時のwidth")) &&
                        !string.IsNullOrWhiteSpace(config_class.config_text_read("起動時のheight")))
                    {

                        this_Width = int.Parse(config_class.config_text_read("起動時のwidth"));
                        this_Height = int.Parse(config_class.config_text_read("起動時のheight"));
                    }
                }
                catch (System.Exception ex)
                {
                    error.write_error_log(ex.Message + ex.StackTrace);
                    Debug.WriteLine("config読み込みでエラー：" + ex.Message);
                }




            }
            if (config_class.config_int_read("起動時のウインドウサイズ") == 2)
            {
                try
                {
                    if (!string.IsNullOrWhiteSpace(config_class.config_text_read("復元width")) &&
                        !string.IsNullOrWhiteSpace(config_class.config_text_read("復元height")))
                    {

                        this_Width = int.Parse(config_class.config_text_read("復元width"));
                        this_Height = int.Parse(config_class.config_text_read("復元height"));
                    }
                }
                catch (System.Exception ex)
                {
                    error.write_error_log(ex.Message + ex.StackTrace);
                    Debug.WriteLine("config読み込みでエラー：" + ex.Message);
                }
                //復元
            }
            if (config_class.config_int_read("起動時のウインドウサイズ") == 3)
            {
                this.WindowState = FormWindowState.Maximized;
                //フルスクリーン
            }

            if (config_class.config_int_read("起動時のウインドウサイズ") == 4)
            {
                this.WindowState = FormWindowState.Maximized;
                //最大化
            }
            if (config_class.config_int_read("起動時のウインドウサイズ") == 5)
            {
                this.Width = Screen.GetBounds(this).Width;
                this.Height = Screen.GetBounds(this).Height;
                //デスクトップの解像度に合わせる
            }
            this.Width = this_Width;
            this.Height = this_Height;


            InitializeUI();





            capter_menuStrip = new MenuStrip();



            this.FormClosing += new FormClosingEventHandler(formClosing);
            this.DragEnter += Form1_DragEnter;
            this.DragDrop += Form1_DragDrop;
            this.Load += Form1_Load;
          
         
            this.KeyDown += Form1_KeyDown;
            videoPanel.MouseDown += VideoPanel_MouseDown;
          
            this.Resize+= Form1_Resize;


            this.FormClosing += close;

            this.KeyPreview = true;
            this.MouseWheel += Form1_MouseWheel;
            videoPanel.CreateControl();
            _myplayer = new MpvPlayer(videoPanel.Handle);

            _myplayer.MpvMessageReceived += HandleMpvMessage;

            volume_Slider.Scroll += trackBarVolume_Scroll;

            Speed_Slider.Scroll += trackBarSpeed_Scroll;


            _frameStepTimer = new System.Windows.Forms.Timer();
            _frameStepTimer.Interval = 80; // 30msごと（好みで調整）
            _frameStepTimer.Tick += (s, e) =>
            {

                FrameStep();
            };
            _frameBackStepTimer = new System.Windows.Forms.Timer();
            _frameBackStepTimer.Interval = 80; // 30msごと（好みで調整）
            _frameBackStepTimer.Tick += (s, e) =>
            {

                FrameBackStep();
            };
            if (config_class.config_bool_read("タスクトレイに常駐") == true)
            {
                InitTray();
            }

            vr360Timer = new System.Windows.Forms.Timer();
            vr360Timer.Interval = 16; // 約60fps
            vr360Timer.Tick += (s, e) =>
            {
                if (!vr360Dirty) return;

                vr360Dirty = false;
                UpdateVRView();
            };
            vr360Timer.Start();
        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            if (WindowState == FormWindowState.Minimized)
            {
                bool trayEnabled = config_class.config_bool_read("タスクトレイに常駐");

                if (trayEnabled)
                {
                    Hide(); // トレイに隠す
                }
                else
                {
                    ShowInTaskbar = true; // 普通にタスクバーへ
                }
            }
        }

        private void VideoPanel_MouseDown(object sender, MouseEventArgs e)
        {
            if (_isMiniPlayer && e.Button == MouseButtons.Left)
            {
                ReleaseCapture();
                SendMessage(this.Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);

            }
           

        }
        public void ToggleMiniPlayer()
        {

            Debug.WriteLine("ToggleMini");
            if (!_isMiniPlayer)
                EnterMiniPlayer();
            else
                ExitMiniPlayer();
        }


        public void vr_360mode()
        {

            if (!_isVr360Mode)
            {
                _myplayer.Video.vr360_mode_enable();
                _isVr360Mode = true;
            }
            else
            {
                _myplayer.Video.vf_normal();
                _isVr360Mode = false;
            }
               
        }
        private void EnterMiniPlayer()
        {

            // フルスクリーン中なら解除してから
            if (_isFullScreen)
                ToggleFullScreen();

            _prevMiniBounds = this.Bounds;
            _prevMiniBorderStyle = this.FormBorderStyle;
            _prevMiniWindowState = this.WindowState;

            // レイアウトの上下UIを消す
            _mainLayout.RowStyles[0].Height = 0;
            _mainLayout.RowStyles[2].Height = 0;

            TopMenuPanel.Visible = false;
            BottomControlPanel.Visible = false;
            capter_menuStrip.Visible = false;

            FormBorderStyle = FormBorderStyle.None;
            TopMost = true;
            WindowState = FormWindowState.Normal;

            Size = new Size(480, 270);

            var area = Screen.FromControl(this).WorkingArea;
            Location = new Point(
                area.Right - Width - 16,
                area.Bottom - Height - 16
            );

            _isMiniPlayer = true;
        }


        private void ExitMiniPlayer()
        {
            this.Bounds = _prevMiniBounds;
            this.FormBorderStyle = _prevMiniBorderStyle;
            this.WindowState = _prevMiniWindowState;

            _mainLayout.RowStyles[0].SizeType = SizeType.AutoSize;
            _mainLayout.RowStyles[2].SizeType = SizeType.AutoSize;

            TopMenuPanel.Visible = true;
            BottomControlPanel.Visible = true;
            capter_menuStrip.Visible = true;

            TopMost = false;

            _isMiniPlayer = false;
        }
     
      protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            if (config_class.config_bool_read("タスクトレイに常駐"))
            {
                if (WindowState == FormWindowState.Minimized)
                {
                    Hide();
                }
            }
            
        }

        //public void saishou()
        //{
        //    WindowState = FormWindowState.Normal;
        //}
        private void InitTray()
        {
            trayMenu = new ContextMenuStrip();

            trayMenu.Items.Add("最大化", null, (s, e) =>
            {
                Show();
                WindowState = FormWindowState.Normal;
                Activate();
            });

            trayMenu.Items.Add("最小化", null, (s, e) =>
            {
                WindowState = FormWindowState.Minimized;
            });
            trayMenu.Items.Add("フルスクリーン", null, (s, e) =>
            {
                ToggleFullScreen();
            });
            trayMenu.Items.Add("ミニプレイヤー", null, (s, e) =>
            {
                ToggleMiniPlayer();
            });
            trayMenu.Items.Add("閉じる", null, (s, e) =>
                {
                    trayIcon.Visible = false;
                    Application.Exit();
                });

            trayIcon = new NotifyIcon
            {
                Icon = this.Icon,
                Text = "mpv Player",
                Visible = true,
                ContextMenuStrip = trayMenu
            };


            trayIcon.DoubleClick += (s, e) =>
            {

                if (Visible && WindowState != FormWindowState.Minimized)
                {
                    Hide();
                }
                else
                {
                    Show();
                    WindowState = FormWindowState.Normal;
                    Activate();
                }

            };
           
        }
        // ================= UI =================

        void InitializeUI()
        {

            primehome_lists = new List<string>();
            List<string> history_list = new List<string>();
            rakuten_lists = new List<string>();
            history_list = sql_class.sql_history(config_class.config_int_read("履歴数"));

            search_lists = new List<string>();

            List<string> ranking_list = new List<string>();
            ranking_list = sql_class.sql_ranking(config_class.config_int_read("ランキング数"));
            string db = Path.Combine(AppContext.BaseDirectory, "abema.txt");

            abema_stream_lists = TextListLoader.Load("abema.txt");
            primehome_lists = TextListLoader.Load("primehome.txt");
            mov3_lists = TextListLoader.Load("mov3.txt");
            utako_moe_lists = TextListLoader.Load("utako_moe.txt");

            arva_lists = TextListLoader.Load("arva.txt");

            rakuten_lists = TextListLoader.Load("rakuten.txt");
            UIBuilder.Build(this, abema_stream_lists, primehome_lists, mov3_lists, utako_moe_lists, history_list, ranking_list, rakuten_lists,arva_lists);
            var searec_menuStrip = new MenuStrip();
            if (config_class.config_bool_read("検索窓を有効") == true)
            {


                // 検索ボックス
                searchBox = new ToolStripTextBox();
                searchBox.Width = 200;

                // 検索ボックス
                searchBox = new ToolStripTextBox();
                searchBox.Width = 200;

                // 検索ボタン
                searchButton = new ToolStripButton("検索");
                searchButton.Click += SearchButton_Click;

                // 検索結果メニュー（ここに追加される）
                resultMenu = new ToolStripMenuItem("検索結果");

                // Menuに追加
                searec_menuStrip.Items.Add(new ToolStripLabel("検索: "));
                searec_menuStrip.Items.Add(searchBox);
                searec_menuStrip.Items.Add(searchButton);
                searec_menuStrip.Items.Add(resultMenu);

                this.MainMenuStrip = searec_menuStrip;
                this.Controls.Add(searec_menuStrip);
            }

        }


       
        void formClosing(object sender, FormClosingEventArgs e)
        {
            StopMpv();



            config_class.save_config_file("復元width", this.Width.ToString());
            config_class.save_config_file("復元height", this.Height.ToString());
        }
        public void stats_script_binding(String page)
        {
            _myplayer.stats_script_binding(page);
        }
        public void search_youtube_func()
        {

            string result = Interaction.InputBox(
    "検索キーワードを入力してください",
    "検索ダイアログ",
    ""
);

            if (!string.IsNullOrEmpty(result))
            {

                StartMpv($"ytdl://ytsearch100:{result}");
                list_youtube_playlist();
            }

            list_youtube_playlist();


        }
        public void search_func()
        {

            string result = Interaction.InputBox(
    "検索キーワードを入力してください",
    "検索ダイアログ",
    ""
);

            if (!string.IsNullOrEmpty(result))
            {
                if (config_class.config_bool_read("検索窓を有効") == true)
                {

                    search_lists = sql_class.sql_kensaku(result, config_class.config_int_read("動画DBのソート"), config_class.config_int_read("動画DBのソートの順序"), 200, 0);

                    ShowResults(search_lists);
                }
                search_lists = sql_class.sql_kensaku(result, config_class.config_int_read("動画DBのソート"), config_class.config_int_read("動画DBのソートの順序"));


            }
            list_seach();
        }
        public void search_youtube_bt_click(String keyword)
        {

            if (string.IsNullOrEmpty(keyword))
            {
                return;
            }



            StartMpv($"ytdl://ytsearch100:{keyword}");

            list_youtube_playlist();


        }
        private void ShowResults(List<string> results)
        {
            resultMenu.DropDownItems.Clear();

            foreach (var path in results)
            {
                var item = new ToolStripMenuItem(Path.GetFileName(path));

                // クリックで再生
                item.Click += (s, e) =>
                {
                    StartMpv(path);
                };

                resultMenu.DropDownItems.Add(item);
            }
        }

        private void SearchButton_Click(object sender, EventArgs e)
        {
            string keyword = searchBox.Text;

            search_lists = sql_class.sql_kensaku(keyword, config_class.config_int_read("動画DBのソート"), config_class.config_int_read("動画DBのソートの順序"), 200, 0);

            ShowResults(search_lists);
        }


        private void Form1_Load(object sender, EventArgs e)
        {



            if (config_class.config_bool_read("ボリュームを保存する") == true)
            {

                if (!string.IsNullOrEmpty(config_class.config_text_read("ボリューム数")))
                {

                    String vol_st = config_class.config_text_read("ボリューム数");
                    volume_label.Text = vol_st;
                    if (int.TryParse(vol_st, out int vol_int))
                    {
                        _volume = vol_int;
                        Debug.WriteLine(vol_int);
                        if (volume_Slider.Maximum >= vol_int)
                            volume_Slider.Value = vol_int;


                    }
                }

                
                     }

            youtube_play_lists_url = new List<string>();


            youtube_play_lists_title = new List<string>();
            folder_movie_lists = new List<string>();
            main_video_lists = new List<string>();



            db_all_video_lists = new List<string>();



            main_video_count = 0;
            string[] cmds = null;
            try
            {
                cmds = System.Environment.GetCommandLineArgs();
            }
            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);
                Debug.WriteLine(ex.Message + ex.StackTrace);


            }
        
            if (cmds != null)
            {
                try
                {

                    if (cmds.Length == 1)
                    {
                        currentFilePath = config_class.config_text_read("url");
                    }
                    if (cmds.Length > 1)
                    {
                        String kidou_path = cmds[1];
                     
                        currentFilePath = kidou_path;
                        start_list_update(kidou_path);
                      
                        if (System.IO.File.Exists(kidou_path))
                        {
                            if (System.Text.RegularExpressions.Regex.IsMatch(kidou_path, config_class.config_text_read("動画取得の拡張子の正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                            {
                                StartMpv(kidou_path);
                           
                            }

                        }
                    }
                }
                catch (System.Exception ex)
                {
                    error.write_error_log(ex.Message + ex.StackTrace);
                    Debug.WriteLine(ex.Message + ex.StackTrace);

                }

            }


         
            db_all_video_lists = sql_class.sql_all_db(config_class.config_int_read("動画DBのソート"), config_class.config_int_read("動画DBのソートの順序"));
            if (config_class.config_int_read("起動時のリスト") == 1)
            {
                list_folder();
            }
            if (config_class.config_int_read("起動時のリスト") == 2)
            {
                list_db();

            }
            if (config_class.config_int_read("起動時のリスト") == 3)
            {
                list_abema();

            }
            if (config_class.config_int_read("起動時のリスト") == 4)
            {


                list_primehome();

            }
            if (config_class.config_int_read("起動時のリスト") == 5)
            {


                list_utako_moe();

            }
            if (config_class.config_int_read("起動時のリスト") == 6)
            {


                list_rakuten();

            }
            if (config_class.config_bool_read("OverClockedReMixをリスト追加") == true)
            {

                Task.Run(() =>
                               OverClocked_remix_lists = TextListLoader.Load_no_Contains("OverClocked_remix.txt")



                            );
            }
        }


        private void UpdatePlaylistMenu(List<string> titleList, List<string> urlList)
        {

            capter_menuStrip.Items.Clear();

            ToolStripMenuItem playlistMenu = new ToolStripMenuItem("list");


            for (int i = 0; i < titleList.Count; i++)
            {
                try
                {
                    Debug.WriteLine(titleList[i]);
                    Debug.WriteLine(urlList[i]);
                    var item = new ToolStripMenuItem(titleList[i]);


                    item.Tag = urlList[i];

                    item.Click += PlaylistItem_Click;

                    playlistMenu.DropDownItems.Add(item);
                }
                catch (System.Exception ex)
                {
                    error.write_error_log(ex.Message + ex.StackTrace);
                    Debug.WriteLine(ex.Message + ex.StackTrace);

                }




            }

            capter_menuStrip.Items.Add(playlistMenu);

            this.Controls.Add(capter_menuStrip);
        }
        private void PlaylistItem_Click(object sender, EventArgs e)
        {
            if (sender is ToolStripMenuItem item)
            {
                string url = item.Tag as string;

                if (!string.IsNullOrEmpty(url))
                {
                    Debug.WriteLine("クリックされたURL: " + url);
                    StartMpv(url);

                }
            }
        }

        public async void radiko_url_update()
        {
            try
            {
                if (System.IO.File.Exists("radiko.txt") == true)
                {
                    try { 
                    File.Delete(@"radiko.txt");
                }
                catch (System.Exception ex)
            {
              
                Debug.WriteLine(ex.Message + ex.StackTrace);

            }
        }
                    if (System.IO.File.Exists("radiko.txt") == false)
                {
                  
                    using (FileStream fs = File.Create(@"radiko.txt")) ;
                }


            }
            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);
                Debug.WriteLine(ex.Message + ex.StackTrace);

            }

            var radiko = new RadikoClient();
            try
            {
                await radiko.Init();

                Debug.WriteLine("Area: " + radiko.AreaId);

                var stations = await radiko.GetStations();

                foreach (var s in stations)
                {
                    Debug.WriteLine($"{s.id} {s.name}");

                    File.AppendAllText("radiko.txt", "https://radiko.jp/#!/live/" + s.id + Environment.NewLine);



                }
            }
            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);
                Debug.WriteLine(ex.Message + ex.StackTrace);

            }



        }
        public async void mov3_url_update()
        {
            var service = new Web_update();

            await service.update_mov3();
        }
        public async void abema_url_update()
        {
            var service = new Web_update();
            await service.AbemaUpdateFilesAsync();

        }
        public async void arva_url_update()
        {
            var service = new Web_update();
            await service.ArvaUpdateFilesAsync();

        }
        public async void ytdlp_update()
        {
            var service = new Web_update();
            String ytdlp_path = config_class.config_text_read("yt-dlpのパス");
           
                 service.YtDlpUpdate(ytdlp_path);
            

        }
        public void PlayerPanel_SIngleClick(object? sender, EventArgs e)
        {
            if (config_class.config_bool_read("動画ウインドウをシングルクリックで動作を有効") == true)
            {
                if (config_class.config_int_read("動画ウインドウのシングルクリックの動作") == 1)
                {
                    next_movie();
                }
                if (config_class.config_int_read("動画ウインドウのシングルクリックの動作") == 2)
                {
                    ToggleFullScreen();
                }
                if (config_class.config_int_read("動画ウインドウのシングルクリックの動作") == 3)
                {
                    pause_func();
                }
                if (config_class.config_int_read("動画ウインドウのシングルクリックの動作") == 4)
                {
                    mute_func();
                }
            }
        }
        private void Form1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop) ||
        e.Data.GetDataPresent(DataFormats.Text) ||
        e.Data.GetDataPresent("UniformResourceLocator"))
            {
                e.Effect = DragDropEffects.Copy;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }
        private async void Form1_DragDrop(System.Object sender, System.Windows.Forms.DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] paths = (string[])e.Data.GetData(DataFormats.FileDrop);
                if (paths.Length > 0 && System.IO.File.Exists(paths[0]))
                {
                    currentFilePath = paths[0];
                    
                    if (System.IO.File.Exists(paths[0]))
                    {

                        if (System.Text.RegularExpressions.Regex.IsMatch(paths[0], config_class.config_text_read("動画取得の拡張子の正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                        {
                            StartMpv(paths[0]);
                        }
                      
                    }

                    await Task.Run(() =>
                    {
                        foreach (var get_path in paths)
                        {
                            if (folder_movie_lists.Contains(get_path) == false)
                            {
                                if (System.IO.File.Exists(get_path))
                                {
                                    if (System.Text.RegularExpressions.Regex.IsMatch(paths[0], config_class.config_text_read("動画取得の拡張子の正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                                    {
                                        folder_movie_lists.Add(get_path);
                                    }
                                }
                            }




                        }

                    });
                    start_list_update(paths[0]);

                }


            }




            // URL（テキスト）が来た場合
            if (e.Data.GetDataPresent(DataFormats.Text))
            {
                string text = e.Data.GetData(DataFormats.Text).ToString();




                if (System.Uri.IsWellFormedUriString(text, UriKind.Absolute))
                {
                    StartMpv(text);
                }
            }



        }
        public void argument_window_open()
        {
            argument_window ins = new argument_window(_myplayer.Mpv_argument);
            ins.Show();


        }
        public void yoyaku_window_open()
        {
            ReservationForm ins = new ReservationForm();
            ins.Show();


        }
        public void setting_open()
        {

            SettingsForm ins = new SettingsForm();

            ins.Show();

        }
        public void listview_open()
        {
            VideoListView ins = new VideoListView(this);

            ins.Show();

        }


        public void audio_window_open()
        {
            EqualizerForm ins = new EqualizerForm(_myplayer);

            ins.Show();

        }

        public void d_d_window_open()
        {
            DragDropForm ins = new DragDropForm();
            ins.Show();

        }


        public void videoinfo_window_open()
        {
            InfoForm ins = new InfoForm(_videoState);
            ins.Show();

        }
        public void reboot()
        {
            StopMpv();
            try
            {
                Process[] ps = Process.GetProcessesByName("mpv");
                foreach (Process item in ps)
                {

                    item.Kill();
                    item.Close();
                    item.Dispose();
                }
            }
            catch (System.Exception ex)
            {
                Debug.WriteLine(ex.Message + ex.StackTrace);

            }
            if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, "https?:", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
            {


                if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"https://linear-abematv.akamaized.net/preview/channel/[A-Za-z0-9\-_]+/playlist.m3u8", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                {
                    try
                    {
                        Process[] ps = Process.GetProcessesByName("streamlink");
                        foreach (Process item in ps)
                        {

                            item.Kill();
                            item.Close();
                            item.Dispose();
                        }
                    }
                    catch (System.Exception ex)
                    {
                        Debug.WriteLine(ex.Message + ex.StackTrace);

                    }
                }

                else
                {
                    try
                    {
                        Process[] ps = Process.GetProcessesByName("yt-dlp");
                        foreach (Process item in ps)
                        {

                            item.Kill();
                            item.Close();
                            item.Dispose();
                        }
                    }
                    catch (System.Exception ex)
                    {
                        Debug.WriteLine(ex.Message + ex.StackTrace);

                    }

                }
            }

            play_func();
        }

        public void url_paste_func()
        {
            if (Clipboard.ContainsText())
            {
                string text = Clipboard.GetText();
                if (System.Text.RegularExpressions.Regex.IsMatch(text, "https?://.*", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                {
                    StartMpv(text);
                }
                else
                {
                    return;
                }




            }
        }
        public void close_func()
        {
            this.Close();
        }
        private void close(object sender, FormClosingEventArgs e)
        {
            Debug.WriteLine("close_fun" + currentFilePath);
            config_class.save_config_file("url", currentFilePath);



            StopMpv();
            try
            {
                Process[] ps = Process.GetProcessesByName("mpv");
                foreach (Process item in ps)
                {

                    item.Kill();
                    item.Close();
                    item.Dispose();
                }
            }
            catch (System.Exception ex)
            {
                Debug.WriteLine(ex.Message + ex.StackTrace);

            }



        }

        public void Speed_change(Double value)
        {
            _myplayer.ChangeSpeed(value);
        }
        public void Speed_change_no_osd(Double value)
        {
            _myplayer.ChangeSpeed_no_osd(value);
        }
        public void SpeedUp()
        {

            string val = config_class.config_text_read("SPEEDアップ数");

            if (!double.TryParse(val, NumberStyles.Float, CultureInfo.InvariantCulture, out double up_su))
            {
                up_su = 0.1; // デフォルト
            }

            // 減算
            _currentSpeed = _currentSpeed + up_su;


            if (_currentSpeed > 10)
                _currentSpeed = 10.0;

            _currentSpeed = Math.Round(_currentSpeed, 1);
            Speed_change(_currentSpeed);

        }

        public void SpeedDown()
        {
            string val = config_class.config_text_read("SPEEDアップ数");

            if (!double.TryParse(val, NumberStyles.Float, CultureInfo.InvariantCulture, out double down))
            {
                down = 0.1; // デフォルト
            }

            // 減算
            _currentSpeed = _currentSpeed - down;

            // 下限ガード（重要）
            if (_currentSpeed < 0.1)
                _currentSpeed = 0.1;
            _currentSpeed = Math.Round(_currentSpeed, 1);
            Speed_change(_currentSpeed);
        }




        public void bt_cap_prev()
        {

            cap_position = cap_position - 1;
            if (cap_position <= 0)
            {
                cap_position = cap_size;
            }
            _myplayer.ChangeChapter(cap_position);



        }



        public void bt_cap_next()
        {

            cap_position = cap_position + 1;
            if (cap_position > cap_size)
            {
                cap_position = 0;

            }

            _myplayer.ChangeChapter(cap_position);



        }


        public void NextSeek()
        {

            if (_duration <= 0) return;
            string val = config_class.config_text_read("シークする時の飛ばすフレーム数");

            if (!double.TryParse(val, NumberStyles.Float, CultureInfo.InvariantCulture, out double seek_flame))
            {
                seek_flame = 10.0; // デフォルト
            }
           
            _myplayer.NextSeek(seek_flame);




        }

        public void PrevSeek()
        {
            if (_duration <= 0) return;
            string val = config_class.config_text_read("シークする時の飛ばすフレーム数");

            if (!double.TryParse(val, NumberStyles.Float, CultureInfo.InvariantCulture, out double seek_flame))
            {
                seek_flame = 10.0; // デフォルト
            }

            _myplayer.PrevSeek(seek_flame);


        }
        public void play_func()
        {
            Debug.WriteLine("currentFilePath" + currentFilePath);
            StartMpv(currentFilePath);


        }
        public void pause_func()
        {
            _myplayer.TogglePause();

        }
        private async void folder_get(String folder_path)
        {
            folder_movie_lists = new List<String>();
            if (System.IO.Directory.Exists(folder_path) == false)
            {
                return;

            }
            try
            {



                string[] files = System.IO.Directory.GetFiles(
       folder_path, "*", System.IO.SearchOption.TopDirectoryOnly);

                foreach (string movie_path in files)
                {



                    if (System.Text.RegularExpressions.Regex.IsMatch(movie_path, config_class.config_text_read("動画取得の拡張子の正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                    {
                        if (System.IO.File.Exists(movie_path) == true)
                        {
                            folder_movie_lists.Add(movie_path);
                        }
                    }


                }

            }
            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);
                Debug.WriteLine(ex.Message + ex.StackTrace);

            }






        }
        private async void folder_get_movie(String video_path)
        {
            

            if (System.IO.File.Exists(video_path) == false)
            {
                return;

            }
            String dir_path = "";
            try
            {
                dir_path = System.IO.Path.GetDirectoryName(video_path);
             
            
          




            var files2 = new DirectoryInfo(dir_path)
             .GetFiles("*", System.IO.SearchOption.TopDirectoryOnly)
             .Where(f => Regex.IsMatch(f.FullName,
                 config_class.config_text_read("動画取得の拡張子の正規表現"),
                 RegexOptions.IgnoreCase));
              
                int sortType = config_class.config_int_read("フォルダ動画のソート");
                Debug.WriteLine("1377:"+ sortType);
                IEnumerable<FileInfo> sorted=files2;

            switch (sortType)
            {
                case 1: // 更新日時
                    if (config_class.config_int_read("フォルダ動画のソートの順序") == 1)
                    {
                            Debug.WriteLine("1385フォルダ動画のソート");
                        sorted = files2.OrderByDescending(f => f.LastWriteTime);

                    }
                    if (config_class.config_int_read("フォルダ動画のソートの順序") == 2)
                        {
                            Debug.WriteLine("1390フォルダ動画のソート");
                            sorted = files2.OrderBy(f => f.LastWriteTime);

                    }
                    break;

                case 2: // 作成順
                    if (config_class.config_int_read("フォルダ動画のソートの順序") == 1)
                    {
                        sorted = files2.OrderByDescending(f => f.CreationTime);

                    }
                    if (config_class.config_int_read("フォルダ動画のソートの順序") == 2)
                    {
                        sorted = files2.OrderBy(f => f.CreationTime);

                    }


                    break;
                case 3: // 名前順
                    if (config_class.config_int_read("フォルダ動画のソートの順序") == 1)
                    {
                        sorted = files2.OrderByDescending(f => f.Name);

                    }
                    if (config_class.config_int_read("フォルダ動画のソートの順序") == 2)
                    {
                        sorted = files2.OrderBy(f => f.Name);

                    }
                    break;
                case 4: // サイズ順 
                    if (config_class.config_int_read("フォルダ動画のソートの順序") == 1)
                    {
                        sorted = files2.OrderByDescending(f => f.Length);

                    }
                    if (config_class.config_int_read("フォルダ動画のソートの順序") == 2)
                    {
                        sorted = files2.OrderBy(f => f.Length);

                    }
                    break;


               
            }
          
            folder_movie_lists = sorted.Select(f => f.FullName).ToList();
            }
            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);
                Debug.WriteLine(ex.Message + ex.StackTrace);

            }


        }
        private void UpdateVRView()
        {
            _myplayer.Video.vr360_mode_command(yaw_360,  fov_360, pitch_360, roll_360);
        }
        public void list_change(String name, List<String> list)
        {
            main_video_count = 0;
            main_video_lists = list;
            BeginInvoke(() =>
            {
                lbl_list_name.Text = name;
                if (main_video_lists != null)
                {
                    ListSlider.Maximum = main_video_lists.Count();
                    lbl_Listsize.Text = main_video_count.ToString() + "/" + main_video_lists.Count().ToString();
                }
            });

        }
        public void list_abema()
        {
            list_change("Abema", abema_stream_lists);

        }
        public void list_OverClocked_remix()
        {
            Debug.WriteLine(OverClocked_remix_lists.Count);
            list_change("Ocremix", OverClocked_remix_lists);

        }
        public void list_seach()
        {
            list_change("検索", search_lists);


        }
        public void list_folder()
        {
            list_change("フォルダ", folder_movie_lists);


        }
        public void list_primehome()
        {
            list_change("primehome", primehome_lists);


        }


        public void list_youtube_playlist()
        {
            list_change("playlist", youtube_play_lists_url);


        }
        public void list_utako_moe()
        {
            list_change("utako_moee", utako_moe_lists);


        }

        public void open_video_window()
        {


            video_window ins = new video_window(_myplayer.Controller);

            ins.Show();
        }
        public void open_audio_window()
        {
            EqualizerForm ins = new EqualizerForm(_myplayer);

            ins.Show();
        }
        private void OnVideoEnded()
        {

            if (config_class.config_int_read("終了後の動作") == 1)
            {
                next_movie();
                StartMpv(currentFilePath);

            }
            if (config_class.config_int_read("終了後の動作") == 2)
            {
                StartMpv(currentFilePath);
            }

            if (config_class.config_int_read("終了後の動作") == 3)
            {
                randam_movie();
                StartMpv(currentFilePath);
            }
            if (config_class.config_int_read("終了後の動作") == 4)
            {
                StopMpv();
            }


        }
        public void home_movie()
        {

            main_video_count = 0;
            String url = "";

            try
            {
                url = main_video_lists[main_video_count];
            }

            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);

                Debug.WriteLine(ex.Message + ex.StackTrace);
             
            }

            url_replace(url);
            lbl_Listsize.Text = main_video_count.ToString() + "/" + main_video_lists.Count().ToString();
            if (ListSlider.Maximum >= main_video_count)
            {
                ListSlider.Value = main_video_count;
            }
        }
        public void half_movie()
        {

            Double count_d = main_video_lists.Count/2;
            main_video_count = (int)Math.Round(count_d);
            String url = "";

            try
            {
                url = main_video_lists[main_video_count];
            }

            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);

                Debug.WriteLine(ex.Message + ex.StackTrace);
                
            }

            url_replace(url);
            lbl_Listsize.Text = main_video_count.ToString() + "/" + main_video_lists.Count().ToString();
            if (ListSlider.Maximum >= main_video_count)
            {
                ListSlider.Value = main_video_count;
            }
        }

        public void randam_movie()
        {

            int ran_saidai = main_video_lists.Count;
            Random rnd = new Random();    // Randomオブジェクトの作成
            main_video_count = rnd.Next(0, ran_saidai);  //1以上10未満の値がランダムに出deo_count = 0;

            String url = "";

            try
            {
                url = main_video_lists[main_video_count];
            }

            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);

                Debug.WriteLine(ex.Message + ex.StackTrace);
                
            }

            url_replace(url);
            lbl_Listsize.Text = main_video_count.ToString() + "/" + main_video_lists.Count().ToString();
            if (ListSlider.Maximum >= main_video_count)
            {
                ListSlider.Value = main_video_count;
            }
        }
        public void next_movie()
        {

            if (main_video_lists.Count <= 1)
            {

                return;
            }

            main_video_count = main_video_count + 1;



            if (main_video_lists.Count < main_video_count)
            {
                main_video_count = 0;
            }
            String url = "";

            try
            {
                url = main_video_lists[main_video_count];
                currentFilePath = url;
            }

            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);

                Debug.WriteLine(ex.Message + ex.StackTrace);
                
            }
            if (System.Text.RegularExpressions.Regex.IsMatch(url, config_class.config_text_read("streamlinkで取得するURLの正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase))
            {
                return;
            }
            else
            {

                url_replace(url);
            }

            lbl_Listsize.Text = main_video_count.ToString() + "/" + main_video_lists.Count().ToString();
            if (ListSlider.Maximum >= main_video_count)
            {
                ListSlider.Value = main_video_count;
            }
        }
        public void prev_movie()
        {
            if (main_video_lists.Count == 1)
            {

                return;
            }
            main_video_count = main_video_count - 1;
            if (main_video_count < 0)
            {
                main_video_count = main_video_lists.Count;
            }
            String url = "";

            try
            {
                url = main_video_lists[main_video_count];
                currentFilePath = url;
            }

            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);

                Debug.WriteLine(ex.Message + ex.StackTrace);
                
            }

            if (System.Text.RegularExpressions.Regex.IsMatch(url, config_class.config_text_read("streamlinkで取得するURLの正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase))
            {
                return;
            }
            else
            {

                url_replace(url);
            }
            lbl_Listsize.Text = main_video_count.ToString() + "/" + main_video_lists.Count().ToString();
            if (ListSlider.Maximum >= main_video_count)
            {
                ListSlider.Value = main_video_count;
            }
        }
        public void delete()
        {
            if (string.IsNullOrEmpty(currentFilePath))
            {
                return;
            }

            if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, "https?:", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
            {

                return;

            }
            
            if (System.IO.File.Exists(currentFilePath) == false)
            {
                return;
            }
          


            if (config_class.config_bool_read("削除機能を有効") == true)
            {
                if (config_class.config_bool_read("削除で確認する") == true)
                {     //メッセージボックスを表示する
                    DialogResult result = MessageBox.Show(currentFilePath + "を削除しますか？",
                "質問",
                MessageBoxButtons.YesNoCancel,
                MessageBoxIcon.Exclamation,
                MessageBoxDefaultButton.Button2);

                    //何が選択されたか調べる
                    if (result == DialogResult.Yes)
                    {
                        StopMpv();
                        try
                        {
                            Microsoft.VisualBasic.FileIO.FileSystem.DeleteFile(
                        currentFilePath,
                        UIOption.AllDialogs,
                        RecycleOption.SendToRecycleBin,
                        UICancelOption.DoNothing
                        );
                            this.Text = currentFilePath + "を削除しました。";
                        }
                        catch (System.Exception ex)
                        {
                            error.write_error_log(ex.Message + ex.StackTrace);

                            Debug.WriteLine(ex.Message);

                        }
                    }
                    else if (result == DialogResult.No)
                    {
                        //「いいえ」が選択された時
                        this.Text = currentFilePath + "削除をキャンセルしました";
                    }
                    else if (result == DialogResult.Cancel)
                    {
                        //「キャンセル」が選択された時
                        this.Text = currentFilePath + "削除をキャンセルしました";
                    }
                    return;
                }
                else
                {

                    StopMpv();
                    try
                    {
                        Microsoft.VisualBasic.FileIO.FileSystem.DeleteFile(
                             currentFilePath,
                             UIOption.AllDialogs,
                             RecycleOption.SendToRecycleBin,
                             UICancelOption.DoNothing
                             );
                        this.Text = currentFilePath + "を削除しました。";
                    }
                    catch (System.Exception ex)
                    {
                        error.write_error_log(ex.Message + ex.StackTrace);

                        Debug.WriteLine(ex.Message);

                    }
                }
            }
           
               



           



        }
        private void Audio_Click(object sender, EventArgs e)
        {
            if (sender is ToolStripMenuItem item && item.Tag is int id)
            {
                _myplayer.Set_mutli_audio(id);

            }
        }
        private void Sub_Click(object sender, EventArgs e)
        {
            if (sender is ToolStripMenuItem item && item.Tag is int id)
            {
                if (id == -1)
                {

                    _myplayer.Set_mutli_sub_no();

                }
                else
                {

                    _myplayer.Set_mutli_sub(id);

                }
            }
        }
        private void UpdateTrackMenu(List<MpvTrack> tracks)
        {

            capter_menuStrip.Items.Remove(menuAudio);
            capter_menuStrip.Items.Remove(menuSub);


            menuAudio = new ToolStripMenuItem("音声");
            menuSub = new ToolStripMenuItem("字幕");

            var audioTracks = tracks.Where(t => t.type == "audio").ToList();
            var subTracks = tracks.Where(t => t.type == "sub").ToList();

            // --- 音声 ---
            menuAudio.DropDownItems.Clear();

            foreach (var t in audioTracks)
            {
                var item = new ToolStripMenuItem(t.DisplayName);
                item.Tag = t.id;
                item.Click += Audio_Click;

                menuAudio.DropDownItems.Add(item);
            }

            // --- 字幕 ---
            menuSub.DropDownItems.Clear();

            // OFF
            var offItem = new ToolStripMenuItem("OFF");
            offItem.Tag = -1;
            offItem.Click += Sub_Click;
            menuSub.DropDownItems.Add(offItem);

            foreach (var t in subTracks)
            {
                var item = new ToolStripMenuItem(t.DisplayName);
                item.Tag = t.id;
                item.Click += Sub_Click;

                menuSub.DropDownItems.Add(item);
            }


            capter_menuStrip.Items.Add(menuAudio);
            capter_menuStrip.Items.Add(menuSub);




            this.Controls.Add(capter_menuStrip);
        }

        public void FrameStep()
        {

            _myplayer.FrameStep();
        }
        public void FrameBackStep()
        {

            _myplayer.FrameBackStep();
        }
        private void ZoomUp()
        {
            _myplayer.ZoomUp();
        }

        private void ZoomDown()
        {
            _myplayer.ZoomDown();
        }
        private void ZoomNormal()
        {
            _myplayer.ZoomNormal();
        }
        private void pan_x_plus()
        {
            _myplayer.pan_x_plus();
        }
        private void pan_x_minus()
        {
            _myplayer.pan_x_minus();
        }
        private void pan_y_plus()
        {
            _myplayer.pan_y_plus();
        }
        private void pan_y_minus()
        {
            _myplayer.pan_y_minus();
        }

        public void video_crop(String crop)
        {
            _myplayer.Video.video_crop(crop);
        }
        private void sub_srt_zoom()
        {

            // 減算
            _subsize = _subsize + 0.05;

            if (_subsize > 5)
                _subsize = 8.0;


            _myplayer.sub_srt_zoom(_subsize);
        }
        public void PositionSlider_MouseDown(object sender, MouseEventArgs e)
        {

            _pos_slidr_isDragging = true;

            //// ★ クリック位置で即ジャンプ（WPFと同じ挙動）
            SetSliderValueFromMouse(e.X);
        }
        private void sub_srt_zoom_out()
        {
            // 減算
            _subsize = _subsize - 0.05;

            // 下限ガード（重要）
            if (_subsize < 0.3)
                _subsize = 0.3;


            _myplayer.sub_srt_zoom(_subsize);
        }
        private void sub_pos_y_plus()
        {

            // 減算
            _sub_pos_y = _sub_pos_y + 1;

            if (_sub_pos_y > 100)
                _sub_pos_y = 100;


            _myplayer.sub_pos_y(_sub_pos_y);

        }
        private void sub_pos_y_minus()
        {

            // 減算
            _sub_pos_y = _sub_pos_y - 1;

            if (_sub_pos_y < 0)
                _sub_pos_y = 0;


            _myplayer.sub_pos_y(_sub_pos_y);

        }




        private void Form1_KeyDown(object sender, KeyEventArgs e)

        {
           
            if (_isVr360Mode)
            {
               

                    if (e.Control)
                    {

                        switch (e.KeyCode)
                        {
                            case Keys.NumPad8: // 上
                                pitch_360 += step_360;
                                vr360Dirty = true;
                                break;
                            case Keys.Z:
                                // 正面
                                yaw_360 = 0;
                                pitch_360 = 0;
                                vr360Dirty = true;
                                break;

                            case Keys.X:
                                // 右
                                yaw_360 = 90;
                                vr360Dirty = true;
                                break;

                            case Keys.C:
                                // 後ろ
                                yaw_360 = 180;
                                vr360Dirty = true;
                                break;
                            case Keys.V:
                                // 左
                                yaw_360 = -90;
                                vr360Dirty = true;
                                break;
                            case Keys.NumPad2: // 下

                                pitch_360 -= step_360;
                                vr360Dirty = true;
                                break;

                            case Keys.NumPad4: // 左
                                yaw_360 -= step_360;
                                vr360Dirty = true;
                                break;

                            case Keys.NumPad6: // 右
                                yaw_360 += step_360;
                                vr360Dirty = true;
                                break;
                            case Keys.Add:
                                fov_360 -= 5; // ズームイン
                                vr360Dirty = true;
                                break;
                            case Keys.Subtract:
                                fov_360 += 5; // ズームアウト
                                vr360Dirty = true;
                                break;
                            case Keys.NumPad7: // 傾ける
                                roll_360 += 5;
                                vr360Dirty = true;
                                break;

                            case Keys.NumPad9: // 傾ける
                                roll_360 -= 5;
                                vr360Dirty = true;

                                break;
                        default:
                            break;
                    }
                    fov_360 = Math.Max(30, Math.Min(120, fov_360));

                    // 上下制限（ひっくり返り防止）
                    pitch_360 = Math.Max(-90, Math.Min(90, pitch_360));
                    roll_360 = Math.Max(-180, Math.Min(180, roll_360));


                }
                if (e.Alt)
                    {
                        switch (e.KeyCode)
                        {
                            case Keys.NumPad8:
                                // 上
                                pitch_360 = -90;
                                vr360Dirty = true;

                                break;

                            case Keys.NumPad2:
                                // 下
                                pitch_360 = 90;
                                vr360Dirty = true;
                                break;

                            case Keys.NumPad4:
                                // 左
                                yaw_360 = -90;

                                vr360Dirty = true;
                                break;

                            case Keys.NumPad6:
                                // 右
                                yaw_360 = 90;
                                vr360Dirty = true;
                                break;
                            case Keys.NumPad7:
                                // 後ろ
                                yaw_360 = 180;
                                vr360Dirty = true;
                                break;
                            case Keys.NumPad9:
                                // 正面
                                yaw_360 = 0;
                                pitch_360 = 0;
                                vr360Dirty = true;
                                break;
                        default:
                            break;
                    }
                    fov_360 = Math.Max(30, Math.Min(120, fov_360));

                    // 上下制限（ひっくり返り防止）
                    pitch_360 = Math.Max(-90, Math.Min(90, pitch_360));
                    roll_360 = Math.Max(-180, Math.Min(180, roll_360));


                }


            }
            if (!_isVr360Mode)
            {
                if (e.Control && e.KeyCode == Keys.Add)
                {
                    sub_srt_zoom();

                }


                if (e.Control && e.KeyCode == Keys.Subtract)
                {
                    sub_srt_zoom_out();

                }

                if (e.Control && e.KeyCode == Keys.NumPad8)
                {
                    sub_pos_y_minus();

                }
                if (e.Control && e.KeyCode == Keys.NumPad2)
                {
                    sub_pos_y_plus();

                }
            }
            if (e.KeyData == Keys.Delete)
            {
                delete();
            }
            if (e.KeyData == Keys.Subtract)
            {
                ZoomDown();
            }
            if (e.KeyData == Keys.NumPad6)
            {
                pan_x_plus();
            }
            if (e.KeyData == Keys.NumPad4)
            {
                pan_x_minus();
            }
            if (e.KeyData == Keys.NumPad8)
            {
                pan_y_minus();
            }
            if (e.KeyData == Keys.NumPad2)
            {
                pan_y_plus();
            }
            if (e.KeyData == Keys.NumPad5)
            {
                ZoomNormal();
            }
            if (e.KeyData == Keys.Add)
            {
                ZoomUp();
            }
            if (e.KeyData == Keys.Q)
            {
                ZoomNormal();
            }


            if (e.KeyData == Keys.Oemcomma)
            {
                if (!_frameBackStepTimer.Enabled)
                {

                    FrameBackStep(); // 1回目は即実行
                    _frameBackStepTimer.Start();
                }
            }
            if (e.KeyData == Keys.OemPeriod)
            {
                if (!_frameStepTimer.Enabled)
                {

                    FrameStep(); // 1回目は即実行
                    _frameStepTimer.Start();
                }
            }
            //ランダムな動画
            if (e.KeyData == Keys.R)
            {
                randam_movie();
            }

            if (e.KeyData == Keys.F)
            {
                ToggleFullScreen();


            }
            if (e.KeyData == Keys.I)
            {
                reboot();


            }
            //SPEED UP
            if (e.KeyData == Keys.K)
            {
                SpeedUp();
            }
            if (e.KeyData == Keys.J)
            {
                SpeedDown();


            }



            if (e.KeyData == Keys.L)
            {
                Speed_change(1.0);


            }

            if (e.KeyData == Keys.T)
            {
                audio_delay_down();


            }
            if (e.KeyData == Keys.Y)
            {
                audio_delay_up();


            }
         
            if (e.KeyData == Keys.Right)
            {
          
                NextSeek();
                return;

            }
            if (e.KeyData == Keys.Left)
            {

                PrevSeek();
                return;

            }
            if (e.KeyData == Keys.G)
            {
                list_type = list_type + 1;
                if (list_type >= 4)
                {
                    list_type = 0;

                }
                list_key();
                return;

            }
            if (e.KeyData == Keys.H)
            {
                list_type = list_type - 1;
                if (list_type < 0)
                {
                    list_type = 4;

                }
                list_key();


                return;

            }
            if (e.KeyData == Keys.PageUp)
            {

                next_movie();
                return;

            }
            if (e.KeyData == Keys.Home)
            {

                home_movie();
                return;

            }
            if (e.KeyData == Keys.End)
            {

                half_movie();
                return;

            }
            if (e.KeyData == Keys.PageDown)
            {

                prev_movie();
                return;

            }
            if (e.KeyData == Keys.A)
            {

                a_marker_creat();
                return;

            }
            if (e.KeyData == Keys.B)
            {

                b_marker_creat();
                return;

            }
            if (e.KeyData == Keys.N)
            {

                ab_loop_start();
                return;

            }
            if (e.KeyData == Keys.O)
            {
                sub_delay_down();
                return;

            }

            if (e.KeyData == Keys.P)
            {
                sub_delay_up();

                return;

            }
        }
        private void sub_delay_up()
        {
            _myplayer.sub_delay_up();
        }
        private void sub_delay_down()
        {
            _myplayer.sub_delay_down();
        }
        private void Form_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.U)
            {
                _frameStepTimer.Stop();
            }
        }
        private void list_key()
        {
            if (list_type == 0)
            {
                list_folder();
            }
            if (list_type == 1)
            {
                list_db();
            }
            if (list_type == 2)
            {
                list_abema();
            }
            if (list_type == 3)
            {
                list_primehome();
            }


        }
      
        
        public void PlayerPanel_MouseMove(object sender, MouseEventArgs e)
        {
            if (!_isFullScreen) return;

            Point clientCursorPos = this.PointToClient(Cursor.Position);

            BottomControlPanel.Top = this.ClientSize.Height - BottomControlPanel.Height;

            // 判定
            if (clientCursorPos.Y >= BottomControlPanel.Top - 10)
            {
                if (!BottomControlPanel.Visible)
                {
                    BottomControlPanel.Visible = true;
                    BottomControlPanel.BringToFront();
                }
            }
            else
            {
                if (BottomControlPanel.Visible)
                {
                    BottomControlPanel.Visible = false;
                }
            }

            // ===== 上（追加） =====
            //if (clientCursorPos.Y <= 30) // 上から30px以内
            //{
            //    if (!TopMenuPanel.Visible)
            //    {
            //        TopMenuPanel.Visible = true;
            //        TopMenuPanel.BringToFront();
            //    }
            //}
            //else
            //{
            //    if (TopMenuPanel.Visible)
            //    {
            //        TopMenuPanel.Visible = false;
            //    }
            //}
        }

        public void PlayerPanel_DoubleClick(object sender, EventArgs e)
        {


            if (config_class.config_bool_read("ダブルクリックでフルスクリーン有効") == true)
            {
                ToggleFullScreen();
            }
        }
        public void ToggleFullScreen()
        {
            if (!_isFullScreen)
            {
                _mainLayout.RowStyles[0].Height = 0; // MenuStripの行を詰める
                _mainLayout.RowStyles[2].Height = 0; // コントロールの行を詰める
                _prevBorderStyle = this.FormBorderStyle;
                _prevWindowState = this.WindowState;

                // 一旦レイアウトから外してForm直下に追加
                _mainLayout.Controls.Remove(BottomControlPanel);
                this.Controls.Add(BottomControlPanel);

                // 先にフォームをフルスクリーンにする（サイズを確定させる）
                this.FormBorderStyle = FormBorderStyle.None;
                this.WindowState = FormWindowState.Maximized;

                // フルスクリーン化後の「実際のサイズ」を使って位置を決める
                BottomControlPanel.Dock = DockStyle.None;
                BottomControlPanel.Width = this.DisplayRectangle.Width; // ClientSizeより確実
                                                                        // BottomControlPanel.Height = 130;
                BottomControlPanel.Left = 0;
                // 計算を「Formの高さ - パネルの高さ」に固定
                BottomControlPanel.Top = this.DisplayRectangle.Height - BottomControlPanel.Height;

                BottomControlPanel.Visible = false;
                BottomControlPanel.BringToFront();

                TopMenuPanel.Visible = false;
                _isFullScreen = true;
                capter_menuStrip.Visible = false;
            }
            else
            {
                _mainLayout.RowStyles[0].SizeType = SizeType.AutoSize;
                _mainLayout.RowStyles[2].SizeType = SizeType.AutoSize;
                this.FormBorderStyle = _prevBorderStyle;
                this.WindowState = _prevWindowState;

                this.Controls.Remove(BottomControlPanel);
                _mainLayout.Controls.Add(BottomControlPanel, 0, 2);
                BottomControlPanel.Dock = DockStyle.Fill;
                BottomControlPanel.Visible = true;

                TopMenuPanel.Visible = true;
                _isFullScreen = false;
                capter_menuStrip.Visible = true;


            }
        }

      

        public void PositionSlider_MouseMove(object sender, MouseEventArgs e)
        {

            if (!_pos_slidr_isDragging) return;

            SetSliderValueFromMouse(e.X);
        }
        private void SetSliderValueFromMouse(int mouseX)
        {
            double ratio = (double)mouseX / PositionSlider.Width;

            ratio = Math.Max(0, Math.Min(1, ratio));

            int newValue = (int)(PositionSlider.Minimum +
                (PositionSlider.Maximum - PositionSlider.Minimum) * ratio);


            PositionSlider.Value = newValue;
        }
        public void PositionSlider_MouseUp(object sender, MouseEventArgs e)
        {


            _pos_slidr_isDragging = false;

            double seconds = PositionSlider.Value;
            _myplayer.Seek(seconds);
        }



        public void ListSlider_MouseDown(object sender, MouseEventArgs e)
        {

            _list_slidr_isDragging = true;

            //// ★ クリック位置で即ジャンプ（WPFと同じ挙動）
            SetListValueFromMouse(e.X);
        }

        public void ListSlider_MouseMove(object sender, MouseEventArgs e)
        {
            if (!_list_slidr_isDragging) return;

            SetSliderValueFromMouse(e.X);
        }
        private void SetListValueFromMouse(int mouseX)
        {
            double ratio = (double)mouseX / ListSlider.Width;

            ratio = Math.Max(0, Math.Min(1, ratio));

            int newValue = (int)(ListSlider.Minimum +
                (ListSlider.Maximum - ListSlider.Minimum) * ratio);

            if (ListSlider.Maximum >= main_video_count)
            {
                ListSlider.Value = newValue;
            }
            lbl_Listsize.Text = newValue.ToString() + "/" + main_video_lists.Count().ToString();

        }
        public void ListSlider_MouseUp(object sender, MouseEventArgs e)
        {

            _list_slidr_isDragging = false;

            int Value = ListSlider.Value;
            main_video_count = Value;
            if (Value >= 0 && Value < main_video_lists.Count)
            {
                string url = main_video_lists[Value];

                if (System.Text.RegularExpressions.Regex.IsMatch(url, config_class.config_text_read("streamlinkで取得するURLの正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                {
                    return;
                }
                else
                {

                    url_replace(url);
                }
            }

        }
        private void url_replace(String url)
        {
            nokori_jikan = 1;


            if (string.IsNullOrEmpty(url))
            {
                return;
            }

            //if (System.Text.RegularExpressions.Regex.IsMatch(url, "https?:", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
            //{
            //    if (System.Text.RegularExpressions.Regex.IsMatch(url, config_class.config_text_read("streamlinkで取得するURLの正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase)||
            //   System.Text.RegularExpressions.Regex.IsMatch(url, @"linear\-abematv.akamaized.net", System.Text.RegularExpressions.RegexOptions.IgnoreCase))             {
            //    }
            //    else
            //    {
            //        loadingGif.Visible = true;

            //    }


            //}
            currentFilePath = url;
            _videoState.Full_path = url;
            Double db_time = 0;

            if (_myplayer.IsMpvRunning)
            {

                _myplayer.url_replace(url, db_time);
            }
            else
            {
                StartMpv(url);

            }

        }
        public void DVD_Play()
        {
            StartMpv("dvd://");

        }
        public void Blueray_Play()
        {
            StartMpv("bd://");

        }
        public void open_mp4_folder()
        {
            if (string.IsNullOrEmpty(currentFilePath) == false)
            {
                String dir_path = "";
                try
                {
                    dir_path = System.IO.Path.GetDirectoryName(currentFilePath);
                    if (System.IO.Directory.Exists(currentFilePath) == false)
                   {
                    Process.Start(new ProcessStartInfo
                    {
                        FileName = dir_path,
                        UseShellExecute = true
                    });
                }


                       }
                catch (System.Exception ex)
                {
                  

                }
            }

        }

        public void a_marker_creat()
        {
           
                _myplayer.show_text("A地点を作成");
           
            _a_maker = _timePos;

        }
        public void b_marker_creat()
        {
            _myplayer.show_text("B地点を作成");
            _b_maker = _timePos;

        }
        private void a_b_LoopTimer_Tick(object sender, EventArgs e)
        {
            if (!_a_b_isLooping) return;

            double current = _timePos;

            if (current >= _b_maker)
            {
                _myplayer.Seek(_a_maker);
            }
        }
        public void ab_loop_start()
        {
            _myplayer.show_text("A-Bループ開始");
            if (_a_maker >= 0 && _b_maker > _a_maker)
            {
                _a_b_isLooping = true;

                // 最初にAへジャンプ
                _myplayer.Seek(_a_maker);

                _a_b_loopTimer.Start();

            }
        }
       

      
      
       
        public void mute_func()
        {

           _myplayer.ToggleMute();

        }
        public void audio_delay_up()
        {
         
            _myplayer.audio_delay_up();

        }
        public void audio_delay_down()
        {
            _myplayer.audio_delay_down();

        }
       
        public void ss_func()
        {

            _myplayer.Screenshot();

        }
        public void button_SaveSubtitleDelay_Click()
        {
            if (System.IO.File.Exists(currentFilePath))
            {
                String currentSubtitlePath = Path.ChangeExtension(currentFilePath, ".srt");
                SrtTimeShifter.ApplySubDelayToSrt(currentSubtitlePath, _currentSubDelay);
            }
        }

        public void record_url()
        {
            if (System.IO.File.Exists(currentFilePath))
            {
                return;
            }
            if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, "https?:", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
            {


                if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, config_class.config_text_read("streamlinkで取得するURLの正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                {
                    string date_st = DateTime.Now.ToString("yyyy年M月d日HH時mm分");
                    _title = filename.FileName_repalce(_title);
                    Download_class.DownloadStream(currentFilePath, _title + "_" + date_st + ".mp4");
                }
                else
                {
                    if (Regex.IsMatch(currentFilePath, @"\.m3u8?(\?|$)", RegexOptions.IgnoreCase))
                    {
                        string date_st = DateTime.Now.ToString("yyyy年M月d日HH時mm分");
                        _title = filename.FileName_repalce(_title);
                        Download_class.Download_Ytdlp_nopart(currentFilePath, _title + "_" + date_st + ".mp4");
                    }
                    else
                    {
                        Download_class.Download_Ytdlp(currentFilePath);
                    }
                }

            }

        }
        public void StopMpv()
        {
            _a_b_isLooping = false;

            if (config_class.config_bool_read("ボリュームを保存する") == true)
            {
                int currentVol = volume_Slider.Value;
                config_class.save_config_file("ボリューム数", currentVol.ToString());

            }
            config_class.save_config_file("ミュート", bool_to_text.to_st(_mute_bool));

            if (config_class.config_bool_read("起動時SPEED変更") == true)
            {
                config_class.save_config_file("起動時SPEED数", _currentSpeed.ToString());

            }



            // loadingGif.Visible = false;

            _myplayer.StopMpv(currentFilePath);
            if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, config_class.config_text_read("streamlinkで取得するURLの正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase) ||
                System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"\.m3u8?(\?|$)", RegexOptions.IgnoreCase))
            {
            }
            else
            {
                if (config_class.config_bool_read("レジューム機能") == true ||
                    config_class.config_bool_read("再生時にDB更新を有効") == true)
                {
                    Debug.WriteLine("レジューム保存");
                    //レジューム保存

                    sql_class.time_update(currentFilePath, _timePos);
                }
            }

        }
        private async void trackBarSpeed_Scroll(object sender, EventArgs e)
        {
            if (_myplayer == null || !_myplayer.IsMpvRunning)
                return;
            double speed = Speed_Slider.Value / 10.0;

            Speed_change(speed);

            speed_label.Text = speed.ToString();

        }
        private void trackBarVolume_Scroll(object sender, EventArgs e)
        {
            if (_myplayer == null || !_myplayer.IsMpvRunning)
                return;

            String vol_st = volume_Slider.Value.ToString();
            volume_label.Text = vol_st;
            if (int.TryParse(vol_st, out int vol_int))
            {
                _volume = vol_int;
                _myplayer.VolumeChange(vol_int);
            }
        }
        private void Form1_MouseWheel(object sender, MouseEventArgs e)
        {
            // Delta はホイールが1回カチッっとなると、+120/-120という値になる。
            // よって、120で割ってあげれば解りやすい値になる。

            if (config_class.config_bool_read("マウスホイール") == true)
            {
                int wheel_int = (e.Delta / 120);
                if (wheel_int == 1)
                {
                    if (config_class.config_int_read("マウスホイールの動作") == 1)
                    {

                        next_movie();
                    }
                    if (config_class.config_int_read("マウスホイールの動作") == 2)
                    {

                        NextSeek();
                    }
                    if (config_class.config_int_read("マウスホイールの動作") == 3)
                    {
                        VolumeUp();
                    }
                    if (config_class.config_int_read("マウスホイールの動作") == 4)
                    {
                        ZoomUp();
                    }
                    if (config_class.config_int_read("マウスホイールの動作") == 5)
                    {
                        SpeedUp();
                    }
                }
                if (wheel_int == -1)
                {
                    if (config_class.config_int_read("マウスホイールの動作") == 1)
                    {

                        prev_movie();
                    }
                    if (config_class.config_int_read("マウスホイールの動作") == 2)
                    {

                        PrevSeek();
                    }
                    if (config_class.config_int_read("マウスホイールの動作") == 3)
                    {
                        VolumeDown();
                    }
                    if (config_class.config_int_read("マウスホイールの動作") == 4)
                    {
                        ZoomDown();
                    }
                    if (config_class.config_int_read("マウスホイールの動作") == 4)
                    {
                        SpeedDown();
                    }
                }
            }
        }

        private void VolumeUp()
        {

            if (volume_Slider.Value <= volume_Slider.Maximum)
            {
                _myplayer.VolumeUp();
                volume_Slider.Value += 5;
            }

        }

        private void VolumeDown()
        {
            if (volume_Slider.Value > 0)
            {
                _myplayer.VolumeDown();
                volume_Slider.Value -= 5;
            }

        }
        public void ver_mes_bosx()
        {
            Version ins = new Version();

            ins.Show();

        }


        public async void StartMpv(string pathOrUrl)
        {
            String mpv_path = config_class.config_text_read("mpvのパス");
            if (!string.IsNullOrWhiteSpace(mpv_path))
            {

            }
            else
            {


                MessageBox.Show("mpvのパスの設定が空です。");
                return;
            }

            if (System.IO.File.Exists(mpv_path))
            {

            }
            else
            {
                MessageBox.Show(mpv_path + ":mpv.exeが無いです。");
                return;


            }
           
                String ytdlp_path = config_class.config_text_read("yt-dlpのパス");
                if (!string.IsNullOrWhiteSpace(ytdlp_path))
                {

                   
            }
            else
            {
                MessageBox.Show("yt-dlpのパスの設定が空です。");
                return;
            }

                if (System.IO.File.Exists(ytdlp_path))
                {

                }
                else
                {
                    MessageBox.Show(ytdlp_path + ":yt-dlp.exeが無いです。");
                    return;


                }
            String add_comand = "";
            if (config_class.config_bool_read("mpvの追加起動コマンドを有効") == true)
            {
                if (string.IsNullOrEmpty(config_class.config_text_read("mpvの追加起動コマンド")) == false)
                {
                    add_comand = config_class.config_text_read("mpvの追加起動コマンド");
                }



            }
                String force_window = "";

            if (config_class.config_bool_read("force-window=yesを起動引数に入れる") == true)
            {
                force_window = " --force-window=yes";
            }
            String idle_yes = "";
            if (config_class.config_bool_read("idle=yesを起動引数に入れる") == true)
            {
                idle_yes = " --idle=yes";
            }

            nokori_jikan = 1;
            if (string.IsNullOrEmpty(pathOrUrl))
            {
                return;
            }
            string PipeName = "mpv-pipe-" + Guid.NewGuid().ToString("N");
            _videoState.Full_path = pathOrUrl;
            currentFilePath = pathOrUrl;


            if (InvokeRequired)
            {
                Invoke(new Action(() => StartMpv(pathOrUrl)));
                return;
            }

            StopMpv();





         
            String mpv_log_text = "";
            if (config_class.config_bool_read("mpvのログを有効") == true)
            {

                mpv_log_text = " --log-file=mpv_log.txt --msg-level=all=debug";


            }
            String thread_text = "";
            if (config_class.config_bool_read("スレッド有効") == true)
            {
                if (string.IsNullOrEmpty(config_class.config_text_read("スレッド数")) == false)
                {
                    thread_text = " --vd-lavc-threads=" + config_class.config_text_read("スレッド数");

                }
            }
            String cache_text = "";
            if (config_class.config_bool_read("キャッシュを有効") == true)
            {   //--cache-pause=yes --cache-pause-initial=yes
                cache_text = " --cache=yes";
                if (string.IsNullOrEmpty(config_class.config_text_read("キャッシュサイズ")) == false)
                {
                    cache_text = cache_text + " --demuxer-max-bytes=" + config_class.config_text_read("キャッシュサイズ") + "M";

                }
                if (string.IsNullOrEmpty(config_class.config_text_read("キャッシュ時間")) == false)
                {
                    cache_text = cache_text + " --cache-secs=" + config_class.config_text_read("キャッシュ時間");


                }
                if (config_class.config_bool_read("キャッシュが溜まるまで待つ") == true)
                {
                    cache_text = cache_text + " --cache-pause=yes --cache-pause-initial=yes";

                }

            }



            string videoEq = "";
            if (config_class.config_bool_read("ビデオイコライザーを保存") == true)
            {

                if (string.IsNullOrEmpty(config_class.config_text_read("video_setting")) == false)
                {

                    try
                    {
                        string[] elements = config_class.config_text_read("video_setting").Split(',', StringSplitOptions.RemoveEmptyEntries);

                        videoEq =
         $" --brightness={elements[0]} " +
         $"--contrast={elements[1]} " +
         $"--gamma={elements[2]} " +
         $"--saturation={elements[3]} " +
         $"--hue={elements[4]}";
                    }
                    catch (System.Exception ex)
                    {

                        Debug.WriteLine(ex.Message + ex.StackTrace);



                    }
                }
            }
            Debug.WriteLine("@@" + videoEq);

            String srt_sub = "";
            if (config_class.config_bool_read("SRT字幕の設定を有効") == true)
            {
               if(string.IsNullOrEmpty(config_class.config_text_read("字幕のフォントサイズ")) == false)
            {
                    srt_sub = srt_sub+ $" --sub-font-size={config_class.config_text_read("字幕のフォントサイズ")}";
                }
                if (string.IsNullOrEmpty(config_class.config_text_read("字幕のフォント名")) == false)
                {
                    srt_sub = srt_sub + $" --sub-font=\"{config_class.config_text_read("字幕のフォント名")}\"";
                }
                if (string.IsNullOrEmpty(config_class.config_text_read("字幕のフォントカラー")) == false)
                {
                    srt_sub = srt_sub + $" --sub-color={config_class.config_text_read("字幕のフォントカラー")}";
                }
                if (string.IsNullOrEmpty(config_class.config_text_read("字幕の枠の大きさ")) == false)
                {
                    srt_sub = srt_sub + $" --sub-border-size={config_class.config_text_read("字幕の枠の大きさ")}";
                }
                if (string.IsNullOrEmpty(config_class.config_text_read("字幕の枠の色")) == false)
                {
                    srt_sub = srt_sub + $" --sub-border-color={config_class.config_text_read("字幕の枠の色")}";
                }
                if (string.IsNullOrEmpty(config_class.config_text_read("字幕の影のオフセット")) == false)
                {
                    srt_sub = srt_sub + $" --sub-shadow-offset={config_class.config_text_read("字幕の影のオフセット")}";
                }
                if (string.IsNullOrEmpty(config_class.config_text_read("字幕の縦位置")) == false)
                {
                    srt_sub = srt_sub + $" --sub-pos={config_class.config_text_read("字幕の縦位置")}";
                }
            }
            Debug.WriteLine("字幕；；："+srt_sub);
                String hwdec_text = "";
            if (config_class.config_bool_read("hwdecを有効") == true &&
                string.IsNullOrEmpty(config_class.config_text_read("hwdecの値")) == false)
            {
                hwdec_text = $" --hwdec={config_class.config_text_read("hwdecの値")}";
            }

            String gpuapi_text = "";
            if (config_class.config_bool_read("gpu-apiを有効") == true &&
                string.IsNullOrEmpty(config_class.config_text_read("gpu-apiの値")) == false)
            {
                gpuapi_text = $" --gpu-api={config_class.config_text_read("gpu-apiの値")}";
            }

            String scale_text = "";
            if (config_class.config_bool_read("scaleを有効") == true &&
                string.IsNullOrEmpty(config_class.config_text_read("scaleの値")) == false)
            {
                scale_text = $" --scale={config_class.config_text_read("scaleの値")}";
            }

            String interpolation_text = "";
            if (config_class.config_bool_read("interpolationを有効") == true &&
                string.IsNullOrEmpty(config_class.config_text_read("interpolationの値")) == false)
            {
                interpolation_text = $" --interpolation={config_class.config_text_read("interpolationの値")}";
            }

            String vo_text = "";
            if (config_class.config_bool_read("voを有効") == true)
            {
                vo_text = $" --vo={config_class.config_text_read("voの値")}";
            }

            String glsl_text = "";
            if (config_class.config_bool_read("glslを有効") == true &&
                string.IsNullOrEmpty(config_class.config_text_read("glslのパス")) == false)
            {
                glsl_text = " --glsl-shader=\"" + config_class.config_text_read("glslのパス") + "\"";

            }



            String pipe_Arguments = $" --input-ipc-server=\\\\.\\pipe\\{PipeName}";
            String Arguments = $"{force_window}{idle_yes}{cache_text}{thread_text}{glsl_text}{hwdec_text}{gpuapi_text}{scale_text}{interpolation_text}{vo_text}{videoEq}{mpv_log_text}{srt_sub}{add_comand}";



            if (System.Text.RegularExpressions.Regex.IsMatch(pathOrUrl, config_class.config_text_read("streamlinkで取得するURLの正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase))
            {

                String steam_path = config_class.config_text_read("streamlinkのパス");
                if (!string.IsNullOrWhiteSpace(steam_path))
                {

                   
                }
                else
                {
                    MessageBox.Show("streamlinkのパスの設定が空です。");
                    return;
                }

                if (System.IO.File.Exists(steam_path))
                {

                }
                else
                {
                    MessageBox.Show(steam_path + ":streamlink.exeが無いです。");
                    return;


                }
                await Task.Run(() =>
                         _myplayer.StartStream(pathOrUrl, Arguments, pipe_Arguments, PipeName,mpv_path, steam_path)
                 );

                return;
            }
            else
            {
                //if (System.Text.RegularExpressions.Regex.IsMatch(pathOrUrl, "https?:", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                //{


                //    if (System.Text.RegularExpressions.Regex.IsMatch(pathOrUrl, config_class.config_text_read("streamlinkで取得するURLの正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase) ||
                //   System.Text.RegularExpressions.Regex.IsMatch(pathOrUrl, @"linear\-abematv.akamaized.net", System.Text.RegularExpressions.RegexOptions.IgnoreCase)){        
                //    }
                //    else
                //    {
                //        loadingGif.Visible = true;

                //    }

                //}


                await Task.Run(() =>
                   _myplayer.StartMpv(pathOrUrl, Arguments, pipe_Arguments, PipeName,mpv_path, ytdlp_path)

                );

            }





            lblFilesize.Text = GetFileSize(pathOrUrl);




        }



        private void UpdateChapterMenu(List<MpvChapter> chapters)
        {
            // ① 一旦チャプターメニュー削除
            if (menuChapters != null)
            {
                capter_menuStrip.Items.Remove(menuChapters);
            }

            // ② チャプター無いなら何も表示しない
            if (chapters == null || chapters.Count == 0)
            {
                return;
            }

            menuChapters = new ToolStripMenuItem("チャプター");


            for (int i = 0; i < chapters.Count; i++)
            {
                var ch = chapters[i];

                var item = new ToolStripMenuItem(ch.Display);
                item.Tag = i;
                item.Click += Chapter_Click;

                menuChapters.DropDownItems.Add(item);
            }
            capter_menuStrip.Items.Add(menuChapters);
            this.Controls.Add(capter_menuStrip);
        }
        private void Chapter_Click(object sender, EventArgs e)
        {
            if (sender is ToolStripMenuItem item && item.Tag is int index)
            {
                _myplayer.ChangeChapter(index);

            }
        }
        private void HandleMpvMessage(string json)
        {


            if (string.IsNullOrWhiteSpace(json))
                return;

            json = json.Trim();

            // JSON で始まっていない行はログなので無視
            if (!json.StartsWith("{") && !json.StartsWith("["))
                return;


            JObject obj = null;
            try
            {

                obj = JObject.Parse(json);
            }
            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);
                Debug.WriteLine(ex.Message + ex.StackTrace);
                return;
            }
            if (obj == null)
                return;




            string evt = (string)obj["event"];

            switch (evt)
            {
                case "file-loaded":

                    Debug.WriteLine("file-loaded");
                    if (config_class.config_bool_read("起動時にパンスキャン") == true)
                    {

                        _myplayer.Video.panscan_delay();
                    }
                    Debug.WriteLine("file-loaded");
               
                    if (config_class.config_bool_read("オーディオイコライザーを保存") == true)
                    {
                        string audio_eq_filter = "";
                        if (config_class.config_bool_read("オーディオイコライザーを保存") == true)
                        {
                            if (string.IsNullOrEmpty(config_class.config_text_read("オーディオイコライザーの値")) == false)
                            {
                                string eqText = config_class.config_text_read("オーディオイコライザーを保存");
                                try
                                {
                                    double[] eq = eqText
                                        .Split(',')
                                        .Select(s => double.Parse(s, CultureInfo.InvariantCulture))
                                        .ToArray();

                                    int[] freq = { 31, 62, 125, 250, 500, 1000, 2000, 4000, 8000, 16000 };

                                    var filters = new List<string>();

                                    for (int i = 0; i < 10; i++)
                                    {
                                        filters.Add($"equalizer=f={freq[i]}:g={eq[i].ToString(System.Globalization.CultureInfo.InvariantCulture)}");
                                    }

                                    audio_eq_filter = "lavfi=[" + string.Join(",", filters) + "]";

                                }
                                catch (System.Exception ex)
                                {
                                    Debug.WriteLine(ex.Message + ex.StackTrace);



                                }
                            }
                        }
                        if (
                                              string.IsNullOrEmpty(audio_eq_filter) == false)
                        {

                            _myplayer.Audio.audio_Equalizer_start(config_class.config_text_read("オーディオエフェクトの値"));

                        }
                    }

                    if (config_class.config_bool_read("速度変更しても音程を維持する") == true)
                    {
                        _myplayer.audio_pitch_correction();
                    }
                    if (config_class.config_bool_read("ビデオエフェクトを保存") == true &&
                        string.IsNullOrEmpty(config_class.config_text_read("ビデオエフェクトの値")) == false)
                    {
                        _myplayer.Video.video_lavfi_start(config_class.config_text_read("ビデオエフェクトの値"));
                    }

                    if (config_class.config_bool_read("オーディオエフェクトを保存") == true &&
                        string.IsNullOrEmpty(config_class.config_text_read("オーディオエフェクトの値")) == false)
                    {
                        _myplayer.Audio.audio_lavfi_start(config_class.config_text_read("オーディオエフェクトの値"));


                    }
                    if (config_class.config_bool_read("起動時に360度VRモード有効") == true) {
                        vr_360mode();
                    }

                    if (config_class.config_bool_read("cropを起動時に実行") == true &&
                       string.IsNullOrEmpty(config_class.config_text_read("crop")) == false)
                    {
                        _myplayer.Video.video_crop(config_class.config_text_read("crop"));
                    }


                    if (Regex.IsMatch(currentFilePath, @"\.m3u8?(\?|$)", RegexOptions.IgnoreCase))
                    {
                    }
                    else
                    {
                        if (config_class.config_bool_read("起動時SPEED変更") == true)
                        {

                            var str = config_class.config_text_read("起動時SPEED数");



                            if (double.TryParse(str, out double speed))
                            {
                                _currentSpeed = speed;
                                Speed_change_no_osd(speed);

                            }
                        }

                    }


                    _myplayer.VolumeChange(_volume);

                    BeginInvoke(() =>
                    {
                        volume_label.Text = _volume.ToString();
                        volume_Slider.Value = _volume;
                    });



                    if (config_class.config_bool_read("ミュート") == true)
                    {
                        mute_func();
                    }

                    if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, config_class.config_text_read("streamlinkで取得するURLの正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase) ||
Regex.IsMatch(currentFilePath, @"\.m3u8?(\?|$)", RegexOptions.IgnoreCase))
                    {
                    }
                    else
                    {

                        if (config_class.config_bool_read("レジューム機能") == true ||
                            config_class.config_bool_read("再生時にDB更新を有効") == false)
                        {
                            double db_time = sql_class.sql_add(currentFilePath);
                            Debug.WriteLine("db_time:" + db_time);
                            if (config_class.config_bool_read("レジューム機能") == true &&
                        config_class.config_bool_read("再生開始時に途中から再生する") == false)
                            {
                                if (db_time > 0)
                                    _myplayer.Seek(db_time);
                            }
                        }
                    }
                    if (config_class.config_bool_read("再生開始時に途中から再生する") == true)
                    {
                        Debug.WriteLine("再生開始時に途中から再");
                        var str = config_class.config_text_read("開始する時間");



                        if (double.TryParse(str,
                            System.Globalization.NumberStyles.Float,
                            System.Globalization.CultureInfo.InvariantCulture,
                            out double minutes))
                        {
                            double seconds = minutes * 60;
                            _myplayer.Seek(seconds);

                        }

                    }



                    break;

                case "end-file":
                    if (nokori_jikan < 0.5)
                    {
                        BeginInvoke(() =>
                    {

                        OnVideoEnded();
                    });
                    }

                    break;


            }
            var dataToken = obj["data"];

            if (dataToken == null || dataToken.Type == JTokenType.Null)
                return;

            string name = obj["name"]?.ToString();

            switch (name)
            {
                case "time-remaining":

                    nokori_jikan = dataToken.Value<double>();

                    break;
                case "sub-delay":
                    _currentSubDelay = dataToken.Value<double>();
                    break;
                case "mute":
                  
                    _mute_bool = dataToken.Value<bool>();
                    config_class.save_config_file("ミュート", bool_to_text.to_st(_mute_bool));

                    break;
                case "volume":
                    
                    int vol = (int)Math.Round(dataToken.Value<double>());
                    _volume = vol;

                    BeginInvoke(() =>
                    {
                        vol = Math.Max(volume_Slider.Minimum,
                              Math.Min(volume_Slider.Maximum, vol));

                        volume_Slider.Value = vol;
                        volume_label.Text = vol.ToString();
                    });
                    break;

                case "width":
                    _videoWidth = dataToken.Value<double>();
                    _videoState.videoWidth = dataToken.Value<double>();
                    UpdateResolutionLabel();
                    break;
                case "chapter-list":
                    var chapters = JsonSerializer.Deserialize<List<MpvChapter>>(dataToken.ToString());


                    cap_size = chapters.Count;

                    if (config_class.config_bool_read("チャプターを上部メニューに表示") == true)
                    {
                        BeginInvoke(() =>
                    {
                        UpdateChapterMenu(chapters);
                    });
                    }
                    break;

                case "track-list":

                    var tracks = JsonSerializer.Deserialize<List<MpvTrack>>(dataToken.ToString());

                    BeginInvoke(() =>
                    {
                        if (config_class.config_bool_read("DVDの音声と字幕の自動選択を有効") == true)
                        {
                            if (config_class.config_int_read("DVDの自動選択設定") == 1)
                            {
                                AutoSelectJapaneseAudioAndSubtitle(tracks);
                            }
                            if (config_class.config_int_read("DVDの自動選択設定") == 2)
                            {
                                AutoSelectEnglishAudioAndSubtitle(tracks);
                            }
                        }
                        if (config_class.config_bool_read("字幕と音声選択メニューを表示") == true)
                        {
                            UpdateTrackMenu(tracks); // ← ここに
                        }

                    });




                    break;

                case "playlist":

                    // 重複防止用
                    HashSet<string> urlSet = new HashSet<string>(youtube_play_lists_url);

                    if (dataToken is JArray arr)
                    {
                        bool isReady = arr.Any(x => (bool?)x["playing"] == true);

                        if (!isReady)
                        {
                            // まだ途中なので無視
                            return;
                        }
                        youtube_play_lists_url.Clear();
                        youtube_play_lists_title.Clear();

                        foreach (var item in arr.OfType<JObject>())
                        {
                          
                            string filename = item["filename"]?.ToString();
                            string title = item["title"]?.ToString();
                           
                                if (string.IsNullOrWhiteSpace(filename))
                                continue;

                            // --- 現在再生中URLを除外 ---
                            if (string.Equals(filename, currentFilePath, StringComparison.OrdinalIgnoreCase))
                                continue;

                            // --- 重複除外 ---
                            if (!urlSet.Add(filename))
                                continue;
                            if (!Regex.IsMatch(filename, @"^https?://", RegexOptions.IgnoreCase))
                                continue;

                            if (string.Equals(filename, currentFilePath, StringComparison.OrdinalIgnoreCase))
                                continue;

                            if (!urlSet.Add(filename))
                                continue;
                            youtube_play_lists_url.Add(filename);
                            youtube_play_lists_title.Add(
                                string.IsNullOrWhiteSpace(title) ? filename : title
                            );
                        }
                    }

                    if (youtube_play_lists_url.Count > 1)
                    {
                        if (config_class.config_bool_read("プレイリストをメニューに表示") == true)
                        {

                            BeginInvoke(() =>
                        {
                            UpdatePlaylistMenu(youtube_play_lists_title, youtube_play_lists_url);
                        });
                        }
                    }

                    break;


                case "file-size":
                    _filesize = dataToken.Value<double>();
                    _videoState.filesize = dataToken.Value<double>();
                    UpdateResolutionLabel();
                    break;
              
                case "height":
                    _videoHeight = dataToken.Value<double>();
                    _videoState.videoHeight = dataToken.Value<double>();
                    UpdateResolutionLabel();
                    break;
                case "media-title":
                    _videoState.video_title = dataToken.ToString();

                    if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"rakutentvjapan", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                    {
                        BeginInvoke(() =>
                        {

                            this.Text = title_generate.GetName_rakuten(currentFilePath, 2);
                            lbl_title.Text = title_generate.GetName_rakuten(currentFilePath, 2);
                        });
                        break;
                    }
                    if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"utako.moe", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                    {
                        BeginInvoke(() =>
                        {
                            _title = title_generate.Get_UtakoMoe(currentFilePath);
                            this.Text = _title;
                            lbl_title.Text = _title;
                        });
                        break;
                    }
                    if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"arva.netgenx.site", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                    {
                        BeginInvoke(() =>
                        {
                            _title = title_generate.Get_arva_netgen(currentFilePath);
                            this.Text = _title;
                            lbl_title.Text = _title;
                        });
                        break;
                    }
                    if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"https://abema.tv/now-on-air/[\-_a-zA-Z0-9]+", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                    {
                        BeginInvoke(() =>
                        {
                            _title = title_generate.Get_abema(currentFilePath, 2);
                            this.Text = _title;
                            lbl_title.Text = _title;
                        });

                        break;
                    }
                    if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"https://linear-abematv.akamaized.net/preview/channel/[\-_a-zA-Z0-9]+/playlist.m3u8", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                    {
                        BeginInvoke(() =>
                        {
                            _title = title_generate.Get_abema(currentFilePath, 3);
                            this.Text = _title;
                            lbl_title.Text = _title;
                        });
                        break;
                    }
                    if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"(mov3.co|ok.ru)", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                    {
                        BeginInvoke(() =>
                        {
                            _title = title_generate.Get_mov3(currentFilePath);
                            this.Text = _title;
                            lbl_title.Text = _title;
                        });
                        break;
                    }
                    if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"cdns.jp-primehome.com", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                    {
                        BeginInvoke(() =>
                        {
                            _title = title_generate.Get_primehome(currentFilePath);
                            this.Text = _title;
                            lbl_title.Text = _title;
                        });
                        break;
                    }
                    if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"https://radiko.jp/#\!/live/", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                    {
                        BeginInvoke(() =>
                        {
                            _title = title_generate.GetRadikoStation(currentFilePath);
                            this.Text = _title;
                            lbl_title.Text = _title;
                        });
                        break;
                    }
                    BeginInvoke(() =>
                    {
                        this.Text = dataToken.ToString();   // ← フォームタイトルに設定
                        lbl_title.Text = dataToken.ToString();
                    });
                    break;





                case "video-codec":
                    _videoState.video_codec = dataToken.ToString();

                    break;

                case "audio-codec":

                    _videoState.audio_codec = dataToken.ToString();
                    break;

                case "video-bitrate":
                    _videoState.video_bitrate = dataToken.ToString(); ;
                    break;
                case "container-fps":
                    _videoState.container_fps = dataToken.ToString(); ;

                    break;
                case "estimated-vf-fps":
                    _videoState.estimated_fps = dataToken.ToString(); ;

                    break;

                case "audio-bitrate":
                    _videoState.audio_bitrate = dataToken.ToString(); ;
                    break;


                case "duration":

                    if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"\.m3u8($|\?)", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                    {

                    }
                    else if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath,
                             config_class.config_text_read("streamlinkで取得するURLの正規表現"),
                             System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                    {
                    }
                    else
                    {
                        _duration = dataToken.Value<double>();
                        _videoState.duration = dataToken.Value<double>();
                        BeginInvoke(() =>
                        {
                            PositionSlider.Minimum = 0;
                            PositionSlider.Maximum = (int)(_duration);
                        });
                    }
                    break;

                case "time-pos":
                 
                    if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"\.m3u8($|\?)", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                    {
                        // m3u8なので処理しない
                    }
                    else if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath,
                             config_class.config_text_read("streamlinkで取得するURLの正規表現"),
                             System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                    {
                    }
                    else
                    {
                        _timePos = dataToken.Value<double>();

                        BeginInvoke(() =>
                        {
                            if (!_pos_slidr_isDragging && PositionSlider.Maximum > 0)
                                if (PositionSlider.Maximum >= (int)(_timePos))
                                {
                                    PositionSlider.Value = (int)(_timePos);
                                }
                        });
                    }
                    UpdateTimeLabel();
                    break;
            }
         
            

        }
        private void AutoSelectEnglishAudioAndSubtitle(List<MpvTrack> tracks)
        {
            var jaCodes = new[] { "jpn", "ja", "jp", "japanese" };
            var enCodes = new[] { "eng", "en", "english" };

            var jpSub = tracks.FirstOrDefault(t =>
                t.type == "sub" &&
                !string.IsNullOrEmpty(t.lang) &&
                jaCodes.Contains(t.lang.ToLower()));

            var enAudio = tracks.FirstOrDefault(t =>
                t.type == "audio" &&
                !string.IsNullOrEmpty(t.lang) &&
                enCodes.Contains(t.lang.ToLower()));

            var jpAudio = tracks.FirstOrDefault(t =>
                t.type == "audio" &&
                !string.IsNullOrEmpty(t.lang) &&
                jaCodes.Contains(t.lang.ToLower()));

            // ----------------------------
            // ① 日本語字幕がある → 英語音声 + 日本語字幕
            // ----------------------------
            if (jpSub != null)
            {
                if (enAudio != null)
                {
                    _myplayer.SendToMpv(
                        $"{{\"command\": [\"set_property\", \"aid\", {enAudio.id}]}}");
                }

                _myplayer.SendToMpv(
                    $"{{\"command\": [\"set_property\", \"sid\", {jpSub.id}]}}");

                return;
            }

            // ----------------------------
            // ② 日本語字幕が無い → 日本語音声 + 字幕OFF
            // ----------------------------
            if (jpAudio != null)
            {
                _myplayer.SendToMpv(
                    $"{{\"command\": [\"set_property\", \"aid\", {jpAudio.id}]}}");

                _myplayer.SendToMpv(
                    "{\"command\": [\"set_property\", \"sid\", \"no\"]}");
            }
        }
        private void AutoSelectJapaneseAudioAndSubtitle(List<MpvTrack> tracks)
        {
            var jaCodes = new[] { "jpn", "ja", "jp", "japanese" };

            var jpAudio = tracks.FirstOrDefault(t =>
                t.type == "audio" &&
                !string.IsNullOrEmpty(t.lang) &&
                jaCodes.Contains(t.lang.ToLower()));

            var jpSub = tracks.FirstOrDefault(t =>
                t.type == "sub" &&
                !string.IsNullOrEmpty(t.lang) &&
                jaCodes.Contains(t.lang.ToLower()));

            if (jpAudio != null)
            {
                // 日本語音声
                _myplayer.SendToMpv($"{{\"command\": [\"set_property\", \"aid\", {jpAudio.id}]}}");

                // 字幕OFF
                _myplayer.SendToMpv("{\"command\": [\"set_property\", \"sid\", \"no\"]}");
            }
            else if (jpSub != null)
            {
                // 日本語字幕ON
                _myplayer.SendToMpv($"{{\"command\": [\"set_property\", \"sid\", {jpSub.id}]}}");
            }
        }
        public void panscan()
        {

            _myplayer.Video.panscan();
        }


        public string seiki_string_get(string text, String reg_st)
        {
            String re_text = "";
            try
            {
                System.Text.RegularExpressions.Regex Regex = new System.Text.RegularExpressions.Regex(reg_st, System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                System.Text.RegularExpressions.Match Match = Regex.Match(text);


                while (Match.Success)
                {

                    re_text = Match.Groups[1].Value;



                    Match = Match.NextMatch();
                }
            }
            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);
                Debug.WriteLine(ex.Message + ex.StackTrace);
            }
            return re_text;
        }
        private string FormatTime(double seconds)
        {
            var ts = System.TimeSpan.FromSeconds(seconds);
            return ts.ToString(@"h\:mm\:ss");
        }
        private void UpdateTimeLabel()
        {
            BeginInvoke(() =>
            {
                lblTime.Text =
                    $"{FormatTime(_timePos)} / {FormatTime(_duration)}";
            });
        }
        private string FormatFileSize(double bytes)
        {
            const double GB = 1024 * 1024 * 1024;
            const double MB = 1024 * 1024;

            if (bytes >= GB)
            {
                double g = bytes / GB;
                return $"{g:F1}G";
            }
            else
            {
                double m = bytes / MB;
                return $"{m:F0}M";
            }
        }
        private void UpdateResolutionLabel()
        {

            String size_st = FormatFileSize(_filesize);
            BeginInvoke(() =>
            {
                lblFilesize.Text = $"{size_st} ";
                lblResolution.Text = $"{_videoWidth} x {_videoHeight}";
            });
        }

        private async void open_func()
        {

            using OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "Video Files|*.mp4;*.iso;*.mkv;*.avi;*.mov|All Files|*.*";
            if (ofd.ShowDialog() == DialogResult.OK)
                StartMpv(ofd.FileName);
            currentFilePath = ofd.FileName;
            start_list_update(currentFilePath);

        }


        public async void open_folder_func()
        {

            FolderBrowserDialog dialog = new FolderBrowserDialog();

            dialog.Description = "フォルダを選択してください";

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                string folderPath = dialog.SelectedPath;
                Debug.WriteLine(folderPath);
                await Task.Run(() => folder_get(folderPath));
                if (config_class.config_int_read("起動時のリスト") == 1)
                {
                    list_folder();
                }
            }
        }

        public void ApplyGlsl(String glsl_path)
        {

            _myplayer.Video.ApplyGlsl(glsl_path);

        }
        public void vf_normal()
        {

            _myplayer.Video.vf_normal();
        }
        public void video_flip()
        {

            _myplayer.Video.video_flip();
        }
        public void video_rotate_90_right()
        {

            _myplayer.Video.video_rotate_90_right();
        }
        public void video_rotate_90_left()
        {

            _myplayer.Video.video_rotate_90_left();
        }
        public void audio_lavfi_normal()
        {
            _myplayer.Audio.audio_lavfi_normal();
        }

        public void audio_lavfi(String name)
        {
            _myplayer.Audio.audio_lavfi(name);

        }
        public void audio_lavfi_single(String name)
        {
            _myplayer.Audio.audio_lavfi_single(name);

        }


        public void video_lavfi(String name)
        {

            _myplayer.Video.video_lavfi(name);
        }

        public void Video_Preset(String name)
        {

            _myplayer.Video.ApplyPreset(name);
        }
        public void Audio_Preset(String name)
        {

            _myplayer.Audio.ApplyEqPreset(name);
        }

        public void list_arva()
        {
            list_change("arva", arva_lists);


        }
        public void list_rakuten()
        {
            list_change("楽天", rakuten_lists);


        }
        public void video_aspect(String value)
        {
            _myplayer.Video.aspect(value);
        }

        public void panscan_normal()
        {

            _myplayer.Video.panscan_normal();
        }
        public void list_db()
        {
            list_change("動画DB", db_all_video_lists);





        }




        private async void start_list_update(String path)
        {
         
            if (config_class.config_bool_read("再生時にフォルダの動画をリストに入れる") == true)
            {
            
                await Task.Run(() => folder_get_movie(path));
            }


            if (config_class.config_int_read("起動時のリスト") == 1)
            {
                list_folder();
            }

        }


        string GetFileSize(string path)
        {

            if (System.Text.RegularExpressions.Regex.IsMatch(path, "https?:", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
            {
                return "";
            }
            if (System.IO.File.Exists(path) == false)
            {
                return "";
            }
            long size = new FileInfo(path).Length;
            return $"{size / 1024 / 1024} MB";
        }

        public void BtnOpen_Click(object sender, EventArgs e)
        {
            open_func();

        }
    }
}