/* DSSISynthesizer.java -- DSSI Synthesizer Provider
   Copyright (C) 2005 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.javax.sound.midi.dssi;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.sound.midi.Instrument;
import javax.sound.midi.MidiChannel;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Patch;
import javax.sound.midi.Receiver;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.Soundbank;
import javax.sound.midi.SoundbankResource;
import javax.sound.midi.Synthesizer;
import javax.sound.midi.Transmitter;
import javax.sound.midi.VoiceStatus;

// FIXME: This import in only required for gcj it seems.
import javax.sound.midi.MidiDevice.Info;

/**
 * DSSI soft-synth support.
 * 
 * All DSSI soft-synths are expected to be installed in /usr/lib/dssi.
 * 
 * @author Anthony Green (green@redhat.com)
 *
 */
public class DSSISynthesizer implements Synthesizer
{
  /**
   * The DSSI Instrument class.
   * 
   * @author Anthony Green (green@redhat.com)
   *
   */
  class DSSIInstrument extends Instrument
  {
    DSSIInstrument (Soundbank soundbank, Patch patch, String name)
    {
      super (soundbank, patch, name, null);
    }
    
    /* @see javax.sound.midi.SoundbankResource#getData()
     */
    public Object getData()
    {
      return null;
    }

  }

/**
   * DSSISoundbank holds all instruments.
   * 
   * @author Anthony Green (green@redhat.com)
   *
   */
  class DSSISoundbank implements Soundbank
  {
    private String name;
    private String description;
    private List instruments = new ArrayList();
    private List resources = new ArrayList();
    private String vendor;
    private String version;
    
    public DSSISoundbank(String name, String description, String vendor, String version)
    {
      this.name = name;
      this.description = description;
      this.vendor = vendor;
      this.version = version;
    }
    
    void add(Instrument instrument)
    {
      instruments.add(instrument);
    }
    
    /* @see javax.sound.midi.Soundbank#getName()
     */
    public String getName()
    {
      return name;
    }

    /* @see javax.sound.midi.Soundbank#getVersion()
     */
    public String getVersion()
    {
      return version;
    }

    /* @see javax.sound.midi.Soundbank#getVendor()
     */
    public String getVendor()
    {
      return vendor;
    }

    /* @see javax.sound.midi.Soundbank#getDescription()
     */
    public String getDescription()
    {
      return description;
    }

    /* @see javax.sound.midi.Soundbank#getResources()
     */
    public SoundbankResource[] getResources()
    {
      return (SoundbankResource[])
        resources.toArray(new SoundbankResource[resources.size()]);
    }

    /* @see javax.sound.midi.Soundbank#getInstruments()
     */
    public Instrument[] getInstruments()
    {
      return (Instrument[])
        instruments.toArray(new Instrument[instruments.size()]);
    }

    /* @see javax.sound.midi.Soundbank#getInstrument(javax.sound.midi.Patch)
     */
    public Instrument getInstrument(Patch patch)
    {
      Iterator itr = instruments.iterator();
      
      while (itr.hasNext())
      {
        Instrument i = (Instrument) itr.next();
        if (i.getPatch().equals(patch))
          return i;
      }
      
      return null;
    }
  }

/**
   * The Receiver class receives all MIDI messages from a connected
   * Transmitter.
   * 
   * @author Anthony Green (green@redhat.com)
   *
   */
  class DSSIReceiver implements Receiver
  {
    /* (non-Javadoc)
     * @see javax.sound.midi.Receiver#send(javax.sound.midi.MidiMessage, long)
     */
    public void send(MidiMessage message, long timeStamp)
        throws IllegalStateException
    {
      if (message instanceof ShortMessage)
      {
        ShortMessage smessage = (ShortMessage) message;
      
        switch (message.getStatus())
        {
        case ShortMessage.NOTE_ON:
          int velocity = smessage.getData2();
          if (velocity > 0)
            channels[smessage.getChannel()].noteOn(smessage.getData1(), 
                                                   smessage.getData2());
          else
            channels[smessage.getChannel()].noteOff(smessage.getData1());
          break;
        case ShortMessage.CONTROL_CHANGE:
          channels[smessage.getChannel()].controlChange(smessage.getData1(),
                                                        smessage.getData2());
          break;
        default:
          System.out.println ("Unhandled message: " + message.getStatus());
          break;
        }
      }
    }

