#include <linux/types.h>
#include <linux/ctype.h>	/* for isdigit() and friends */
#include <linux/fs.h>
#include <linux/mm.h>		/* for verify_area */
#include <linux/errno.h>	/* for -EBUSY */
#include <linux/ioport.h>	/* for check_region, request_region */
#include <linux/interrupt.h>
#include <linux/delay.h>	/* for loops_per_sec */
#include <linux/kmod.h>
#include <linux/jiffies.h>
#include <linux/uaccess.h> /* for copy_from_user */
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/kthread.h>

#include "spk_priv.h"
#include "speakup.h"
#include "serialio.h"

#define MAXSYNTHS       16      /* Max number of synths in array. */
static struct spk_synth *synths[MAXSYNTHS];
struct spk_synth *synth;
char pitch_buff[32] = "";
static int module_status;
bool quiet_boot;

struct speakup_info_t speakup_info = {
	.spinlock = __SPIN_LOCK_UNLOCKED(speakup_info.spinlock),
	.flushing = 0,
};
EXPORT_SYMBOL_GPL(speakup_info);

static int do_synth_init(struct spk_synth *in_synth);

int serial_synth_probe(struct spk_synth *synth)
{
	const struct old_serial_port *ser;
	int failed = 0;

	if ((synth->ser >= SPK_LO_TTY) && (synth->ser <= SPK_HI_TTY)) {
		ser = spk_serial_init(synth->ser);
		if (ser == NULL) {
			failed = -1;
		} else {
			outb_p(0, ser->port);
			mdelay(1);
			outb_p('\r', ser->port);
		}
	} else {
		failed = -1;
		pr_warn("ttyS%i is an invalid port\n", synth->ser);
	}
	if (failed) {
		pr_info("%s: not found\n", synth->long_name);
		return -ENODEV;
	}
	pr_info("%s: ttyS%i, Driver Version %s\n",
			synth->long_name, synth->ser, synth->version);
	synth->alive = 1;
	return 0;
}
EXPORT_SYMBOL_GPL(serial_synth_probe);

/* Main loop of the progression thread: keep eating from the buffer
 * and push to the serial port, waiting as needed
 *
 * For devices that have a "full" notification mechanism, the driver can
 * adapt the loop the way they prefer.
 */
void spk_do_catch_up(struct spk_synth *synth)
{
	u_char ch;
	unsigned long flags;
	unsigned long jiff_max;
	struct var_t *delay_time;
	struct var_t *full_time;
	struct var_t *jiffy_delta;
	int jiffy_delta_val;
	int delay_time_val;
	int full_time_val;

	jiffy_delta = get_var(JIFFY);
	full_time = get_var(FULL);
	delay_time = get_var(DELAY);

	spk_lock(flags);
	jiffy_delta_val = jiffy_delta->u.n.value;
	spk_unlock(flags);

	jiff_max = jiffies + jiffy_delta_val;
	while (!kthread_should_stop()) {
		spk_lock(flags);
		if (speakup_info.flushing) {
			speakup_info.flushing = 0;
			spk_unlock(flags);
			synth->flush(synth);
			continue;
		}
		if (synth_buffer_empty()) {
			spk_unlock(flags);
			break;
		}
		ch = synth_buffer_peek();
		set_current_state(TASK_INTERRUPTIBLE);
		full_time_val = full_time->u.n.value;
		spk_unlock(flags);
		if (ch == '\n')
			ch = synth->procspeech;
		if (!spk_serial_out(ch)) {
			schedule_timeout(msecs_to_jiffies(full_time_val));
			continue;
		}
		if ((jiffies >= jiff_max) && (ch == SPACE)) {
			spk_lock(flags);
			jiffy_delta_val = jiffy_delta->u.n.value;
			delay_time_val = delay_time->u.n.value;
			full_time_val = full_time->u.n.value;
			spk_unlock(flags);
			if (spk_serial_out(synth->procspeech))
				schedule_timeout(
					msecs_to_jiffies(delay_time_val));
			else
				schedule_timeout(
					msecs_to_jiffies(full_time_val));
			jiff_max = jiffies + jiffy_delta_val;
		}
		set_current_state(TASK_RUNNING);
		spk_lock(flags);
		synth_buffer_getc();
		spk_unlock(flags);
	}
	spk_serial_out(synth->procspeech);
}
EXPORT_SYMBOL_GPL(spk_do_catch_up);

const char *spk_synth_immediate(struct spk_synth *synth, const char *buff)
{
	u_char ch;
	while ((ch = *buff)) {
		if (ch == '\n')
			ch = synth->procspeech;
		if (wait_for_xmitr())
			outb(ch, speakup_info.port_tts);
		else
			return buff;
		buff++;
	}
	return 0;
}
EXPORT_SYMBOL_GPL(spk_synth_immediate);

