/*
 * mixer_widget.c - mixer widget and keys handling
 * Copyright (c) 1998,1999 Tim Janik
 *                         Jaroslav Kysela <perex@perex.cz>
 * Copyright (c) 2009      Clemens Ladisch <clemens@ladisch.de>
 *
 * 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, see <http://www.gnu.org/licenses/>.
 */

#include "aconfig.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <alsa/asoundlib.h>
#include "gettext_curses.h"
#include "version.h"
#include "utils.h"
#include "die.h"
#include "mem.h"
#include "colors.h"
#include "widget.h"
#include "textbox.h"
#include "proc_files.h"
#include "card_select.h"
#include "volume_mapping.h"
#include "mixer_controls.h"
#include "mixer_display.h"
#include "mixer_widget.h"

snd_mixer_t *mixer;
char *mixer_device_name;
bool unplugged;

struct widget mixer_widget;

enum view_mode view_mode;

int focus_control_index;
snd_mixer_selem_id_t *current_selem_id;
unsigned int current_control_flags;

bool controls_changed;

enum channel_mask {
	LEFT = 1,
	RIGHT = 2,
};

static int elem_callback(snd_mixer_elem_t *elem, unsigned int mask)
{
	unsigned int i;

	if (mask & (SND_CTL_EVENT_MASK_REMOVE |
		    SND_CTL_EVENT_MASK_INFO |
		    SND_CTL_EVENT_MASK_VALUE))
		controls_changed = TRUE;

	if (mask & SND_CTL_EVENT_MASK_INFO)
		for (i = 0; i < controls_count; ++i)
			if (controls[i].elem == elem) {
				controls[i].flags &= ~IS_ACTIVE;
				if (snd_mixer_selem_is_active(controls[i].elem))
					controls[i].flags |= IS_ACTIVE;
			}

	return 0;
}

static int mixer_callback(snd_mixer_t *mixer, unsigned int mask, snd_mixer_elem_t *elem)
{
	if (mask & SND_CTL_EVENT_MASK_ADD) {
		snd_mixer_elem_set_callback(elem, elem_callback);
		controls_changed = TRUE;
	}
	return 0;
}

void create_mixer_object(struct snd_mixer_selem_regopt *selem_regopt)
{
	int err;

	err = snd_mixer_open(&mixer, 0);
	if (err < 0)
		fatal_alsa_error(_("cannot open mixer"), err);

	mixer_device_name = cstrdup(selem_regopt->device);
	err = snd_mixer_selem_register(mixer, selem_regopt, NULL);
	if (err < 0)
		fatal_alsa_error(_("cannot open mixer"), err);

	snd_mixer_set_callback(mixer, mixer_callback);

	err = snd_mixer_load(mixer);
	if (err < 0)
		fatal_alsa_error(_("cannot load mixer controls"), err);

	err = snd_mixer_selem_id_malloc(&current_selem_id);
	if (err < 0)
		fatal_error("out of memory");
}

static void set_view_mode(enum view_mode m)
{
	view_mode = m;
	create_controls();
}

static void close_hctl(void)
{
	free_controls();
	if (mixer_device_name) {
		snd_mixer_detach(mixer, mixer_device_name);
		free(mixer_device_name);
		mixer_device_name = NULL;
	}
}

static void check_unplugged(void)
{
	snd_hctl_t *hctl;
	snd_ctl_t *ctl;
	unsigned int state;
	int err;

	unplugged = FALSE;
	if (mixer_device_name) {
		err = snd_mixer_get_hctl(mixer, mixer_device_name, &hctl);
		if (err >= 0) {
			ctl = snd_hctl_ctl(hctl);
			/* just any random function that does an ioctl() */
			err = snd_ctl_get_power_state(ctl, &state);
			if (err == -ENODEV)
				unplugged = TRUE;
		}
	}
}

void close_mixer_device(void)
{
	check_unplugged();
	close_hctl();

	display_card_info();
	set_view_mode(view_mode);
}

bool select_card_by_name(const char *device_name)
{
	int err;
	bool opened;
	char *msg;

	close_hctl();
	unplugged = FALSE;

	opened = FALSE;
	if (device_name) {
		err = snd_mixer_attach(mixer, device_name);
		if (err >= 0)
			opened = TRUE;
		else {
			msg = casprintf(_("Cannot open mixer device '%s'."), device_name);
			show_alsa_error(msg, err);
			free(msg);
		}
	}
	if (opened) {
		mixer_device_name = cstrdup(device_name);

		err = snd_mixer_load(mixer);
		if (err < 0)
			fatal_alsa_error(_("cannot load mixer controls"), err);
	}

	display_card_info();
	set_view_mode(view_mode);
	return opened;
}

