// This code is generated by blanco Framework.
// <summary>ファイル定義書(CSV)から作成されたライタクラス。</summary>
using System;
using System.IO;

using blanco.sample.csv.record;
using blanco.sample.csv.util;

namespace blanco.sample.csv.io
{
    /// <summary>ファイル定義[BlancoCsvSampleDotNet/このクラスは単にサンプルです。実際の動作には利用されません。]のライタクラス。</summary>
    /// <remarks>
    /// <newpara>このクラスはファイル定義書(CSV)から自動生成されたライタクラスです。</newpara>
    /// <newpara>　1.文字列長チェックには、デフォルトエンコーディングを利用します。</newpara>
    /// <newpara>　2.クラスの利用した後は必ず Close()を呼び出してください。</newpara>
    /// </remarks>
    public class BlancoCsvSampleDotNetCsvWriter
    {
        /// <summary>ライタオブジェクト。</summary>
        /// <remarks>
        /// <newpara>内部的に実際に出力を行うのライタを記憶します。</newpara>
        /// </remarks>
        private TextWriter fWriter;

        /// <summary>処理中の行カウンタ。</summary>
        /// <remarks>
        /// <newpara>現在処理を行っている行の位置を記憶します。</newpara>
        /// </remarks>
        private long fLineCounter = 0;

        /// <summary>項目[field_5]の書き込みの際に利用するフォーマッター。</summary>
        /// <remarks>
        /// <newpara>※インスタンス化しておくことによりメモリゴミ発生を抑制します。</newpara>
        /// </remarks>
        private string fSimpleDateFormatField5;

        /// <summary>項目[field_15]の書き込みの際に利用するフォーマッター。</summary>
        /// <remarks>
        /// <newpara>※インスタンス化しておくことによりメモリゴミ発生を抑制します。</newpara>
        /// </remarks>
        private string fSimpleDateFormatField15;

        /// <summary>CSVライタクラスのコンストラクタ。</summary>
        /// <remarks>
        /// <newpara>与えられたライタと連結します。</newpara>
        /// </remarks>
        /// <param name="arg">連結するライタ。</param>
        public BlancoCsvSampleDotNetCsvWriter(TextWriter arg)
        {
            fWriter = arg;
            fSimpleDateFormatField5 = "yyyy/MM/dd HH:mm:ss";
            fSimpleDateFormatField15 = "yyyy/MM/dd HH:mm:ss";
        }

        /// <summary>CSVファイルのタイトル行をを書き出します。</summary>
        /// <remarks>
        /// <newpara>タイトルはデリミタで区切られながらライタに出力され、最後に改行コードが付与されます。</newpara>
        /// <newpara>タイトルはダブルクオーテーションで囲まれます。</newpara>
        /// </remarks>
        public void writeTitle()
        {
            fWriter.Write("\"フィールド1\"");
            fWriter.Write(",\"フィールド2\"");
            fWriter.Write(",\"フィールド3\"");
            fWriter.Write(",\"フィールド4\"");
            fWriter.Write(",\"フィールド5\"");
            fWriter.Write(",\"フィールド6\"");
            fWriter.Write(",\"フィールド11\"");
            fWriter.Write(",\"フィールド12\"");
            fWriter.Write(",\"フィールド13\"");
            fWriter.Write(",\"フィールド14\"");
            fWriter.Write(",\"フィールド15\"");
            fWriter.Write(",\"フィールド16\"");
            fWriter.WriteLine();
        }

