/*
 * blanco Framework
 * Copyright (C) 2004-2007 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.text.converter;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;

import blanco.text.converter.valueobject.BlancoTextConverterSrcTxtStructure;

/**
 * 「ソーステキスト」から「HTMLファイル」に変換します。
 * 
 * この前に、SrcTxtへのインポート展開は終了している必要がありそうです。
 */
public class BlancoTextConverterSrcTxt2Html {
    public void convert(final File inFile, final File outFile)
            throws IOException {
        convertInternal(inFile, outFile);
    }

    private void convertInternal(final File inFile, final File outFile)
            throws IOException {
        BlancoTextConverterSrcTxtStructure structure = null;
        {
            // ファイルの内容を読み込み。
            byte[] wrk = readFile(inFile);

            // インポート展開。
            {
                final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                final BufferedReader reader = new BufferedReader(
                        new InputStreamReader(new ByteArrayInputStream(wrk)));
                final BufferedWriter writer = new BufferedWriter(
                        new OutputStreamWriter(outStream));
                new BlancoTextConverterSrcTxtCmdInclude().execute(reader,
                        writer);
                reader.close();
                writer.close();

                wrk = outStream.toByteArray();
            }

            // パースして構造体に変換。
            {
                final BufferedReader reader = new BufferedReader(
                        new InputStreamReader(new ByteArrayInputStream(wrk)));
                structure = new BlancoTextConverterSrcTxtParser().parse(reader);
                reader.close();
            }
        }

        {
            final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            final BufferedWriter writer = new BufferedWriter(
                    new OutputStreamWriter(outStream,
                            BlancoTextConverterConstants.HTML_ENCODING));
            // 構造体の内容をファイルに書き込み！
            new BlancoTextConverterSrcTxtStructure2Html().structure2File(
                    structure, writer);
            writer.close();

            final byte[] wrk = outStream.toByteArray();
            writeFile(wrk, inFile.lastModified(), outFile);
        }
    }

    private void writeFile(final byte[] outBytes, final long lastModified,
            final File outFile) throws IOException {
        BufferedReader reader = null;
        BufferedWriter writer = null;
        try {
            reader = new BufferedReader(new InputStreamReader(
                    new ByteArrayInputStream(outBytes),
                    BlancoTextConverterConstants.HTML_ENCODING));
            writer = new BufferedWriter(new OutputStreamWriter(
                    new FileOutputStream(outFile),
                    BlancoTextConverterConstants.HTML_ENCODING));

            copy(reader, writer);

            reader.close();
            reader = null;
            writer.close();
            writer = null;

            outFile.setLastModified(lastModified);
        } finally {
            if (reader != null) {
                reader.close();
            }
            if (writer != null) {
                writer.close();
            }
        }
    }

    private byte[] readFile(final File inFile) throws IOException {
        final ByteArrayOutputStream outBytes = new ByteArrayOutputStream();

        BufferedReader reader = null;
        BufferedWriter writer = null;
        try {
            reader = new BufferedReader(new InputStreamReader(
                    new FileInputStream(inFile)));

            writer = new BufferedWriter(new OutputStreamWriter(outBytes));

            copy(reader, writer);

            reader.close();
            reader = null;
            writer.close();
            writer = null;
        } finally {
            if (reader != null) {
                reader.close();
            }
            if (writer != null) {
                writer.close();
            }
        }

        return outBytes.toByteArray();
    }

    private void copy(final Reader reader, final Writer writer)
            throws IOException {
        final char[] buf = new char[8192];
        for (;;) {
            final int length = reader.read(buf, 0, buf.length);
            if (length < 0) {
                break;
            }
            writer.write(buf, 0, length);
        }
    }
}
