/*
 * 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.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sound.midi.Patch;

/**
 * This class is used to store information to describe instrument.
 * It contains list of regions and modulators.
 * It is stored inside a "ins " List Chunk inside DLS files.
 * In the DLS documentation a modulator is called articulator.
 *
 * @author Karl Helgason
 */
public final class DLSInstrument extends ModelInstrument {

    int preset = 0;
    int bank = 0;
    boolean druminstrument = false;
    byte[] guid = null;
    DLSInfo info = new DLSInfo();
    List<DLSRegion> regions = new ArrayList<DLSRegion>();
    List<DLSModulator> modulators = new ArrayList<DLSModulator>();

    public DLSInstrument() {
        super(null, null, null, null);
    }

    public DLSInstrument(DLSSoundbank soundbank) {
        super(soundbank, null, null, null);
    }

    public DLSInfo getInfo() {
        return info;
    }

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

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

    public ModelPatch getPatch() {
        return new ModelPatch(bank, preset, druminstrument);
    }

    public void setPatch(Patch patch) {
        if (patch instanceof ModelPatch && ((ModelPatch)patch).isPercussion()) {
            druminstrument = true;
            bank = patch.getBank();
            preset = patch.getProgram();
        } else {
            druminstrument = false;
            bank = patch.getBank();
            preset = patch.getProgram();
        }
    }

    public Object getData() {
        return null;
    }

    public List<DLSRegion> getRegions() {
        return regions;
    }

    public List<DLSModulator> getModulators() {
        return modulators;
    }

    public String toString() {
        if (druminstrument)
            return "Drumkit: " + info.name
                    + " bank #" + bank + " preset #" + preset;
        else
            return "Instrument: " + info.name
                    + " bank #" + bank + " preset #" + preset;
    }

    private ModelIdentifier convertToModelDest(int dest) {
        if (dest == DLSModulator.CONN_DST_NONE)
            return null;
        if (dest == DLSModulator.CONN_DST_GAIN)
            return ModelDestination.DESTINATION_GAIN;
        if (dest == DLSModulator.CONN_DST_PITCH)
            return ModelDestination.DESTINATION_PITCH;
        if (dest == DLSModulator.CONN_DST_PAN)
            return ModelDestination.DESTINATION_PAN;

        if (dest == DLSModulator.CONN_DST_LFO_FREQUENCY)
            return ModelDestination.DESTINATION_LFO1_FREQ;
        if (dest == DLSModulator.CONN_DST_LFO_STARTDELAY)
            return ModelDestination.DESTINATION_LFO1_DELAY;

        if (dest == DLSModulator.CONN_DST_EG1_ATTACKTIME)
            return ModelDestination.DESTINATION_EG1_ATTACK;
        if (dest == DLSModulator.CONN_DST_EG1_DECAYTIME)
            return ModelDestination.DESTINATION_EG1_DECAY;
        if (dest == DLSModulator.CONN_DST_EG1_RELEASETIME)
            return ModelDestination.DESTINATION_EG1_RELEASE;
        if (dest == DLSModulator.CONN_DST_EG1_SUSTAINLEVEL)
            return ModelDestination.DESTINATION_EG1_SUSTAIN;

        if (dest == DLSModulator.CONN_DST_EG2_ATTACKTIME)
            return ModelDestination.DESTINATION_EG2_ATTACK;
        if (dest == DLSModulator.CONN_DST_EG2_DECAYTIME)
            return ModelDestination.DESTINATION_EG2_DECAY;
        if (dest == DLSModulator.CONN_DST_EG2_RELEASETIME)
            return ModelDestination.DESTINATION_EG2_RELEASE;
        if (dest == DLSModulator.CONN_DST_EG2_SUSTAINLEVEL)
            return ModelDestination.DESTINATION_EG2_SUSTAIN;

        // DLS2 Destinations
        if (dest == DLSModulator.CONN_DST_KEYNUMBER)
            return ModelDestination.DESTINATION_KEYNUMBER;

        if (dest == DLSModulator.CONN_DST_CHORUS)
            return ModelDestination.DESTINATION_CHORUS;
        if (dest == DLSModulator.CONN_DST_REVERB)
            return ModelDestination.DESTINATION_REVERB;

        if (dest == DLSModulator.CONN_DST_VIB_FREQUENCY)
            return ModelDestination.DESTINATION_LFO2_FREQ;
        if (dest == DLSModulator.CONN_DST_VIB_STARTDELAY)
            return ModelDestination.DESTINATION_LFO2_DELAY;

        if (dest == DLSModulator.CONN_DST_EG1_DELAYTIME)
            return ModelDestination.DESTINATION_EG1_DELAY;
        if (dest == DLSModulator.CONN_DST_EG1_HOLDTIME)
            return ModelDestination.DESTINATION_EG1_HOLD;
        if (dest == DLSModulator.CONN_DST_EG1_SHUTDOWNTIME)
            return ModelDestination.DESTINATION_EG1_SHUTDOWN;

        if (dest == DLSModulator.CONN_DST_EG2_DELAYTIME)
            return ModelDestination.DESTINATION_EG2_DELAY;
        if (dest == DLSModulator.CONN_DST_EG2_HOLDTIME)
            return ModelDestination.DESTINATION_EG2_HOLD;

        if (dest == DLSModulator.CONN_DST_FILTER_CUTOFF)
            return ModelDestination.DESTINATION_FILTER_FREQ;
        if (dest == DLSModulator.CONN_DST_FILTER_Q)
            return ModelDestination.DESTINATION_FILTER_Q;

        return null;
    }