static void show_help(void)
{
	const char *help[] = {
		_("Esc     Exit"),
		_("F1 ? H  Help"),
		_("F2 /    System information"),
		_("F3      Show playback controls"),
		_("F4      Show capture controls"),
		_("F5      Show all controls"),
		_("Tab     Toggle view mode (F3/F4/F5)"),
		_("F6 S    Select sound card"),
		_("L       Redraw screen"),
		"",
		_("Left    Move to the previous control"),
		_("Right   Move to the next control"),
		"",
		_("Up/Down    Change volume"),
		_("+ -        Change volume"),
		_("Page Up/Dn Change volume in big steps"),
		_("End        Set volume to 0%"),
		_("0-9        Set volume to 0%-90%"),
		_("Q W E      Increase left/both/right volumes"),
		/* TRANSLATORS: or Y instead of Z */
		_("Z X C      Decrease left/both/right volumes"),
		_("B          Balance left and right volumes"),
		"",
		_("M          Toggle mute"),
		/* TRANSLATORS: or , . */
		_("< >        Toggle left/right mute"),
		"",
		_("Space      Toggle capture"),
		/* TRANSLATORS: or Insert Delete */
		_("; '        Toggle left/right capture"),
		"",
		_("Authors:"),
		_("  Tim Janik"),
		_("  Jaroslav Kysela <perex@perex.cz>"),
		_("  Clemens Ladisch <clemens@ladisch.de>"),
	};
	show_text(help, ARRAY_SIZE(help), _("Help"));
}

void refocus_control(void)
{
	if (focus_control_index < controls_count) {
		snd_mixer_selem_get_id(controls[focus_control_index].elem, current_selem_id);
		current_control_flags = controls[focus_control_index].flags;
	}

	display_controls();
}

static struct control *get_focus_control(unsigned int type)
{
	if (focus_control_index >= 0 &&
	    focus_control_index < controls_count &&
	    (controls[focus_control_index].flags & IS_ACTIVE) &&
	    (controls[focus_control_index].flags & type))
		return &controls[focus_control_index];
	else
		return NULL;
}

static void change_enum_to_percent(struct control *control, int value)
{
	unsigned int i;
	unsigned int index;
	unsigned int new_index;
	int items;
	int err;

	i = ffs(control->enum_channel_bits) - 1;
	err = snd_mixer_selem_get_enum_item(control->elem, i, &index);
	if (err < 0)
		return;
	new_index = index;
	if (value == 0) {
		new_index = 0;
	} else if (value == 100) {
		items = snd_mixer_selem_get_enum_items(control->elem);
		if (items < 1)
			return;
		new_index = items - 1;
	}
	if (new_index == index)
		return;
	for (i = 0; i <= SND_MIXER_SCHN_LAST; ++i)
		if (control->enum_channel_bits & (1 << i))
			snd_mixer_selem_set_enum_item(control->elem, i, new_index);
}

static void change_enum_relative(struct control *control, int delta)
{
	int items;
	unsigned int i;
	unsigned int index;
	int new_index;
	int err;

	items = snd_mixer_selem_get_enum_items(control->elem);
	if (items < 1)
		return;
	err = snd_mixer_selem_get_enum_item(control->elem, 0, &index);
	if (err < 0)
		return;
	new_index = (int)index + delta;
	if (new_index < 0)
		new_index = 0;
	else if (new_index >= items)
		new_index = items - 1;
	if (new_index == index)
		return;
	for (i = 0; i <= SND_MIXER_SCHN_LAST; ++i)
		if (control->enum_channel_bits & (1 << i))
			snd_mixer_selem_set_enum_item(control->elem, i, new_index);
}

static void change_volume_to_percent(struct control *control, int value, unsigned int channels)
{
	int (*set_func)(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t, double, int);

	if (!(control->flags & HAS_VOLUME_1))
		channels = LEFT;
	if (control->flags & TYPE_PVOLUME)
		set_func = set_normalized_playback_volume;
	else
		set_func = set_normalized_capture_volume;
	if (channels & LEFT)
		set_func(control->elem, control->volume_channels[0], value / 100.0, 0);
	if (channels & RIGHT)
		set_func(control->elem, control->volume_channels[1], value / 100.0, 0);
}

static double clamp_volume(double v)
{
	if (v < 0)
		return 0;
	if (v > 1)
		return 1;
	return v;
}

