/*
 * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package com.sun.media.sound;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.sound.midi.Instrument;
import javax.sound.midi.Patch;
import javax.sound.midi.Soundbank;
import javax.sound.midi.SoundbankResource;

/**
 * A SoundFont 2.04 soundbank reader.
 *
 * Based on SoundFont 2.04 specification from:
 * <p>  http://developer.creative.com <br>
 *      http://www.soundfont.com/ ;
 *
 * @author Karl Helgason
 */
public class SF2Soundbank implements Soundbank {

    // version of the Sound Font RIFF file
    protected int major = 2;
    protected int minor = 1;
    // target Sound Engine
    protected String targetEngine = "EMU8000";
    // Sound Font Bank Name
    protected String name = "untitled";
    // Sound ROM Name
    protected String romName = null;
    // Sound ROM Version
    protected int romVersionMajor = -1;
    protected int romVersionMinor = -1;
    // Date of Creation of the Bank
    protected String creationDate = null;
    // Sound Designers and Engineers for the Bank
    protected String engineers = null;
    // Product for which the Bank was intended
    protected String product = null;
    // Copyright message
    protected String copyright = null;
    // Comments
    protected String comments = null;
    // The SoundFont tools used to create and alter the bank
    protected String tools = null;
    // The Sample Data loaded from the SoundFont
    private ModelByteBuffer sampleData = null;
    private ModelByteBuffer sampleData24 = null;
    private File sampleFile = null;
    private boolean largeFormat = false;
    private List<SF2Instrument> instruments = new ArrayList<SF2Instrument>();
    private List<SF2Layer> layers = new ArrayList<SF2Layer>();
    private List<SF2Sample> samples = new ArrayList<SF2Sample>();

    public SF2Soundbank() {
    }

    public SF2Soundbank(URL url) throws IOException {

        InputStream is = url.openStream();
        try {
            readSoundbank(is);
        } finally {
            is.close();
        }
    }

    public SF2Soundbank(File file) throws IOException {
        largeFormat = true;
        sampleFile = file;
        InputStream is = new FileInputStream(file);
        try {
            readSoundbank(is);
        } finally {
            is.close();
        }
    }

    public SF2Soundbank(InputStream inputstream) throws IOException {
        readSoundbank(inputstream);
    }

    private void readSoundbank(InputStream inputstream) throws IOException {
        RIFFReader riff = new RIFFReader(inputstream);
        if (!riff.getFormat().equals("RIFF")) {
            throw new RIFFInvalidFormatException(
                    "Input stream is not a valid RIFF stream!");
        }
        if (!riff.getType().equals("sfbk")) {
            throw new RIFFInvalidFormatException(
                    "Input stream is not a valid SoundFont!");
        }
        while (riff.hasNextChunk()) {
            RIFFReader chunk = riff.nextChunk();
            if (chunk.getFormat().equals("LIST")) {
                if (chunk.getType().equals("INFO"))
                    readInfoChunk(chunk);
                if (chunk.getType().equals("sdta"))
                    readSdtaChunk(chunk);
                if (chunk.getType().equals("pdta"))
                    readPdtaChunk(chunk);
            }
        }
    }

    private void readInfoChunk(RIFFReader riff) throws IOException {
        while (riff.hasNextChunk()) {
            RIFFReader chunk = riff.nextChunk();
            String format = chunk.getFormat();
            if (format.equals("ifil")) {
                major = chunk.readUnsignedShort();
                minor = chunk.readUnsignedShort();
            } else if (format.equals("isng")) {
                this.targetEngine = chunk.readString(chunk.available());
            } else if (format.equals("INAM")) {
                this.name = chunk.readString(chunk.available());
            } else if (format.equals("irom")) {
                this.romName = chunk.readString(chunk.available());
            } else if (format.equals("iver")) {
                romVersionMajor = chunk.readUnsignedShort();
                romVersionMinor = chunk.readUnsignedShort();
            } else if (format.equals("ICRD")) {
                this.creationDate = chunk.readString(chunk.available());
            } else if (format.equals("IENG")) {
                this.engineers = chunk.readString(chunk.available());
            } else if (format.equals("IPRD")) {
                this.product = chunk.readString(chunk.available());
            } else if (format.equals("ICOP")) {
                this.copyright = chunk.readString(chunk.available());
            } else if (format.equals("ICMT")) {
                this.comments = chunk.readString(chunk.available());
            } else if (format.equals("ISFT")) {
                this.tools = chunk.readString(chunk.available());
            }

        }
    }