        /// <summary>与えられた一行を書き出します。</summary>
        /// <remarks>
        /// <newpara>データはデリミタで区切られながらライタに出力され、最後に改行コードが付与されます。</newpara>
        /// </remarks>
        /// <param name="record">レコードオブジェクト。</param>
        public void WriteRecord(BlancoCsvSampleDotNetCsvRecord record)
        {
            string writeToken = null;

            // 項目番号[1] 項目名[field_1/フィールド1]
            // 任意項目で文字列の項目に nullまたは長さ0の文字列が与えられた場合には、いずれも値が入っていないものとみなします。
            // この場合には長さチェックは行いません。
            writeToken = record.GetField1() == null ? "" : record.GetField1();
            if (writeToken.Length > 0) {
                if (BlancoCsvRuntimeUtil.GetBytes(writeToken).Length < 1) {
                    throw new BlancoCsvIOException("出力" + (fLineCounter + 1) + "行目 1項目目。項目番号[1] 項目名[field_1/フィールド1]の処理中においてMIN長さ(1)よりも短い値[" + writeToken + "]を検知しました。");
                }
                if (BlancoCsvRuntimeUtil.GetBytes(writeToken).Length > 10) {
                    throw new BlancoCsvIOException("出力" + (fLineCounter + 1) + "行目 1項目目。項目番号[1] 項目名[field_1/フィールド1]の処理中においてMAX長さ(10)よりも長い値[" + writeToken + "]を検知しました。");
                }
            }
            if (writeToken.IndexOf(",") >= 0) {
                throw new BlancoCsvIOException("出力" + (fLineCounter + 1) + "行目 1項目目。項目番号[1] 項目名[field_1/フィールド1]の処理中においてデータ中[" + writeToken + "]に項目のデリミタ[,]が含まれることを検知しました。");
            }
            fWriter.Write(writeToken);
            fWriter.Write(',');

            // 項目番号[2] 項目名[field_2/フィールド2]
            // 任意項目で文字列の項目に nullまたは長さ0の文字列が与えられた場合には、いずれも値が入っていないものとみなします。
            // この場合には長さチェックは行いません。
            writeToken = record.GetField2() == null ? "" : record.GetField2();
            if (writeToken.Length > 0) {
                if (BlancoCsvRuntimeUtil.GetBytes(writeToken).Length < 4) {
                    throw new BlancoCsvIOException("出力" + (fLineCounter + 1) + "行目 2項目目。項目番号[2] 項目名[field_2/フィールド2]の処理中においてMIN長さ(4)よりも短い値[" + writeToken + "]を検知しました。");
                }
                if (BlancoCsvRuntimeUtil.GetBytes(writeToken).Length > 4) {
                    throw new BlancoCsvIOException("出力" + (fLineCounter + 1) + "行目 2項目目。項目番号[2] 項目名[field_2/フィールド2]の処理中においてMAX長さ(4)よりも長い値[" + writeToken + "]を検知しました。");
                }
            }
            // ダブルクオート処理付きで書き出しを行います。
            fWriter.Write(BlancoCsvRuntimeUtil.GetTokenWithQuote(writeToken));
            fWriter.Write(',');

            // 項目番号[3] 項目名[field_3/フィールド3]
            if (record.GetField3() == int.MinValue) {
                writeToken = "";
            } else {
                writeToken = record.GetField3().ToString();
            }
            fWriter.Write(writeToken);
            fWriter.Write(',');

            // 項目番号[4] 項目名[field_4/フィールド4]
            if (record.GetField4() == long.MinValue) {
                writeToken = "";
            } else {
                writeToken = record.GetField4().ToString();
            }
            fWriter.Write(writeToken);
            fWriter.Write(',');

            // 項目番号[5] 項目名[field_5/フィールド5]
            if (record.GetField5() == System.DateTime.MinValue) {
                writeToken = "";
            } else {
                writeToken = record.GetField5().ToString(fSimpleDateFormatField5);
            }
            fWriter.Write(writeToken);
            fWriter.Write(',');

            // 項目番号[6] 項目名[field_6/フィールド6]
            if (record.GetField6() == decimal.MinValue) {
                writeToken = "";
            } else {
                writeToken = record.GetField6().ToString();
            }
            fWriter.Write(writeToken);
            fWriter.Write(',');

            // 項目番号[7] 項目名[field_11/フィールド11]
            if (record.GetField11() == null) {
                throw new BlancoCsvIOException("出力" + (fLineCounter + 1) + "行目 7項目目。項目番号[7] 項目名[field_11/フィールド11]の処理中において必須項目にnullが与えられていることを検知しました。");
            }
            if (record.GetField11().Length == 0) {
                throw new BlancoCsvIOException("出力" + (fLineCounter + 1) + "行目 7項目目。項目番号[7] 項目名[field_11/フィールド11]の処理中において必須項目に長さ0の文字列が与えられていることを検知しました。");
            }
            writeToken = record.GetField11();
            if (writeToken == null) {
                throw new BlancoCsvIOException("出力" + (fLineCounter + 1) + "行目 7項目目。項目番号[7] 項目名[field_11/フィールド11]の処理中において必須項目にnullが与えられていることを検知しました。");
            }
            if (BlancoCsvRuntimeUtil.GetBytes(writeToken).Length < 1) {
                throw new BlancoCsvIOException("出力" + (fLineCounter + 1) + "行目 7項目目。項目番号[7] 項目名[field_11/フィールド11]の処理中においてMIN長さ(1)よりも短い値[" + writeToken + "]を検知しました。");
            }
            if (BlancoCsvRuntimeUtil.GetBytes(writeToken).Length > 10) {
                throw new BlancoCsvIOException("出力" + (fLineCounter + 1) + "行目 7項目目。項目番号[7] 項目名[field_11/フィールド11]の処理中においてMAX長さ(10)よりも長い値[" + writeToken + "]を検知しました。");
            }
            if (writeToken.IndexOf(",") >= 0) {
                throw new BlancoCsvIOException("出力" + (fLineCounter + 1) + "行目 7項目目。項目番号[7] 項目名[field_11/フィールド11]の処理中においてデータ中[" + writeToken + "]に項目のデリミタ[,]が含まれることを検知しました。");
            }
            fWriter.Write(writeToken);
            fWriter.Write(',');

            // 項目番号[8] 項目名[field_12/フィールド12]
            if (record.GetField12() == null) {
                throw new BlancoCsvIOException("出力" + (fLineCounter + 1) + "行目 8項目目。項目番号[8] 項目名[field_12/フィールド12]の処理中において必須項目にnullが与えられていることを検知しました。");
            }
            if (record.GetField12().Length == 0) {
                throw new BlancoCsvIOException("出力" + (fLineCounter + 1) + "行目 8項目目。項目番号[8] 項目名[field_12/フィールド12]の処理中において必須項目に長さ0の文字列が与えられていることを検知しました。");
            }
            writeToken = record.GetField12();
            if (writeToken == null) {
                throw new BlancoCsvIOException("出力" + (fLineCounter + 1) + "行目 8項目目。項目番号[8] 項目名[field_12/フィールド12]の処理中において必須項目にnullが与えられていることを検知しました。");
            }
            if (BlancoCsvRuntimeUtil.GetBytes(writeToken).Length < 4) {
                throw new BlancoCsvIOException("出力" + (fLineCounter + 1) + "行目 8項目目。項目番号[8] 項目名[field_12/フィールド12]の処理中においてMIN長さ(4)よりも短い値[" + writeToken + "]を検知しました。");
            }
            if (BlancoCsvRuntimeUtil.GetBytes(writeToken).Length > 4) {
                throw new BlancoCsvIOException("出力" + (fLineCounter + 1) + "行目 8項目目。項目番号[8] 項目名[field_12/フィールド12]の処理中においてMAX長さ(4)よりも長い値[" + writeToken + "]を検知しました。");
            }
            // ダブルクオート処理付きで書き出しを行います。
            fWriter.Write(BlancoCsvRuntimeUtil.GetTokenWithQuote(writeToken));
            fWriter.Write(',');

            // 項目番号[9] 項目名[field_13/フィールド13]
            writeToken = record.GetField13().ToString();
            if (record.GetField13() == int.MinValue) {
                throw new BlancoCsvIOException("出力" + (fLineCounter + 1) + "行目 9項目目。項目番号[9] 項目名[field_13/フィールド13]の処理中において必須項目に値が入っていない(MinValueの値である)ことを検知しました。");
            }
            fWriter.Write(writeToken);
            fWriter.Write(',');

            // 項目番号[10] 項目名[field_14/フィールド14]
            writeToken = record.GetField14().ToString();
            if (record.GetField14() == long.MinValue) {
                throw new BlancoCsvIOException("出力" + (fLineCounter + 1) + "行目 10項目目。項目番号[10] 項目名[field_14/フィールド14]の処理中において必須項目に値が入っていない(MinValueの値である)ことを検知しました。");
            }
            fWriter.Write(writeToken);
            fWriter.Write(',');

            // 項目番号[11] 項目名[field_15/フィールド15]
            writeToken = record.GetField15().ToString(fSimpleDateFormatField15);
            if (record.GetField15() == System.DateTime.MinValue) {
                throw new BlancoCsvIOException("出力" + (fLineCounter + 1) + "行目 11項目目。項目番号[11] 項目名[field_15/フィールド15]の処理中において必須項目に値が入っていない(MinValueの値である)ことを検知しました。");
            }
            fWriter.Write(writeToken);
            fWriter.Write(',');

            // 項目番号[12] 項目名[field_16/フィールド16]
            writeToken = record.GetField16().ToString();
            if (record.GetField16() == decimal.MinValue) {
                throw new BlancoCsvIOException("出力" + (fLineCounter + 1) + "行目 12項目目。項目番号[12] 項目名[field_16/フィールド16]の処理中において必須項目に値が入っていない(MinValueの値である)ことを検知しました。");
            }
            fWriter.Write(writeToken);

            // 最後に改行コードが付与されます。
            fWriter.WriteLine();
            fLineCounter++;
        }

        /// <summary>現在処理中の行カウンタを返します。</summary>
        /// <returns>現在処理中の行カウンタ。</returns>
        public long GetLineCounter()
        {
            return fLineCounter;
        }

        /// <summary>このライタをフラッシュします。</summary>
        /// <remarks>
        /// <newpara>関連づけられていたライタに対してもflush()を呼び出します。</newpara>
        /// </remarks>
        public void Flush()
        {
            fWriter.Flush();
        }

        /// <summary>このライタを閉じます。</summary>
        /// <remarks>
        /// <newpara>関連づけられていたライタに対してもClose()を呼び出します。</newpara>
        /// </remarks>
        public void Close()
        {
            fWriter.Close();
        }
    }
}