void spk_synth_flush(struct spk_synth *synth)
{
	spk_serial_out(synth->clear);
}
EXPORT_SYMBOL_GPL(spk_synth_flush);

int spk_synth_is_alive_nop(struct spk_synth *synth)
{
	synth->alive = 1;
	return 1;
}
EXPORT_SYMBOL_GPL(spk_synth_is_alive_nop);

int spk_synth_is_alive_restart(struct spk_synth *synth)
{
	if (synth->alive)
		return 1;
	if (!synth->alive && wait_for_xmitr() > 0) {
		/* restart */
		synth->alive = 1;
		synth_printf("%s", synth->init);
		return 2; /* reenabled */
	}
	pr_warn("%s: can't restart synth\n", synth->long_name);
	return 0;
}
EXPORT_SYMBOL_GPL(spk_synth_is_alive_restart);

static void thread_wake_up(u_long data)
{
	wake_up_interruptible_all(&speakup_event);
}

static DEFINE_TIMER(thread_timer, thread_wake_up, 0, 0);

void synth_start(void)
{
	struct var_t *trigger_time;

	if (!synth->alive) {
		synth_buffer_clear();
		return;
	}
	trigger_time = get_var(TRIGGER);
	if (!timer_pending(&thread_timer))
		mod_timer(&thread_timer, jiffies +
			msecs_to_jiffies(trigger_time->u.n.value));
}

void do_flush(void)
{
	speakup_info.flushing = 1;
	synth_buffer_clear();
	if (synth->alive) {
		if (pitch_shift) {
			synth_printf("%s", pitch_buff);
			pitch_shift = 0;
		}
	}
	wake_up_interruptible_all(&speakup_event);
	wake_up_process(speakup_task);
}

void synth_write(const char *buf, size_t count)
{
	while (count--)
		synth_buffer_add(*buf++);
	synth_start();
}

void synth_printf(const char *fmt, ...)
{
	va_list args;
	unsigned char buf[160], *p;
	int r;

	va_start(args, fmt);
	r = vsnprintf(buf, sizeof(buf), fmt, args);
	va_end(args);
	if (r > sizeof(buf) - 1)
		r = sizeof(buf) - 1;

	p = buf;
	while (r--)
		synth_buffer_add(*p++);
	synth_start();
}
EXPORT_SYMBOL_GPL(synth_printf);

static int index_count;
static int sentence_count;

void reset_index_count(int sc)
{
	static int first = 1;
	if (first)
		first = 0;
	else
		synth->get_index();
	index_count = 0;
	sentence_count = sc;
}

int synth_supports_indexing(void)
{
	if (synth->get_index != NULL)
		return 1;
	return 0;
}

void synth_insert_next_index(int sent_num)
{
	int out;
	if (synth->alive) {
		if (sent_num == 0) {
			synth->indexing.currindex++;
			index_count++;
			if (synth->indexing.currindex >
					synth->indexing.highindex)
				synth->indexing.currindex =
					synth->indexing.lowindex;
		}

		out = synth->indexing.currindex * 10 + sent_num;
		synth_printf(synth->indexing.command, out, out);
	}
}

void get_index_count(int *linecount, int *sentcount)
{
	int ind = synth->get_index();
	if (ind) {
		sentence_count = ind % 10;

		if ((ind / 10) <= synth->indexing.currindex)
			index_count = synth->indexing.currindex-(ind/10);
		else
			index_count = synth->indexing.currindex
				-synth->indexing.lowindex
				+ synth->indexing.highindex-(ind/10)+1;

	}
	*sentcount = sentence_count;
	*linecount = index_count;
}

static struct resource synth_res;

int synth_request_region(unsigned long start, unsigned long n)
{
	struct resource *parent = &ioport_resource;
	memset(&synth_res, 0, sizeof(synth_res));
	synth_res.name = synth->name;
	synth_res.start = start;
	synth_res.end = start + n - 1;
	synth_res.flags = IORESOURCE_BUSY;
	return request_resource(parent, &synth_res);
}
EXPORT_SYMBOL_GPL(synth_request_region);

int synth_release_region(unsigned long start, unsigned long n)
{
	return release_resource(&synth_res);
}
EXPORT_SYMBOL_GPL(synth_release_region);