    private void readSdtaChunk(RIFFReader riff) throws IOException {
        while (riff.hasNextChunk()) {
            RIFFReader chunk = riff.nextChunk();
            if (chunk.getFormat().equals("smpl")) {
                if (!largeFormat) {
                    byte[] sampleData = new byte[chunk.available()];

                    int read = 0;
                    int avail = chunk.available();
                    while (read != avail) {
                        if (avail - read > 65536) {
                            chunk.readFully(sampleData, read, 65536);
                            read += 65536;
                        } else {
                            chunk.readFully(sampleData, read, avail - read);
                            read = avail;
                        }

                    }
                    this.sampleData = new ModelByteBuffer(sampleData);
                    //chunk.read(sampleData);
                } else {
                    this.sampleData = new ModelByteBuffer(sampleFile,
                            chunk.getFilePointer(), chunk.available());
                }
            }
            if (chunk.getFormat().equals("sm24")) {
                if (!largeFormat) {
                    byte[] sampleData24 = new byte[chunk.available()];
                    //chunk.read(sampleData24);

                    int read = 0;
                    int avail = chunk.available();
                    while (read != avail) {
                        if (avail - read > 65536) {
                            chunk.readFully(sampleData24, read, 65536);
                            read += 65536;
                        } else {
                            chunk.readFully(sampleData24, read, avail - read);
                            read = avail;
                        }

                    }
                    this.sampleData24 = new ModelByteBuffer(sampleData24);
                } else {
                    this.sampleData24 = new ModelByteBuffer(sampleFile,
                            chunk.getFilePointer(), chunk.available());
                }

            }
        }
    }

