/*
 * Copyright (c) 2007, 2013, 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.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

import javax.sound.midi.Instrument;
import javax.sound.midi.Patch;
import javax.sound.midi.Soundbank;
import javax.sound.midi.SoundbankResource;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.AudioFormat.Encoding;

/**
 * A DLS Level 1 and Level 2 soundbank reader (from files/url/streams).
 *
 * @author Karl Helgason
 */
public final class DLSSoundbank implements Soundbank {

    static private class DLSID {
        long i1;
        int s1;
        int s2;
        int x1;
        int x2;
        int x3;
        int x4;
        int x5;
        int x6;
        int x7;
        int x8;

        private DLSID() {
        }

        DLSID(long i1, int s1, int s2, int x1, int x2, int x3, int x4,
                int x5, int x6, int x7, int x8) {
            this.i1 = i1;
            this.s1 = s1;
            this.s2 = s2;
            this.x1 = x1;
            this.x2 = x2;
            this.x3 = x3;
            this.x4 = x4;
            this.x5 = x5;
            this.x6 = x6;
            this.x7 = x7;
            this.x8 = x8;
        }

        public static DLSID read(RIFFReader riff) throws IOException {
            DLSID d = new DLSID();
            d.i1 = riff.readUnsignedInt();
            d.s1 = riff.readUnsignedShort();
            d.s2 = riff.readUnsignedShort();
            d.x1 = riff.readUnsignedByte();
            d.x2 = riff.readUnsignedByte();
            d.x3 = riff.readUnsignedByte();
            d.x4 = riff.readUnsignedByte();
            d.x5 = riff.readUnsignedByte();
            d.x6 = riff.readUnsignedByte();
            d.x7 = riff.readUnsignedByte();
            d.x8 = riff.readUnsignedByte();
            return d;
        }

        public int hashCode() {
            return (int)i1;
        }

        public boolean equals(Object obj) {
            if (!(obj instanceof DLSID)) {
                return false;
            }
            DLSID t = (DLSID) obj;
            return i1 == t.i1 && s1 == t.s1 && s2 == t.s2
                && x1 == t.x1 && x2 == t.x2 && x3 == t.x3 && x4 == t.x4
                && x5 == t.x5 && x6 == t.x6 && x7 == t.x7 && x8 == t.x8;
        }
    }

    /** X = X & Y */
    private static final int DLS_CDL_AND = 0x0001;
    /** X = X | Y */
    private static final int DLS_CDL_OR = 0x0002;
    /** X = X ^ Y */
    private static final int DLS_CDL_XOR = 0x0003;
    /** X = X + Y */
    private static final int DLS_CDL_ADD = 0x0004;
    /** X = X - Y */
    private static final int DLS_CDL_SUBTRACT = 0x0005;
    /** X = X * Y */
    private static final int DLS_CDL_MULTIPLY = 0x0006;
    /** X = X / Y */
    private static final int DLS_CDL_DIVIDE = 0x0007;
    /** X = X && Y */
    private static final int DLS_CDL_LOGICAL_AND = 0x0008;
    /** X = X || Y */
    private static final int DLS_CDL_LOGICAL_OR = 0x0009;
    /** X = (X < Y) */
    private static final int DLS_CDL_LT = 0x000A;
    /** X = (X <= Y) */
    private static final int DLS_CDL_LE = 0x000B;
    /** X = (X > Y) */
    private static final int DLS_CDL_GT = 0x000C;
    /** X = (X >= Y) */
    private static final int DLS_CDL_GE = 0x000D;
    /** X = (X == Y) */
    private static final int DLS_CDL_EQ = 0x000E;
    /** X = !X */
    private static final int DLS_CDL_NOT = 0x000F;
    /** 32-bit constant */
    private static final int DLS_CDL_CONST = 0x0010;
    /** 32-bit value returned from query */
    private static final int DLS_CDL_QUERY = 0x0011;
    /** 32-bit value returned from query */
    private static final int DLS_CDL_QUERYSUPPORTED = 0x0012;