static void change_volume_relative(struct control *control, int delta, unsigned int channels)
{
	double (*get_func)(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t);
	int (*set_func)(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t, double, int);
	double left, right;
	int dir;

	if (!(control->flags & HAS_VOLUME_1))
		channels = LEFT;
	if (control->flags & TYPE_PVOLUME) {
		get_func = get_normalized_playback_volume;
		set_func = set_normalized_playback_volume;
	} else {
		get_func = get_normalized_capture_volume;
		set_func = set_normalized_capture_volume;
	}
	if (channels & LEFT)
		left = get_func(control->elem, control->volume_channels[0]);
	if (channels & RIGHT)
		right = get_func(control->elem, control->volume_channels[1]);
	dir = delta > 0 ? 1 : -1;
	if (channels & LEFT) {
		left = clamp_volume(left + delta / 100.0);
		set_func(control->elem, control->volume_channels[0], left, dir);
	}
	if (channels & RIGHT) {
		right = clamp_volume(right + delta / 100.0);
		set_func(control->elem, control->volume_channels[1], right, dir);
	}
}

static void change_control_to_percent(int value, unsigned int channels)
{
	struct control *control;

	control = get_focus_control(TYPE_PVOLUME | TYPE_CVOLUME | TYPE_ENUM);
	if (!control)
		return;
	if (control->flags & TYPE_ENUM)
		change_enum_to_percent(control, value);
	else
		change_volume_to_percent(control, value, channels);
	display_controls();
}

static void change_control_relative(int delta, unsigned int channels)
{
	struct control *control;

	control = get_focus_control(TYPE_PVOLUME | TYPE_CVOLUME | TYPE_ENUM);
	if (!control)
		return;
	if (control->flags & TYPE_ENUM)
		change_enum_relative(control, delta);
	else
		change_volume_relative(control, delta, channels);
	display_controls();
}

static void toggle_switches(unsigned int type, unsigned int channels)
{
	struct control *control;
	unsigned int switch_1_mask;
	int (*get_func)(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t, int *);
	int (*set_func)(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t, int);
	snd_mixer_selem_channel_id_t channel_ids[2];
	int left, right;
	int err;

	control = get_focus_control(type);
	if (!control)
		return;
	if (type == TYPE_PSWITCH) {
		switch_1_mask = HAS_PSWITCH_1;
		get_func = snd_mixer_selem_get_playback_switch;
		set_func = snd_mixer_selem_set_playback_switch;
		channel_ids[0] = control->pswitch_channels[0];
		channel_ids[1] = control->pswitch_channels[1];
	} else {
		switch_1_mask = HAS_CSWITCH_1;
		get_func = snd_mixer_selem_get_capture_switch;
		set_func = snd_mixer_selem_set_capture_switch;
		channel_ids[0] = control->cswitch_channels[0];
		channel_ids[1] = control->cswitch_channels[1];
	}
	if (!(control->flags & switch_1_mask))
		channels = LEFT;
	if (channels & LEFT) {
		err = get_func(control->elem, channel_ids[0], &left);
		if (err < 0)
			return;
	}
	if (channels & RIGHT) {
		err = get_func(control->elem, channel_ids[1], &right);
		if (err < 0)
			return;
	}
	if (channels & LEFT)
		set_func(control->elem, channel_ids[0], !left);
	if (channels & RIGHT)
		set_func(control->elem, channel_ids[1], !right);
	display_controls();
}

static void toggle_mute(unsigned int channels)
{
	toggle_switches(TYPE_PSWITCH, channels);
}

static void toggle_capture(unsigned int channels)
{
	toggle_switches(TYPE_CSWITCH, channels);
}

static void balance_volumes(void)
{
	struct control *control;
	double left, right;
	int err;

	control = get_focus_control(TYPE_PVOLUME | TYPE_CVOLUME);
	if (!control || !(control->flags & HAS_VOLUME_1))
		return;
	if (control->flags & TYPE_PVOLUME) {
		left = get_normalized_playback_volume(control->elem, control->volume_channels[0]);
		right = get_normalized_playback_volume(control->elem, control->volume_channels[1]);
	} else {
		left = get_normalized_capture_volume(control->elem, control->volume_channels[0]);
		right = get_normalized_capture_volume(control->elem, control->volume_channels[1]);
	}
	left = (left + right) / 2;
	if (control->flags & TYPE_PVOLUME) {
		set_normalized_playback_volume(control->elem, control->volume_channels[0], left, 0);
		set_normalized_playback_volume(control->elem, control->volume_channels[1], left, 0);
	} else {
		set_normalized_capture_volume(control->elem, control->volume_channels[0], left, 0);
		set_normalized_capture_volume(control->elem, control->volume_channels[1], left, 0);
	}
	display_controls();
}