    private void readPdtaChunk(RIFFReader riff) throws IOException {

        List<SF2Instrument> presets = new ArrayList<SF2Instrument>();
        List<Integer> presets_bagNdx = new ArrayList<Integer>();
        List<SF2InstrumentRegion> presets_splits_gen
                = new ArrayList<SF2InstrumentRegion>();
        List<SF2InstrumentRegion> presets_splits_mod
                = new ArrayList<SF2InstrumentRegion>();

        List<SF2Layer> instruments = new ArrayList<SF2Layer>();
        List<Integer> instruments_bagNdx = new ArrayList<Integer>();
        List<SF2LayerRegion> instruments_splits_gen
                = new ArrayList<SF2LayerRegion>();
        List<SF2LayerRegion> instruments_splits_mod
                = new ArrayList<SF2LayerRegion>();

        while (riff.hasNextChunk()) {
            RIFFReader chunk = riff.nextChunk();
            String format = chunk.getFormat();
            if (format.equals("phdr")) {
                // Preset Header / Instrument
                if (chunk.available() % 38 != 0)
                    throw new RIFFInvalidDataException();
                int count = chunk.available() / 38;
                for (int i = 0; i < count; i++) {
                    SF2Instrument preset = new SF2Instrument(this);
                    preset.name = chunk.readString(20);
                    preset.preset = chunk.readUnsignedShort();
                    preset.bank = chunk.readUnsignedShort();
                    presets_bagNdx.add(chunk.readUnsignedShort());
                    preset.library = chunk.readUnsignedInt();
                    preset.genre = chunk.readUnsignedInt();
                    preset.morphology = chunk.readUnsignedInt();
                    presets.add(preset);
                    if (i != count - 1)
                        this.instruments.add(preset);
                }
            } else if (format.equals("pbag")) {
                // Preset Zones / Instruments splits
                if (chunk.available() % 4 != 0)
                    throw new RIFFInvalidDataException();
                int count = chunk.available() / 4;

                // Skip first record
                {
                    int gencount = chunk.readUnsignedShort();
                    int modcount = chunk.readUnsignedShort();
                    while (presets_splits_gen.size() < gencount)
                        presets_splits_gen.add(null);
                    while (presets_splits_mod.size() < modcount)
                        presets_splits_mod.add(null);
                    count--;
                }

                int offset = presets_bagNdx.get(0);
                // Offset should be 0 (but just case)
                for (int i = 0; i < offset; i++) {
                    if (count == 0)
                        throw new RIFFInvalidDataException();
                    int gencount = chunk.readUnsignedShort();
                    int modcount = chunk.readUnsignedShort();
                    while (presets_splits_gen.size() < gencount)
                        presets_splits_gen.add(null);
                    while (presets_splits_mod.size() < modcount)
                        presets_splits_mod.add(null);
                    count--;
                }

                for (int i = 0; i < presets_bagNdx.size() - 1; i++) {
                    int zone_count = presets_bagNdx.get(i + 1)
                                     - presets_bagNdx.get(i);
                    SF2Instrument preset = presets.get(i);
                    for (int ii = 0; ii < zone_count; ii++) {
                        if (count == 0)
                            throw new RIFFInvalidDataException();
                        int gencount = chunk.readUnsignedShort();
                        int modcount = chunk.readUnsignedShort();
                        SF2InstrumentRegion split = new SF2InstrumentRegion();
                        preset.regions.add(split);
                        while (presets_splits_gen.size() < gencount)
                            presets_splits_gen.add(split);
                        while (presets_splits_mod.size() < modcount)
                            presets_splits_mod.add(split);
                        count--;
                    }
                }
            } else if (format.equals("pmod")) {
                // Preset Modulators / Split Modulators
                for (int i = 0; i < presets_splits_mod.size(); i++) {
                    SF2Modulator modulator = new SF2Modulator();
                    modulator.sourceOperator = chunk.readUnsignedShort();
                    modulator.destinationOperator = chunk.readUnsignedShort();
                    modulator.amount = chunk.readShort();
                    modulator.amountSourceOperator = chunk.readUnsignedShort();
                    modulator.transportOperator = chunk.readUnsignedShort();
                    SF2InstrumentRegion split = presets_splits_mod.get(i);
                    if (split != null)
                        split.modulators.add(modulator);
                }
            } else if (format.equals("pgen")) {
                // Preset Generators / Split Generators
                for (int i = 0; i < presets_splits_gen.size(); i++) {
                    int operator = chunk.readUnsignedShort();
                    short amount = chunk.readShort();
                    SF2InstrumentRegion split = presets_splits_gen.get(i);
                    if (split != null)
                        split.generators.put(operator, amount);
                }
            } else if (format.equals("inst")) {
                // Instrument Header / Layers
                if (chunk.available() % 22 != 0)
                    throw new RIFFInvalidDataException();
                int count = chunk.available() / 22;
                for (int i = 0; i < count; i++) {
                    SF2Layer layer = new SF2Layer(this);
                    layer.name = chunk.readString(20);
                    instruments_bagNdx.add(chunk.readUnsignedShort());
                    instruments.add(layer);
                    if (i != count - 1)
                        this.layers.add(layer);
                }
            } else if (format.equals("ibag")) {
                // Instrument Zones / Layer splits
                if (chunk.available() % 4 != 0)
                    throw new RIFFInvalidDataException();
                int count = chunk.available() / 4;

                // Skip first record
                {
                    int gencount = chunk.readUnsignedShort();
                    int modcount = chunk.readUnsignedShort();
                    while (instruments_splits_gen.size() < gencount)
                        instruments_splits_gen.add(null);
                    while (instruments_splits_mod.size() < modcount)
                        instruments_splits_mod.add(null);
                    count--;
                }

                int offset = instruments_bagNdx.get(0);
                // Offset should be 0 (but just case)
                for (int i = 0; i < offset; i++) {
                    if (count == 0)
                        throw new RIFFInvalidDataException();
                    int gencount = chunk.readUnsignedShort();
                    int modcount = chunk.readUnsignedShort();
                    while (instruments_splits_gen.size() < gencount)
                        instruments_splits_gen.add(null);
                    while (instruments_splits_mod.size() < modcount)
                        instruments_splits_mod.add(null);
                    count--;
                }

                for (int i = 0; i < instruments_bagNdx.size() - 1; i++) {
                    int zone_count = instruments_bagNdx.get(i + 1) - instruments_bagNdx.get(i);
                    SF2Layer layer = layers.get(i);
                    for (int ii = 0; ii < zone_count; ii++) {
                        if (count == 0)
                            throw new RIFFInvalidDataException();
                        int gencount = chunk.readUnsignedShort();
                        int modcount = chunk.readUnsignedShort();
                        SF2LayerRegion split = new SF2LayerRegion();
                        layer.regions.add(split);
                        while (instruments_splits_gen.size() < gencount)
                            instruments_splits_gen.add(split);
                        while (instruments_splits_mod.size() < modcount)
                            instruments_splits_mod.add(split);
                        count--;
                    }
                }

            } else if (format.equals("imod")) {
                // Instrument Modulators / Split Modulators
                for (int i = 0; i < instruments_splits_mod.size(); i++) {
                    SF2Modulator modulator = new SF2Modulator();
                    modulator.sourceOperator = chunk.readUnsignedShort();
                    modulator.destinationOperator = chunk.readUnsignedShort();
                    modulator.amount = chunk.readShort();
                    modulator.amountSourceOperator = chunk.readUnsignedShort();
                    modulator.transportOperator = chunk.readUnsignedShort();
                    SF2LayerRegion split = instruments_splits_gen.get(i);
                    if (split != null)
                        split.modulators.add(modulator);
                }
            } else if (format.equals("igen")) {
                // Instrument Generators / Split Generators
                for (int i = 0; i < instruments_splits_gen.size(); i++) {
                    int operator = chunk.readUnsignedShort();
                    short amount = chunk.readShort();
                    SF2LayerRegion split = instruments_splits_gen.get(i);
                    if (split != null)
                        split.generators.put(operator, amount);
                }
            } else if (format.equals("shdr")) {
                // Sample Headers
                if (chunk.available() % 46 != 0)
                    throw new RIFFInvalidDataException();
                int count = chunk.available() / 46;
                for (int i = 0; i < count; i++) {
                    SF2Sample sample = new SF2Sample(this);
                    sample.name = chunk.readString(20);
                    long start = chunk.readUnsignedInt();
                    long end = chunk.readUnsignedInt();
                    sample.data = sampleData.subbuffer(start * 2, end * 2, true);
                    if (sampleData24 != null)
                        sample.data24 = sampleData24.subbuffer(start, end, true);
                    /*
                    sample.data = new ModelByteBuffer(sampleData, (int)(start*2),
                            (int)((end - start)*2));
                    if (sampleData24 != null)
                        sample.data24 = new ModelByteBuffer(sampleData24,
                                (int)start, (int)(end - start));
                     */
                    sample.startLoop = chunk.readUnsignedInt() - start;
                    sample.endLoop = chunk.readUnsignedInt() - start;
                    if (sample.startLoop < 0)
                        sample.startLoop = -1;
                    if (sample.endLoop < 0)
                        sample.endLoop = -1;
                    sample.sampleRate = chunk.readUnsignedInt();
                    sample.originalPitch = chunk.readUnsignedByte();
                    sample.pitchCorrection = chunk.readByte();
                    sample.sampleLink = chunk.readUnsignedShort();
                    sample.sampleType = chunk.readUnsignedShort();
                    if (i != count - 1)
                        this.samples.add(sample);
                }
            }
        }

        Iterator<SF2Layer> liter = this.layers.iterator();
        while (liter.hasNext()) {
            SF2Layer layer = liter.next();
            Iterator<SF2LayerRegion> siter = layer.regions.iterator();
            SF2Region globalsplit = null;
            while (siter.hasNext()) {
                SF2LayerRegion split = siter.next();
                if (split.generators.get(SF2LayerRegion.GENERATOR_SAMPLEID) != null) {
                    int sampleid = split.generators.get(
                            SF2LayerRegion.GENERATOR_SAMPLEID);
                    split.generators.remove(SF2LayerRegion.GENERATOR_SAMPLEID);
                    split.sample = samples.get(sampleid);
                } else {
                    globalsplit = split;
                }
            }
            if (globalsplit != null) {
                layer.getRegions().remove(globalsplit);
                SF2GlobalRegion gsplit = new SF2GlobalRegion();
                gsplit.generators = globalsplit.generators;
                gsplit.modulators = globalsplit.modulators;
                layer.setGlobalZone(gsplit);
            }
        }


        Iterator<SF2Instrument> iiter = this.instruments.iterator();
        while (iiter.hasNext()) {
            SF2Instrument instrument = iiter.next();
            Iterator<SF2InstrumentRegion> siter = instrument.regions.iterator();
            SF2Region globalsplit = null;
            while (siter.hasNext()) {
                SF2InstrumentRegion split = siter.next();
                if (split.generators.get(SF2LayerRegion.GENERATOR_INSTRUMENT) != null) {
                    int instrumentid = split.generators.get(
                            SF2InstrumentRegion.GENERATOR_INSTRUMENT);
                    split.generators.remove(SF2LayerRegion.GENERATOR_INSTRUMENT);
                    split.layer = layers.get(instrumentid);
                } else {
                    globalsplit = split;
                }
            }

            if (globalsplit != null) {
                instrument.getRegions().remove(globalsplit);
                SF2GlobalRegion gsplit = new SF2GlobalRegion();
                gsplit.generators = globalsplit.generators;
                gsplit.modulators = globalsplit.modulators;
                instrument.setGlobalZone(gsplit);
            }
        }

    }

