/***********************************************************//*!
 * @brief ログ処理
 * @details
 **************************************************************/
using System.Windows.Forms;

namespace OfficeImageReducer
{
    /***********************************************************//*!
     * @brief ログクラス
     * @details ログを管理する
     **************************************************************/
    internal class ClassLog
    {
        //! ログを保存するフルパス付ファイル名
        private string LogFileName;

        //! ファイル保存用のログ文字列を確保する
        private string _ShadowBuf;

        //! ログ表示用テキストボックス
        private TextBox _LogTextBox;

        /***********************************************************//*!
         * @brief コンストラクタ
         * @param[in] LogTextBox ログ表示用のテキストボックス
         * @details
         **************************************************************/
        public ClassLog(TextBox LogTextBox)
        {
            _LogTextBox = LogTextBox;
            _LogTextBox.Text = "";
            _ShadowBuf = "";
            LogFileName = ClassMyCommon.AppPath() + ClassMyCommon.TITLE
                + "Log" + System.DateTime.Now.ToString("yyMMdd") + ".txt";
        }

        /***********************************************************//*!
         * @brief 他のスレッドからコールする為のデリゲート
         **************************************************************/
        private delegate void Add_Callback(string stradd);

        /***********************************************************//*!
         * @brief ログに文字列を追加する
         * @param[in] stradd ログへ追加する文字列
         * @details ログの表示は更新スクロールされない
         **************************************************************/
        public void Add(string stradd)
        {
            if (stradd == "")
            {
                //! 文字列がカラなら即終了
                return;
            }

            if (_LogTextBox.InvokeRequired)
            {
                // 別スレッドから呼び出された場合デリゲートからコールバックさせる
                _LogTextBox.Invoke(new Add_Callback(Add), stradd);
                return;
            }

            //! 表示されている古いログは削除する
            DeleteOld();

            // タイムスタンプ文字列を生成
            string TimeStamp = System.DateTime.Now.ToString("MM/dd HH:mm:ss : ");
            // ログ追加文字列の先頭にタイムスタンプを追加
            stradd = TimeStamp + stradd;

            // ログ追加文字列の最後尾に "\r\n" があった場合は、いったん削除する
            if (stradd.Substring(stradd.Length - "\r\n".Length, "\r\n".Length) == "\r\n")
            {
                stradd = stradd.Substring(0, stradd.Length - "\r\n".Length);
            }

            // ログ追加文字列の中に "\r\n" があった場合は、"\r\n+タイムスタンプ" に置換する
            stradd = stradd.Replace("\r\n", "\r\n" + TimeStamp);

            // ログ追加文字列の最後尾に "\r\n" を追加
            stradd += "\r\n";

            // 加工したログ追加文字列を保存用文字列とテキストボックスへ追加
            _LogTextBox.Text += stradd;
            _ShadowBuf += stradd;
        }

        /***********************************************************//*!
         * @brief 他のスレッドからコールする為のデリゲート
         **************************************************************/
        private delegate void Put_Callback(string stradd);

        /***********************************************************//*!
         * @brief ログに文字列を追加しログ表示を最下行へ強制スクロールする
         * @param[in] stradd ログへ追加する文字列
         * @details
         **************************************************************/
        public void Put(string stradd)
        {
            if (_LogTextBox.InvokeRequired)
            {
                // 別スレッドから呼び出された場合デリゲートからコールバックさせる
                _LogTextBox.Invoke(new Put_Callback(Put), stradd);
                return;
            }

            // ログ追加
            Add(stradd);

            // ログ表示を最下行へスクロールする。
            _LogTextBox.SelectionStart = _LogTextBox.Text.Length;
            _LogTextBox.ScrollToCaret();
        }

        /***********************************************************//*!
         * @brief ログにデバッグ用文字列を追加
         * @param[in] stradd ログへ追加する文字列
         * @details
         **************************************************************/
        public void DebugPut(string stradd)
        {
#if false
            Put(stradd);
#endif
        }

        /***********************************************************//*!
         * @brief ログをファイルに保存
         * @details
         **************************************************************/
        public void Save()
        {
#if false
            using (StreamWriter sw = new StreamWriter(
                LogFileName,
                true,
                System.Text.Encoding.GetEncoding("shift-jis")))
            {
                // ファイルへの書き込み
                sw.Write(_ShadowBuf);
            }
#endif
        }

        /***********************************************************//*!
         * @brief ログ表示部から古いログを削除
         * @details 削除されるのは表示部のみ。保存用文字列からは削除しない。
         **************************************************************/
        private void DeleteOld()
        {
            //! ログ表示量が MaxLength-1024 より大きくなったら破棄する
            if (_LogTextBox.Text.Length > (_LogTextBox.MaxLength - 1024))
            {
                _LogTextBox.Text = _LogTextBox.Text.Substring(_LogTextBox.MaxLength / 2);
            }
        }

        /***********************************************************//*!
         * @brief ログ表示部からログをすべて削除
         * @details 削除されるのは表示部のみ。保存用文字列からは削除しない。
         **************************************************************/
        public void Clear()
        {
            _LogTextBox.Text = "";
        }
    }
}