/*
 * Very simple multibyte buffer editor. Allows to maintaine the current
 * position in the string, add and remove chars on the current position.
 *
 * This file may be distributed under the terms of the
 * GNU Lesser General Public License.
 *
 * Copyright (C) 2017 Karel Zak <kzak@redhat.com>
 */
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>

#include "mbsalign.h"
#include "mbsedit.h"

struct mbs_editor *mbs_new_edit(char *buf, size_t bufsz, size_t ncells)
{
	struct mbs_editor *edit = calloc(1, sizeof(*edit));

	if (edit) {
		edit->buf = buf;
		edit->max_bytes = bufsz;
		edit->max_cells = ncells;
		edit->cur_cells = mbs_safe_width(buf);
		edit->cur_bytes = strlen(buf);
	}
	return edit;
}

char *mbs_free_edit(struct mbs_editor *edit)
{
	char *ret = edit ? edit->buf : NULL;

	free(edit);
	return ret;
}

static size_t mbs_next(const char *str, size_t *ncells)
{
#ifdef HAVE_WIDECHAR
	wchar_t wc;
	size_t n = 0;

	if (!str || !*str)
		return 0;

	n = mbrtowc(&wc, str, MB_CUR_MAX, NULL);
	*ncells = wcwidth(wc);
	return n;
#else
	if (!str || !*str)
		return 0;
	*ncells = 1;
	return 1;
#endif
}

static size_t mbs_prev(const char *start, const char *end, size_t *ncells)
{
#ifdef HAVE_WIDECHAR
	wchar_t wc = 0;
	const char *p, *prev;
	size_t n = 0;

	if (!start || !end || start == end || !*start)
		return 0;

	prev = p = start;
	while (p < end) {
		n = mbrtowc(&wc, p, MB_CUR_MAX, NULL);
		prev = p;

		if (n == (size_t) -1 || n == (size_t) -2)
			p++;
		else
			p += n;
	}

	if (prev == end)
		return 0;
	*ncells = wcwidth(wc);
	return n;
#else
	if (!start || !end || start == end || !*start)
		return 0;
	*ncells = 1;
	return 1;
#endif
}

int mbs_edit_goto(struct mbs_editor *edit, int where)
{
	switch (where) {
	case MBS_EDIT_LEFT:
		if (edit->cursor == 0)
			return 1;
		else {
			size_t n, cells;
			n = mbs_prev(edit->buf, edit->buf + edit->cursor, &cells);
			if (n) {
				edit->cursor -= n;
				edit->cursor_cells -= cells;
			}
		}
		break;
	case MBS_EDIT_RIGHT:
		if (edit->cursor_cells >= edit->cur_cells)
			return 1;
		else {
			size_t n, cells;
			n = mbs_next(edit->buf + edit->cursor, &cells);
			if (n) {
				edit->cursor += n;
				edit->cursor_cells += cells;
			}
		}
		break;
	case MBS_EDIT_HOME:
		edit->cursor = 0;
		edit->cursor_cells = 0;
		break;
	case MBS_EDIT_END:
		edit->cursor = edit->cur_bytes;
		edit->cursor_cells = edit->cur_cells;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

/* Remove next MB from @str, returns number of removed bytes */
static size_t remove_next(char *str, size_t *ncells)
{
	/* all in bytes! */
	size_t bytes, move_bytes, n;

	n          = mbs_next(str, ncells);
	bytes      = strlen(str);
	move_bytes = bytes - n;

	memmove(str, str + n, move_bytes);
	str[bytes - n] = '\0';
	return n;
}

static size_t mbs_insert(char *str, wint_t c, size_t *ncells)
{
	/* all in bytes! */
	size_t n = 1, bytes;
	char *in;

#ifdef HAVE_WIDECHAR
	wchar_t wc = (wchar_t) c;
	char in_buf[MB_CUR_MAX];

	n = wctomb(in_buf, wc);
	if (n == (size_t) -1)
		return n;
	*ncells = wcwidth(wc);
	in = in_buf;
#else
	*ncells = 1;
	in = (char *) &c;
#endif
	bytes       = strlen(str);

	memmove(str + n, str, bytes);
	memcpy(str, in, n);
	str[bytes + n] = '\0';
	return n;
}

static int mbs_edit_remove(struct mbs_editor *edit)
{
	size_t n, ncells;

	if (edit->cur_cells == 0 || edit->cursor >= edit->cur_bytes)
		return 1;

	n = remove_next(edit->buf + edit->cursor, &ncells);
	if (n == (size_t)-1)
		return 1;

	edit->cur_bytes -= n;
	edit->cur_cells = mbs_safe_width(edit->buf);
	return 0;
}

int mbs_edit_delete(struct mbs_editor *edit)
{
	if (edit->cursor >= edit->cur_bytes
	    && mbs_edit_goto(edit, MBS_EDIT_LEFT) == 1)
		return 1;

	return mbs_edit_remove(edit);
}

int mbs_edit_backspace(struct mbs_editor *edit)
{
	if (mbs_edit_goto(edit, MBS_EDIT_LEFT) == 0)
		return mbs_edit_remove(edit);
	return 1;
}

int mbs_edit_insert(struct mbs_editor *edit, wint_t c)
{
	size_t n, ncells;

	if (edit->cur_bytes + MB_CUR_MAX > edit->max_bytes)
		return 1;

	n = mbs_insert(edit->buf + edit->cursor, c, &ncells);
	if (n == (size_t)-1)
		return 1;

	edit->cursor += n;
	edit->cursor_cells += ncells;
	edit->cur_bytes += n;
	edit->cur_cells = mbs_safe_width(edit->buf);
	return 0;
}