    private ModelIdentifier convertToModelSrc(int src) {
        if (src == DLSModulator.CONN_SRC_NONE)
            return null;

        if (src == DLSModulator.CONN_SRC_LFO)
            return ModelSource.SOURCE_LFO1;
        if (src == DLSModulator.CONN_SRC_KEYONVELOCITY)
            return ModelSource.SOURCE_NOTEON_VELOCITY;
        if (src == DLSModulator.CONN_SRC_KEYNUMBER)
            return ModelSource.SOURCE_NOTEON_KEYNUMBER;
        if (src == DLSModulator.CONN_SRC_EG1)
            return ModelSource.SOURCE_EG1;
        if (src == DLSModulator.CONN_SRC_EG2)
            return ModelSource.SOURCE_EG2;
        if (src == DLSModulator.CONN_SRC_PITCHWHEEL)
            return ModelSource.SOURCE_MIDI_PITCH;
        if (src == DLSModulator.CONN_SRC_CC1)
            return new ModelIdentifier("midi_cc", "1", 0);
        if (src == DLSModulator.CONN_SRC_CC7)
            return new ModelIdentifier("midi_cc", "7", 0);
        if (src == DLSModulator.CONN_SRC_CC10)
            return new ModelIdentifier("midi_cc", "10", 0);
        if (src == DLSModulator.CONN_SRC_CC11)
            return new ModelIdentifier("midi_cc", "11", 0);
        if (src == DLSModulator.CONN_SRC_RPN0)
            return new ModelIdentifier("midi_rpn", "0", 0);
        if (src == DLSModulator.CONN_SRC_RPN1)
            return new ModelIdentifier("midi_rpn", "1", 0);

        if (src == DLSModulator.CONN_SRC_POLYPRESSURE)
            return ModelSource.SOURCE_MIDI_POLY_PRESSURE;
        if (src == DLSModulator.CONN_SRC_CHANNELPRESSURE)
            return ModelSource.SOURCE_MIDI_CHANNEL_PRESSURE;
        if (src == DLSModulator.CONN_SRC_VIBRATO)
            return ModelSource.SOURCE_LFO2;
        if (src == DLSModulator.CONN_SRC_MONOPRESSURE)
            return ModelSource.SOURCE_MIDI_CHANNEL_PRESSURE;

        if (src == DLSModulator.CONN_SRC_CC91)
            return new ModelIdentifier("midi_cc", "91", 0);
        if (src == DLSModulator.CONN_SRC_CC93)
            return new ModelIdentifier("midi_cc", "93", 0);

        return null;
    }