    public void save(String name) throws IOException {
        writeSoundbank(new RIFFWriter(name, "sfbk"));
    }

    public void save(File file) throws IOException {
        writeSoundbank(new RIFFWriter(file, "sfbk"));
    }

    public void save(OutputStream out) throws IOException {
        writeSoundbank(new RIFFWriter(out, "sfbk"));
    }

    private void writeSoundbank(RIFFWriter writer) throws IOException {
        writeInfo(writer.writeList("INFO"));
        writeSdtaChunk(writer.writeList("sdta"));
        writePdtaChunk(writer.writeList("pdta"));
        writer.close();
    }

    private void writeInfoStringChunk(RIFFWriter writer, String name,
            String value) throws IOException {
        if (value == null)
            return;
        RIFFWriter chunk = writer.writeChunk(name);
        chunk.writeString(value);
        int len = value.getBytes("ascii").length;
        chunk.write(0);
        len++;
        if (len % 2 != 0)
            chunk.write(0);
    }

    private void writeInfo(RIFFWriter writer) throws IOException {
        if (this.targetEngine == null)
            this.targetEngine = "EMU8000";
        if (this.name == null)
            this.name = "";

        RIFFWriter ifil_chunk = writer.writeChunk("ifil");
        ifil_chunk.writeUnsignedShort(this.major);
        ifil_chunk.writeUnsignedShort(this.minor);
        writeInfoStringChunk(writer, "isng", this.targetEngine);
        writeInfoStringChunk(writer, "INAM", this.name);
        writeInfoStringChunk(writer, "irom", this.romName);
        if (romVersionMajor != -1) {
            RIFFWriter iver_chunk = writer.writeChunk("iver");
            iver_chunk.writeUnsignedShort(this.romVersionMajor);
            iver_chunk.writeUnsignedShort(this.romVersionMinor);
        }
        writeInfoStringChunk(writer, "ICRD", this.creationDate);
        writeInfoStringChunk(writer, "IENG", this.engineers);
        writeInfoStringChunk(writer, "IPRD", this.product);
        writeInfoStringChunk(writer, "ICOP", this.copyright);
        writeInfoStringChunk(writer, "ICMT", this.comments);
        writeInfoStringChunk(writer, "ISFT", this.tools);

        writer.close();
    }

