#include "steuern_ch.h"

/*************************************************************************
** Example of init function
** Arguments:
** initid	Points to a structure that the init function should fill.
**		This argument is given to all other functions.
**	my_bool maybe_null	1 if function can return NULL
**				Default value is 1 if any of the arguments
**				is declared maybe_null.
**	unsigned int decimals	Number of decimals.
**				Default value is max decimals in any of the
**				arguments.
**	unsigned int max_length  Length of string result.
**				The default value for integer functions is 21
**				The default value for real functions is 13+
**				default number of decimals.
**				The default value for string functions is
**				the longest string argument.
**	char *ptr;		A pointer that the function can use.
**
** args		Points to a structure which contains:
**	unsigned int arg_count		Number of arguments
**	enum Item_result *arg_t	ts for each argument.
**					ts are STRING_RESULT, REAL_RESULT
**					and INT_RESULT.
**	char **args			Pointer to constant arguments.
**					Contains 0 for not constant argument.
**	unsigned long *lengths;		max string length for each argument
**	char *maybe_null		Information of which arguments
**					may be NULL
**
** message	Error message that should be passed to the user on fail.
**		The message buffer is MYSQL_ERRMSG_SIZE big, but one should
**		try to keep the error message less than 80 bytes long!
**
** This function should return 1 if something goes wrong. In this case
** message should contain something usefull!
**************************************************************************/

my_bool steuern_ch_e_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
	return steuern_ch_init(initid,args,message);
}
my_bool steuern_ch_v_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
	return steuern_ch_init(initid,args,message);
}

my_bool steuern_ch_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
	
	initid->maybe_null = 0;

	if (args->arg_count != 4 && args->arg_count != 5) {
		strcpy(message,"steuern_ch needs 4 or 5 arguments");
		return 1;
	}

	if (args->arg_type[0] != STRING_RESULT) {
		strcpy(message,"steuern_ch needs string as 1st argument");
		return 1;
	}

	if (args->arg_type[1] != REAL_RESULT && args->arg_type[1] != INT_RESULT) {
		strcpy(message,"steuern_ch needs float as 2nd argument");
		return 1;
	}

	if (args->arg_type[2] != INT_RESULT) {
		strcpy(message,"steuern_ch needs integer as 3rd argument");
		return 1;
	}

	if (args->arg_type[3] != INT_RESULT) {
		strcpy(message,"steuern_ch needs integer as 4th argument");
		return 1;
	}

	if (args->arg_count > 4 && args->arg_type[4] != INT_RESULT) {
		strcpy(message,"steuern_ch needs integer as 5th argument (if there is such an argument)");
		return 1;
	}

	return 0;
}

/****************************************************************************
** Deinit function. This should free all resources allocated by
** this function.
** Arguments:
** initid	Return value from xxxx_init
****************************************************************************/
void steuern_ch_e_deinit(UDF_INIT *initid) {}
void steuern_ch_v_deinit(UDF_INIT *initid) {}

/***************************************************************************
** UDF string function.
** Arguments:
** initid	Structure filled by xxx_init
** args		The same structure as to xxx_init. This structure
**		contains values for all parameters.
**		Note that the functions MUST check and convert all
**		to the t it wants!  Null values are represented by
**		a NULL pointer
** result	Possible buffer to save result. At least 255 byte long.
** length	Pointer to length of the above buffer.	In this the function
**		should save the result length
** is_null	If the result is null, one should store 1 here.
** error	If something goes fatally wrong one should store 1 here.
**
** This function should return a pointer to the result string.
** Normally this is 'result' but may also be an alloced string.
***************************************************************************/

