package net.argius.filetool;

import java.io.*;
import java.util.*;
import java.util.zip.*;

import jp.gr.java_conf.dangan.util.lha.*;

/**
 * LHAアーカイバ。
 * jLHAを使用してLZH形式のアーカイブを作成する。
 */
public final class LhaArchiver implements Archiver {

    private LhaOutputStream los;
    private boolean includesDirectory;

    /**
     * LhaArchiverの生成。
     * @param os 出力先ストリーム
     */
    public LhaArchiver(OutputStream os) {
        this.los = new LhaOutputStream(os);
        this.includesDirectory = true;
    }

    /**
     * includesDirectoryの設定。
     * @param includesDirectory includesDirectory
     */
    public void setIncludesDirectory(boolean includesDirectory) {
        this.includesDirectory = includesDirectory;
    }

    /* (overridden)
     * @see net.argius.filetool.compress.Archiver#addEntry(net.argius.filetool.compress.ArchiverEntry, java.io.InputStream, int, long)
     */
    public void addEntry(ArchiveEntry ae, InputStream is, long length) throws IOException {
        if (ae.isDirectory()) {
            // ディレクトリ
            if (includesDirectory) {
                LhaHeader header = new LhaHeader(ae.getName());
                header.setCompressMethod(CompressMethod.LHD);
                header.setCRC(0);
                header.setOriginalSize(0);
                header.setCompressedSize(0);
                header.setLastModified(new Date(ae.getLastModified()));
                los.putNextEntry(header);
                los.closeEntry();
            }
        } else {
            // ファイル
            LhaHeader header = new LhaHeader(ae.getName());
            los.putNextEntry(header);
            CheckedInputStream cis = new CheckedInputStream(is, new CRC32());
            long totalSize = IOUtilities.transferAll(cis, los);
            header.setCRC((int)cis.getChecksum().getValue()); // long->int
            header.setOriginalSize(totalSize);
            header.setCompressedSize(totalSize);
            header.setLastModified(new Date(ae.getLastModified()));
            los.closeEntry();
        }
    }

    /* (overridden)
     * @see java.io.Closeable#close()
     */
    public void close() throws IOException {
        los.close();
    }

}
