/*
 *   Copyright (c) 2006,2007 Daniel Mack
 *
 *   This program 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 of the License, or
 *   (at your option) any later version.
 *
 *   This program 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 this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
*/

#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/interrupt.h>
#include <linux/usb.h>
#include <linux/input.h>
#include <linux/spinlock.h>
#include <sound/core.h>
#include <sound/rawmidi.h>
#include <sound/pcm.h>

#include "caiaq-device.h"
#include "caiaq-midi.h"


static int snd_usb_caiaq_midi_input_open(struct snd_rawmidi_substream *substream)
{
	return 0;
}

static int snd_usb_caiaq_midi_input_close(struct snd_rawmidi_substream *substream)
{
	return 0;
}

static void snd_usb_caiaq_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
{
	struct snd_usb_caiaqdev *dev = substream->rmidi->private_data;

	if (!dev)
		return;
	
	dev->midi_receive_substream = up ? substream : NULL;
}


static int snd_usb_caiaq_midi_output_open(struct snd_rawmidi_substream *substream)
{
	return 0;
}

static int snd_usb_caiaq_midi_output_close(struct snd_rawmidi_substream *substream)
{
	struct snd_usb_caiaqdev *dev = substream->rmidi->private_data;
	if (dev->midi_out_active) {
		usb_kill_urb(&dev->midi_out_urb);
		dev->midi_out_active = 0;
	}
	return 0;
}

static void snd_usb_caiaq_midi_send(struct snd_usb_caiaqdev *dev,
				    struct snd_rawmidi_substream *substream)
{
	int len, ret;
	
	dev->midi_out_buf[0] = EP1_CMD_MIDI_WRITE;
	dev->midi_out_buf[1] = 0; /* port */
	len = snd_rawmidi_transmit(substream, dev->midi_out_buf + 3,
				   EP1_BUFSIZE - 3);
	
	if (len <= 0)
		return;
	
	dev->midi_out_buf[2] = len;
	dev->midi_out_urb.transfer_buffer_length = len+3;
	
	ret = usb_submit_urb(&dev->midi_out_urb, GFP_ATOMIC);
	if (ret < 0)
		log("snd_usb_caiaq_midi_send(%p): usb_submit_urb() failed,"
		    "ret=%d, len=%d\n",
		    substream, ret, len);
	else
		dev->midi_out_active = 1;
}

static void snd_usb_caiaq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
{
	struct snd_usb_caiaqdev *dev = substream->rmidi->private_data;
	
	if (up) {
		dev->midi_out_substream = substream;
		if (!dev->midi_out_active)
			snd_usb_caiaq_midi_send(dev, substream);
	} else {
		dev->midi_out_substream = NULL;
	}
}


static struct snd_rawmidi_ops snd_usb_caiaq_midi_output =
{
	.open =		snd_usb_caiaq_midi_output_open,
	.close =	snd_usb_caiaq_midi_output_close,
	.trigger =      snd_usb_caiaq_midi_output_trigger,
};

static struct snd_rawmidi_ops snd_usb_caiaq_midi_input =
{
	.open =		snd_usb_caiaq_midi_input_open,
	.close =	snd_usb_caiaq_midi_input_close,
	.trigger =      snd_usb_caiaq_midi_input_trigger,
};

void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, 
				     int port, const char *buf, int len)
{
	if (!dev->midi_receive_substream)
		return;
	
	snd_rawmidi_receive(dev->midi_receive_substream, buf, len);
}

int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *device)
{
	int ret;
	struct snd_rawmidi *rmidi;

	ret = snd_rawmidi_new(device->chip.card, device->product_name, 0,
					device->spec.num_midi_out,
					device->spec.num_midi_in,
					&rmidi);

	if (ret < 0)
		return ret;

	strcpy(rmidi->name, device->product_name);

	rmidi->info_flags = SNDRV_RAWMIDI_INFO_DUPLEX;
	rmidi->private_data = device;

	if (device->spec.num_midi_out > 0) {
		rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
		snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, 
				    &snd_usb_caiaq_midi_output);
	}

	if (device->spec.num_midi_in > 0) {
		rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
		snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, 
				    &snd_usb_caiaq_midi_input);
	}
	
	device->rmidi = rmidi;

	return 0;
}

void snd_usb_caiaq_midi_output_done(struct urb* urb)
{
	struct snd_usb_caiaqdev *dev = urb->context;
	
	dev->midi_out_active = 0;
	if (urb->status != 0)
		return;

	if (!dev->midi_out_substream)
		return;

	snd_usb_caiaq_midi_send(dev, dev->midi_out_substream);
}