    private void writeSdtaChunk(RIFFWriter writer) throws IOException {

        byte[] pad = new byte[32];

        RIFFWriter smpl_chunk = writer.writeChunk("smpl");
        for (SF2Sample sample : samples) {
            ModelByteBuffer data = sample.getDataBuffer();
            data.writeTo(smpl_chunk);
            /*
            smpl_chunk.write(data.array(),
            data.arrayOffset(),
            data.capacity());
             */
            smpl_chunk.write(pad);
            smpl_chunk.write(pad);
        }
        if (major < 2)
            return;
        if (major == 2 && minor < 4)
            return;


        for (SF2Sample sample : samples) {
            ModelByteBuffer data24 = sample.getData24Buffer();
            if (data24 == null)
                return;
        }

        RIFFWriter sm24_chunk = writer.writeChunk("sm24");
        for (SF2Sample sample : samples) {
            ModelByteBuffer data = sample.getData24Buffer();
            data.writeTo(sm24_chunk);
            /*
            sm24_chunk.write(data.array(),
            data.arrayOffset(),
            data.capacity());*/
            smpl_chunk.write(pad);
        }
    }

    private void writeModulators(RIFFWriter writer, List<SF2Modulator> modulators)
            throws IOException {
        for (SF2Modulator modulator : modulators) {
            writer.writeUnsignedShort(modulator.sourceOperator);
            writer.writeUnsignedShort(modulator.destinationOperator);
            writer.writeShort(modulator.amount);
            writer.writeUnsignedShort(modulator.amountSourceOperator);
            writer.writeUnsignedShort(modulator.transportOperator);
        }
    }

