/*
 * 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.IOException;
import java.util.Arrays;

import javax.sound.midi.MidiChannel;
import javax.sound.midi.VoiceStatus;

/**
 * Abstract resampler class.
 *
 * @author Karl Helgason
 */
public abstract class SoftAbstractResampler implements SoftResampler {

    private class ModelAbstractResamplerStream implements SoftResamplerStreamer {

        AudioFloatInputStream stream;
        boolean stream_eof = false;
        int loopmode;
        boolean loopdirection = true; // true = forward
        float loopstart;
        float looplen;
        float target_pitch;
        float[] current_pitch = new float[1];
        boolean started;
        boolean eof;
        int sector_pos = 0;
        int sector_size = 400;
        int sector_loopstart = -1;
        boolean markset = false;
        int marklimit = 0;
        int streampos = 0;
        int nrofchannels = 2;
        boolean noteOff_flag = false;
        float[][] ibuffer;
        boolean ibuffer_order = true;
        float[] sbuffer;
        int pad;
        int pad2;
        float[] ix = new float[1];
        int[] ox = new int[1];
        float samplerateconv = 1;
        float pitchcorrection = 0;

        ModelAbstractResamplerStream() {
            pad = getPadding();
            pad2 = getPadding() * 2;
            ibuffer = new float[2][sector_size + pad2];
            ibuffer_order = true;
        }

        public void noteOn(MidiChannel channel, VoiceStatus voice,
                int noteNumber, int velocity) {
        }

        public void noteOff(int velocity) {
            noteOff_flag = true;
        }

        public void open(ModelWavetable osc, float outputsamplerate)
                throws IOException {

            eof = false;
            nrofchannels = osc.getChannels();
            if (ibuffer.length < nrofchannels) {
                ibuffer = new float[nrofchannels][sector_size + pad2];
            }

            stream = osc.openStream();
            streampos = 0;
            stream_eof = false;
            pitchcorrection = osc.getPitchcorrection();
            samplerateconv
                    = stream.getFormat().getSampleRate() / outputsamplerate;
            looplen = osc.getLoopLength();
            loopstart = osc.getLoopStart();
            sector_loopstart = (int) (loopstart / sector_size);
            sector_loopstart = sector_loopstart - 1;

            sector_pos = 0;

            if (sector_loopstart < 0)
                sector_loopstart = 0;
            started = false;
            loopmode = osc.getLoopType();

            if (loopmode != 0) {
                markset = false;
                marklimit = nrofchannels * (int) (looplen + pad2 + 1);
            } else
                markset = true;
            // loopmode = 0;

            target_pitch = samplerateconv;
            current_pitch[0] = samplerateconv;

            ibuffer_order = true;
            loopdirection = true;
            noteOff_flag = false;

            for (int i = 0; i < nrofchannels; i++)
                Arrays.fill(ibuffer[i], sector_size, sector_size + pad2, 0);
            ix[0] = pad;
            eof = false;

            ix[0] = sector_size + pad;
            sector_pos = -1;
            streampos = -sector_size;

            nextBuffer();
        }

        public void setPitch(float pitch) {
            /*
            this.pitch = (float) Math.pow(2f,
            (pitchcorrection + pitch) / 1200.0f)
             * samplerateconv;
             */
            this.target_pitch = (float)Math.exp(
                    (pitchcorrection + pitch) * (Math.log(2.0) / 1200.0))
                * samplerateconv;

            if (!started)
                current_pitch[0] = this.target_pitch;
        }

        public void nextBuffer() throws IOException {
            if (ix[0] < pad) {
                if (markset) {
                    // reset to target sector
                    stream.reset();
                    ix[0] += streampos - (sector_loopstart * sector_size);
                    sector_pos = sector_loopstart;
                    streampos = sector_pos * sector_size;

                    // and go one sector backward
                    ix[0] += sector_size;
                    sector_pos -= 1;
                    streampos -= sector_size;
                    stream_eof = false;
                }
            }

            if (ix[0] >= sector_size + pad) {
                if (stream_eof) {
                    eof = true;
                    return;
                }
            }

            if (ix[0] >= sector_size * 4 + pad) {
                int skips = (int)((ix[0] - sector_size * 4 + pad) / sector_size);
                ix[0] -= sector_size * skips;
                sector_pos += skips;
                streampos += sector_size * skips;
                stream.skip(sector_size * skips);
            }

            while (ix[0] >= sector_size + pad) {
                if (!markset) {
                    if (sector_pos + 1 == sector_loopstart) {
                        stream.mark(marklimit);
                        markset = true;
                    }
                }
                ix[0] -= sector_size;
                sector_pos++;
                streampos += sector_size;

                for (int c = 0; c < nrofchannels; c++) {
                    float[] cbuffer = ibuffer[c];
                    for (int i = 0; i < pad2; i++)
                        cbuffer[i] = cbuffer[i + sector_size];
                }

                int ret;
                if (nrofchannels == 1)
                    ret = stream.read(ibuffer[0], pad2, sector_size);
                else {
                    int slen = sector_size * nrofchannels;
                    if (sbuffer == null || sbuffer.length < slen)
                        sbuffer = new float[slen];
                    int sret = stream.read(sbuffer, 0, slen);
                    if (sret == -1)
                        ret = -1;
                    else {
                        ret = sret / nrofchannels;
                        for (int i = 0; i < nrofchannels; i++) {
                            float[] buff = ibuffer[i];
                            int ix = i;
                            int ix_step = nrofchannels;
                            int ox = pad2;
                            for (int j = 0; j < ret; j++, ix += ix_step, ox++)
                                buff[ox] = sbuffer[ix];
                        }
                    }

                }

                if (ret == -1) {
                    ret = 0;
                    stream_eof = true;
                    for (int i = 0; i < nrofchannels; i++)
                        Arrays.fill(ibuffer[i], pad2, pad2 + sector_size, 0f);
                    return;
                }
                if (ret != sector_size) {
                    for (int i = 0; i < nrofchannels; i++)
                        Arrays.fill(ibuffer[i], pad2 + ret, pad2 + sector_size, 0f);
                }

                ibuffer_order = true;

            }

        }

