//////////////////////
// Replacer.cs
//////////////////////
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Reflection;		//Assemblyを使う為
using System.Resources;			//リソース関係クラス等の使用の為
using System.IO;				//Stream関係クラス等の使用の為
using System.Diagnostics;		//Processを使用する為

///////////////////////////
//エントリーポイントクラス
///////////////////////////
class MainApp
{
	[STAThread]
	public static void Main()
	{
		Application.Run(new MainWnd());
	}
}

///////////////////////
//メインフォームクラス
///////////////////////
public partial class MainWnd : Form
{
	//クラスメンバー変数
	string OwnPath;
	MenuItem miRepManu, miRepLog;				//「手動置換」、「ログ置換」メニューアイテム
	MenuItem miBackUp;							//「バックアップ」メニューアイテム
	ToolStrip toolStrip;						//ツールバー
	ToolStripButton[] toolStripButton;			//ツールバーボタン
	StatusStrip statusStrip;					//ステータスバー
	ToolStripStatusLabel[] tssl;				//ステータスバーラベル
	Button SelFile_Btn;							//ファイル選択ボタン
	Button SelFolder_Btn;						//フォールダー選択ボタン
	Button Replace_Btn;							//文字列置換ボタン
	TextBox tbPath;								//Path表示用テキストボックス
	TextBox tbToRep;							//検索文字列用テキストボックス
	TextBox tbRepWith;							//置換文字列用テキストボックス
	ListView FileList;							//変換対象ファイルリスト用リストビュー
	Label lblSelFolder;							//フォールダー選択ボタン説明ラベル
	Label lblToRep;								//検索文字列説明ラベル
	Label lblRepWith;							//置換文字列説明ラベル

	public MainWnd()
	{
		Assembly myOwn = Assembly.GetEntryAssembly();
		this.Icon = Icon.ExtractAssociatedIcon(myOwn.Location);	//プログラムアイコンをフォームにつける
		this.Load += new EventHandler(MainForm_Load);
		this.Text = "文字列一括変換ユーティリティ";
		this.ClientSize = new Size(480, 341);					//Size = (496, 380);
		this.MinimumSize = new Size(496, 380);					//最小サイズ
		this.BackColor = SystemColors.Window;
	}

	//WM_CREATE時処理
	private void MainForm_Load(object sender, EventArgs e)
	{
		//メニュー作成
		SetMenu();
		//ツールバーとステータスバー作成
		SetBars();
		//コントロール作成
		SetControls();
	}