    private void writeGenerators(RIFFWriter writer, Map<Integer, Short> generators)
            throws IOException {
        Short keyrange = (Short) generators.get(SF2Region.GENERATOR_KEYRANGE);
        Short velrange = (Short) generators.get(SF2Region.GENERATOR_VELRANGE);
        if (keyrange != null) {
            writer.writeUnsignedShort(SF2Region.GENERATOR_KEYRANGE);
            writer.writeShort(keyrange);
        }
        if (velrange != null) {
            writer.writeUnsignedShort(SF2Region.GENERATOR_VELRANGE);
            writer.writeShort(velrange);
        }
        for (Map.Entry<Integer, Short> generator : generators.entrySet()) {
            if (generator.getKey() == SF2Region.GENERATOR_KEYRANGE)
                continue;
            if (generator.getKey() == SF2Region.GENERATOR_VELRANGE)
                continue;
            writer.writeUnsignedShort(generator.getKey());
            writer.writeShort(generator.getValue());
        }
    }

    private void writePdtaChunk(RIFFWriter writer) throws IOException {

        RIFFWriter phdr_chunk = writer.writeChunk("phdr");
        int phdr_zone_count = 0;
        for (SF2Instrument preset : this.instruments) {
            phdr_chunk.writeString(preset.name, 20);
            phdr_chunk.writeUnsignedShort(preset.preset);
            phdr_chunk.writeUnsignedShort(preset.bank);
            phdr_chunk.writeUnsignedShort(phdr_zone_count);
            if (preset.getGlobalRegion() != null)
                phdr_zone_count += 1;
            phdr_zone_count += preset.getRegions().size();
            phdr_chunk.writeUnsignedInt(preset.library);
            phdr_chunk.writeUnsignedInt(preset.genre);
            phdr_chunk.writeUnsignedInt(preset.morphology);
        }
        phdr_chunk.writeString("EOP", 20);
        phdr_chunk.writeUnsignedShort(0);
        phdr_chunk.writeUnsignedShort(0);
        phdr_chunk.writeUnsignedShort(phdr_zone_count);
        phdr_chunk.writeUnsignedInt(0);
        phdr_chunk.writeUnsignedInt(0);
        phdr_chunk.writeUnsignedInt(0);


        RIFFWriter pbag_chunk = writer.writeChunk("pbag");
        int pbag_gencount = 0;
        int pbag_modcount = 0;
        for (SF2Instrument preset : this.instruments) {
            if (preset.getGlobalRegion() != null) {
                pbag_chunk.writeUnsignedShort(pbag_gencount);
                pbag_chunk.writeUnsignedShort(pbag_modcount);
                pbag_gencount += preset.getGlobalRegion().getGenerators().size();
                pbag_modcount += preset.getGlobalRegion().getModulators().size();
            }
            for (SF2InstrumentRegion region : preset.getRegions()) {
                pbag_chunk.writeUnsignedShort(pbag_gencount);
                pbag_chunk.writeUnsignedShort(pbag_modcount);
                if (layers.indexOf(region.layer) != -1) {
                    // One generator is used to reference to instrument record
                    pbag_gencount += 1;
                }
                pbag_gencount += region.getGenerators().size();
                pbag_modcount += region.getModulators().size();

            }
        }
        pbag_chunk.writeUnsignedShort(pbag_gencount);
        pbag_chunk.writeUnsignedShort(pbag_modcount);

        RIFFWriter pmod_chunk = writer.writeChunk("pmod");
        for (SF2Instrument preset : this.instruments) {
            if (preset.getGlobalRegion() != null) {
                writeModulators(pmod_chunk,
                        preset.getGlobalRegion().getModulators());
            }
            for (SF2InstrumentRegion region : preset.getRegions())
                writeModulators(pmod_chunk, region.getModulators());
        }
        pmod_chunk.write(new byte[10]);

        RIFFWriter pgen_chunk = writer.writeChunk("pgen");
        for (SF2Instrument preset : this.instruments) {
            if (preset.getGlobalRegion() != null) {
                writeGenerators(pgen_chunk,
                        preset.getGlobalRegion().getGenerators());
            }
            for (SF2InstrumentRegion region : preset.getRegions()) {
                writeGenerators(pgen_chunk, region.getGenerators());
                int ix = (int) layers.indexOf(region.layer);
                if (ix != -1) {
                    pgen_chunk.writeUnsignedShort(SF2Region.GENERATOR_INSTRUMENT);
                    pgen_chunk.writeShort((short) ix);
                }
            }
        }
        pgen_chunk.write(new byte[4]);

        RIFFWriter inst_chunk = writer.writeChunk("inst");
        int inst_zone_count = 0;
        for (SF2Layer instrument : this.layers) {
            inst_chunk.writeString(instrument.name, 20);
            inst_chunk.writeUnsignedShort(inst_zone_count);
            if (instrument.getGlobalRegion() != null)
                inst_zone_count += 1;
            inst_zone_count += instrument.getRegions().size();
        }
        inst_chunk.writeString("EOI", 20);
        inst_chunk.writeUnsignedShort(inst_zone_count);


        RIFFWriter ibag_chunk = writer.writeChunk("ibag");
        int ibag_gencount = 0;
        int ibag_modcount = 0;
        for (SF2Layer instrument : this.layers) {
            if (instrument.getGlobalRegion() != null) {
                ibag_chunk.writeUnsignedShort(ibag_gencount);
                ibag_chunk.writeUnsignedShort(ibag_modcount);
                ibag_gencount
                        += instrument.getGlobalRegion().getGenerators().size();
                ibag_modcount
                        += instrument.getGlobalRegion().getModulators().size();
            }
            for (SF2LayerRegion region : instrument.getRegions()) {
                ibag_chunk.writeUnsignedShort(ibag_gencount);
                ibag_chunk.writeUnsignedShort(ibag_modcount);
                if (samples.indexOf(region.sample) != -1) {
                    // One generator is used to reference to instrument record
                    ibag_gencount += 1;
                }
                ibag_gencount += region.getGenerators().size();
                ibag_modcount += region.getModulators().size();

            }
        }
        ibag_chunk.writeUnsignedShort(ibag_gencount);
        ibag_chunk.writeUnsignedShort(ibag_modcount);


        RIFFWriter imod_chunk = writer.writeChunk("imod");
        for (SF2Layer instrument : this.layers) {
            if (instrument.getGlobalRegion() != null) {
                writeModulators(imod_chunk,
                        instrument.getGlobalRegion().getModulators());
            }
            for (SF2LayerRegion region : instrument.getRegions())
                writeModulators(imod_chunk, region.getModulators());
        }
        imod_chunk.write(new byte[10]);

        RIFFWriter igen_chunk = writer.writeChunk("igen");
        for (SF2Layer instrument : this.layers) {
            if (instrument.getGlobalRegion() != null) {
                writeGenerators(igen_chunk,
                        instrument.getGlobalRegion().getGenerators());
            }
            for (SF2LayerRegion region : instrument.getRegions()) {
                writeGenerators(igen_chunk, region.getGenerators());
                int ix = samples.indexOf(region.sample);
                if (ix != -1) {
                    igen_chunk.writeUnsignedShort(SF2Region.GENERATOR_SAMPLEID);
                    igen_chunk.writeShort((short) ix);
                }
            }
        }
        igen_chunk.write(new byte[4]);


        RIFFWriter shdr_chunk = writer.writeChunk("shdr");
        long sample_pos = 0;
        for (SF2Sample sample : samples) {
            shdr_chunk.writeString(sample.name, 20);
            long start = sample_pos;
            sample_pos += sample.data.capacity() / 2;
            long end = sample_pos;
            long startLoop = sample.startLoop + start;
            long endLoop = sample.endLoop + start;
            if (startLoop < start)
                startLoop = start;
            if (endLoop > end)
                endLoop = end;
            shdr_chunk.writeUnsignedInt(start);
            shdr_chunk.writeUnsignedInt(end);
            shdr_chunk.writeUnsignedInt(startLoop);
            shdr_chunk.writeUnsignedInt(endLoop);
            shdr_chunk.writeUnsignedInt(sample.sampleRate);
            shdr_chunk.writeUnsignedByte(sample.originalPitch);
            shdr_chunk.writeByte(sample.pitchCorrection);
            shdr_chunk.writeUnsignedShort(sample.sampleLink);
            shdr_chunk.writeUnsignedShort(sample.sampleType);
            sample_pos += 32;
        }
        shdr_chunk.writeString("EOS", 20);
        shdr_chunk.write(new byte[26]);

    }

