/*-
 * Copyright (C) 2021 Erik Larsson
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.catacombae.hfsexplorer.types.dsstore;

import java.io.PrintStream;
import org.catacombae.util.Util;

/** This class was generated by CStructToJavaClass. */
public class DSStoreTreeBlock {
    /*
     * struct DSStoreTreeBlock
     * size: 20 bytes
     * description:
     *
     * BP  Size  Type  Identifier              Description
     * ---------------------------------------------------
     * 0   4     be32  firstDataBlockID
     * 4   4     be32  recordsInTree
     * 8   4     be32  levelsOfInternalBlocks
     * 12  4     be32  totalTreeBlocks
     * 16  4     be32  unknownAlways0x1000
     */

    public static final int STRUCTSIZE = 20;

    private int firstDataBlockID;
    private int recordsInTree;
    private int levelsOfInternalBlocks;
    private int totalTreeBlocks;
    private int unknownAlways0x1000;

    public DSStoreTreeBlock(byte[] data, int offset) {
        this.firstDataBlockID = Util.readIntBE(data, offset + 0);
        this.recordsInTree = Util.readIntBE(data, offset + 4);
        this.levelsOfInternalBlocks = Util.readIntBE(data, offset + 8);
        this.totalTreeBlocks = Util.readIntBE(data, offset + 12);
        this.unknownAlways0x1000 = Util.readIntBE(data, offset + 16);
    }

    public static int length() { return STRUCTSIZE; }

    /**  */
    public final long getFirstDataBlockID() {
        return Util.unsign(getRawFirstDataBlockID());
    }

    /**  */
    public final long getRecordsInTree() {
        return Util.unsign(getRawRecordsInTree());
    }

    /**  */
    public final long getLevelsOfInternalBlocks() {
        return Util.unsign(getRawLevelsOfInternalBlocks());
    }

    /**  */
    public final long getTotalTreeBlocks() {
        return Util.unsign(getRawTotalTreeBlocks());
    }

    /**  */
    public final long getUnknownAlways0x1000() {
        return Util.unsign(getRawUnknownAlways0x1000());
    }

    /**
     * <b>Note that the return value from this function should be interpreted as
     * an unsigned integer, for instance using Util.unsign(...).</b>
     */
    public final int getRawFirstDataBlockID() {
        return this.firstDataBlockID;
    }

    /**
     * <b>Note that the return value from this function should be interpreted as
     * an unsigned integer, for instance using Util.unsign(...).</b>
     */
    public final int getRawRecordsInTree() {
        return this.recordsInTree;
    }

    /**
     * <b>Note that the return value from this function should be interpreted as
     * an unsigned integer, for instance using Util.unsign(...).</b>
     */
    public final int getRawLevelsOfInternalBlocks() {
        return this.levelsOfInternalBlocks;
    }

    /**
     * <b>Note that the return value from this function should be interpreted as
     * an unsigned integer, for instance using Util.unsign(...).</b>
     */
    public final int getRawTotalTreeBlocks() {
        return this.totalTreeBlocks;
    }

    /**
     * <b>Note that the return value from this function should be interpreted as
     * an unsigned integer, for instance using Util.unsign(...).</b>
     */
    public final int getRawUnknownAlways0x1000() {
        return this.unknownAlways0x1000;
    }

    public void printFields(PrintStream ps, String prefix) {
        ps.println(prefix + " firstDataBlockID: " + getFirstDataBlockID());
        ps.println(prefix + " recordsInTree: " + getRecordsInTree());
        ps.println(prefix + " levelsOfInternalBlocks: " + getLevelsOfInternalBlocks());
        ps.println(prefix + " totalTreeBlocks: " + getTotalTreeBlocks());
        ps.println(prefix + " unknownAlways0x1000: " + getUnknownAlways0x1000());
    }

    public void print(PrintStream ps, String prefix) {
        ps.println(prefix + "DSStoreTreeBlock:");
        printFields(ps, prefix);
    }

    public byte[] getBytes() {
        byte[] result = new byte[length()];
        getBytes(result, 0);
        return result;
    }

    public int getBytes(byte[] result, int offset) {
        final int startOffset = offset;

        Util.arrayPutBE(result, offset, this.firstDataBlockID); offset += 4;
        Util.arrayPutBE(result, offset, this.recordsInTree); offset += 4;
        Util.arrayPutBE(result, offset, this.levelsOfInternalBlocks); offset += 4;
        Util.arrayPutBE(result, offset, this.totalTreeBlocks); offset += 4;
        Util.arrayPutBE(result, offset, this.unknownAlways0x1000); offset += 4;

        return offset - startOffset;
    }
}