    private ModelConnectionBlock convertToModel(DLSModulator mod) {
        ModelIdentifier source = convertToModelSrc(mod.getSource());
        ModelIdentifier control = convertToModelSrc(mod.getControl());
        ModelIdentifier destination_id =
                convertToModelDest(mod.getDestination());

        int scale = mod.getScale();
        double f_scale;
        if (scale == Integer.MIN_VALUE)
            f_scale = Double.NEGATIVE_INFINITY;
        else
            f_scale = scale / 65536.0;

        if (destination_id != null) {
            ModelSource src = null;
            ModelSource ctrl = null;
            ModelConnectionBlock block = new ModelConnectionBlock();
            if (control != null) {
                ModelSource s = new ModelSource();
                if (control == ModelSource.SOURCE_MIDI_PITCH) {
                    ((ModelStandardTransform)s.getTransform()).setPolarity(
                            ModelStandardTransform.POLARITY_BIPOLAR);
                } else if (control == ModelSource.SOURCE_LFO1
                        || control == ModelSource.SOURCE_LFO2) {
                    ((ModelStandardTransform)s.getTransform()).setPolarity(
                            ModelStandardTransform.POLARITY_BIPOLAR);
                }
                s.setIdentifier(control);
                block.addSource(s);
                ctrl = s;
            }
            if (source != null) {
                ModelSource s = new ModelSource();
                if (source == ModelSource.SOURCE_MIDI_PITCH) {
                    ((ModelStandardTransform)s.getTransform()).setPolarity(
                            ModelStandardTransform.POLARITY_BIPOLAR);
                } else if (source == ModelSource.SOURCE_LFO1
                        || source == ModelSource.SOURCE_LFO2) {
                    ((ModelStandardTransform)s.getTransform()).setPolarity(
                            ModelStandardTransform.POLARITY_BIPOLAR);
                }
                s.setIdentifier(source);
                block.addSource(s);
                src = s;
            }
            ModelDestination destination = new ModelDestination();
            destination.setIdentifier(destination_id);
            block.setDestination(destination);

            if (mod.getVersion() == 1) {
                //if (mod.getTransform() ==  DLSModulator.CONN_TRN_CONCAVE) {
                //    ((ModelStandardTransform)destination.getTransform())
                //            .setTransform(
                //            ModelStandardTransform.TRANSFORM_CONCAVE);
                //}
                if (mod.getTransform() == DLSModulator.CONN_TRN_CONCAVE) {
                    if (src != null) {
                        ((ModelStandardTransform)src.getTransform())
                                .setTransform(
                                    ModelStandardTransform.TRANSFORM_CONCAVE);
                        ((ModelStandardTransform)src.getTransform())
                                .setDirection(
                                    ModelStandardTransform.DIRECTION_MAX2MIN);
                    }
                    if (ctrl != null) {
                        ((ModelStandardTransform)ctrl.getTransform())
                                .setTransform(
                                    ModelStandardTransform.TRANSFORM_CONCAVE);
                        ((ModelStandardTransform)ctrl.getTransform())
                                .setDirection(
                                    ModelStandardTransform.DIRECTION_MAX2MIN);
                    }
                }

            } else if (mod.getVersion() == 2) {
                int transform = mod.getTransform();
                int src_transform_invert = (transform >> 15) & 1;
                int src_transform_bipolar = (transform >> 14) & 1;
                int src_transform = (transform >> 10) & 8;
                int ctr_transform_invert = (transform >> 9) & 1;
                int ctr_transform_bipolar = (transform >> 8) & 1;
                int ctr_transform = (transform >> 4) & 8;


                if (src != null) {
                    int trans = ModelStandardTransform.TRANSFORM_LINEAR;
                    if (src_transform == DLSModulator.CONN_TRN_SWITCH)
                        trans = ModelStandardTransform.TRANSFORM_SWITCH;
                    if (src_transform == DLSModulator.CONN_TRN_CONCAVE)
                        trans = ModelStandardTransform.TRANSFORM_CONCAVE;
                    if (src_transform == DLSModulator.CONN_TRN_CONVEX)
                        trans = ModelStandardTransform.TRANSFORM_CONVEX;
                    ((ModelStandardTransform)src.getTransform())
                            .setTransform(trans);
                    ((ModelStandardTransform)src.getTransform())
                            .setPolarity(src_transform_bipolar == 1);
                    ((ModelStandardTransform)src.getTransform())
                            .setDirection(src_transform_invert == 1);

                }

                if (ctrl != null) {
                    int trans = ModelStandardTransform.TRANSFORM_LINEAR;
                    if (ctr_transform == DLSModulator.CONN_TRN_SWITCH)
                        trans = ModelStandardTransform.TRANSFORM_SWITCH;
                    if (ctr_transform == DLSModulator.CONN_TRN_CONCAVE)
                        trans = ModelStandardTransform.TRANSFORM_CONCAVE;
                    if (ctr_transform == DLSModulator.CONN_TRN_CONVEX)
                        trans = ModelStandardTransform.TRANSFORM_CONVEX;
                    ((ModelStandardTransform)ctrl.getTransform())
                            .setTransform(trans);
                    ((ModelStandardTransform)ctrl.getTransform())
                            .setPolarity(ctr_transform_bipolar == 1);
                    ((ModelStandardTransform)ctrl.getTransform())
                            .setDirection(ctr_transform_invert == 1);
                }

                /* No output transforms are defined the DLS Level 2
                int out_transform = transform % 8;
                int trans = ModelStandardTransform.TRANSFORM_LINEAR;
                if (out_transform == DLSModulator.CONN_TRN_SWITCH)
                    trans = ModelStandardTransform.TRANSFORM_SWITCH;
                if (out_transform == DLSModulator.CONN_TRN_CONCAVE)
                    trans = ModelStandardTransform.TRANSFORM_CONCAVE;
                if (out_transform == DLSModulator.CONN_TRN_CONVEX)
                    trans = ModelStandardTransform.TRANSFORM_CONVEX;
                if (ctrl != null) {
                    ((ModelStandardTransform)destination.getTransform())
                            .setTransform(trans);
                }
                */

            }

            block.setScale(f_scale);

            return block;
        }

        return null;
    }