    private static final DLSID DLSID_GMInHardware = new DLSID(0x178f2f24,
            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
    private static final DLSID DLSID_GSInHardware = new DLSID(0x178f2f25,
            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
    private static final DLSID DLSID_XGInHardware = new DLSID(0x178f2f26,
            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
    private static final DLSID DLSID_SupportsDLS1 = new DLSID(0x178f2f27,
            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
    private static final DLSID DLSID_SupportsDLS2 = new DLSID(0xf14599e5,
            0x4689, 0x11d2, 0xaf, 0xa6, 0x0, 0xaa, 0x0, 0x24, 0xd8, 0xb6);
    private static final DLSID DLSID_SampleMemorySize = new DLSID(0x178f2f28,
            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
    private static final DLSID DLSID_ManufacturersID = new DLSID(0xb03e1181,
            0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
    private static final DLSID DLSID_ProductID = new DLSID(0xb03e1182,
            0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
    private static final DLSID DLSID_SamplePlaybackRate = new DLSID(0x2a91f713,
            0xa4bf, 0x11d2, 0xbb, 0xdf, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);

    private long major = -1;
    private long minor = -1;

    private final DLSInfo info = new DLSInfo();

    private final List<DLSInstrument> instruments = new ArrayList<DLSInstrument>();
    private final List<DLSSample> samples = new ArrayList<DLSSample>();

    private boolean largeFormat = false;
    private File sampleFile;

    public DLSSoundbank() {
    }

    public DLSSoundbank(URL url) throws IOException {
        InputStream is = url.openStream();
        try {
            readSoundbank(is);
        } finally {
            is.close();
        }
    }

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

    public DLSSoundbank(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("DLS ")) {
            throw new RIFFInvalidFormatException(
                    "Input stream is not a valid DLS soundbank!");
        }
        while (riff.hasNextChunk()) {
            RIFFReader chunk = riff.nextChunk();
            if (chunk.getFormat().equals("LIST")) {
                if (chunk.getType().equals("INFO"))
                    readInfoChunk(chunk);
                if (chunk.getType().equals("lins"))
                    readLinsChunk(chunk);
                if (chunk.getType().equals("wvpl"))
                    readWvplChunk(chunk);
            } else {
                if (chunk.getFormat().equals("cdl ")) {
                    if (!readCdlChunk(chunk)) {
                        throw new RIFFInvalidFormatException(
                                "DLS file isn't supported!");
                    }
                }
                if (chunk.getFormat().equals("colh")) {
                    // skipped because we will load the entire bank into memory
                    // long instrumentcount = chunk.readUnsignedInt();
                    // System.out.println("instrumentcount = "+ instrumentcount);
                }
                if (chunk.getFormat().equals("ptbl")) {
                    // Pool Table Chunk
                    // skipped because we will load the entire bank into memory
                }
                if (chunk.getFormat().equals("vers")) {
                    major = chunk.readUnsignedInt();
                    minor = chunk.readUnsignedInt();
                }
            }
        }

        for (Map.Entry<DLSRegion, Long> entry : temp_rgnassign.entrySet()) {
            entry.getKey().sample = samples.get((int)entry.getValue().longValue());
        }

        temp_rgnassign = null;
    }

    private boolean cdlIsQuerySupported(DLSID uuid) {
        return uuid.equals(DLSID_GMInHardware)
            || uuid.equals(DLSID_GSInHardware)
            || uuid.equals(DLSID_XGInHardware)
            || uuid.equals(DLSID_SupportsDLS1)
            || uuid.equals(DLSID_SupportsDLS2)
            || uuid.equals(DLSID_SampleMemorySize)
            || uuid.equals(DLSID_ManufacturersID)
            || uuid.equals(DLSID_ProductID)
            || uuid.equals(DLSID_SamplePlaybackRate);
    }

    private long cdlQuery(DLSID uuid) {
        if (uuid.equals(DLSID_GMInHardware))
            return 1;
        if (uuid.equals(DLSID_GSInHardware))
            return 0;
        if (uuid.equals(DLSID_XGInHardware))
            return 0;
        if (uuid.equals(DLSID_SupportsDLS1))
            return 1;
        if (uuid.equals(DLSID_SupportsDLS2))
            return 1;
        if (uuid.equals(DLSID_SampleMemorySize))
            return Runtime.getRuntime().totalMemory();
        if (uuid.equals(DLSID_ManufacturersID))
            return 0;
        if (uuid.equals(DLSID_ProductID))
            return 0;
        if (uuid.equals(DLSID_SamplePlaybackRate))
            return 44100;
        return 0;
    }


    // Reading cdl-ck Chunk
    // "cdl " chunk can only appear inside : DLS,lart,lar2,rgn,rgn2
    private boolean readCdlChunk(RIFFReader riff) throws IOException {

        DLSID uuid;
        long x;
        long y;
        Stack<Long> stack = new Stack<Long>();

        while (riff.available() != 0) {
            int opcode = riff.readUnsignedShort();
            switch (opcode) {
            case DLS_CDL_AND:
                x = stack.pop();
                y = stack.pop();
                stack.push(Long.valueOf(((x != 0) && (y != 0)) ? 1 : 0));
                break;
            case DLS_CDL_OR:
                x = stack.pop();
                y = stack.pop();
                stack.push(Long.valueOf(((x != 0) || (y != 0)) ? 1 : 0));
                break;
            case DLS_CDL_XOR:
                x = stack.pop();
                y = stack.pop();
                stack.push(Long.valueOf(((x != 0) ^ (y != 0)) ? 1 : 0));
                break;
            case DLS_CDL_ADD:
                x = stack.pop();
                y = stack.pop();
                stack.push(Long.valueOf(x + y));
                break;
            case DLS_CDL_SUBTRACT:
                x = stack.pop();
                y = stack.pop();
                stack.push(Long.valueOf(x - y));
                break;
            case DLS_CDL_MULTIPLY:
                x = stack.pop();
                y = stack.pop();
                stack.push(Long.valueOf(x * y));
                break;
            case DLS_CDL_DIVIDE:
                x = stack.pop();
                y = stack.pop();
                stack.push(Long.valueOf(x / y));
                break;
            case DLS_CDL_LOGICAL_AND:
                x = stack.pop();
                y = stack.pop();
                stack.push(Long.valueOf(((x != 0) && (y != 0)) ? 1 : 0));
                break;
            case DLS_CDL_LOGICAL_OR:
                x = stack.pop();
                y = stack.pop();
                stack.push(Long.valueOf(((x != 0) || (y != 0)) ? 1 : 0));
                break;
            case DLS_CDL_LT:
                x = stack.pop();
                y = stack.pop();
                stack.push(Long.valueOf((x < y) ? 1 : 0));
                break;
            case DLS_CDL_LE:
                x = stack.pop();
                y = stack.pop();
                stack.push(Long.valueOf((x <= y) ? 1 : 0));
                break;
            case DLS_CDL_GT:
                x = stack.pop();
                y = stack.pop();
                stack.push(Long.valueOf((x > y) ? 1 : 0));
                break;
            case DLS_CDL_GE:
                x = stack.pop();
                y = stack.pop();
                stack.push(Long.valueOf((x >= y) ? 1 : 0));
                break;
            case DLS_CDL_EQ:
                x = stack.pop();
                y = stack.pop();
                stack.push(Long.valueOf((x == y) ? 1 : 0));
                break;
            case DLS_CDL_NOT:
                x = stack.pop();
                y = stack.pop();
                stack.push(Long.valueOf((x == 0) ? 1 : 0));
                break;
            case DLS_CDL_CONST:
                stack.push(Long.valueOf(riff.readUnsignedInt()));
                break;
            case DLS_CDL_QUERY:
                uuid = DLSID.read(riff);
                stack.push(cdlQuery(uuid));
                break;
            case DLS_CDL_QUERYSUPPORTED:
                uuid = DLSID.read(riff);
                stack.push(Long.valueOf(cdlIsQuerySupported(uuid) ? 1 : 0));
                break;
            default:
                break;
            }
        }
        if (stack.isEmpty())
            return false;

        return stack.pop() == 1;
    }

    private void readInfoChunk(RIFFReader riff) throws IOException {
        info.name = null;
        while (riff.hasNextChunk()) {
            RIFFReader chunk = riff.nextChunk();
            String format = chunk.getFormat();
            if (format.equals("INAM"))
                info.name = chunk.readString(chunk.available());
            else if (format.equals("ICRD"))
                info.creationDate = chunk.readString(chunk.available());
            else if (format.equals("IENG"))
                info.engineers = chunk.readString(chunk.available());
            else if (format.equals("IPRD"))
                info.product = chunk.readString(chunk.available());
            else if (format.equals("ICOP"))
                info.copyright = chunk.readString(chunk.available());
            else if (format.equals("ICMT"))
                info.comments = chunk.readString(chunk.available());
            else if (format.equals("ISFT"))
                info.tools = chunk.readString(chunk.available());
            else if (format.equals("IARL"))
                info.archival_location = chunk.readString(chunk.available());
            else if (format.equals("IART"))
                info.artist = chunk.readString(chunk.available());
            else if (format.equals("ICMS"))
                info.commissioned = chunk.readString(chunk.available());
            else if (format.equals("IGNR"))
                info.genre = chunk.readString(chunk.available());
            else if (format.equals("IKEY"))
                info.keywords = chunk.readString(chunk.available());
            else if (format.equals("IMED"))
                info.medium = chunk.readString(chunk.available());
            else if (format.equals("ISBJ"))
                info.subject = chunk.readString(chunk.available());
            else if (format.equals("ISRC"))
                info.source = chunk.readString(chunk.available());
            else if (format.equals("ISRF"))
                info.source_form = chunk.readString(chunk.available());
            else if (format.equals("ITCH"))
                info.technician = chunk.readString(chunk.available());
        }
    }

    private void readLinsChunk(RIFFReader riff) throws IOException {
        while (riff.hasNextChunk()) {
            RIFFReader chunk = riff.nextChunk();
            if (chunk.getFormat().equals("LIST")) {
                if (chunk.getType().equals("ins "))
                    readInsChunk(chunk);
            }
        }
    }

    private void readInsChunk(RIFFReader riff) throws IOException {
        DLSInstrument instrument = new DLSInstrument(this);

        while (riff.hasNextChunk()) {
            RIFFReader chunk = riff.nextChunk();
            String format = chunk.getFormat();
            if (format.equals("LIST")) {
                if (chunk.getType().equals("INFO")) {
                    readInsInfoChunk(instrument, chunk);
                }
                if (chunk.getType().equals("lrgn")) {
                    while (chunk.hasNextChunk()) {
                        RIFFReader subchunk = chunk.nextChunk();
                        if (subchunk.getFormat().equals("LIST")) {
                            if (subchunk.getType().equals("rgn ")) {
                                DLSRegion split = new DLSRegion();
                                if (readRgnChunk(split, subchunk))
                                    instrument.getRegions().add(split);
                            }
                            if (subchunk.getType().equals("rgn2")) {
                                // support for DLS level 2 regions
                                DLSRegion split = new DLSRegion();
                                if (readRgnChunk(split, subchunk))
                                    instrument.getRegions().add(split);
                            }
                        }
                    }
                }
                if (chunk.getType().equals("lart")) {
                    List<DLSModulator> modlist = new ArrayList<DLSModulator>();
                    while (chunk.hasNextChunk()) {
                        RIFFReader subchunk = chunk.nextChunk();
                        if (chunk.getFormat().equals("cdl ")) {
                            if (!readCdlChunk(chunk)) {
                                modlist.clear();
                                break;
                            }
                        }
                        if (subchunk.getFormat().equals("art1"))
                            readArt1Chunk(modlist, subchunk);
                    }
                    instrument.getModulators().addAll(modlist);
                }
                if (chunk.getType().equals("lar2")) {
                    // support for DLS level 2 ART
                    List<DLSModulator> modlist = new ArrayList<DLSModulator>();
                    while (chunk.hasNextChunk()) {
                        RIFFReader subchunk = chunk.nextChunk();
                        if (chunk.getFormat().equals("cdl ")) {
                            if (!readCdlChunk(chunk)) {
                                modlist.clear();
                                break;
                            }
                        }
                        if (subchunk.getFormat().equals("art2"))
                            readArt2Chunk(modlist, subchunk);
                    }
                    instrument.getModulators().addAll(modlist);
                }
            } else {
                if (format.equals("dlid")) {
                    instrument.guid = new byte[16];
                    chunk.readFully(instrument.guid);
                }
                if (format.equals("insh")) {
                    chunk.readUnsignedInt(); // Read Region Count - ignored

                    int bank = chunk.read();             // LSB
                    bank += (chunk.read() & 127) << 7;   // MSB
                    chunk.read(); // Read Reserved byte
                    int drumins = chunk.read();          // Drum Instrument

                    int id = chunk.read() & 127; // Read only first 7 bits
                    chunk.read(); // Read Reserved byte
                    chunk.read(); // Read Reserved byte
                    chunk.read(); // Read Reserved byte

                    instrument.bank = bank;
                    instrument.preset = (int) id;
                    instrument.druminstrument = (drumins & 128) > 0;
                    //System.out.println("bank="+bank+" drumkit="+drumkit
                    //        +" id="+id);
                }

            }
        }
        instruments.add(instrument);
    }

    private void readArt1Chunk(List<DLSModulator> modulators, RIFFReader riff)
            throws IOException {
        long size = riff.readUnsignedInt();
        long count = riff.readUnsignedInt();

        if (size - 8 != 0)
            riff.skipBytes(size - 8);

        for (int i = 0; i < count; i++) {
            DLSModulator modulator = new DLSModulator();
            modulator.version = 1;
            modulator.source = riff.readUnsignedShort();
            modulator.control = riff.readUnsignedShort();
            modulator.destination = riff.readUnsignedShort();
            modulator.transform = riff.readUnsignedShort();
            modulator.scale = riff.readInt();
            modulators.add(modulator);
        }
    }

    private void readArt2Chunk(List<DLSModulator> modulators, RIFFReader riff)
            throws IOException {
        long size = riff.readUnsignedInt();
        long count = riff.readUnsignedInt();

        if (size - 8 != 0)
            riff.skipBytes(size - 8);

        for (int i = 0; i < count; i++) {
            DLSModulator modulator = new DLSModulator();
            modulator.version = 2;
            modulator.source = riff.readUnsignedShort();
            modulator.control = riff.readUnsignedShort();
            modulator.destination = riff.readUnsignedShort();
            modulator.transform = riff.readUnsignedShort();
            modulator.scale = riff.readInt();
            modulators.add(modulator);
        }
    }

    private Map<DLSRegion, Long> temp_rgnassign = new HashMap<DLSRegion, Long>();

    private boolean readRgnChunk(DLSRegion split, RIFFReader riff)
            throws IOException {
        while (riff.hasNextChunk()) {
            RIFFReader chunk = riff.nextChunk();
            String format = chunk.getFormat();
            if (format.equals("LIST")) {
                if (chunk.getType().equals("lart")) {
                    List<DLSModulator> modlist = new ArrayList<DLSModulator>();
                    while (chunk.hasNextChunk()) {
                        RIFFReader subchunk = chunk.nextChunk();
                        if (chunk.getFormat().equals("cdl ")) {
                            if (!readCdlChunk(chunk)) {
                                modlist.clear();
                                break;
                            }
                        }
                        if (subchunk.getFormat().equals("art1"))
                            readArt1Chunk(modlist, subchunk);
                    }
                    split.getModulators().addAll(modlist);
                }
                if (chunk.getType().equals("lar2")) {
                    // support for DLS level 2 ART
                    List<DLSModulator> modlist = new ArrayList<DLSModulator>();
                    while (chunk.hasNextChunk()) {
                        RIFFReader subchunk = chunk.nextChunk();
                        if (chunk.getFormat().equals("cdl ")) {
                            if (!readCdlChunk(chunk)) {
                                modlist.clear();
                                break;
                            }
                        }
                        if (subchunk.getFormat().equals("art2"))
                            readArt2Chunk(modlist, subchunk);
                    }
                    split.getModulators().addAll(modlist);
                }
            } else {

                if (format.equals("cdl ")) {
                    if (!readCdlChunk(chunk))
                        return false;
                }
                if (format.equals("rgnh")) {
                    split.keyfrom = chunk.readUnsignedShort();
                    split.keyto = chunk.readUnsignedShort();
                    split.velfrom = chunk.readUnsignedShort();
                    split.velto = chunk.readUnsignedShort();
                    split.options = chunk.readUnsignedShort();
                    split.exclusiveClass = chunk.readUnsignedShort();
                }
                if (format.equals("wlnk")) {
                    split.fusoptions = chunk.readUnsignedShort();
                    split.phasegroup = chunk.readUnsignedShort();
                    split.channel = chunk.readUnsignedInt();
                    long sampleid = chunk.readUnsignedInt();
                    temp_rgnassign.put(split, sampleid);
                }
                if (format.equals("wsmp")) {
                    split.sampleoptions = new DLSSampleOptions();
                    readWsmpChunk(split.sampleoptions, chunk);
                }
            }
        }
        return true;
    }

    private void readWsmpChunk(DLSSampleOptions sampleOptions, RIFFReader riff)
            throws IOException {
        long size = riff.readUnsignedInt();
        sampleOptions.unitynote = riff.readUnsignedShort();
        sampleOptions.finetune = riff.readShort();
        sampleOptions.attenuation = riff.readInt();
        sampleOptions.options = riff.readUnsignedInt();
        long loops = riff.readInt();

        if (size > 20)
            riff.skipBytes(size - 20);

        for (int i = 0; i < loops; i++) {
            DLSSampleLoop loop = new DLSSampleLoop();
            long size2 = riff.readUnsignedInt();
            loop.type = riff.readUnsignedInt();
            loop.start = riff.readUnsignedInt();
            loop.length = riff.readUnsignedInt();
            sampleOptions.loops.add(loop);
            if (size2 > 16)
                riff.skipBytes(size2 - 16);
        }
    }

    private void readInsInfoChunk(DLSInstrument dlsinstrument, RIFFReader riff)
            throws IOException {
        dlsinstrument.info.name = null;
        while (riff.hasNextChunk()) {
            RIFFReader chunk = riff.nextChunk();
            String format = chunk.getFormat();
            if (format.equals("INAM")) {
                dlsinstrument.info.name = chunk.readString(chunk.available());
            } else if (format.equals("ICRD")) {
                dlsinstrument.info.creationDate =
                        chunk.readString(chunk.available());
            } else if (format.equals("IENG")) {
                dlsinstrument.info.engineers =
                        chunk.readString(chunk.available());
            } else if (format.equals("IPRD")) {
                dlsinstrument.info.product = chunk.readString(chunk.available());
            } else if (format.equals("ICOP")) {
                dlsinstrument.info.copyright =
                        chunk.readString(chunk.available());
            } else if (format.equals("ICMT")) {
                dlsinstrument.info.comments =
                        chunk.readString(chunk.available());
            } else if (format.equals("ISFT")) {
                dlsinstrument.info.tools = chunk.readString(chunk.available());
            } else if (format.equals("IARL")) {
                dlsinstrument.info.archival_location =
                        chunk.readString(chunk.available());
            } else if (format.equals("IART")) {
                dlsinstrument.info.artist = chunk.readString(chunk.available());
            } else if (format.equals("ICMS")) {
                dlsinstrument.info.commissioned =
                        chunk.readString(chunk.available());
            } else if (format.equals("IGNR")) {
                dlsinstrument.info.genre = chunk.readString(chunk.available());
            } else if (format.equals("IKEY")) {
                dlsinstrument.info.keywords =
                        chunk.readString(chunk.available());
            } else if (format.equals("IMED")) {
                dlsinstrument.info.medium = chunk.readString(chunk.available());
            } else if (format.equals("ISBJ")) {
                dlsinstrument.info.subject = chunk.readString(chunk.available());
            } else if (format.equals("ISRC")) {
                dlsinstrument.info.source = chunk.readString(chunk.available());
            } else if (format.equals("ISRF")) {
                dlsinstrument.info.source_form =
                        chunk.readString(chunk.available());
            } else if (format.equals("ITCH")) {
                dlsinstrument.info.technician =
                        chunk.readString(chunk.available());
            }
        }
    }

    private void readWvplChunk(RIFFReader riff) throws IOException {
        while (riff.hasNextChunk()) {
            RIFFReader chunk = riff.nextChunk();
            if (chunk.getFormat().equals("LIST")) {
                if (chunk.getType().equals("wave"))
                    readWaveChunk(chunk);
            }
        }
    }

    private void readWaveChunk(RIFFReader riff) throws IOException {
        DLSSample sample = new DLSSample(this);

        while (riff.hasNextChunk()) {
            RIFFReader chunk = riff.nextChunk();
            String format = chunk.getFormat();
            if (format.equals("LIST")) {
                if (chunk.getType().equals("INFO")) {
                    readWaveInfoChunk(sample, chunk);
                }
            } else {
                if (format.equals("dlid")) {
                    sample.guid = new byte[16];
                    chunk.readFully(sample.guid);
                }

                if (format.equals("fmt ")) {
                    int sampleformat = chunk.readUnsignedShort();
                    if (sampleformat != 1 && sampleformat != 3) {
                        throw new RIFFInvalidDataException(
                                "Only PCM samples are supported!");
                    }
                    int channels = chunk.readUnsignedShort();
                    long samplerate = chunk.readUnsignedInt();
                    // bytes per sec
                    /* long framerate = */ chunk.readUnsignedInt();
                    // block align, framesize
                    int framesize = chunk.readUnsignedShort();
                    int bits = chunk.readUnsignedShort();
                    AudioFormat audioformat = null;
                    if (sampleformat == 1) {
                        if (bits == 8) {
                            audioformat = new AudioFormat(
                                    Encoding.PCM_UNSIGNED, samplerate, bits,
                                    channels, framesize, samplerate, false);
                        } else {
                            audioformat = new AudioFormat(
                                    Encoding.PCM_SIGNED, samplerate, bits,
                                    channels, framesize, samplerate, false);
                        }
                    }
                    if (sampleformat == 3) {
                        audioformat = new AudioFormat(
                                Encoding.PCM_FLOAT, samplerate, bits,
                                channels, framesize, samplerate, false);
                    }

                    sample.format = audioformat;
                }

                if (format.equals("data")) {
                    if (largeFormat) {
                        sample.setData(new ModelByteBuffer(sampleFile,
                                chunk.getFilePointer(), chunk.available()));
                    } else {
                        byte[] buffer = new byte[chunk.available()];
                        //  chunk.read(buffer);
                        sample.setData(buffer);

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

                if (format.equals("wsmp")) {
                    sample.sampleoptions = new DLSSampleOptions();
                    readWsmpChunk(sample.sampleoptions, chunk);
                }
            }
        }

        samples.add(sample);

    }

    private void readWaveInfoChunk(DLSSample dlssample, RIFFReader riff)
            throws IOException {
        dlssample.info.name = null;
        while (riff.hasNextChunk()) {
            RIFFReader chunk = riff.nextChunk();
            String format = chunk.getFormat();
            if (format.equals("INAM")) {
                dlssample.info.name = chunk.readString(chunk.available());
            } else if (format.equals("ICRD")) {
                dlssample.info.creationDate =
                        chunk.readString(chunk.available());
            } else if (format.equals("IENG")) {
                dlssample.info.engineers = chunk.readString(chunk.available());
            } else if (format.equals("IPRD")) {
                dlssample.info.product = chunk.readString(chunk.available());
            } else if (format.equals("ICOP")) {
                dlssample.info.copyright = chunk.readString(chunk.available());
            } else if (format.equals("ICMT")) {
                dlssample.info.comments = chunk.readString(chunk.available());
            } else if (format.equals("ISFT")) {
                dlssample.info.tools = chunk.readString(chunk.available());
            } else if (format.equals("IARL")) {
                dlssample.info.archival_location =
                        chunk.readString(chunk.available());
            } else if (format.equals("IART")) {
                dlssample.info.artist = chunk.readString(chunk.available());
            } else if (format.equals("ICMS")) {
                dlssample.info.commissioned =
                        chunk.readString(chunk.available());
            } else if (format.equals("IGNR")) {
                dlssample.info.genre = chunk.readString(chunk.available());
            } else if (format.equals("IKEY")) {
                dlssample.info.keywords = chunk.readString(chunk.available());
            } else if (format.equals("IMED")) {
                dlssample.info.medium = chunk.readString(chunk.available());
            } else if (format.equals("ISBJ")) {
                dlssample.info.subject = chunk.readString(chunk.available());
            } else if (format.equals("ISRC")) {
                dlssample.info.source = chunk.readString(chunk.available());
            } else if (format.equals("ISRF")) {
                dlssample.info.source_form = chunk.readString(chunk.available());
            } else if (format.equals("ITCH")) {
                dlssample.info.technician = chunk.readString(chunk.available());
            }
        }
    }

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

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

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

    private void writeSoundbank(RIFFWriter writer) throws IOException {
        RIFFWriter colh_chunk = writer.writeChunk("colh");
        colh_chunk.writeUnsignedInt(instruments.size());

        if (major != -1 && minor != -1) {
            RIFFWriter vers_chunk = writer.writeChunk("vers");
            vers_chunk.writeUnsignedInt(major);
            vers_chunk.writeUnsignedInt(minor);
        }

        writeInstruments(writer.writeList("lins"));

        RIFFWriter ptbl = writer.writeChunk("ptbl");
        ptbl.writeUnsignedInt(8);
        ptbl.writeUnsignedInt(samples.size());
        long ptbl_offset = writer.getFilePointer();
        for (int i = 0; i < samples.size(); i++)
            ptbl.writeUnsignedInt(0);

        RIFFWriter wvpl = writer.writeList("wvpl");
        long off = wvpl.getFilePointer();
        List<Long> offsettable = new ArrayList<Long>();
        for (DLSSample sample : samples) {
            offsettable.add(Long.valueOf(wvpl.getFilePointer() - off));
            writeSample(wvpl.writeList("wave"), sample);
        }

        // small cheat, we are going to rewrite data back in wvpl
        long bak = writer.getFilePointer();
        writer.seek(ptbl_offset);
        writer.setWriteOverride(true);
        for (Long offset : offsettable)
            writer.writeUnsignedInt(offset.longValue());
        writer.setWriteOverride(false);
        writer.seek(bak);

        writeInfo(writer.writeList("INFO"), info);

        writer.close();
    }

    private void writeSample(RIFFWriter writer, DLSSample sample)
            throws IOException {

        AudioFormat audioformat = sample.getFormat();

        Encoding encoding = audioformat.getEncoding();
        float sampleRate = audioformat.getSampleRate();
        int sampleSizeInBits = audioformat.getSampleSizeInBits();
        int channels = audioformat.getChannels();
        int frameSize = audioformat.getFrameSize();
        float frameRate = audioformat.getFrameRate();
        boolean bigEndian = audioformat.isBigEndian();

        boolean convert_needed = false;

        if (audioformat.getSampleSizeInBits() == 8) {
            if (!encoding.equals(Encoding.PCM_UNSIGNED)) {
                encoding = Encoding.PCM_UNSIGNED;
                convert_needed = true;
            }
        } else {
            if (!encoding.equals(Encoding.PCM_SIGNED)) {
                encoding = Encoding.PCM_SIGNED;
                convert_needed = true;
            }
            if (bigEndian) {
                bigEndian = false;
                convert_needed = true;
            }
        }

        if (convert_needed) {
            audioformat = new AudioFormat(encoding, sampleRate,
                    sampleSizeInBits, channels, frameSize, frameRate, bigEndian);
        }

        // fmt
        RIFFWriter fmt_chunk = writer.writeChunk("fmt ");
        int sampleformat = 0;
        if (audioformat.getEncoding().equals(Encoding.PCM_UNSIGNED))
            sampleformat = 1;
        else if (audioformat.getEncoding().equals(Encoding.PCM_SIGNED))
            sampleformat = 1;
        else if (audioformat.getEncoding().equals(Encoding.PCM_FLOAT))
            sampleformat = 3;

        fmt_chunk.writeUnsignedShort(sampleformat);
        fmt_chunk.writeUnsignedShort(audioformat.getChannels());
        fmt_chunk.writeUnsignedInt((long) audioformat.getSampleRate());
        long srate = ((long)audioformat.getFrameRate())*audioformat.getFrameSize();
        fmt_chunk.writeUnsignedInt(srate);
        fmt_chunk.writeUnsignedShort(audioformat.getFrameSize());
        fmt_chunk.writeUnsignedShort(audioformat.getSampleSizeInBits());
        fmt_chunk.write(0);
        fmt_chunk.write(0);

        writeSampleOptions(writer.writeChunk("wsmp"), sample.sampleoptions);

        if (convert_needed) {
            RIFFWriter data_chunk = writer.writeChunk("data");
            AudioInputStream stream = AudioSystem.getAudioInputStream(
                    audioformat, (AudioInputStream)sample.getData());
            byte[] buff = new byte[1024];
            int ret;
            while ((ret = stream.read(buff)) != -1) {
                data_chunk.write(buff, 0, ret);
            }
        } else {
            RIFFWriter data_chunk = writer.writeChunk("data");
            ModelByteBuffer databuff = sample.getDataBuffer();
            databuff.writeTo(data_chunk);
            /*
            data_chunk.write(databuff.array(),
            databuff.arrayOffset(),
            databuff.capacity());
             */
        }

        writeInfo(writer.writeList("INFO"), sample.info);
    }

    private void writeInstruments(RIFFWriter writer) throws IOException {
        for (DLSInstrument instrument : instruments) {
            writeInstrument(writer.writeList("ins "), instrument);
        }
    }

    private void writeInstrument(RIFFWriter writer, DLSInstrument instrument)
            throws IOException {

        int art1_count = 0;
        int art2_count = 0;
        for (DLSModulator modulator : instrument.getModulators()) {
            if (modulator.version == 1)
                art1_count++;
            if (modulator.version == 2)
                art2_count++;
        }
        for (DLSRegion region : instrument.regions) {
            for (DLSModulator modulator : region.getModulators()) {
                if (modulator.version == 1)
                    art1_count++;
                if (modulator.version == 2)
                    art2_count++;
            }
        }

        int version = 1;
        if (art2_count > 0)
            version = 2;

        RIFFWriter insh_chunk = writer.writeChunk("insh");
        insh_chunk.writeUnsignedInt(instrument.getRegions().size());
        insh_chunk.writeUnsignedInt(instrument.bank +
                (instrument.druminstrument ? 2147483648L : 0));
        insh_chunk.writeUnsignedInt(instrument.preset);

        RIFFWriter lrgn = writer.writeList("lrgn");
        for (DLSRegion region: instrument.regions)
            writeRegion(lrgn, region, version);

        writeArticulators(writer, instrument.getModulators());

        writeInfo(writer.writeList("INFO"), instrument.info);

    }

    private void writeArticulators(RIFFWriter writer,
            List<DLSModulator> modulators) throws IOException {
        int art1_count = 0;
        int art2_count = 0;
        for (DLSModulator modulator : modulators) {
            if (modulator.version == 1)
                art1_count++;
            if (modulator.version == 2)
                art2_count++;
        }
        if (art1_count > 0) {
            RIFFWriter lar1 = writer.writeList("lart");
            RIFFWriter art1 = lar1.writeChunk("art1");
            art1.writeUnsignedInt(8);
            art1.writeUnsignedInt(art1_count);
            for (DLSModulator modulator : modulators) {
                if (modulator.version == 1) {
                    art1.writeUnsignedShort(modulator.source);
                    art1.writeUnsignedShort(modulator.control);
                    art1.writeUnsignedShort(modulator.destination);
                    art1.writeUnsignedShort(modulator.transform);
                    art1.writeInt(modulator.scale);
                }
            }
        }
        if (art2_count > 0) {
            RIFFWriter lar2 = writer.writeList("lar2");
            RIFFWriter art2 = lar2.writeChunk("art2");
            art2.writeUnsignedInt(8);
            art2.writeUnsignedInt(art2_count);
            for (DLSModulator modulator : modulators) {
                if (modulator.version == 2) {
                    art2.writeUnsignedShort(modulator.source);
                    art2.writeUnsignedShort(modulator.control);
                    art2.writeUnsignedShort(modulator.destination);
                    art2.writeUnsignedShort(modulator.transform);
                    art2.writeInt(modulator.scale);
                }
            }
        }
    }

    private void writeRegion(RIFFWriter writer, DLSRegion region, int version)
            throws IOException {
        RIFFWriter rgns = null;
        if (version == 1)
            rgns = writer.writeList("rgn ");
        if (version == 2)
            rgns = writer.writeList("rgn2");
        if (rgns == null)
            return;

        RIFFWriter rgnh = rgns.writeChunk("rgnh");
        rgnh.writeUnsignedShort(region.keyfrom);
        rgnh.writeUnsignedShort(region.keyto);
        rgnh.writeUnsignedShort(region.velfrom);
        rgnh.writeUnsignedShort(region.velto);
        rgnh.writeUnsignedShort(region.options);
        rgnh.writeUnsignedShort(region.exclusiveClass);

        if (region.sampleoptions != null)
            writeSampleOptions(rgns.writeChunk("wsmp"), region.sampleoptions);

        if (region.sample != null) {
            if (samples.indexOf(region.sample) != -1) {
                RIFFWriter wlnk = rgns.writeChunk("wlnk");
                wlnk.writeUnsignedShort(region.fusoptions);
                wlnk.writeUnsignedShort(region.phasegroup);
                wlnk.writeUnsignedInt(region.channel);
                wlnk.writeUnsignedInt(samples.indexOf(region.sample));
            }
        }
        writeArticulators(rgns, region.getModulators());
        rgns.close();
    }

    private void writeSampleOptions(RIFFWriter wsmp,
            DLSSampleOptions sampleoptions) throws IOException {
        wsmp.writeUnsignedInt(20);
        wsmp.writeUnsignedShort(sampleoptions.unitynote);
        wsmp.writeShort(sampleoptions.finetune);
        wsmp.writeInt(sampleoptions.attenuation);
        wsmp.writeUnsignedInt(sampleoptions.options);
        wsmp.writeInt(sampleoptions.loops.size());

        for (DLSSampleLoop loop : sampleoptions.loops) {
            wsmp.writeUnsignedInt(16);
            wsmp.writeUnsignedInt(loop.type);
            wsmp.writeUnsignedInt(loop.start);
            wsmp.writeUnsignedInt(loop.length);
        }
    }

    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, DLSInfo info) throws IOException {
        writeInfoStringChunk(writer, "INAM", info.name);
        writeInfoStringChunk(writer, "ICRD", info.creationDate);
        writeInfoStringChunk(writer, "IENG", info.engineers);
        writeInfoStringChunk(writer, "IPRD", info.product);
        writeInfoStringChunk(writer, "ICOP", info.copyright);
        writeInfoStringChunk(writer, "ICMT", info.comments);
        writeInfoStringChunk(writer, "ISFT", info.tools);
        writeInfoStringChunk(writer, "IARL", info.archival_location);
        writeInfoStringChunk(writer, "IART", info.artist);
        writeInfoStringChunk(writer, "ICMS", info.commissioned);
        writeInfoStringChunk(writer, "IGNR", info.genre);
        writeInfoStringChunk(writer, "IKEY", info.keywords);
        writeInfoStringChunk(writer, "IMED", info.medium);
        writeInfoStringChunk(writer, "ISBJ", info.subject);
        writeInfoStringChunk(writer, "ISRC", info.source);
        writeInfoStringChunk(writer, "ISRF", info.source_form);
        writeInfoStringChunk(writer, "ITCH", info.technician);
    }

    public DLSInfo getInfo() {
        return info;
    }

    public String getName() {
        return info.name;
    }

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

    public String getVendor() {
        return info.engineers;
    }

    public String getDescription() {
        return info.comments;
    }

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

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

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

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

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

    public DLSSample[] getSamples() {
        return samples.toArray(new DLSSample[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 void addResource(SoundbankResource resource) {
        if (resource instanceof DLSInstrument)
            instruments.add((DLSInstrument) resource);
        if (resource instanceof DLSSample)
            samples.add((DLSSample) resource);
    }

    public void removeResource(SoundbankResource resource) {
        if (resource instanceof DLSInstrument)
            instruments.remove((DLSInstrument) resource);
        if (resource instanceof DLSSample)
            samples.remove((DLSSample) resource);
    }

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

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

    public long getMajor() {
        return major;
    }

    public void setMajor(long major) {
        this.major = major;
    }

    public long getMinor() {
        return minor;
    }

    public void setMinor(long minor) {
        this.minor = minor;
    }
}