	//WM_CLOSE時処理
	protected override void OnFormClosing(FormClosingEventArgs e)
	{
		base.OnFormClosing(e);
		DialogResult dr = MessageBox.Show("終了しますか？", "確認", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
		if(dr == DialogResult.No)
		{
			e.Cancel = true;
		}
	}

	//メニューの設定
	protected void SetMenu()
	{
		//メインメニュー作成
		MainMenu menu = new MainMenu();
		Menu = menu;
		//メニューアイテム付加
		MenuItem miFile = new MenuItem();		//「ファイル」メニュー
		miFile.Text = "ファイル(&F)";
		miFile.Index = 0;
		menu.MenuItems.Add(miFile);
		MenuItem miReplace = new MenuItem();	//「置換」メニュー
		miReplace.Text = "置換(&R)";
		miReplace.Index = 1;
		menu.MenuItems.Add(miReplace);
		MenuItem miHelp = new MenuItem();		//「ヘルプ」メニュー
		miHelp.Text = "ヘルプ(&H)";
		miHelp.Index = 2;
		menu.MenuItems.Add(miHelp);
		MenuItem miOpen = new MenuItem();		//「ログファイルを開く」メニューアイテム
		miOpen.Text = "ログファイルを開く(&O)";
		miOpen.Index = 0;
		miOpen.Click += OnOpen_Click;
		miOpen.Shortcut = Shortcut.CtrlO;
		miFile.MenuItems.Add(miOpen);
		miFile.MenuItems.Add("-");				//セパレーター
		MenuItem miExit = new MenuItem();		//「終了」メニューアイテム
		miExit.Text = "終了(&X)";
		miExit.Index = 1;
		miExit.Click += OnExit_Click;
		miExit.Shortcut = Shortcut.CtrlX;
		miFile.MenuItems.Add(miExit);
		miRepManu = new MenuItem();				//「手動置換」メニューアイテム
		miRepManu.Text = "手動置換(&M)";
		miRepManu.Index = 0;
		miRepManu.Click += OnRepManu_Click;
		miRepManu.Shortcut = Shortcut.CtrlM;
		miReplace.MenuItems.Add(miRepManu);
		miRepLog = new MenuItem();				//「ログ置換」メニューアイテム
		miRepLog.Text = "ログ置換(&C)";
		miRepLog.Index = 1;
		miRepLog.Click += OnRepLog_Click;
		miRepLog.Shortcut = Shortcut.CtrlC;
		miReplace.MenuItems.Add(miRepLog);
		miRepLog.Enabled = false;				//初期値は無効
		miReplace.MenuItems.Add("-");			//セパレーター
		miBackUp = new MenuItem();				//「設定」メニューアイテム
		miBackUp.Text = "バックアップ(&B)";
		miBackUp.Index = 2;
		miBackUp.Click += OnSetUp_Click;
		miBackUp.Checked = true;					//メニュー項目にレ点をつける
		miBackUp.Shortcut = Shortcut.CtrlS;
		miReplace.MenuItems.Add(miBackUp);
		MenuItem miHowtoUse = new MenuItem();	//「使い方」メニューアイテム
		miHowtoUse.Text = "使い方(&U)";
		miHowtoUse.Index = 0;
		miHowtoUse.Click += OnHowtoUse_Click;
		miHowtoUse.Shortcut = Shortcut.CtrlU;
		miHelp.MenuItems.Add(miHowtoUse);
		MenuItem miVer = new MenuItem();		//「バージョン」メニューアイテム
		miVer.Text = "バージョン(&V)";
		miVer.Index = 1;
		miVer.Click += OnVersion_Click;
		miVer.Shortcut = Shortcut.CtrlV;
		miHelp.MenuItems.Add(miVer);
	}

	//ツールバーとステータスバーの設定
	protected void SetBars()
	{
		//フォームのレイアウトを一時停止
		this.SuspendLayout();
		///////////////////////////////////
		//ツールバーとステータスバーの配置
		///////////////////////////////////
		//ToolStripクラスインスタンスの生成
		this.toolStrip = new ToolStrip();
		//ツールバーのレイアウトを一時停止
		this.toolStrip.SuspendLayout();
		//ToolStripButton配列を作成
		this.toolStripButton = new ToolStripButton[12];
		//本プログラムの埋め込みリソースのリソースマネージャーを作成
		Assembly asm = Assembly.GetExecutingAssembly();
		ResourceManager rm = new ResourceManager("Replacer", asm);
		//ツールバービットマップの読み込み
		ImageList imgList = new ImageList();
		imgList.ImageSize = new Size(16, 15);
		imgList.Images.AddStrip((Bitmap)rm.GetObject("ToolBar"));
		imgList.TransparentColor = Color.White;
		//ToolStripButton[0]を作成
		this.toolStripButton[0] = new ToolStripButton();
		this.toolStripButton[0].Text = "開く(&O)";								//テキスト設定
		this.toolStripButton[0].Image = (Bitmap)imgList.Images[0];				//画像設定
		this.toolStripButton[0].DisplayStyle = ToolStripItemDisplayStyle.Image;	//画像表示のみ
		this.toolStripButton[0].Click += OnOpen_Click;							//Clickイベントハンドラ追加
		this.toolStrip.Items.Add(this.toolStripButton[0]);						//ボタンを追加
		//セパレーターを挿入
		this.toolStrip.Items.Add(new ToolStripSeparator());
		//ToolStripButton[1]を作成
		this.toolStripButton[1] = new ToolStripButton();
		this.toolStripButton[1].Text = "終了(&X)";								//テキスト設定
		this.toolStripButton[1].Image = (Bitmap)imgList.Images[1];				//画像設定
		this.toolStripButton[1].DisplayStyle = ToolStripItemDisplayStyle.Image;	//画像表示のみ
		this.toolStripButton[1].Click += OnExit_Click;							//Clickイベントハンドラ追加
		this.toolStrip.Items.Add(this.toolStripButton[1]);						//ボタンを追加
		//セパレーターを挿入
		this.toolStrip.Items.Add(new ToolStripSeparator());
		//ToolStripButton[2]を作成
		this.toolStripButton[2] = new ToolStripButton();
		this.toolStripButton[2].Text = "手動置換(&R)";							//テキスト設定
		this.toolStripButton[2].Image = (Bitmap)imgList.Images[2];				//画像設定
		this.toolStripButton[2].DisplayStyle = ToolStripItemDisplayStyle.Image;	//画像表示のみ
		this.toolStripButton[2].Click += OnRepManu_Click;						//Clickイベントハンドラ追加
		this.toolStrip.Items.Add(this.toolStripButton[2]);						//ボタンを追加
		//ToolStripButton[3]を作成
		this.toolStripButton[3] = new ToolStripButton();
		this.toolStripButton[3].Text = "ログ置換(&R)";							//テキスト設定
		this.toolStripButton[3].Image = (Bitmap)imgList.Images[3];				//画像設定
		this.toolStripButton[3].DisplayStyle = ToolStripItemDisplayStyle.Image;	//画像表示のみ
		this.toolStripButton[3].Click += OnRepLog_Click;						//Clickイベントハンドラ追加
		this.toolStrip.Items.Add(this.toolStripButton[3]);						//ボタンを追加
		this.toolStripButton[3].Enabled = false;								//初期状態は無効
		//セパレーターを挿入
		this.toolStrip.Items.Add(new ToolStripSeparator());
		//ToolStripButton[4]を作成
		this.toolStripButton[4] = new ToolStripButton();
		this.toolStripButton[4].Text = "使い方(&U)";							//テキスト設定
		this.toolStripButton[4].Image = (Bitmap)imgList.Images[4];				//画像設定
		this.toolStripButton[4].DisplayStyle = ToolStripItemDisplayStyle.Image;	//画像表示のみ
		this.toolStripButton[4].Click += OnHowtoUse_Click;						//Clickイベントハンドラ追加
		this.toolStrip.Items.Add(this.toolStripButton[4]);						//ボタンを追加
		//ToolStripButton[5]を作成
		this.toolStripButton[5] = new ToolStripButton();
		this.toolStripButton[5].Text = "バージョン情報(&V)";					//テキスト設定
		this.toolStripButton[5].Image = (Bitmap)imgList.Images[5];				//画像設定
		this.toolStripButton[5].DisplayStyle = ToolStripItemDisplayStyle.Image;	//画像表示のみ
		this.toolStripButton[5].Click += OnVersion_Click;						//Clickイベントハンドラ追加
		this.toolStrip.Items.Add(this.toolStripButton[5]);						//ボタンを追加
		//ツールバーの設定
		this.Controls.Add(this.toolStrip);
		//ツールバーのレイアウトを再開
		this.toolStrip.ResumeLayout(false);
		this.toolStrip.PerformLayout();

		//StatusStripクラスインスタンスの生成
		this.statusStrip = new StatusStrip();
		//ステータスバーのレイアウトを一時停止
		this.statusStrip.SuspendLayout();
		//ステータスバーにパネルとテキストを追加
		tssl = new ToolStripStatusLabel[3];
		tssl[0] = new ToolStripStatusLabel();
		tssl[0].BorderSides = ToolStripStatusLabelBorderSides.All;
		tssl[0].BorderStyle = Border3DStyle.SunkenInner;
		tssl[0].BackColor = SystemColors.Control;
		tssl[0].Text = "Replacer Ver. 1.0";
		tssl[0].AutoSize = true;
		tssl[0].TextAlign = ContentAlignment.MiddleLeft;
		tssl[1] = new ToolStripStatusLabel();
		tssl[1].BorderSides = ToolStripStatusLabelBorderSides.All;
		tssl[1].BorderStyle = Border3DStyle.SunkenInner;
		tssl[1].BackColor = SystemColors.Control;
		tssl[1].Text = "手動置換";
		tssl[1].ToolTipText = "手動置換";				//ToolTip設定
		tssl[1].AutoSize = true;
		tssl[1].TextAlign = ContentAlignment.MiddleLeft;
		tssl[2] = new ToolStripStatusLabel();
		tssl[2].BorderSides = ToolStripStatusLabelBorderSides.All;
		tssl[2].BorderStyle = Border3DStyle.SunkenInner;
		tssl[2].BackColor = SystemColors.Control;
		tssl[2].Text = "（ログファイル名）";
		tssl[2].ToolTipText = "（ログファイル名）";		//ToolTip設定
		tssl[2].Spring = true;
		tssl[2].TextAlign = ContentAlignment.MiddleLeft;
		statusStrip.Items.AddRange(tssl);
		statusStrip.ShowItemToolTips = true;			//ToolTip表示
		this.Controls.Add(this.statusStrip);			//StatusStrip(ステータスバー)を追加
		//ステータスバーのレイアウトを再開
		this.statusStrip.ResumeLayout(false);
		this.statusStrip.PerformLayout();
		//メインフォームのレイアウトを再開
		this.ResumeLayout(false);
		this.PerformLayout();
	}

	//コントロールの設定
	protected void SetControls()
	{
		/////////////////////
		//コントロールの配置
		/////////////////////
		//ファイル選択ボタン
		SelFile_Btn = new Button();
		SelFile_Btn.Size = new Size(140, 30);
		SelFile_Btn.Location = new Point(10, toolStrip.Height + 10);
		SelFile_Btn.Anchor = (AnchorStyles.Top | AnchorStyles.Left);
		SelFile_Btn.Text = "対象ファイルを選択";
		SelFile_Btn.Image = toolStripButton[0].Image;
		SelFile_Btn.TextImageRelation = TextImageRelation.ImageBeforeText;
		SelFile_Btn.TabStop = true;
		SelFile_Btn.TabIndex = 0;
		SelFile_Btn.Click += OnSelFile_Btn_Click;
		this.Controls.Add(SelFile_Btn);
		//フォールダー選択ボタン説明ラベル
		lblSelFolder = new Label();
		lblSelFolder.Size = new Size(200, 30);
		lblSelFolder.Location = new Point(this.ClientSize.Width - lblSelFolder.Width, toolStrip.Height + 5);
		lblSelFolder.Anchor = (AnchorStyles.Top | AnchorStyles.Right);
		lblSelFolder.Text = "フォールダー内全ファイルを選択\r\n（削除するにはクリックで行を選択）";
		lblSelFolder.TextAlign = ContentAlignment.MiddleCenter;
		lblSelFolder.TabStop = false;
		this.Controls.Add(lblSelFolder);
		//フォールダー選択ボタン
		SelFolder_Btn = new Button();
		SelFolder_Btn.Size = new Size(30, 30);
		SelFolder_Btn.Location = new Point(this.ClientSize.Width - SelFolder_Btn.Width - 10, toolStrip.Height + SelFile_Btn.Height + 5);
		SelFolder_Btn.Anchor = (AnchorStyles.Top | AnchorStyles.Right);
		SelFolder_Btn.Image = toolStripButton[0].Image;
		SelFolder_Btn.TabStop = true;
		SelFolder_Btn.TabIndex = 1;
		SelFolder_Btn.Click += OnSelFolder_Btn_Click;
		this.Controls.Add(SelFolder_Btn);
		//Path表示用テキストボックス
		tbPath = new TextBox();
		tbPath.Size = new Size(ClientSize.Width - SelFolder_Btn.Width - 25, 20);
		tbPath.Location = new Point(10, toolStrip.Height + SelFile_Btn.Height + 15);
		tbPath.Anchor = (AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right);
		tbPath.Text = "";
		tbPath.ReadOnly = true;
		tbPath.TabStop = false;
		this.Controls.Add(tbPath);
		//リストビューの生成とプロパティの設定
		//https://dot-sharp.com/csharp-listview-event-order/
		FileList = new ListView();
		FileList.Size = new Size(ClientSize.Width - 20, ClientSize.Height - 170);	//サイズ
		FileList.Location = new Point(10,  toolStrip.Height + SelFile_Btn.Height + tbPath.Height + 20);	//位置
		FileList.Anchor = (AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Right);
		FileList.FullRowSelect = true;					//一行選択
		FileList.GridLines = true;						//グリッドラインの表示
		FileList.Sorting = SortOrder.Ascending;			//並び替え表示
		FileList.HoverSelection = false;				//ポイントで選択できるようにする
		FileList.Activation = ItemActivation.OneClick;	//シングルクリック選択
		FileList.CheckBoxes = false;					//チェックボックス有効化
		FileList.View = View.Details;					//リストビューの表示方法
		FileList.TabStop = false;
		FileList.ItemActivate += new EventHandler(OnListView_ItemActivate);
		//ヘッダー定義
		FileList.Columns.Add("ファイル名", 380, HorizontalAlignment.Left);
		FileList.Columns.Add("変換回数", 76, HorizontalAlignment.Left);
		FileList.Columns.Add("詳細", 540, HorizontalAlignment.Left);
		//FormにListViewを追加
		this.Controls.Add(FileList);
		//置換文字列説明ラベル
		lblRepWith = new Label();
		lblRepWith.Location = new Point(10, ClientSize.Height - statusStrip.Height - lblRepWith.Height);
		lblRepWith.Size = new Size(75, 20);
		lblRepWith.Anchor = (AnchorStyles.Bottom | AnchorStyles.Left);
		lblRepWith.Text = "置換文字列";
		lblRepWith.TextAlign = ContentAlignment.MiddleLeft;
		lblRepWith.TabStop = false;
		this.Controls.Add(lblRepWith);
		//検索文字列説明ラベル
		lblToRep = new Label();
		lblToRep.Location = new Point(10, ClientSize.Height - statusStrip.Height - lblToRep.Height - lblRepWith.Height);
		lblToRep.Size = new Size(75, 20);
		lblToRep.Anchor = (AnchorStyles.Bottom | AnchorStyles.Left);
		lblToRep.Text = "検索文字列";
		lblToRep.TextAlign = ContentAlignment.MiddleLeft;
		lblToRep.TabStop = false;
		this.Controls.Add(lblToRep);
		//文字列置換ボタン
		Replace_Btn = new Button();
		Replace_Btn.Size = new Size(70, 35);
		Replace_Btn.Location = new Point(this.ClientSize.Width - Replace_Btn.Width - 10, ClientSize.Height - statusStrip.Height - Replace_Btn.Height - 7);
		Replace_Btn.Anchor = (AnchorStyles.Bottom | AnchorStyles.Right);
		Replace_Btn.Image = toolStripButton[2].Image;
		Replace_Btn.TabStop = true;
		Replace_Btn.TabIndex = 4;
		Replace_Btn.Click += OnReplace_Btn_Click;
		this.Controls.Add(Replace_Btn);
		//置換文字列用テキストボックス
		tbRepWith = new TextBox();
		tbRepWith.Location = new Point(85, ClientSize.Height - statusStrip.Height - tbRepWith.Height - 5);
		tbRepWith.Size = new Size(ClientSize.Width - Replace_Btn.Width - lblRepWith.Width - 25, 20);
		tbRepWith.Anchor = (AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right);
		tbRepWith.Text = "";
		tbRepWith.TabStop = true;
		tbRepWith.TabIndex = 3;
		this.Controls.Add(tbRepWith);
		//検索文字列用テキストボックス
		tbToRep = new TextBox();
		tbToRep.Location = new Point(85, ClientSize.Height - statusStrip.Height - tbToRep.Height - tbRepWith.Height - 5);
		tbToRep.Size = new Size(ClientSize.Width - Replace_Btn.Width - lblToRep.Width - 25, 20);
		tbToRep.Anchor = (AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right);
		tbToRep.Text = "";
		tbToRep.TabStop = true;
		tbToRep.TabIndex = 2;
		this.Controls.Add(tbToRep);
	}

	///////////////////////////////////
	//メニュー、ツールバー関連メソッド
	///////////////////////////////////
	//「ログファイルを開く」処理
	private void OnOpen_Click(object sender, EventArgs e)
	{
		DialogResult dr = MessageBox.Show("ログファイルを開きますか？（「はい」）\r\nそれとも総てのファイルですか？（「いいえ」）\r\n或いは中止しますか？（「キャンセル」）", "ファイル種類確認", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
		OpenFileDialog ofDlg = new OpenFileDialog();
		ofDlg.AddExtension = true;		//拡張子自動付加
		switch(dr)
		{
		case DialogResult.Yes:
			ofDlg.FileName = "*.log";	//拡張子
			ofDlg.FilterIndex = 1;		//ファイルフィルターインデックス
			break;
		case DialogResult.No:
			ofDlg.FileName = "*.*";		//拡張子
			ofDlg.FilterIndex = 2;		//ファイルフィルターインデックス
			break;
		default:
			return;
		}
		//ファイルフィルターの指定
		ofDlg.Filter = "ログファイル(*.log)|*.log|総てのファイル(*.*)|*.*";
		ofDlg.RestoreDirectory = true;	//初期ディレクトリへ復帰
		ofDlg.CheckFileExists = true;	//ファイルの存在チェック
		ofDlg.CheckPathExists = true;	//ファイルパスの存在チェック
		ofDlg.InitialDirectory = ".";	// デフォルトのフォルダーの指定
		ofDlg.Title = "ファイルを開く";	//ダイアログのタイトルを指定する
		if(ofDlg.ShowDialog() == DialogResult.OK)	//ダイアログを表示する
		{
			SwitchManuLog(true);		//「ログ置換」設定にする
			tssl[2].ToolTipText = tssl[2].Text = ofDlg.FileName;	//ステータスバーにログファイルを表示する
		}
		else
		{
			MessageBox.Show("キャンセルされました。", "キャンセル", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
		}
		// オブジェクトを破棄する
		ofDlg.Dispose();
	}

	//「終了」処理
	private void OnExit_Click(object sender, EventArgs e)
	{
		Close();	//修了確認はOnClosingメソッドで行う
	}

	//「手動置換」処理
	private void OnRepManu_Click(object sender, EventArgs e)
	{
		if(String.IsNullOrEmpty(tbToRep.Text))
			MessageBox.Show("検索文字列が入力されていません","エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
		else
			RepFilesInLV(tbToRep.Text, tbRepWith.Text);	//「検索文字列」、「置換文字列」テキストボックスで処理
	}

	//「ログ置換」処理（ファイルによるバッチ処理）
	private void OnRepLog_Click(object sender, EventArgs e)
	{
		//最終の実行確認を行う
		DialogResult res = MessageBox.Show("本当にログ置換を実行しますか？", "最終確認", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
		if(res == DialogResult.Yes)
		{
			//ログファイル（各行がカンマ区切り2つの文字列のcsvファイル）による置換処理
			Encoding enc = Encoding.GetEncoding("shift_jis");	//Sift-JISを選択しているが、変更可能
			//ログファイル（File.ReadAllText(tssl[2].Textはファイル名）を読む
			StringReader sr = new StringReader(File.ReadAllText(tssl[2].Text, enc));
			string line = string.Empty;			//一行データ読み込み用変数
			while(true)							//無限ループ
			{
				line = sr.ReadLine();
				if(String.IsNullOrEmpty(line))	//文末チェック
					break;
				else							//行データがある場合
				{
					try							//改行コード（0X0D0A）変換余りでデータ行以外がすり抜ける場合
					{
						//line.Contains(',')で「値がnul」エラーが生じるリスク
						if(!line.Contains(','))	//データ行か否かのチェック（カンマが無ければ終了）
							break;
						//「Indexが配列境界外」エラーリスク対処
						string[] words = line.Split(',');
						RepFilesInLV((tbToRep.Text = words[0]), (tbRepWith.Text = words[1]));
					}
					catch	//エラー発生時はループを抜け出す
					{
						break;
					}
				}
			}
			sr.Close();
		}
		tssl[2].ToolTipText = tssl[2].Text = "（ログファイル名）";	//ステータスバーのファイル表示を初期化する
		SwitchManuLog(false);				//「手動置換」設定にする
		Replace_Btn.Enabled = true;			//文字列置換ボタンを処理処理後、有効にする
	}

	//「バックアップ」処理
	private void OnSetUp_Click(object sender, EventArgs e)
	{
		if(miBackUp.Checked)
			miBackUp.Checked = false;
		else
			miBackUp.Checked = true;
	}

	//「使い方」処理
	private void OnHowtoUse_Click(object sender, EventArgs e)
	{
		OwnPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);	//自分自身のパスを取得
		//Process.Start("ファイル名", "引き数");も可
		ProcessStartInfo processInfo = new ProcessStartInfo
		{
			FileName = "hh",
			Arguments = OwnPath + @"\ReplacerHelp.chm"
		};
		Process.Start(processInfo);

	}

	//「バージョン」処理
	private void OnVersion_Click(object sender, EventArgs e)
	{
		VersionDlg verDlg = new VersionDlg(this.Icon);	//バージョンダイアログの表示
		verDlg.ShowDialog();
		verDlg.Dispose();
	}

	///////////////////////////
	//コントロール関連メソッド
	///////////////////////////
	//「ファイルを開く」処理
	private void OnSelFile_Btn_Click(object sender, EventArgs e)
	{
		DialogResult dr = MessageBox.Show("入れ替えますか（はい）、または\r\n追加しますか（いいえ）？", "確認", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
		if(dr == DialogResult.Yes)
		{
			FileList.Items.Clear();	//入替えの場合、リストビュー内の項目を全削除
		}
		OpenFileDialog ofDlg = new OpenFileDialog();
		ofDlg.FileName = "*.*";						//初期ファイル名の指定
		ofDlg.Filter = "C#ファイル(*.cs)|*.cs|すべてのファイル(*.*)|*.*";	//ファイルフィルターの指定
		ofDlg.FilterIndex = 2;						//ファイルフィルターインデックスの指定
		ofDlg.RestoreDirectory = true;				//ダイアログボックスを閉じる前に現在のディレクトリを復元するようにする
		ofDlg.CheckFileExists = true;				//存在しないファイルの名前が指定されたとき警告を表示する
		ofDlg.CheckPathExists = true;				//存在しないパスが指定されたとき警告を表示する
		ofDlg.Multiselect = true;					//複数ファイルの選択を行う
		ofDlg.InitialDirectory = @".\";				// デフォルトのフォルダを指定する
		ofDlg.Title = "ファイルを開く";				//ダイアログのタイトルを指定する
		if(ofDlg.ShowDialog() == DialogResult.OK)	//ダイアログを表示する
		{
			foreach(string fn in ofDlg.FileNames)	//複数選択ファイル名コレクションの表示
			{
				ListViewItem item = FileList.Items.Add(Path.GetFileName(fn));
				item.SubItems.Add("0");
				item.SubItems.Add(fn);
			}
 		}
		else
		{
			MessageBox.Show("キャンセルされました。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
		}
		// オブジェクトを破棄する
		ofDlg.Dispose();
	}

	//「フォールダーを開く」処理
	private void OnSelFolder_Btn_Click(object sender, EventArgs e)
	{
		DialogResult dr = MessageBox.Show("入れ替えますか（はい）、または\r\n追加しますか（いいえ）？", "確認", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
		if(dr == DialogResult.Yes)
		{
			FileList.Items.Clear();	//入替えの場合、リストビュー内の項目を全削除
		}
		FolderBrowserDialog fbDlg = new FolderBrowserDialog();
		fbDlg.Description = "対象ファイルのあるフォルダーを選択してください。";	// ダイアログの説明文
		fbDlg.SelectedPath = ".\\";					// デフォルトのフォルダー
		if(fbDlg.ShowDialog() == DialogResult.OK)	//フォルダを選択するダイアログを表示する
		{
			tbPath.Text = fbDlg.SelectedPath;		//「パス名」テキストボックスに表示
			//フォルダ内のファイル名だけ表示
		 	IEnumerable<string> files = Directory.EnumerateFiles(fbDlg.SelectedPath, "*", SearchOption.TopDirectoryOnly);
			foreach (string fn in files)			//フォールダー内ファイルの表示
			{
				ListViewItem item = FileList.Items.Add(Path.GetFileName(fn));
				item.SubItems.Add("0");
				item.SubItems.Add(fn);
			}
		}
		else
		{
			MessageBox.Show("キャンセルされました。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
		}
		// オブジェクトを破棄する
		fbDlg.Dispose();
	}

	//「行削除」処理
	private void OnListView_ItemActivate(object sender, EventArgs e)
	{
		ListView lv = (ListView)sender;
		//アイテムがアクティブになった時
		DialogResult dr = MessageBox.Show("選択項目" + lv.FocusedItem.Text + "を削除しますか？", "確認", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
		if(dr == DialogResult.Yes)
		{
			//フォーカスのあるアイテムを削除する
			lv.FocusedItem.Remove();
		}
	}

	//「置換ボタン」処理
	private void OnReplace_Btn_Click(object sender, EventArgs e)
	{
		if(tssl[2].Text == "（ログファイル名）")	//規定値の場合手動置換
		{
			OnRepManu_Click(sender, e);
		}
		else										//ログ置換
		{
			Replace_Btn.Enabled = false;			//このボタンを処理が済むまで無効にする
			OnRepLog_Click(sender, e);
		}
	}

	//「手動置換」、「ログ置換」モードの切り替え
	private void SwitchManuLog(bool flag)				//true−「ログ置換」、false−「手動置換」
	{
		if(flag)
		{
			miRepManu.Enabled = false;					//手動置換メニューを無効にする
			miRepLog.Enabled = true;					//ログ置換メニューを有効にする
			toolStripButton[2].Enabled = false;			//手動置換ボタンを無効にする
			toolStripButton[3].Enabled = true;			//ログ置換ボタンを有効にする
			tssl[1].Text = "ログ置換";					//ステータスバー表示
			tssl[1].ToolTipText = "ログ置換";			//ステータスバーToolTip設定
			tbRepWith.Text = "";						//検索文字列テキストボックスを初期化する
			tbRepWith.Enabled = false;					//検索文字列テキストボックスを無効にする
			tbToRep.Text = "";							//置換文字列テキストボックスを初期化する
			tbToRep.Enabled = false;					//置換文字列テキストボックスを無効にする
			Replace_Btn.Image = (Bitmap)toolStripButton[3].Image;	//ボタンイメージの変更
		}
		else
		{
			miRepManu.Enabled = true;					//手動置換メニューを有効にする
			miRepLog.Enabled = false;					//ログ置換メニューを無効にする
			toolStripButton[2].Enabled = true;			//手動置換ボタンを有効にする
			toolStripButton[3].Enabled = false;			//ログ置換ボタンを無効にする
			tssl[1].Text = "手動置換";					//ステータスバー表示
			tssl[1].ToolTipText = "手動置換";			//ステータスバーToolTip設定
			tbRepWith.Text = "";						//検索文字列テキストボックスを初期化する
			tbRepWith.Enabled = true;					//検索文字列テキストボックスを無効にする
			tbToRep.Text = "";							//置換文字列テキストボックスを初期化する
			tbToRep.Enabled = true;						//置換文字列テキストボックスを無効にする
			Replace_Btn.Image = (Bitmap)toolStripButton[2].Image;	//ボタンイメージの変更
		}
	}

	/////////////////////////////////
	//ファイル文字列置換関連メソッド
	/////////////////////////////////
	//リストボックスのファイルの置換を行う
	private void RepFilesInLV(string ToRep, string RepWith)
	{
		foreach(ListViewItem item in FileList.Items)
		{
			//オリジナルファイルのバックアップ作成
			string backup = Path.ChangeExtension(item.SubItems[2].Text, ".bak");
			if(miBackUp.Checked)
				File.Copy(item.SubItems[2].Text, backup, true);	//3番目の引数をつけずに、同名ファイルがあるとIOエラーとなる
			//オリジナルファイルの変更
			int n = CountFindRepInFile(item.SubItems[2].Text, ToRep, RepWith);
			if(n > 0)
				item.SubItems[1].Text = n.ToString();	//変換回数を表示
			else	//変換されなかった場合、作成したバックアップを削除
				File.Delete(backup);
		}
	}

	//ファイルの文字列置換（または検索）回数を返す
	private int CountFindRepInFile(string filename, string ToRep, string RepWith)
	{
		//テキストファイルの中身をすべて読み込む
		string str = string.Empty;		//ファイル読み込み用変数
		using (StreamReader sr = new StreamReader(filename, Encoding.GetEncoding("shift_jis")))	// シフトJISのテキスト用
	//	using (StreamReader sr = new StreamReader(filename))	// UTF-8のテキスト用
		{
			str = sr.ReadToEnd();	// ファイルのデータを「すべて」取得する
			sr.Close();
		}
		int count = CountFindRep(ref str, ToRep, RepWith);
		using (StreamWriter sw = new StreamWriter(filename, false, Encoding.GetEncoding("shift_jis")))	// シフトJISのテキスト上書き（false）用−trueはAppend
		{
			sw.Write(str);
			sw.Close();
		}
		return count;
	}

	//文字列置換（または検索）回数を返す−最初の検索対象文字列は置換後のものとなる
	private int CountFindRep(ref string str, string ToRep, string RepWith = "")
	{
		int position, count = 0;
		position = str.IndexOf(ToRep, 0);
		while(position != -1)
		{
			count++;
			position = str.IndexOf(ToRep, position + 1);
		}
		if(!String.IsNullOrEmpty(RepWith))
			str = str.Replace(ToRep, RepWith);
		return count;
	}
}

/////////////////////
//Version ダイアログ
/////////////////////
class VersionDlg : Form
{
	public VersionDlg(Icon ico)
	{
		//ダイアログの属性設定
		this.Text = "バーション情報";
		this.ClientSize = new Size(320, 100);
		this.MaximizeBox = false;		// 最大化ボタン
		this.MinimizeBox = false;		// 最小化ボタン
		this.ShowInTaskbar = false;		//タスクバー上表示
		this.FormBorderStyle = FormBorderStyle.FixedDialog;		// 境界のスタイル
		this.StartPosition = FormStartPosition.CenterParent;	// 親フォームの中央に配置
		//コントロールの属性設定
		Button btnOK = new Button();
		btnOK.Size = new Size(40, 28);
		btnOK.Location = new Point(ClientSize.Width - btnOK.Width - 10, (ClientSize.Height - btnOK.Height) / 2);
		btnOK.Text = "OK";
		btnOK.Click += new EventHandler(OnOK_Click);
		Label imglabel = new Label();
		imglabel.Size = new Size(40, 40);
		imglabel.Location = new Point(10, (ClientSize.Height - imglabel.Height) / 2);
		imglabel.BorderStyle = BorderStyle.Fixed3D;
		imglabel.Image = ico.ToBitmap();	//親のシステムアイコン
		Label label = new Label();
		label.Size = new Size(ClientSize.Width - imglabel.Width - btnOK.Width - 40, ClientSize.Height- 20);
		label.Location = new Point(imglabel.Width + 20, (ClientSize.Height - label.Height) / 2);
		label.BorderStyle = BorderStyle.Fixed3D;
		label.Text = "Replacer Version 1.0\r\nCopyright (c) 2023 by MS C# and Ysama\r\n";
		label.TextAlign = ContentAlignment.MiddleCenter;
		label.Font = new Font("Times New Roman", 10, FontStyle.Bold);
		this.Controls.Add(btnOK);
		this.Controls.Add(imglabel);
		this.Controls.Add(label);
	}

	private void OnOK_Click(object sender, EventArgs e)
	{
		Close();
	}
}
