/*
 * Copyright 2002-2007 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package com.sun.media.sound;

import java.util.Vector;

import javax.sound.sampled.Control;
import javax.sound.sampled.Line;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.Port;
import javax.sound.sampled.BooleanControl;
import javax.sound.sampled.CompoundControl;
import javax.sound.sampled.FloatControl;


/**
 * A Mixer which only provides Ports.
 *
 * @author Florian Bomers
 */
class PortMixer extends AbstractMixer {

    // CONSTANTS
    private static final int SRC_UNKNOWN      = 0x01;
    private static final int SRC_MICROPHONE   = 0x02;
    private static final int SRC_LINE_IN      = 0x03;
    private static final int SRC_COMPACT_DISC = 0x04;
    private static final int SRC_MASK         = 0xFF;

    private static final int DST_UNKNOWN      = 0x0100;
    private static final int DST_SPEAKER      = 0x0200;
    private static final int DST_HEADPHONE    = 0x0300;
    private static final int DST_LINE_OUT     = 0x0400;
    private static final int DST_MASK         = 0xFF00;

    // INSTANCE VARIABLES
    private Port.Info[] portInfos;
    // cache of instantiated ports
    private PortMixerPort[] ports;

    // instance ID of the native implementation
    private long id = 0;

    // CONSTRUCTOR
    PortMixer(PortMixerProvider.PortMixerInfo portMixerInfo) {
        // pass in Line.Info, mixer, controls
        super(portMixerInfo,              // Mixer.Info
              null,                       // Control[]
              null,                       // Line.Info[] sourceLineInfo
              null);                      // Line.Info[] targetLineInfo

        if (Printer.trace) Printer.trace(">> PortMixer: constructor");

        int count = 0;
        int srcLineCount = 0;
        int dstLineCount = 0;

        try {
            try {
                id = nOpen(getMixerIndex());
                if (id != 0) {
                    count = nGetPortCount(id);
                    if (count < 0) {
                        if (Printer.trace) Printer.trace("nGetPortCount() returned error code: " + count);
                        count = 0;
                    }
                }
            } catch (Exception e) {}

            portInfos = new Port.Info[count];

            for (int i = 0; i < count; i++) {
                int type = nGetPortType(id, i);
                srcLineCount += ((type & SRC_MASK) != 0)?1:0;
                dstLineCount += ((type & DST_MASK) != 0)?1:0;
                portInfos[i] = getPortInfo(i, type);
            }
        } finally {
            if (id != 0) {
                nClose(id);
            }
            id = 0;
        }

        // fill sourceLineInfo and targetLineInfos with copies of the ones in portInfos
        sourceLineInfo = new Port.Info[srcLineCount];
        targetLineInfo = new Port.Info[dstLineCount];

        srcLineCount = 0; dstLineCount = 0;
        for (int i = 0; i < count; i++) {
            if (portInfos[i].isSource()) {
                sourceLineInfo[srcLineCount++] = portInfos[i];
            } else {
                targetLineInfo[dstLineCount++] = portInfos[i];
            }
        }

        if (Printer.trace) Printer.trace("<< PortMixer: constructor completed");
    }


    // ABSTRACT MIXER: ABSTRACT METHOD IMPLEMENTATIONS

    public Line getLine(Line.Info info) throws LineUnavailableException {
        Line.Info fullInfo = getLineInfo(info);

        if ((fullInfo != null) && (fullInfo instanceof Port.Info)) {
            for (int i = 0; i < portInfos.length; i++) {
                if (fullInfo.equals(portInfos[i])) {
                    return getPort(i);
                }
            }
        }
        throw new IllegalArgumentException("Line unsupported: " + info);
    }


    public int getMaxLines(Line.Info info) {
        Line.Info fullInfo = getLineInfo(info);

        // if it's not supported at all, return 0.
        if (fullInfo == null) {
            return 0;
        }

        if (fullInfo instanceof Port.Info) {
            //return AudioSystem.NOT_SPECIFIED; // if several instances of PortMixerPort
            return 1;
        }
        return 0;
    }


    protected void implOpen() throws LineUnavailableException {
        if (Printer.trace) Printer.trace(">> PortMixer: implOpen (id="+id+")");

        // open the mixer device
        id = nOpen(getMixerIndex());

        if (Printer.trace) Printer.trace("<< PortMixer: implOpen succeeded.");
    }

    protected void implClose() {
        if (Printer.trace) Printer.trace(">> PortMixer: implClose");

        // close the mixer device
        long thisID = id;
        id = 0;
        nClose(thisID);
        if (ports != null) {
            for (int i = 0; i < ports.length; i++) {
                if (ports[i] != null) {
                    ports[i].disposeControls();
                }
            }
        }

        if (Printer.trace) Printer.trace("<< PortMixer: implClose succeeded");
    }