    /* (non-Javadoc)
     * @see javax.sound.midi.Receiver#close()
     */
    public void close()
    {
      // TODO Auto-generated method stub
    }

  }

  static native void noteOn_(long handle, int channel, int noteNumber, int velocity);  
  static native void noteOff_(long handle, int channel, int noteNumber, int velocity);  
  static native void setPolyPressure_(long handle, int channel, int noteNumber, int pressure);
  static native int getPolyPressure_(long handle, int channel, int noteNumber);
  static native void controlChange_(long handle, int channel, int control, int value);
  static native void open_(long handle);
  static native void close_(long handle);
  static native String getProgramName_(long handle, int index);
  static native int getProgramBank_(long handle, int index);
  static native int getProgramProgram_(long handle, int index);
  static native void selectProgram_(long handle, int bank, int program);
      
  /**
   * @author Anthony Green (green@redhat.com)
   *
   */
  public class DSSIMidiChannel implements MidiChannel
  {
    int channel = 0;
    
    /**
     * Default contructor.
     */
    public DSSIMidiChannel(int channel)
    {
      super();
      this.channel = channel;
    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#noteOn(int, int)
     */
    public void noteOn(int noteNumber, int velocity)
    {
      noteOn_(sohandle, channel, noteNumber, velocity);
    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#noteOff(int, int)
     */
    public void noteOff(int noteNumber, int velocity)
    {
      noteOff_(sohandle, channel, noteNumber, velocity);
    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#noteOff(int)
     */
    public void noteOff(int noteNumber)
    {
      noteOff_(sohandle, channel, noteNumber, -1);
    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#setPolyPressure(int, int)
     */
    public void setPolyPressure(int noteNumber, int pressure)
    {
      setPolyPressure_(sohandle, channel, noteNumber, pressure);
    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#getPolyPressure(int)
     */
    public int getPolyPressure(int noteNumber)
    {
      return getPolyPressure_(sohandle, channel, noteNumber);
    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#setChannelPressure(int)
     */
    public void setChannelPressure(int pressure)
    {
      // TODO Auto-generated method stub

    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#getChannelPressure()
     */
    public int getChannelPressure()
    {
      // TODO Auto-generated method stub
      return 0;
    }

    /* @see javax.sound.midi.MidiChannel#controlChange(int, int)  */
    public void controlChange(int controller, int value)
    {
      controlChange_(sohandle, channel, controller, value);
    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#getController(int)
     */
    public int getController(int controller)
    {
      // TODO Auto-generated method stub
      return 0;
    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#programChange(int)
     */
    public void programChange(int program)
    {
      // TODO Auto-generated method stub

    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#programChange(int, int)
     */
    public void programChange(int bank, int program)
    {
      // TODO Auto-generated method stub

    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#getProgram()
     */
    public int getProgram()
    {
      // TODO Auto-generated method stub
      return 0;
    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#setPitchBend(int)
     */
    public void setPitchBend(int bend)
    {
      // TODO Auto-generated method stub

    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#getPitchBend()
     */
    public int getPitchBend()
    {
      // TODO Auto-generated method stub
      return 0;
    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#resetAllControllers()
     */
    public void resetAllControllers()
    {
      // TODO Auto-generated method stub

    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#allNotesOff()
     */
    public void allNotesOff()
    {
      // TODO Auto-generated method stub

    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#allSoundOff()
     */
    public void allSoundOff()
    {
      // TODO Auto-generated method stub

    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#localControl(boolean)
     */
    public boolean localControl(boolean on)
    {
      // TODO Auto-generated method stub
      return false;
    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#setMono(boolean)
     */
    public void setMono(boolean on)
    {
      // TODO Auto-generated method stub

    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#getMono()
     */
    public boolean getMono()
    {
      // TODO Auto-generated method stub
      return false;
    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#setOmni(boolean)
     */
    public void setOmni(boolean on)
    {
      // TODO Auto-generated method stub

    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#getOmni()
     */
    public boolean getOmni()
    {
      // TODO Auto-generated method stub
      return false;
    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#setMute(boolean)
     */
    public void setMute(boolean mute)
    {
      // TODO Auto-generated method stub

    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#getMute()
     */
    public boolean getMute()
    {
      // TODO Auto-generated method stub
      return false;
    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#setSolo(boolean)
     */
    public void setSolo(boolean solo)
    {
      // TODO Auto-generated method stub

    }

    /* (non-Javadoc)
     * @see javax.sound.midi.MidiChannel#getSolo()
     */
    public boolean getSolo()
    {
      // TODO Auto-generated method stub
      return false;
    }

  }

  long sohandle;
  long handle; 
  private Info info;
  
  MidiChannel channels[] = new MidiChannel[16];
  
  // The list of known soundbanks, and the default one.
  List soundbanks = new ArrayList();
  DSSISoundbank defaultSoundbank;
  
  /**
   * Create a DSSI Synthesizer.
   * 
   * @param info the DSSIInfo for this soft-synth
   * @param soname the name of the .so file for this DSSI synth
   * @param index the DSSI index for this soft-synth
   */
  public DSSISynthesizer(Info info, String soname, long index)
  {
    super();
    this.info = info;
    sohandle = DSSIMidiDeviceProvider.dlopen_(soname);
    handle = DSSIMidiDeviceProvider.getDSSIHandle_(sohandle, index);
    channels[0] = new DSSIMidiChannel(0);
    defaultSoundbank = new DSSISoundbank("name", "description", 
                                         "vendor", "version");
    soundbanks.add(defaultSoundbank);
    
    int i = 0;
    String name;
    do
    {
      name = getProgramName_(sohandle, i);
      if (name != null)
      {
        defaultSoundbank.
          add(new DSSIInstrument(defaultSoundbank, 
                                 new Patch(getProgramBank_(sohandle, i),
                                           getProgramProgram_(sohandle, i)),
                                 name));
        i++;
      }
    } while (name != null);
  }

  /* (non-Javadoc)
   * @see javax.sound.midi.Synthesizer#getMaxPolyphony()
   */
  public int getMaxPolyphony()
  {
    // TODO Auto-generated method stub
    return 0;
  }

  /* (non-Javadoc)
   * @see javax.sound.midi.Synthesizer#getLatency()
   */
  public long getLatency()
  {
    // DSSI and LADSPA provide no way to determine the latency.
    // Let's just return 0 for now.
    return 0;
  }

  /* (non-Javadoc)
   * @see javax.sound.midi.Synthesizer#getChannels()
   */
  public MidiChannel[] getChannels()
  {
    return channels;
  }

  /* (non-Javadoc)
   * @see javax.sound.midi.Synthesizer#getVoiceStatus()
   */
  public VoiceStatus[] getVoiceStatus()
  {
    // TODO Auto-generated method stub
    return null;
  }

  /* (non-Javadoc)
   * @see javax.sound.midi.Synthesizer#isSoundbankSupported(javax.sound.midi.Soundbank)
   */
  public boolean isSoundbankSupported(Soundbank soundbank)
  {
    // TODO Auto-generated method stub
    return false;
  }

  /* @see javax.sound.midi.Synthesizer#loadInstrument(javax.sound.midi.Instrument)
   */
  public boolean loadInstrument(Instrument instrument)
  {
    // FIXME: perhaps this isn't quite right.  It can probably
    // be in any soundbank.
    if (instrument.getSoundbank() != defaultSoundbank)
      throw new IllegalArgumentException ("Synthesizer doesn't support this instrument's soundbank");
      
    Patch patch = instrument.getPatch();
    selectProgram_(sohandle, patch.getBank(), patch.getProgram());
    return true;
  }

  /* (non-Javadoc)
   * @see javax.sound.midi.Synthesizer#unloadInstrument(javax.sound.midi.Instrument)
   */
  public void unloadInstrument(Instrument instrument)
  {
    // TODO Auto-generated method stub

  }

  /* (non-Javadoc)
   * @see javax.sound.midi.Synthesizer#remapInstrument(javax.sound.midi.Instrument, javax.sound.midi.Instrument)
   */
  public boolean remapInstrument(Instrument from, Instrument to)
  {
    // TODO Auto-generated method stub
    return false;
  }

  /* @see javax.sound.midi.Synthesizer#getDefaultSoundbank()
   */
  public Soundbank getDefaultSoundbank()
  {
    return defaultSoundbank;
  }

  /* @see javax.sound.midi.Synthesizer#getAvailableInstruments()
   */
  public Instrument[] getAvailableInstruments()
  {
    List instruments = new ArrayList();
    Iterator itr = soundbanks.iterator();
    while (itr.hasNext())
    {
      Soundbank sb = (Soundbank) itr.next();
      Instrument ins[] = sb.getInstruments();
      for (int i = 0; i < ins.length; i++)
        instruments.add(ins[i]);
    }
    return (Instrument[])
      instruments.toArray(new Instrument[instruments.size()]);
  }

  /* (non-Javadoc)
   * @see javax.sound.midi.Synthesizer#getLoadedInstruments()
   */
  public Instrument[] getLoadedInstruments()
  {
    // TODO Auto-generated method stub
    return null;
  }

  /* (non-Javadoc)
   * @see javax.sound.midi.Synthesizer#loadAllInstruments(javax.sound.midi.Soundbank)
   */
  public boolean loadAllInstruments(Soundbank soundbank)
  {
    // TODO Auto-generated method stub
    return false;
  }

  /* (non-Javadoc)
   * @see javax.sound.midi.Synthesizer#unloadAllInstruments(javax.sound.midi.Soundbank)
   */
  public void unloadAllInstruments(Soundbank soundbank)
  {
    // TODO Auto-generated method stub
  }

  /* (non-Javadoc)
   * @see javax.sound.midi.Synthesizer#loadInstruments(javax.sound.midi.Soundbank, javax.sound.midi.Patch[])
   */
  public boolean loadInstruments(Soundbank soundbank, Patch[] patchList)
  {
    // TODO Auto-generated method stub
    return false;
  }

  /* (non-Javadoc)
   * @see javax.sound.midi.Synthesizer#unloadInstruments(javax.sound.midi.Soundbank, javax.sound.midi.Patch[])
   */
  public void unloadInstruments(Soundbank soundbank, Patch[] patchList)
  {
    // TODO Auto-generated method stub

  }

  /* @see javax.sound.midi.MidiDevice#getDeviceInfo()
   */
  public Info getDeviceInfo()
  {
    return info;
  }

  /* @see javax.sound.midi.MidiDevice#open()
   */
  public void open() throws MidiUnavailableException
  {
    open_(sohandle);
  }

  /* @see javax.sound.midi.MidiDevice#close()
   */
  public void close()
  {
    close_(sohandle);
  }

  /* (non-Javadoc)
   * @see javax.sound.midi.MidiDevice#isOpen()
   */
  public boolean isOpen()
  {
    // TODO Auto-generated method stub
    return false;
  }

  /* (non-Javadoc)
   * @see javax.sound.midi.MidiDevice#getMicrosecondPosition()
   */
  public long getMicrosecondPosition()
  {
    // TODO Auto-generated method stub
    return 0;
  }

  /* @see javax.sound.midi.MidiDevice#getMaxReceivers()
   */
  public int getMaxReceivers()
  {
    return 1;
  }

  /* @see javax.sound.midi.MidiDevice#getMaxTransmitters()
   */
  public int getMaxTransmitters()
  {
    return 0;
  }

  /* @see javax.sound.midi.MidiDevice#getReceiver()
   */
  public Receiver getReceiver() throws MidiUnavailableException
  {
    return new DSSIReceiver();
  }

  /* @see javax.sound.midi.MidiDevice#getTransmitter()
   */
  public Transmitter getTransmitter() throws MidiUnavailableException
  {
    return null;
  }
}