    public ModelPerformer[] getPerformers() {
        List<ModelPerformer> performers = new ArrayList<ModelPerformer>();

        Map<String, DLSModulator> modmap = new HashMap<String, DLSModulator>();
        for (DLSModulator mod: getModulators()) {
            modmap.put(mod.getSource() + "x" + mod.getControl() + "=" +
                    mod.getDestination(), mod);
        }

        Map<String, DLSModulator> insmodmap =
                new HashMap<String, DLSModulator>();

        for (DLSRegion zone: regions) {
            ModelPerformer performer = new ModelPerformer();
            performer.setName(zone.getSample().getName());
            performer.setSelfNonExclusive((zone.getFusoptions() &
                    DLSRegion.OPTION_SELFNONEXCLUSIVE) != 0);
            performer.setExclusiveClass(zone.getExclusiveClass());
            performer.setKeyFrom(zone.getKeyfrom());
            performer.setKeyTo(zone.getKeyto());
            performer.setVelFrom(zone.getVelfrom());
            performer.setVelTo(zone.getVelto());

            insmodmap.clear();
            insmodmap.putAll(modmap);
            for (DLSModulator mod: zone.getModulators()) {
                insmodmap.put(mod.getSource() + "x" + mod.getControl() + "=" +
                        mod.getDestination(), mod);
            }

            List<ModelConnectionBlock> blocks = performer.getConnectionBlocks();
            for (DLSModulator mod: insmodmap.values()) {
                ModelConnectionBlock p = convertToModel(mod);
                if (p != null)
                    blocks.add(p);
            }


            DLSSample sample = zone.getSample();
            DLSSampleOptions sampleopt = zone.getSampleoptions();
            if (sampleopt == null)
                sampleopt = sample.getSampleoptions();

            ModelByteBuffer buff = sample.getDataBuffer();

            float pitchcorrection = (-sampleopt.unitynote * 100) +
                    sampleopt.finetune;

            ModelByteBufferWavetable osc = new ModelByteBufferWavetable(buff,
                    sample.getFormat(), pitchcorrection);
            osc.setAttenuation(osc.getAttenuation() / 65536f);
            if (sampleopt.getLoops().size() != 0) {
                DLSSampleLoop loop = sampleopt.getLoops().get(0);
                osc.setLoopStart((int)loop.getStart());
                osc.setLoopLength((int)loop.getLength());
                if (loop.getType() == DLSSampleLoop.LOOP_TYPE_FORWARD)
                    osc.setLoopType(ModelWavetable.LOOP_TYPE_FORWARD);
                if (loop.getType() == DLSSampleLoop.LOOP_TYPE_RELEASE)
                    osc.setLoopType(ModelWavetable.LOOP_TYPE_RELEASE);
                else
                    osc.setLoopType(ModelWavetable.LOOP_TYPE_FORWARD);
            }

            performer.getConnectionBlocks().add(
                    new ModelConnectionBlock(SoftFilter.FILTERTYPE_LP12,
                        new ModelDestination(
                            new ModelIdentifier("filter", "type", 1))));

            performer.getOscillators().add(osc);

            performers.add(performer);

        }

        return performers.toArray(new ModelPerformer[performers.size()]);
    }

    public byte[] getGuid() {
        return guid == null ? null : Arrays.copyOf(guid, guid.length);
    }

    public void setGuid(byte[] guid) {
        this.guid = guid == null ? null : Arrays.copyOf(guid, guid.length);
    }
}