    protected void implStart() {}
    protected void implStop() {}

    // IMPLEMENTATION HELPERS

    private Port.Info getPortInfo(int portIndex, int type) {
        switch (type) {
        case SRC_UNKNOWN:      return new PortInfo(nGetPortName(getID(), portIndex), true);
        case SRC_MICROPHONE:   return Port.Info.MICROPHONE;
        case SRC_LINE_IN:      return Port.Info.LINE_IN;
        case SRC_COMPACT_DISC: return Port.Info.COMPACT_DISC;

        case DST_UNKNOWN:      return new PortInfo(nGetPortName(getID(), portIndex), false);
        case DST_SPEAKER:      return Port.Info.SPEAKER;
        case DST_HEADPHONE:    return Port.Info.HEADPHONE;
        case DST_LINE_OUT:     return Port.Info.LINE_OUT;
        }
        // should never happen...
        if (Printer.debug) Printer.debug("unknown port type: "+type);
        return null;
    }

    int getMixerIndex() {
        return ((PortMixerProvider.PortMixerInfo) getMixerInfo()).getIndex();
    }

    Port getPort(int index) {
        if (ports == null) {
            ports = new PortMixerPort[portInfos.length];
        }
        if (ports[index] == null) {
            ports[index] = new PortMixerPort((Port.Info)portInfos[index], this, index);
            return ports[index];
        }
        // $$fb TODO: return (Port) (ports[index].clone());
        return ports[index];
    }

    long getID() {
        return id;
    }

    // INNER CLASSES

    /**
     * Private inner class representing a Port for the PortMixer.
     */
    private static class PortMixerPort extends AbstractLine implements Port {
        private int portIndex;
        private long id;

        // CONSTRUCTOR
        private PortMixerPort(Port.Info info,
                              PortMixer mixer,
                              int portIndex) {
            super(info, mixer, null);
            if (Printer.trace) Printer.trace("PortMixerPort CONSTRUCTOR: info: " + info);
            this.portIndex = portIndex;
        }


        // ABSTRACT METHOD IMPLEMENTATIONS

        // ABSTRACT LINE

        void implOpen() throws LineUnavailableException {
            if (Printer.trace) Printer.trace(">> PortMixerPort: implOpen().");
            long newID = ((PortMixer) mixer).getID();
            if ((id == 0) || (newID != id) || (controls.length == 0)) {
                id = newID;
                Vector vector = new Vector();
                synchronized (vector) {
                    nGetControls(id, portIndex, vector);
                    controls = new Control[vector.size()];
                    for (int i = 0; i < controls.length; i++) {
                        controls[i] = (Control) vector.elementAt(i);
                    }
                }
            } else {
                enableControls(controls, true);
            }
            if (Printer.trace) Printer.trace("<< PortMixerPort: implOpen() succeeded");
        }

        private void enableControls(Control[] controls, boolean enable) {
            for (int i = 0; i < controls.length; i++) {
                if (controls[i] instanceof BoolCtrl) {
                    ((BoolCtrl) controls[i]).closed = !enable;
                }
                else if (controls[i] instanceof FloatCtrl) {
                    ((FloatCtrl) controls[i]).closed = !enable;
                }
                else if (controls[i] instanceof CompoundControl) {
                    enableControls(((CompoundControl) controls[i]).getMemberControls(), enable);
                }
            }
        }

        private void disposeControls() {
            enableControls(controls, false);
            controls = new Control[0];
        }


        void implClose() {
            if (Printer.trace) Printer.trace(">> PortMixerPort: implClose()");
            // get rid of controls
            enableControls(controls, false);
            if (Printer.trace) Printer.trace("<< PortMixerPort: implClose() succeeded");
        }

        // METHOD OVERRIDES

        // this is very similar to open(AudioFormat, int) in AbstractDataLine...
        public void open() throws LineUnavailableException {
            synchronized (mixer) {
                // if the line is not currently open, try to open it with this format and buffer size
                if (!isOpen()) {
                    if (Printer.trace) Printer.trace("> PortMixerPort: open");
                    // reserve mixer resources for this line
                    mixer.open(this);
                    try {
                        // open the line.  may throw LineUnavailableException.
                        implOpen();

                        // if we succeeded, set the open state to true and send events
                        setOpen(true);
                    } catch (LineUnavailableException e) {
                        // release mixer resources for this line and then throw the exception
                        mixer.close(this);
                        throw e;
                    }
                    if (Printer.trace) Printer.trace("< PortMixerPort: open succeeded");
                }
            }
        }