struct var_t synth_time_vars[] = {
	{ DELAY, .u.n = {NULL, 100, 100, 2000, 0, 0, NULL } },
	{ TRIGGER, .u.n = {NULL, 20, 10, 2000, 0, 0, NULL } },
	{ JIFFY, .u.n = {NULL, 50, 20, 200, 0, 0, NULL } },
	{ FULL, .u.n = {NULL, 400, 200, 60000, 0, 0, NULL } },
	V_LAST_VAR
};

/* called by: speakup_init() */
int synth_init(char *synth_name)
{
	int i;
	int ret = 0;
	struct spk_synth *synth = NULL;

	if (synth_name == NULL)
		return 0;

	if (strcmp(synth_name, "none") == 0) {
		mutex_lock(&spk_mutex);
		synth_release();
		mutex_unlock(&spk_mutex);
		return 0;
	}

	mutex_lock(&spk_mutex);
	/* First, check if we already have it loaded. */
	for (i = 0; i < MAXSYNTHS && synths[i] != NULL; i++)
		if (strcmp(synths[i]->name, synth_name) == 0)
			synth = synths[i];

	/* If we got one, initialize it now. */
	if (synth)
		ret = do_synth_init(synth);
	else
		ret = -ENODEV;
	mutex_unlock(&spk_mutex);

	return ret;
}

/* called by: synth_add() */
static int do_synth_init(struct spk_synth *in_synth)
{
	struct var_t *var;

	synth_release();
	if (in_synth->checkval != SYNTH_CHECK)
		return -EINVAL;
	synth = in_synth;
	synth->alive = 0;
	pr_warn("synth probe\n");
	if (synth->probe(synth) < 0) {
		pr_warn("%s: device probe failed\n", in_synth->name);
		synth = NULL;
		return -ENODEV;
	}
	synth_time_vars[0].u.n.value =
		synth_time_vars[0].u.n.default_val = synth->delay;
	synth_time_vars[1].u.n.value =
		synth_time_vars[1].u.n.default_val = synth->trigger;
	synth_time_vars[2].u.n.value =
		synth_time_vars[2].u.n.default_val = synth->jiffies;
	synth_time_vars[3].u.n.value =
		synth_time_vars[3].u.n.default_val = synth->full;
	synth_printf("%s", synth->init);
	for (var = synth->vars;
		(var->var_id >= 0) && (var->var_id < MAXVARS); var++)
		speakup_register_var(var);
	if (!quiet_boot)
		synth_printf("%s found\n", synth->long_name);
	if (synth->attributes.name
	&& sysfs_create_group(speakup_kobj, &(synth->attributes)) < 0)
		return -ENOMEM;
	synth_flags = synth->flags;
	wake_up_interruptible_all(&speakup_event);
	if (speakup_task)
		wake_up_process(speakup_task);
	return 0;
}

void synth_release(void)
{
	struct var_t *var;
	unsigned long flags;

	if (synth == NULL)
		return;
	spk_lock(flags);
	pr_info("releasing synth %s\n", synth->name);
	synth->alive = 0;
	del_timer(&thread_timer);
	spk_unlock(flags);
	if (synth->attributes.name)
		sysfs_remove_group(speakup_kobj, &(synth->attributes));
	for (var = synth->vars; var->var_id != MAXVARS; var++)
		speakup_unregister_var(var->var_id);
	stop_serial_interrupt();
	synth->release();
	synth = NULL;
}

/* called by: all_driver_init() */
int synth_add(struct spk_synth *in_synth)
{
	int i;
	int status = 0;
	mutex_lock(&spk_mutex);
	for (i = 0; i < MAXSYNTHS && synths[i] != NULL; i++)
		/* synth_remove() is responsible for rotating the array down */
		if (in_synth == synths[i]) {
			mutex_unlock(&spk_mutex);
			return 0;
		}
	if (i == MAXSYNTHS) {
		pr_warn("Error: attempting to add a synth past end of array\n");
		mutex_unlock(&spk_mutex);
		return -1;
	}
	synths[i++] = in_synth;
	synths[i] = NULL;
	if (in_synth->startup)
		status = do_synth_init(in_synth);
	mutex_unlock(&spk_mutex);
	return status;
}
EXPORT_SYMBOL_GPL(synth_add);

void synth_remove(struct spk_synth *in_synth)
{
	int i;
	mutex_lock(&spk_mutex);
	if (synth == in_synth)
		synth_release();
	for (i = 0; synths[i] != NULL; i++) {
		if (in_synth == synths[i])
			break;
	}
	for ( ; synths[i] != NULL; i++) /* compress table */
		synths[i] = synths[i+1];
	module_status = 0;
	mutex_unlock(&spk_mutex);
}
EXPORT_SYMBOL_GPL(synth_remove);

short punc_masks[] = { 0, SOME, MOST, PUNC, PUNC|B_SYM };