static void on_handle_key(int key)
{
	switch (key) {
	case 27:
	case KEY_CANCEL:
	case KEY_F(10):
		mixer_widget.close();
		break;
	case KEY_F(1):
	case KEY_HELP:
	case 'H':
	case 'h':
	case '?':
		show_help();
		break;
	case KEY_F(2):
	case '/':
		create_proc_files_list();
		break;
	case KEY_F(3):
		set_view_mode(VIEW_MODE_PLAYBACK);
		break;
	case KEY_F(4):
		set_view_mode(VIEW_MODE_CAPTURE);
		break;
	case KEY_F(5):
		set_view_mode(VIEW_MODE_ALL);
		break;
	case '\t':
		set_view_mode((enum view_mode)((view_mode + 1) % VIEW_MODE_COUNT));
		break;
	case KEY_F(6):
	case 'S':
	case 's':
		create_card_select_list();
		break;
	case KEY_REFRESH:
	case 12:
	case 'L':
	case 'l':
		clearok(mixer_widget.window, TRUE);
		display_controls();
		break;
	case KEY_LEFT:
	case 'P':
	case 'p':
		if (focus_control_index > 0) {
			--focus_control_index;
			refocus_control();
		}
		break;
	case KEY_RIGHT:
	case 'N':
	case 'n':
		if (focus_control_index < controls_count - 1) {
			++focus_control_index;
			refocus_control();
		}
		break;
	case KEY_PPAGE:
		change_control_relative(5, LEFT | RIGHT);
		break;
	case KEY_NPAGE:
		change_control_relative(-5, LEFT | RIGHT);
		break;
#if 0
	case KEY_BEG:
	case KEY_HOME:
		change_control_to_percent(100, LEFT | RIGHT);
		break;
#endif
	case KEY_LL:
	case KEY_END:
		change_control_to_percent(0, LEFT | RIGHT);
		break;
	case KEY_UP:
	case '+':
	case 'K':
	case 'k':
	case 'W':
	case 'w':
		change_control_relative(1, LEFT | RIGHT);
		break;
	case KEY_DOWN:
	case '-':
	case 'J':
	case 'j':
	case 'X':
	case 'x':
		change_control_relative(-1, LEFT | RIGHT);
		break;
	case '0': case '1': case '2': case '3': case '4':
	case '5': case '6': case '7': case '8': case '9':
		change_control_to_percent((key - '0') * 10, LEFT | RIGHT);
		break;
	case 'Q':
	case 'q':
		change_control_relative(1, LEFT);
		break;
	case 'Y':
	case 'y':
	case 'Z':
	case 'z':
		change_control_relative(-1, LEFT);
		break;
	case 'E':
	case 'e':
		change_control_relative(1, RIGHT);
		break;
	case 'C':
	case 'c':
		change_control_relative(-1, RIGHT);
		break;
	case 'M':
	case 'm':
		toggle_mute(LEFT | RIGHT);
		break;
	case 'B':
	case 'b':
	case '=':
		balance_volumes();
		break;
	case '<':
	case ',':
		toggle_mute(LEFT);
		break;
	case '>':
	case '.':
		toggle_mute(RIGHT);
		break;
	case ' ':
		toggle_capture(LEFT | RIGHT);
		break;
	case KEY_IC:
	case ';':
		toggle_capture(LEFT);
		break;
	case KEY_DC:
	case '\'':
		toggle_capture(RIGHT);
		break;
	}
}

static void create(void)
{
	static const char title[] = " AlsaMixer v" SND_UTIL_VERSION_STR " ";

	widget_init(&mixer_widget, screen_lines, screen_cols, 0, 0,
		    attr_mixer_frame, WIDGET_BORDER);
	if (screen_cols >= (sizeof(title) - 1) + 2) {
		wattrset(mixer_widget.window, attr_mixer_active);
		mvwaddstr(mixer_widget.window, 0, (screen_cols - (sizeof(title) - 1)) / 2, title);
	}
	init_mixer_layout();
	display_card_info();
	set_view_mode(view_mode);
}

static void on_window_size_changed(void)
{
	create();
}

static void on_close(void)
{
	widget_free(&mixer_widget);
}

void mixer_shutdown(void)
{
	free_controls();
	if (mixer)
		snd_mixer_close(mixer);
	if (current_selem_id)
		snd_mixer_selem_id_free(current_selem_id);
}

struct widget mixer_widget = {
	.handle_key = on_handle_key,
	.window_size_changed = on_window_size_changed,
	.close = on_close,
};

void create_mixer_widget(void)
{
	create();
}
