/*
 *  Sequencer Interface - middle-level routines
 *
 *  Copyright (c) 1999 by Takashi Iwai <tiwai@suse.de>
 *
 *
 *   This library is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as
 *   published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public
 *   License along with this library; if not, write to the Free Software
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include "seq_local.h"
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/ioctl.h>

/**
 * \brief queue controls - start/stop/continue
 * \param seq sequencer handle
 * \param q queue id to control
 * \param type event type
 * \param value event value
 * \param ev event instance
 *
 * This function sets up general queue control event and sends it.
 * To send at scheduled time, set the schedule in \a ev.
 * If \a ev is NULL, the event is composed locally and sent immediately
 * to the specified queue.  In any cases, you need to call #snd_seq_drain_output()
 * appropriately to feed the event.
 *
 * \sa snd_seq_alloc_queue()
 */
int snd_seq_control_queue(snd_seq_t *seq, int q, int type, int value, snd_seq_event_t *ev)
{
	snd_seq_event_t tmpev;
	if (ev == NULL) {
		snd_seq_ev_clear(&tmpev);
		ev = &tmpev;
		snd_seq_ev_set_direct(ev);
	}
	snd_seq_ev_set_queue_control(ev, type, q, value);
	return snd_seq_event_output(seq, ev);
}


/**
 * \brief create a port - simple version
 * \param seq sequencer handle
 * \param name the name of the port
 * \param caps capability bits
 * \param type type bits
 * \return the created port number or negative error code
 *
 * Creates a port with the given capability and type bits.
 *
 * \sa snd_seq_create_port(), snd_seq_delete_simple_port()
 */
int snd_seq_create_simple_port(snd_seq_t *seq, const char *name,
			       unsigned int caps, unsigned int type)
{
	snd_seq_port_info_t pinfo;
	int result;

	memset(&pinfo, 0, sizeof(pinfo));
	if (name)
		strncpy(pinfo.name, name, sizeof(pinfo.name) - 1);
	pinfo.capability = caps;
	pinfo.type = type;
	pinfo.midi_channels = 16;
	pinfo.midi_voices = 64; /* XXX */
	pinfo.synth_voices = 0; /* XXX */

	result = snd_seq_create_port(seq, &pinfo);
	if (result < 0)
		return result;
	else
		return pinfo.addr.port;
}

/**
 * \brief delete the port
 * \param seq sequencer handle
 * \param port port id
 * \return 0 on success or negative error code
 *
 * \sa snd_seq_delete_port(), snd_seq_create_simple_port()
 */
int snd_seq_delete_simple_port(snd_seq_t *seq, int port)
{
	return snd_seq_delete_port(seq, port);
}

/**
 * \brief simple subscription (w/o exclusive & time conversion)
 * \param seq sequencer handle
 * \param myport the port id as receiver
 * \param src_client sender client id
 * \param src_port sender port id
 * \return 0 on success or negative error code
 *
 * Connect from the given sender client:port to the given destination port in the
 * current client.
 *
 * \sa snd_seq_subscribe_port(), snd_seq_disconnect_from()
 */
int snd_seq_connect_from(snd_seq_t *seq, int myport, int src_client, int src_port)
{
	snd_seq_port_subscribe_t subs;
	
	memset(&subs, 0, sizeof(subs));
	subs.sender.client = src_client;
	subs.sender.port = src_port;
	/*subs.dest.client = seq->client;*/
	subs.dest.client = snd_seq_client_id(seq);
	subs.dest.port = myport;

	return snd_seq_subscribe_port(seq, &subs);
}

/**
 * \brief simple subscription (w/o exclusive & time conversion)
 * \param seq sequencer handle
 * \param myport the port id as sender
 * \param dest_client destination client id
 * \param dest_port destination port id
 * \return 0 on success or negative error code
 *
 * Connect from the given receiver port in the current client
 * to the given destination client:port.
 *
 * \sa snd_seq_subscribe_port(), snd_seq_disconnect_to()
 */
int snd_seq_connect_to(snd_seq_t *seq, int myport, int dest_client, int dest_port)
{
	snd_seq_port_subscribe_t subs;
	
	memset(&subs, 0, sizeof(subs));
	/*subs.sender.client = seq->client;*/
	subs.sender.client = snd_seq_client_id(seq);
	subs.sender.port = myport;
	subs.dest.client = dest_client;
	subs.dest.port = dest_port;

	return snd_seq_subscribe_port(seq, &subs);
}

/**
 * \brief simple disconnection
 * \param seq sequencer handle
 * \param myport the port id as receiver
 * \param src_client sender client id
 * \param src_port sender port id
 * \return 0 on success or negative error code
 *
 * Remove connection from the given sender client:port
 * to the given destination port in the current client.
 *
 * \sa snd_seq_unsubscribe_port(), snd_seq_connect_from()
 */