        // this is very similar to close() in AbstractDataLine...
        public void close() {
            synchronized (mixer) {
                if (isOpen()) {
                    if (Printer.trace) Printer.trace("> PortMixerPort.close()");

                    // set the open state to false and send events
                    setOpen(false);

                    // close resources for this line
                    implClose();

                    // release mixer resources for this line
                    mixer.close(this);
                    if (Printer.trace) Printer.trace("< PortMixerPort.close() succeeded");
                }
            }
        }

    } // class PortMixerPort

    /**
     * Private inner class representing a BooleanControl for PortMixerPort
     */
    private static class BoolCtrl extends BooleanControl {
        // the handle to the native control function
        private long controlID;
        private boolean closed = false;

        private static BooleanControl.Type createType(String name) {
            if (name.equals("Mute")) {
                return BooleanControl.Type.MUTE;
            }
            else if (name.equals("Select")) {
                // $$fb add as new static type?
                //return BooleanControl.Type.SELECT;
            }
            return new BCT(name);
        }


        private BoolCtrl(long controlID, String name) {
            this(controlID, createType(name));
        }

        private BoolCtrl(long controlID, BooleanControl.Type typ) {
            super(typ, false);
            this.controlID = controlID;
        }

        public void setValue(boolean value) {
            if (!closed) {
                nControlSetIntValue(controlID, value?1:0);
            }
        }

        public boolean getValue() {
            if (!closed) {
                // never use any cached values
                return (nControlGetIntValue(controlID)!=0)?true:false;
            }
            // ??
            return false;
        }

        /**
         * inner class for custom types
         */
        private static class BCT extends BooleanControl.Type {
            private BCT(String name) {
                super(name);
            }
        }
    }

    /**
     * Private inner class representing a CompoundControl for PortMixerPort
     */
    private static class CompCtrl extends CompoundControl {
        private CompCtrl(String name, Control[] controls) {
            super(new CCT(name), controls);
        }

        /**
         * inner class for custom compound control types
         */
        private static class CCT extends CompoundControl.Type {
            private CCT(String name) {
                super(name);
            }
        }
    }

    /**
     * Private inner class representing a BooleanControl for PortMixerPort
     */
    private static class FloatCtrl extends FloatControl {
        // the handle to the native control function
        private long controlID;
        private boolean closed = false;

        // predefined float control types. See also Ports.h
        private final static FloatControl.Type[] FLOAT_CONTROL_TYPES = {
            null,
            FloatControl.Type.BALANCE,
            FloatControl.Type.MASTER_GAIN,
            FloatControl.Type.PAN,
            FloatControl.Type.VOLUME
        };

        private FloatCtrl(long controlID, String name,
                          float min, float max, float precision, String units) {
            this(controlID, new FCT(name), min, max, precision, units);
        }

        private FloatCtrl(long controlID, int type,
                          float min, float max, float precision, String units) {
            this(controlID, FLOAT_CONTROL_TYPES[type], min, max, precision, units);
        }

        private FloatCtrl(long controlID, FloatControl.Type typ,
                         float min, float max, float precision, String units) {
            super(typ, min, max, precision, 1000, min, units);
            this.controlID = controlID;
        }

        public void setValue(float value) {
            if (!closed) {
                nControlSetFloatValue(controlID, value);
            }
        }

        public float getValue() {
            if (!closed) {
                // never use any cached values
                return nControlGetFloatValue(controlID);
            }
            // ??
            return getMinimum();
        }

        /**
         * inner class for custom types
         */
        private static class FCT extends FloatControl.Type {
            private FCT(String name) {
                super(name);
            }
        }
    }

    /**
     * Private inner class representing a port info
     */
    private static class PortInfo extends Port.Info {
        private PortInfo(String name, boolean isSource) {
            super(Port.class, name, isSource);
        }
    }

    // open the mixer with the given index. Returns a handle ID
    private static native long nOpen(int mixerIndex) throws LineUnavailableException;
    private static native void nClose(long id);

    // gets the number of ports for this mixer
    private static native int nGetPortCount(long id);

    // gets the type of the port with this index
    private static native int nGetPortType(long id, int portIndex);

    // gets the name of the port with this index
    private static native String nGetPortName(long id, int portIndex);

    // fills the vector with the controls for this port
    private static native void nGetControls(long id, int portIndex, Vector vector);

    // getters/setters for controls
    private static native void nControlSetIntValue(long controlID, int value);
    private static native int nControlGetIntValue(long controlID);
    private static native void nControlSetFloatValue(long controlID, float value);
    private static native float nControlGetFloatValue(long controlID);

}