        public void reverseBuffers() {
            ibuffer_order = !ibuffer_order;
            for (int c = 0; c < nrofchannels; c++) {
                float[] cbuff = ibuffer[c];
                int len = cbuff.length - 1;
                int len2 = cbuff.length / 2;
                for (int i = 0; i < len2; i++) {
                    float x = cbuff[i];
                    cbuff[i] = cbuff[len - i];
                    cbuff[len - i] = x;
                }
            }
        }

        public int read(float[][] buffer, int offset, int len)
                throws IOException {

            if (eof)
                return -1;

            if (noteOff_flag)
                if ((loopmode & 2) != 0)
                    if (loopdirection)
                        loopmode = 0;


            float pitchstep = (target_pitch - current_pitch[0]) / len;
            float[] current_pitch = this.current_pitch;
            started = true;

            int[] ox = this.ox;
            ox[0] = offset;
            int ox_end = len + offset;

            float ixend = sector_size + pad;
            if (!loopdirection)
                ixend = pad;
            while (ox[0] != ox_end) {
                nextBuffer();
                if (!loopdirection) {
                    // If we are in backward playing part of pingpong
                    // or reverse loop

                    if (streampos < (loopstart + pad)) {
                        ixend = loopstart - streampos + pad2;
                        if (ix[0] <= ixend) {
                            if ((loopmode & 4) != 0) {
                                // Ping pong loop, change loopdirection
                                loopdirection = true;
                                ixend = sector_size + pad;
                                continue;
                            }

                            ix[0] += looplen;
                            ixend = pad;
                            continue;
                        }
                    }

                    if (ibuffer_order != loopdirection)
                        reverseBuffers();

                    ix[0] = (sector_size + pad2) - ix[0];
                    ixend = (sector_size + pad2) - ixend;
                    ixend++;

                    float bak_ix = ix[0];
                    int bak_ox = ox[0];
                    float bak_pitch = current_pitch[0];
                    for (int i = 0; i < nrofchannels; i++) {
                        if (buffer[i] != null) {
                            ix[0] = bak_ix;
                            ox[0] = bak_ox;
                            current_pitch[0] = bak_pitch;
                            interpolate(ibuffer[i], ix, ixend, current_pitch,
                                    pitchstep, buffer[i], ox, ox_end);
                        }
                    }

                    ix[0] = (sector_size + pad2) - ix[0];
                    ixend--;
                    ixend = (sector_size + pad2) - ixend;

                    if (eof) {
                        current_pitch[0] = this.target_pitch;
                        return ox[0] - offset;
                    }

                    continue;
                }
                if (loopmode != 0) {
                    if (streampos + sector_size > (looplen + loopstart + pad)) {
                        ixend = loopstart + looplen - streampos + pad2;
                        if (ix[0] >= ixend) {
                            if ((loopmode & 4) != 0 || (loopmode & 8) != 0) {
                                // Ping pong or revese loop, change loopdirection
                                loopdirection = false;
                                ixend = pad;
                                continue;
                            }
                            ixend = sector_size + pad;
                            ix[0] -= looplen;
                            continue;
                        }
                    }
                }

                if (ibuffer_order != loopdirection)
                    reverseBuffers();

                float bak_ix = ix[0];
                int bak_ox = ox[0];
                float bak_pitch = current_pitch[0];
                for (int i = 0; i < nrofchannels; i++) {
                    if (buffer[i] != null) {
                        ix[0] = bak_ix;
                        ox[0] = bak_ox;
                        current_pitch[0] = bak_pitch;
                        interpolate(ibuffer[i], ix, ixend, current_pitch,
                                pitchstep, buffer[i], ox, ox_end);
                    }
                }

                if (eof) {
                    current_pitch[0] = this.target_pitch;
                    return ox[0] - offset;
                }
            }

            current_pitch[0] = this.target_pitch;
            return len;
        }

        public void close() throws IOException {
            stream.close();
        }
    }

    public abstract int getPadding();

    public abstract void interpolate(float[] in, float[] in_offset,
            float in_end, float[] pitch, float pitchstep, float[] out,
            int[] out_offset, int out_end);

    public final SoftResamplerStreamer openStreamer() {
        return new ModelAbstractResamplerStream();
    }
}