int snd_seq_disconnect_from(snd_seq_t *seq, int myport, int src_client, int src_port)
{
	snd_seq_port_subscribe_t subs;
	
	memset(&subs, 0, sizeof(subs));
	subs.sender.client = src_client;
	subs.sender.port = src_port;
	/*subs.dest.client = seq->client;*/
	subs.dest.client = snd_seq_client_id(seq);
	subs.dest.port = myport;

	return snd_seq_unsubscribe_port(seq, &subs);
}

/**
 * \brief simple disconnection
 * \param seq sequencer handle
 * \param myport the port id as sender
 * \param dest_client destination client id
 * \param dest_port destination port id
 * \return 0 on success or negative error code
 *
 * Remove connection from the given sender client:port
 * to the given destination port in the current client.
 *
 * \sa snd_seq_unsubscribe_port(), snd_seq_connect_to()
 */
int snd_seq_disconnect_to(snd_seq_t *seq, int myport, int dest_client, int dest_port)
{
	snd_seq_port_subscribe_t subs;
	
	memset(&subs, 0, sizeof(subs));
	/*subs.sender.client = seq->client;*/
	subs.sender.client = snd_seq_client_id(seq);
	subs.sender.port = myport;
	subs.dest.client = dest_client;
	subs.dest.port = dest_port;

	return snd_seq_unsubscribe_port(seq, &subs);
}

/*
 * set client information
 */

/**
 * \brief set client name
 * \param seq sequencer handle
 * \param name name string
 * \return 0 on success or negative error code
 *
 * \sa snd_seq_set_client_info()
 */
int snd_seq_set_client_name(snd_seq_t *seq, const char *name)
{
	snd_seq_client_info_t info;
	int err;

	if ((err = snd_seq_get_client_info(seq, &info)) < 0)
		return err;
	strncpy(info.name, name, sizeof(info.name) - 1);
	return snd_seq_set_client_info(seq, &info);
}

/**
 * \brief add client event filter
 * \param seq sequencer handle
 * \param event_type event type to be added
 * \return 0 on success or negative error code
 *
 * \sa snd_seq_set_client_info()
 */
int snd_seq_set_client_event_filter(snd_seq_t *seq, int event_type)
{
	snd_seq_client_info_t info;
	int err;

	if ((err = snd_seq_get_client_info(seq, &info)) < 0)
		return err;
	snd_seq_client_info_event_filter_add(&info, event_type);
	return snd_seq_set_client_info(seq, &info);
}

/**
 * \brief set client MIDI protocol version
 * \param seq sequencer handle
 * \param midi_version MIDI protocol version to set
 * \return 0 on success or negative error code
 *
 * \sa snd_seq_set_client_info()
 */
int snd_seq_set_client_midi_version(snd_seq_t *seq, int midi_version)
{
	snd_seq_client_info_t info;
	int err;

	if ((err = snd_seq_get_client_info(seq, &info)) < 0)
		return err;
	snd_seq_client_info_set_midi_version(&info, midi_version);
	return snd_seq_set_client_info(seq, &info);
}

/**
 * \brief enable/disable client's automatic conversion of UMP/legacy events
 * \param seq sequencer handle
 * \param enable 0 or 1 to disable/enable the conversion
 * \return 0 on success or negative error code
 *
 * \sa snd_seq_set_client_info()
 */
int snd_seq_set_client_ump_conversion(snd_seq_t *seq, int enable)
{
	snd_seq_client_info_t info;
	int err;

	if ((err = snd_seq_get_client_info(seq, &info)) < 0)
		return err;
	snd_seq_client_info_set_ump_conversion(&info, enable);
	return snd_seq_set_client_info(seq, &info);
}

/**
 * \brief change the output pool size of the given client
 * \param seq sequencer handle
 * \param size output pool size
 * \return 0 on success or negative error code
 *
 * \sa snd_seq_set_client_pool()
 */
int snd_seq_set_client_pool_output(snd_seq_t *seq, size_t size)
{
	snd_seq_client_pool_t info;
	int err;

	if ((err = snd_seq_get_client_pool(seq, &info)) < 0)
		return err;
	info.output_pool = size;
	return snd_seq_set_client_pool(seq, &info);
}

/**
 * \brief change the output room size of the given client
 * \param seq sequencer handle
 * \param size output room size
 * \return 0 on success or negative error code
 *
 * \sa snd_seq_set_client_pool()
 */
int snd_seq_set_client_pool_output_room(snd_seq_t *seq, size_t size)
{
	snd_seq_client_pool_t info;
	int err;

	if ((err = snd_seq_get_client_pool(seq, &info)) < 0)
		return err;
	info.output_room = size;
	return snd_seq_set_client_pool(seq, &info);
}

