/*
 * Copyright 2008-2009 Katholieke Universiteit Leuven
 *
 * Use of this software is governed by the GNU LGPLv2.1 license
 *
 * Written by Sven Verdoolaege, K.U.Leuven, Departement
 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
 */

#include <isl_ctx_private.h>
#include <isl/seq.h>
#include <isl/vec.h>

isl_ctx *isl_vec_get_ctx(__isl_keep isl_vec *vec)
{
	return vec ? vec->ctx : NULL;
}

struct isl_vec *isl_vec_alloc(struct isl_ctx *ctx, unsigned size)
{
	struct isl_vec *vec;

	vec = isl_alloc_type(ctx, struct isl_vec);
	if (!vec)
		return NULL;

	vec->block = isl_blk_alloc(ctx, size);
	if (isl_blk_is_error(vec->block))
		goto error;

	vec->ctx = ctx;
	isl_ctx_ref(ctx);
	vec->ref = 1;
	vec->size = size;
	vec->el = vec->block.data;

	return vec;
error:
	isl_blk_free(ctx, vec->block);
	return NULL;
}

__isl_give isl_vec *isl_vec_extend(__isl_take isl_vec *vec, unsigned size)
{
	if (!vec)
		return NULL;
	if (size <= vec->size)
		return vec;

	vec = isl_vec_cow(vec);
	if (!vec)
		return NULL;

	vec->block = isl_blk_extend(vec->ctx, vec->block, size);
	if (!vec->block.data)
		goto error;

	vec->size = size;
	vec->el = vec->block.data;

	return vec;
error:
	isl_vec_free(vec);
	return NULL;
}

__isl_give isl_vec *isl_vec_zero_extend(__isl_take isl_vec *vec, unsigned size)
{
	int extra;

	if (!vec)
		return NULL;
	if (size <= vec->size)
		return vec;

	vec = isl_vec_cow(vec);
	if (!vec)
		return NULL;

	extra = size - vec->size;
	vec = isl_vec_extend(vec, size);
	if (!vec)
		return NULL;

	isl_seq_clr(vec->el + size - extra, extra);

	return vec;
}

struct isl_vec *isl_vec_copy(struct isl_vec *vec)
{
	if (!vec)
		return NULL;

	vec->ref++;
	return vec;
}

struct isl_vec *isl_vec_dup(struct isl_vec *vec)
{
	struct isl_vec *vec2;

	if (!vec)
		return NULL;
	vec2 = isl_vec_alloc(vec->ctx, vec->size);
	isl_seq_cpy(vec2->el, vec->el, vec->size);
	return vec2;
}

struct isl_vec *isl_vec_cow(struct isl_vec *vec)
{
	struct isl_vec *vec2;
	if (!vec)
		return NULL;

	if (vec->ref == 1)
		return vec;

	vec2 = isl_vec_dup(vec);
	isl_vec_free(vec);
	return vec2;
}

void isl_vec_free(struct isl_vec *vec)
{
	if (!vec)
		return;

	if (--vec->ref > 0)
		return;

	isl_ctx_deref(vec->ctx);
	isl_blk_free(vec->ctx, vec->block);
	free(vec);
}

int isl_vec_is_equal(__isl_keep isl_vec *vec1, __isl_keep isl_vec *vec2)
{
	if (!vec1 || !vec2)
		return -1;

	if (vec1->size != vec2->size)
		return 0;

	return isl_seq_eq(vec1->el, vec2->el, vec1->size);
}

__isl_give isl_printer *isl_printer_print_vec(__isl_take isl_printer *printer,
	__isl_keep isl_vec *vec)
{
	int i;

	if (!printer || !vec)
		goto error;

	printer = isl_printer_print_str(printer, "[");
	for (i = 0; i < vec->size; ++i) {
		if (i)
			printer = isl_printer_print_str(printer, ",");
		printer = isl_printer_print_isl_int(printer, vec->el[i]);
	}
	printer = isl_printer_print_str(printer, "]");

	return printer;
error:
	isl_printer_free(printer);
	return NULL;
}

void isl_vec_dump(struct isl_vec *vec)
{
	isl_printer *printer;

	if (!vec)
		return;

	printer = isl_printer_to_file(vec->ctx, stderr);
	printer = isl_printer_print_vec(printer, vec);
	printer = isl_printer_end_line(printer);

	isl_printer_free(printer);
}

