/*
 * blanco Framework
 * Copyright (C) 2004-2006 IGA Tosiki
 * 
 * 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.fixedlength.expand;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;

import org.xml.sax.SAXException;

import blanco.commons.util.BlancoNameAdjuster;
import blanco.fixedlength.valueobject.BlancoFixedLengthFieldStructureDotNet;
import blanco.fixedlength.valueobject.BlancoFixedLengthStructureDotNet;
import blanco.valueobject.BlancoValueObjectDotNetXml2CsClass;
import blanco.valueobject.concretesax.BlancoValueObjectDotNetSerializer;

public class BlancoFixedLengthExpandRecordDotNet {
    /**
     * レコードを展開します。
     * 
     * @param processStructure
     * @param direcotryValueObjectWork
     * @param directoryTarget
     * @throws IOException
     * @throws TransformerException
     */
    public static void expand(
            final BlancoFixedLengthStructureDotNet processStructure,
            final File direcotryValueObjectWork, final File directoryTarget)
            throws IOException, TransformerException {
        final String className = BlancoNameAdjuster
                .toClassName(processStructure.getFileDefinitionId())
                + "FixedLengthRecord";
        final String packageName = processStructure.getPackageName()
                + ".record";
        final File filePojoWork = new File(direcotryValueObjectWork
                .getAbsolutePath()
                + "/" + className + ".xml");

        OutputStream outStream = null;
        try {
            outStream = new BufferedOutputStream(new FileOutputStream(
                    filePojoWork));
            final BlancoValueObjectDotNetSerializer serializer = new BlancoValueObjectDotNetSerializer(
                    outStream);
            serializer.startDocument();
            serializer.startElementWorkbook();
            serializer.characters("\n");
            serializer.startElementSheet("ValueObject");
            serializer.characters("\n");
            serializer.characters("  ");
            serializer.startElementBlancovalueobjectdotnetCommon();
            serializer.characters("\n");
            serializer.characters("    ");
            serializer.startElementName();
            // 名前
            serializer.characters(className);
            serializer.endElementName();
            serializer.characters("\n");
            serializer.characters("    ");
            serializer.startElementPackage();
            serializer.characters(packageName);
            serializer.endElementPackage();
            serializer.characters("\n");
            serializer.characters("    ");
            serializer.startElementDescription();
            serializer.characters("ファイル定義書(固定長)から作成されたレコードクラス");
            serializer.endElementDescription();
            serializer.characters("\n");
            serializer.characters("    ");
            serializer.startElementFileDescription();
            serializer.characters("ファイル定義["
                    + processStructure.getFileDefinitionId()
                    + (processStructure.getFileDescription() == null ? "" : "/"
                            + processStructure.getFileDescription())
                    + "]のレコードクラス\n");
            serializer.endElementFileDescription();
            serializer.characters("\n");
            serializer.characters("  ");
            serializer.endElementBlancovalueobjectdotnetCommon();
            serializer.characters("\n");
            serializer.characters("  ");
            serializer.startElementBlancovalueobjectdotnetList();
            serializer.characters("\n");

            for (int indexField = 0; indexField < processStructure
                    .getListField().size(); indexField++) {
                final BlancoFixedLengthFieldStructureDotNet field = (BlancoFixedLengthFieldStructureDotNet) processStructure
                        .getListField().get(indexField);

                try {
                    String actualType = field.getType();

                    serializer.characters("    ");
                    serializer.startElementField();
                    serializer.characters("\n");
                    serializer.characters("      ");

                    if (field.getNo() != null) {
                        serializer.startElementNo();
                        serializer.characters(field.getNo());
                        serializer.endElementNo();
                    }

                    serializer.characters("\n");
                    serializer.characters("      ");
                    serializer.startElementName();
                    serializer.characters(field.getName());
                    serializer.endElementName();
                    serializer.characters("\n");
                    serializer.characters("      ");
                    serializer.startElementType();
                    serializer.characters(actualType);
                    serializer.endElementType();
                    serializer.characters("\n");

                    serializer.characters("      ");
                    serializer.startElementDescription();
                    if (field.getNo() != null) {
                        serializer.characters("項目番号: " + field.getNo() + "\n");
                    }
                    if (field.getDescription() != null) {
                        serializer.characters("項目の説明: "
                                + field.getDescription() + "\n");
                    }

                    serializer.characters("長さ: " + field.getLength() + "\n");

                    serializer.endElementDescription();
                    serializer.characters("\n");

                    if (field.getDefault() != null) {
                        serializer.characters("      ");
                        serializer.startElementDefault();
                        serializer.characters(field.getDefault());
                        serializer.endElementDefault();
                        serializer.characters("\n");
                    }

                    serializer.characters("    ");
                    serializer.endElementField();
                    serializer.characters("\n");
                } catch (SAXException e) {
                    e.printStackTrace();
                }
            }

            serializer.characters("  ");
            serializer.endElementBlancovalueobjectdotnetList();
            serializer.characters("\n");
            serializer.endElementSheet();
            serializer.characters("\n");
            serializer.endElementWorkbook();
            serializer.endDocument();

            outStream.flush();
            outStream.close();
            outStream = null;

            new BlancoValueObjectDotNetXml2CsClass().process(filePojoWork,
                    directoryTarget);
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } finally {
            try {
                if (outStream != null) {
                    outStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