/**
 * \brief change the input pool size of the given client
 * \param seq sequencer handle
 * \param size input pool size
 * \return 0 on success or negative error code
 *
 * \sa snd_seq_set_client_pool()
 */
int snd_seq_set_client_pool_input(snd_seq_t *seq, size_t size)
{
	snd_seq_client_pool_t info;
	int err;

	if ((err = snd_seq_get_client_pool(seq, &info)) < 0)
		return err;
	info.input_pool = size;
	return snd_seq_set_client_pool(seq, &info);
}

/**
 * \brief reset client output pool
 * \param seq sequencer handle
 * \return 0 on success or negative error code
 *
 * So far, this works identically like #snd_seq_drop_output().
 */
int snd_seq_reset_pool_output(snd_seq_t *seq)
{
	return snd_seq_drop_output(seq);
}

/**
 * \brief reset client input pool
 * \param seq sequencer handle
 * \return 0 on success or negative error code
 *
 * So far, this works identically like #snd_seq_drop_input().
 */
int snd_seq_reset_pool_input(snd_seq_t *seq)
{
	return snd_seq_drop_input(seq);
}

/**
 * \brief wait until all events are processed
 * \param seq sequencer handle
 * \return 0 on success or negative error code
 *
 * This function waits until all events of this client are processed.
 *
 * \sa snd_seq_drain_output()
 */
int snd_seq_sync_output_queue(snd_seq_t *seq)
{
	int err;
	snd_seq_client_pool_t info;
	int saved_room;
	struct pollfd pfd;

	assert(seq);
	/* reprogram the room size to full */
	if ((err = snd_seq_get_client_pool(seq, &info)) < 0)
		return err;
	saved_room = info.output_room;
	info.output_room = info.output_pool; /* wait until all gone */
	if ((err = snd_seq_set_client_pool(seq, &info)) < 0)
		return err;
	/* wait until all events are purged */
	pfd.fd = seq->poll_fd;
	pfd.events = POLLOUT;
	err = poll(&pfd, 1, -1);
	/* restore the room size */ 
	info.output_room = saved_room;
	snd_seq_set_client_pool(seq, &info);
	return err;
}

/**
 * \brief parse the given string and get the sequencer address
 * \param seq sequencer handle
 * \param addr the address pointer to be returned
 * \param arg the string to be parsed
 * \return 0 on success or negative error code
 *
 * This function parses the sequencer client and port numbers from the given string.
 * The client and port tokens are separated by either colon or period, e.g. 128:1.
 * When \a seq is not NULL, the function accepts also a client name not only
 * digit numbers.
 * Actually \a arg need to be only a prefix of the wanted client.
 * That is, if a client named "Foobar XXL Master 2012" with number 128 is available,
 * then parsing "Foobar" will return the address 128:0 if no other client is
 * an exact match.
 */
int snd_seq_parse_address(snd_seq_t *seq, snd_seq_addr_t *addr, const char *arg)
{
	char *p, *buf;
	const char *s;
	char c;
	long client, port = 0;
	int len;

	assert(addr && arg);

	c = *arg;
	if (c == '"' || c == '\'') {
		s = ++arg;
		while (*s && *s != c) s++;
		len = s - arg;
		if (*s)
			s++;
		if (*s) {
			if (*s != '.' && *s != ':')
				return -EINVAL;
			if ((port = atoi(s + 1)) < 0)
				return -EINVAL;
		}
	} else {
		if ((p = strpbrk(arg, ":.")) != NULL) {
			if ((port = atoi(p + 1)) < 0)
				return -EINVAL;
			len = (int)(p - arg); /* length of client name */
		} else {
			len = strlen(arg);
		}
	}
	if (len == 0)
		return -EINVAL;
	buf = alloca(len + 1);
	strncpy(buf, arg, len);
	buf[len] = '\0';
	addr->port = port;
	if (safe_strtol(buf, &client) == 0) {
		addr->client = client;
	} else {
		/* convert from the name */
		snd_seq_client_info_t cinfo;

		if (! seq)
			return -EINVAL;
		if (len <= 0)
			return -EINVAL;
		client = -1;
		cinfo.client = -1;
		while (snd_seq_query_next_client(seq, &cinfo) >= 0) {
			if (!strncmp(arg, cinfo.name, len)) {
				if (strlen(cinfo.name) == (size_t)len) {
					/* exact match */
					addr->client = cinfo.client;
					return 0;
				}
				if (client < 0)
					client = cinfo.client;
			}
		}
		if (client >= 0) {
			/* prefix match */
			addr->client = client;
			return 0;
		}
		return -ENOENT; /* not found */
	}
	return 0;
}