double steuern_ch_e(UDF_INIT *initid, UDF_ARGS *args, char *result,
			unsigned long *length, char *is_null, char *error) {

	double v;
	unsigned short int t;
	unsigned int k;

	if (args->arg_type[1] == INT_RESULT)
		v = (double) *((long long *) args->args[1]);
	else
		v = (double) *((double *) args->args[1]);

	t = (unsigned short int) *((int *) args->args[2]);
	k = (unsigned int) *((int *) args->args[3]);

	if (strcasecmp(args->args[0],"zh") == 0) {
		return steuern_e_zh(v,t,k);
	} else if (strcasecmp(args->args[0],"be") == 0) {
		return steuern_e_be(v,t,k);
	} else if (strcasecmp(args->args[0],"tg") == 0) {
		return steuern_e_tg(v,t,k);
	} else if (strcasecmp(args->args[0],"so") == 0) {
		return steuern_e_so(v,t,k);
	} else if (strcasecmp(args->args[0],"ag") == 0) {
		return steuern_e_ag(v,t,k);
	} else if (strcasecmp(args->args[0],"lu") == 0) {
		return steuern_e_lu(v,t,k);
	} else if (strcasecmp(args->args[0],"sg") == 0) {
		return steuern_e_sg(v,t,k);
	} else if (strcasecmp(args->args[0],"fr") == 0) {
		return steuern_e_fr(v,t,k);
	} else if (strcasecmp(args->args[0],"ar") == 0) {
		return steuern_e_ar(v,t,k);
	} else if (strcasecmp(args->args[0],"ai") == 0) {
		return steuern_e_ai(v,t,k);
	} else if (strcasecmp(args->args[0],"nw") == 0) {
		return steuern_e_nw(v,t,k);
	} else if (strcasecmp(args->args[0],"ow") == 0) {
		return steuern_e_ow(v,t,k);
	} else if (strcasecmp(args->args[0],"sz") == 0) {
		return steuern_e_sz(v,t,k);
	} else if (strcasecmp(args->args[0],"ur") == 0) {
		return steuern_e_ur(v,t,k);
	} else if (strcasecmp(args->args[0],"sh") == 0) {
		return steuern_e_sh(v,t,k);
	} else if (strcasecmp(args->args[0],"ne") == 0) {
		return steuern_e_ne(v,t,k);
	} else if (strcasecmp(args->args[0],"ju") == 0) {
		return steuern_e_ju(v,t,k);
	} else if (strcasecmp(args->args[0],"vd") == 0) {
		return steuern_e_vd(v,t,k);
	} else if (strcasecmp(args->args[0],"zg") == 0) {
		return steuern_e_zg(v,t,k);
	} else if (strcasecmp(args->args[0],"gl") == 0) {
		return steuern_e_gl(v,t,k);
	} else if (strcasecmp(args->args[0],"gr") == 0) {
		return steuern_e_gr(v,t,k);
	} else if (strcasecmp(args->args[0],"bs") == 0) {
		return steuern_e_bs(v,t,k);
	} else if (strcasecmp(args->args[0],"ti") == 0) {
		return steuern_e_ti(v,t,k);
	}

	return -1;

}

double steuern_ch_v(UDF_INIT *initid, UDF_ARGS *args, char *result,
			unsigned long *length, char *is_null, char *error) {

	double v;
	unsigned short int t;
	unsigned int k;

	if (args->arg_type[1] == INT_RESULT)
		v = (double) *((long long *) args->args[1]);
	else
		v = (double) *((double *) args->args[1]);

	t = (unsigned short int) *((int *) args->args[2]);
	k = (unsigned int) *((int *) args->args[3]);

	if (strcasecmp(args->args[0],"zh") == 0) {
		return steuern_v_zh(v,t,k);
	} else if (strcasecmp(args->args[0],"be") == 0) {
		return steuern_v_be(v,t,k);
	} else if (strcasecmp(args->args[0],"tg") == 0) {
		return steuern_v_tg(v,t,k);
	} else if (strcasecmp(args->args[0],"so") == 0) {
		return steuern_v_so(v,t,k);
	} else if (strcasecmp(args->args[0],"ag") == 0) {
		return steuern_v_ag(v,t,k);
	} else if (strcasecmp(args->args[0],"lu") == 0) {
		return steuern_v_lu(v,t,k);
	} else if (strcasecmp(args->args[0],"sg") == 0) {
		return steuern_v_sg(v,t,k);
	} else if (strcasecmp(args->args[0],"fr") == 0) {
		return steuern_v_fr(v,t,k);
	} else if (strcasecmp(args->args[0],"ar") == 0) {
		return steuern_v_ar(v,t,k);
	} else if (strcasecmp(args->args[0],"ai") == 0) {
		return steuern_v_ai(v,t,k);
	} else if (strcasecmp(args->args[0],"nw") == 0) {
		return steuern_v_nw(v,t,k);
	} else if (strcasecmp(args->args[0],"ow") == 0) {
		return steuern_v_ow(v,t,k);
	} else if (strcasecmp(args->args[0],"sz") == 0) {
		return steuern_v_sz(v,t,k);
	} else if (strcasecmp(args->args[0],"ur") == 0) {
		return steuern_v_ur(v,t,k);
	} else if (strcasecmp(args->args[0],"sh") == 0) {
		return steuern_v_sh(v,t,k);
	} else if (strcasecmp(args->args[0],"ne") == 0) {
		return steuern_v_ne(v,t,k);
	} else if (strcasecmp(args->args[0],"ju") == 0) {
		return steuern_v_ju(v,t,k);
	} else if (strcasecmp(args->args[0],"vd") == 0) {
		return steuern_v_vd(v,t,k);
	} else if (strcasecmp(args->args[0],"zg") == 0) {
		return steuern_v_zg(v,t,k);
	} else if (strcasecmp(args->args[0],"gl") == 0) {
		return steuern_v_gl(v,t,k);
	} else if (strcasecmp(args->args[0],"gr") == 0) {
		return steuern_v_gr(v,t,k);
	} else if (strcasecmp(args->args[0],"bs") == 0) {
		return steuern_v_bs(v,t,k);
	} else if (strcasecmp(args->args[0],"ti") == 0) {
		return steuern_v_ti(v,t,k);
	}

	return -1;

}

