/*
 * blancoCsv Copyright (C) 2005 Tosiki Iga
 * 
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 */
package blanco.csv.expand;

import java.io.File;

import blanco.csv.resourcebundle.BlancoCsvRuntimeUtilDotNetResourceBundle;
import blanco.csv.valueobject.BlancoCsvStructureDotNet;
import blanco.ig.expander.ClassExpander;
import blanco.ig.expander.IgType;
import blanco.ig.expander.IgValue;
import blanco.ig.expander.method.MethodExpander;

public class BlancoCsvExpandRuntimeUtilDotNet {
    final BlancoCsvRuntimeUtilDotNetResourceBundle bundle = new BlancoCsvRuntimeUtilDotNetResourceBundle();

    public void expand(final BlancoCsvStructureDotNet processStructure,
            final File directoryTarget) {

        final String className = bundle.getClassName();
        final ClassExpander classExpander = new ClassExpander(new IgType(
                processStructure.getRuntimePackage()
                        + bundle.getPackagePrefix(), className)) {
            protected void expandClassStruct() {
                addFileComment(bundle.getFilecomment());
                getJavaDoc().addLine(bundle.getClasscomment01());
                getJavaDoc().addLine(bundle.getClasscomment02());
                addImport(new IgType("System.String"));
                addImport(new IgType("System.IO.StringReader"));
                addImport(new IgType("System.Text.StringBuilder"));
                addImport(new IgType(processStructure.getRuntimePackage()
                        + ".io.BlancoCsvIOException"));

                /**
                 * ReadTokenメソッドを展開します。
                 */
                addMethod(new MethodExpander(bundle.getReadtokenName()) {
                    protected boolean isStatic() {
                        return true;
                    }

                    // メソッドのシグニチャ指定
                    public void setupSignature() {
                        getJavaDoc().addLine(bundle.getReadtokenJavadoc());
                        addArgument(new IgValue(new IgType(bundle
                                .getReadtokenArg01Type()), bundle
                                .getReadtokenArg01Name()));
                        getJavaDoc().addParameter(
                                bundle.getReadtokenArg01Name(),
                                bundle.getReadtokenArg01Javadoc());

                        addArgument(new IgValue(new IgType(bundle
                                .getReadtokenArg02Type()), bundle
                                .getReadtokenArg02Name()));
                        getJavaDoc().addParameter(
                                bundle.getReadtokenArg02Name(),
                                bundle.getReadtokenArg02Javadoc());

                        addArgument(new IgValue(new IgType(bundle
                                .getReadtokenArg03Type()), bundle
                                .getReadtokenArg03Name()));
                        getJavaDoc().addParameter(
                                bundle.getReadtokenArg03Name(),
                                bundle.getReadtokenArg03Javadoc());

                        setReturnType(new IgType(bundle
                                .getReadtokenReturnType()));
                        getJavaDoc().addReturn(
                                bundle.getReadtokenReturnJavadoc());
                    }

                    // メソッドの実装
                    public void implement() {
                        getData().addLine("if (argReader == null)");
                        getData().addLine("{");
                        getData()
                                .addLine(
                                        "throw new ArgumentException(\"ReadTokenメソッドのリーダにnullが与えられました。\");");
                        getData().addLine("}");

                        getData().addLine(bundle.getReadtokenLine01());
                        getData().addLine(bundle.getReadtokenLine02());
                        getData().addLine(bundle.getReadtokenLine03());
                        getData().addLine(bundle.getReadtokenLine04());
                        getData().addLine(bundle.getReadtokenLine05());
                        getData().addLine(bundle.getReadtokenLine06());
                        getData().addLine(bundle.getReadtokenLine07());
                        getData().addLine(bundle.getReadtokenLine08());
                        getData().addLine(bundle.getReadtokenLine09());
                        getData().addLine(bundle.getReadtokenLine10());
                        getData().addLine(bundle.getReadtokenLine11());
                        getData().addLine(bundle.getReadtokenLine12());
                        getData().addLine(bundle.getReadtokenLine13());
                        getData().addLine(bundle.getReadtokenLine14());
                        getData().addLine(bundle.getReadtokenLine15());
                        getData().addLine(bundle.getReadtokenLine16());
                        getData().addLine(bundle.getReadtokenLine17());
                        getData().addLine(bundle.getReadtokenLine18());
                        getData().addLine(bundle.getReadtokenLine19());
                        getData().addLine(bundle.getReadtokenLine20());
                    }
                });

                /**
                 * ReadTokenWithQuoteメソッドを展開します。
                 */
                addMethod(new MethodExpander(bundle.getReadtokenwithquoteName()) {
                    protected boolean isStatic() {
                        return true;
                    }

                    // メソッドのシグニチャ指定
                    public void setupSignature() {
                        getJavaDoc().addLine(
                                bundle.getReadtokenwithquoteJavadoc());

                        addArgument(new IgValue(new IgType(bundle
                                .getReadtokenwithquoteArg01Type()), bundle
                                .getReadtokenwithquoteArg01Name()));
                        getJavaDoc().addParameter(
                                bundle.getReadtokenwithquoteArg01Name(),
                                bundle.getReadtokenwithquoteArg01Javadoc());

                        addArgument(new IgValue(new IgType(bundle
                                .getReadtokenwithquoteArg02Type()), bundle
                                .getReadtokenwithquoteArg02Name()));
                        getJavaDoc().addParameter(
                                bundle.getReadtokenwithquoteArg02Name(),
                                bundle.getReadtokenwithquoteArg02Javadoc());

                        setReturnType(new IgType(bundle
                                .getReadtokenwithquoteReturnType()));
                        getJavaDoc().addReturn(
                                bundle.getReadtokenwithquoteReturnJavadoc());
                    }

                    // メソッドの実装
                    public void implement() {
                        getData().addLine("if (argReader == null)");
                        getData().addLine("{");
                        getData()
                                .addLine(
                                        "throw new ArgumentException(\"ReadTokenWithQuoteメソッドのリーダにnullが与えられました。\");");
                        getData().addLine("}");

                        getData().addLine(bundle.getReadtokenwithquoteLine01());
                        getData().addLine(bundle.getReadtokenwithquoteLine02());
                        getData().addLine(
                                bundle.getReadtokenwithquoteLine0301());
                        getData().addLine(
                                bundle.getReadtokenwithquoteLine0302());
                        getData().addLine(
                                bundle.getReadtokenwithquoteLine0303());
                        getData().addLine(
                                bundle.getReadtokenwithquoteLine0401());
                        getData().addLine(
                                bundle.getReadtokenwithquoteLine0402());
                        getData().addLine(
                                bundle.getReadtokenwithquoteLine0403());
                        getData().addLine(
                                bundle.getReadtokenwithquoteLine0404());
                        getData().addLine(
                                bundle.getReadtokenwithquoteLine0405());
                        getData().addLine(
                                bundle.getReadtokenwithquoteLine0406());
                        getData().addLine(
                                bundle.getReadtokenwithquoteLine0407());
                        getData().addLine(
                                bundle.getReadtokenwithquoteLine0408());
                        getData().addLine(
                                bundle.getReadtokenwithquoteLine0409());
                        getData().addLine(
                                bundle.getReadtokenwithquoteLine0410());
                        getData().addLine(
                                bundle.getReadtokenwithquoteLine0411());
                        getData().addLine(bundle.getReadtokenwithquoteLine05());
                        getData().addLine(bundle.getReadtokenwithquoteLine06());
                        getData().addLine(bundle.getReadtokenwithquoteLine07());
                        getData().addLine(bundle.getReadtokenwithquoteLine08());
                        getData().addLine(bundle.getReadtokenwithquoteLine09());
                        getData().addLine(bundle.getReadtokenwithquoteLine10());
                        getData().addLine(bundle.getReadtokenwithquoteLine11());
                        getData().addLine(bundle.getReadtokenwithquoteLine12());
                        getData().addLine(bundle.getReadtokenwithquoteLine13());
                        getData().addLine(bundle.getReadtokenwithquoteLine14());
                        getData().addLine(bundle.getReadtokenwithquoteLine15());
                        getData().addLine(bundle.getReadtokenwithquoteLine16());
                        getData().addLine(bundle.getReadtokenwithquoteLine17());
                        getData().addLine(bundle.getReadtokenwithquoteLine18());
                        getData().addLine(bundle.getReadtokenwithquoteLine19());
                        getData().addLine(bundle.getReadtokenwithquoteLine20());
                        getData().addLine(bundle.getReadtokenwithquoteLine21());
                        getData().addLine(bundle.getReadtokenwithquoteLine22());
                        getData().addLine(bundle.getReadtokenwithquoteLine23());
                        getData().addLine(bundle.getReadtokenwithquoteLine24());
                        getData().addLine(bundle.getReadtokenwithquoteLine25());
                        getData().addLine(bundle.getReadtokenwithquoteLine26());
                        getData().addLine(bundle.getReadtokenwithquoteLine27());
                        getData().addLine(bundle.getReadtokenwithquoteLine28());
                        getData().addLine(bundle.getReadtokenwithquoteLine29());
                        getData().addLine(
                                bundle.getReadtokenwithquoteLine3001());
                        getData().addLine(
                                bundle.getReadtokenwithquoteLine3002());
                        getData().addLine(bundle.getReadtokenwithquoteLine31());
                        getData().addLine(bundle.getReadtokenwithquoteLine32());
                        getData().addLine(bundle.getReadtokenwithquoteLine33());
                        getData().addLine(bundle.getReadtokenwithquoteLine35());
                        getData().addLine(bundle.getReadtokenwithquoteLine36());
                        getData().addLine(bundle.getReadtokenwithquoteLine37());
                        getData().addLine(bundle.getReadtokenwithquoteLine38());
                        getData().addLine(bundle.getReadtokenwithquoteLine39());
                        getData().addLine(bundle.getReadtokenwithquoteLine40());
                        getData().addLine(bundle.getReadtokenwithquoteLine41());
                        getData().addLine(bundle.getReadtokenwithquoteLine42());
                        getData().addLine(bundle.getReadtokenwithquoteLine43());
                        getData().addLine(bundle.getReadtokenwithquoteLine44());
                        getData().addLine(bundle.getReadtokenwithquoteLine45());
                        getData().addLine(bundle.getReadtokenwithquoteLine46());
                        getData().addLine(bundle.getReadtokenwithquoteLine47());
                        getData().addLine(bundle.getReadtokenwithquoteLine48());
                    }
                });

                addMethod(new MethodExpander(bundle.getGettokenwithquoteName()) {
                    protected boolean isStatic() {
                        return true;
                    }

                    // メソッドのシグニチャ指定
                    public void setupSignature() {
                        getJavaDoc().addLine(
                                bundle.getGettokenwithquoteJavadoc());

                        addArgument(new IgValue(new IgType(bundle
                                .getGettokenwithquoteArg01Type()), "value"));
                        getJavaDoc().addParameter("value",
                                bundle.getGettokenwithquoteArg01Javadoc());

                        setReturnType(new IgType(bundle
                                .getGettokenwithquoteReturnType()));
                        getJavaDoc().addReturn(
                                bundle.getGettokenwithquoteReturnJavadoc());
                    }

                    // メソッドの実装
                    public void implement() {
                        getData().addLine("if (value == null)");
                        getData().addLine("{");
                        getData()
                                .addLine(
                                        "throw new ArgumentException(\"GetTokenWithQuoteメソッドのvalueにnullが与えられました。\");");
                        getData().addLine("}");

                        addUsingType(new IgType(bundle
                                .getGettokenwithquoteAddusingtype01()));
                        addUsingType(new IgType(bundle
                                .getGettokenwithquoteAddusingtype02()));
                        getData().addLine(bundle.getGettokenwithquoteLine01());
                        getData().addLine(bundle.getGettokenwithquoteLine02());
                        getData().addLine(bundle.getGettokenwithquoteLine03());
                        getData().addLine(bundle.getGettokenwithquoteLine04());
                        getData().addLine(bundle.getGettokenwithquoteLine05());
                        getData().addLine(bundle.getGettokenwithquoteLine06());
                        getData().addLine(bundle.getGettokenwithquoteLine07());
                        getData().addLine(bundle.getGettokenwithquoteLine08());
                        getData().addLine(bundle.getGettokenwithquoteLine09());
                        getData().addLine(bundle.getGettokenwithquoteLine10());
                        getData().addLine(bundle.getGettokenwithquoteLine11());
                        getData().addLine(bundle.getGettokenwithquoteLine12());
                        getData().addLine(bundle.getGettokenwithquoteLine13());
                        getData().addLine(bundle.getGettokenwithquoteLine14());
                        getData().addLine(bundle.getGettokenwithquoteLine15());
                        getData().addLine(bundle.getGettokenwithquoteLine16());
                        getData().addLine(bundle.getGettokenwithquoteLine17());
                        getData().addLine(bundle.getGettokenwithquoteLine18());
                        getData().addLine(bundle.getGettokenwithquoteLine19());
                        getData().addLine(bundle.getGettokenwithquoteLine20());
                        getData().addLine(bundle.getGettokenwithquoteLine21());
                    }
                });

                addMethod(new MethodExpander("GetBytes") {
                    protected boolean isStatic() {
                        return true;
                    }

                    public void setupSignature() {
                        getJavaDoc().addLine("文字列をバイト配列に変換します。");
                        getJavaDoc().addParameter("inputString", "変換元の文字列。");
                        addArgument(new IgValue(new IgType("string"),
                                "inputString"));
                        getJavaDoc().addReturn("バイト配列に変換後の文字列。");
                        setReturnType(new IgType("byte[]"));
                    }

                    public void implement() {
                        getData().addLine("if (inputString == null)");
                        getData().addLine("{");
                        getData()
                                .addLine(
                                        "throw new ArgumentException(\"GetBytesメソッドにnullが与えられました。\");");
                        getData().addLine("}");

                        getData().addLine("// 文字列をバイト配列に変換します。");
                        getData()
                                .addLine(
                                        "byte[] inputBytes = Encoding.Unicode.GetBytes(inputString);");
                        getData()
                                .addLine(
                                        "// エンコーディングを取得します。ここではシフトJISへのエンコーディングを取得しています。");
                        getData()
                                .addLine("//TODO: 定義書で指定されているエンコードをする必要があります。");
                        getData()
                                .addLine(
                                        "Encoding targetEncoding = Encoding.GetEncoding(932);");
                        getData().addLine("// 実際にコードを変換。");
                        getData()
                                .addLine(
                                        "return Encoding.Convert(Encoding.Unicode, targetEncoding, inputBytes);");
                    }
                });
            }
        };

        ClassExpander.generateCsSource(classExpander, directoryTarget);
    }
}