    public String getName() {
        return name;
    }

    public String getVersion() {
        return major + "." + minor;
    }

    public String getVendor() {
        return engineers;
    }

    public String getDescription() {
        return comments;
    }

    public void setName(String s) {
        name = s;
    }

    public void setVendor(String s) {
        engineers = s;
    }

    public void setDescription(String s) {
        comments = s;
    }

    public SoundbankResource[] getResources() {
        SoundbankResource[] resources
                = new SoundbankResource[layers.size() + samples.size()];
        int j = 0;
        for (int i = 0; i < layers.size(); i++)
            resources[j++] = layers.get(i);
        for (int i = 0; i < samples.size(); i++)
            resources[j++] = samples.get(i);
        return resources;
    }

    public SF2Instrument[] getInstruments() {
        SF2Instrument[] inslist_array
                = instruments.toArray(new SF2Instrument[instruments.size()]);
        Arrays.sort(inslist_array, new ModelInstrumentComparator());
        return inslist_array;
    }

    public SF2Layer[] getLayers() {
        return layers.toArray(new SF2Layer[layers.size()]);
    }

    public SF2Sample[] getSamples() {
        return samples.toArray(new SF2Sample[samples.size()]);
    }

    public Instrument getInstrument(Patch patch) {
        int program = patch.getProgram();
        int bank = patch.getBank();
        boolean percussion = false;
        if (patch instanceof ModelPatch)
            percussion = ((ModelPatch)patch).isPercussion();
        for (Instrument instrument : instruments) {
            Patch patch2 = instrument.getPatch();
            int program2 = patch2.getProgram();
            int bank2 = patch2.getBank();
            if (program == program2 && bank == bank2) {
                boolean percussion2 = false;
                if (patch2 instanceof ModelPatch)
                    percussion2 = ((ModelPatch) patch2).isPercussion();
                if (percussion == percussion2)
                    return instrument;
            }
        }
        return null;
    }