__isl_give isl_vec *isl_vec_clr(__isl_take isl_vec *vec)
{
	vec = isl_vec_cow(vec);
	if (!vec)
		return NULL;
	isl_seq_clr(vec->el, vec->size);
	return vec;
}

void isl_vec_lcm(struct isl_vec *vec, isl_int *lcm)
{
	isl_seq_lcm(vec->block.data, vec->size, lcm);
}

/* Given a rational vector, with the denominator in the first element
 * of the vector, round up all coordinates.
 */
struct isl_vec *isl_vec_ceil(struct isl_vec *vec)
{
	vec = isl_vec_cow(vec);
	if (!vec)
		return NULL;

	isl_seq_cdiv_q(vec->el + 1, vec->el + 1, vec->el[0], vec->size - 1);

	isl_int_set_si(vec->el[0], 1);

	return vec;
}

struct isl_vec *isl_vec_normalize(struct isl_vec *vec)
{
	if (!vec)
		return NULL;
	isl_seq_normalize(vec->ctx, vec->el, vec->size);
	return vec;
}

__isl_give isl_vec *isl_vec_neg(__isl_take isl_vec *vec)
{
	vec = isl_vec_cow(vec);
	if (!vec)
		return NULL;
	isl_seq_neg(vec->el, vec->el, vec->size);
	return vec;
}

__isl_give isl_vec *isl_vec_scale(__isl_take isl_vec *vec, isl_int m)
{
	if (isl_int_is_one(m))
		return vec;
	vec = isl_vec_cow(vec);
	if (!vec)
		return NULL;
	isl_seq_scale(vec->el, vec->el, m, vec->size);
	return vec;
}

__isl_give isl_vec *isl_vec_add(__isl_take isl_vec *vec1,
	__isl_take isl_vec *vec2)
{
	vec1 = isl_vec_cow(vec1);
	if (!vec1 || !vec2)
		goto error;

	isl_assert(vec1->ctx, vec1->size == vec2->size, goto error);

	isl_seq_combine(vec1->el, vec1->ctx->one, vec1->el,
			vec1->ctx->one, vec2->el, vec1->size);
	
	isl_vec_free(vec2);
	return vec1;
error:
	isl_vec_free(vec1);
	isl_vec_free(vec2);
	return NULL;
}

static int qsort_int_cmp(const void *p1, const void *p2)
{
	const isl_int *i1 = (const isl_int *) p1;
	const isl_int *i2 = (const isl_int *) p2;

	return isl_int_cmp(*i1, *i2);
}

__isl_give isl_vec *isl_vec_sort(__isl_take isl_vec *vec)
{
	if (!vec)
		return NULL;
	
	qsort(vec->el, vec->size, sizeof(*vec->el), &qsort_int_cmp);

	return vec;
}

__isl_give isl_vec *isl_vec_drop_els(__isl_take isl_vec *vec,
	unsigned pos, unsigned n)
{
	if (n == 0)
		return vec;
	vec = isl_vec_cow(vec);
	if (!vec)
		return NULL;

	if (pos + n > vec->size)
		isl_die(vec->ctx, isl_error_invalid,
			"range out of bounds", goto error);

	if (pos + n != vec->size)
		isl_seq_cpy(vec->el + pos, vec->el + pos + n,
			    vec->size - pos - n);

	vec->size -= n;
	
	return vec;
error:
	isl_vec_free(vec);
	return NULL;
}

__isl_give isl_vec *isl_vec_insert_els(__isl_take isl_vec *vec,
	unsigned pos, unsigned n)
{
	isl_vec *ext = NULL;

	if (n == 0)
		return vec;
	if (!vec)
		return NULL;

	if (pos > vec->size)
		isl_die(vec->ctx, isl_error_invalid,
			"position out of bounds", goto error);

	ext =  isl_vec_alloc(vec->ctx, vec->size + n);
	if (!ext)
		goto error;

	isl_seq_cpy(ext->el, vec->el, pos);
	isl_seq_cpy(ext->el + pos + n, vec->el + pos, vec->size - pos);

	isl_vec_free(vec);
	return ext;
error:
	isl_vec_free(vec);
	isl_vec_free(ext);
	return NULL;
}

__isl_give isl_vec *isl_vec_insert_zero_els(__isl_take isl_vec *vec,
	unsigned pos, unsigned n)
{
	vec = isl_vec_insert_els(vec, pos, n);
	if (!vec)
		return NULL;

	isl_seq_clr(vec->el + pos, n);

	return vec;
}