    public String getCreationDate() {
        return creationDate;
    }

    public void setCreationDate(String creationDate) {
        this.creationDate = creationDate;
    }

    public String getProduct() {
        return product;
    }

    public void setProduct(String product) {
        this.product = product;
    }

    public String getRomName() {
        return romName;
    }

    public void setRomName(String romName) {
        this.romName = romName;
    }

    public int getRomVersionMajor() {
        return romVersionMajor;
    }

    public void setRomVersionMajor(int romVersionMajor) {
        this.romVersionMajor = romVersionMajor;
    }

    public int getRomVersionMinor() {
        return romVersionMinor;
    }

    public void setRomVersionMinor(int romVersionMinor) {
        this.romVersionMinor = romVersionMinor;
    }

    public String getTargetEngine() {
        return targetEngine;
    }

    public void setTargetEngine(String targetEngine) {
        this.targetEngine = targetEngine;
    }

    public String getTools() {
        return tools;
    }

    public void setTools(String tools) {
        this.tools = tools;
    }

    public void addResource(SoundbankResource resource) {
        if (resource instanceof SF2Instrument)
            instruments.add((SF2Instrument)resource);
        if (resource instanceof SF2Layer)
            layers.add((SF2Layer)resource);
        if (resource instanceof SF2Sample)
            samples.add((SF2Sample)resource);
    }

    public void removeResource(SoundbankResource resource) {
        if (resource instanceof SF2Instrument)
            instruments.remove((SF2Instrument)resource);
        if (resource instanceof SF2Layer)
            layers.remove((SF2Layer)resource);
        if (resource instanceof SF2Sample)
            samples.remove((SF2Sample)resource);
    }

    public void addInstrument(SF2Instrument resource) {
        instruments.add(resource);
    }

    public void removeInstrument(SF2Instrument resource) {
        instruments.remove(resource);
    }
}
