/*******************************************************************
*                                                                  *
*             This software is part of the ast package             *
*                Copyright (c) 1985-2003 AT&T Corp.                *
*        and it may only be used by you under license from         *
*                       AT&T Corp. ("AT&T")                        *
*         A copy of the Source Code Agreement is available         *
*                at the AT&T Internet web site URL                 *
*                                                                  *
*       http://www.research.att.com/sw/license/ast-open.html       *
*                                                                  *
*    If you have copied or used this software without agreeing     *
*        to the terms of the license you are infringing on         *
*           the license and copyright and are violating            *
*               AT&T's intellectual property rights.               *
*                                                                  *
*            Information and Software Systems Research             *
*                        AT&T Labs Research                        *
*                         Florham Park NJ                          *
*                                                                  *
*               Glenn Fowler <gsf@research.att.com>                *
*                David Korn <dgk@research.att.com>                 *
*                 Phong Vo <kpv@research.att.com>                  *
*                                                                  *
*******************************************************************/
#pragma prototyped

/*
 * catopen intercept
 * the ast catalogs are checked first
 * the ast mc* and native cat* routines do all the work
 * catalogs found by mcfind() are converted from utf to ucs
 *
 * nl_catd is cast to void*
 * this is either an Mc_t* (Mc_t.set != 0)
 * or a Cc_t* where Cc_t.cat is the native nl_catd
 */

#include <ast.h>
#include <mc.h>
#include <nl_types.h>
#include <iconv.h>
#include <sfstr.h>

#ifndef DEBUG_trace
#define DEBUG_trace		0
#endif

#if _lib_catopen

#undef	nl_catd
#undef	catopen
#undef	catgets
#undef	catclose

typedef struct
{
	Mcset_t*	set;
	nl_catd		cat;
	iconv_t		cvt;
	Sfio_t*		tmp;
} Cc_t;

#else

#define _ast_nl_catd	nl_catd
#define _ast_catopen	catopen
#define _ast_catgets	catgets
#define _ast_catclose	catclose

#endif

_ast_nl_catd
_ast_catopen(const char* name, int flag)
{
	Mc_t*		mc;
	char*		s;
	Sfio_t*		ip;
	char		path[PATH_MAX];

	/*
	 * first try the ast catalogs
	 */

#if DEBUG_trace
sfprintf(sfstderr, "AHA#%d:%s %s\n", __LINE__, __FILE__, name);
#endif
	if ((s = mcfind(path, NiL, name, LC_MESSAGES, flag)) && (ip = sfopen(NiL, s, "r")))
	{
#if DEBUG_trace
sfprintf(sfstderr, "AHA#%d:%s %s\n", __LINE__, __FILE__, s);
#endif
		mc = mcopen(ip);
		sfclose(ip);
		if (mc)
			return (_ast_nl_catd)mc;
	}
#if _lib_catopen
	if (strcmp(setlocale(LC_MESSAGES, NiL), "debug"))
	{
		Cc_t*		cc;
		nl_catd		d;

		/*
		 * now the native catalogs
		 */

		if (s && (d = catopen(s, flag)) != (nl_catd)(-1) || !(s = 0) && (d = catopen(name, flag)) != (nl_catd)(-1))
		{
			if (!(cc = newof(0, Cc_t, 1, 0)))
			{
				catclose(d);
				return (_ast_nl_catd)(-1);
			}
			cc->cat = d;
			if ((s || *name == '/') && (ast.locale.set & (1<<AST_LC_MESSAGES)))
			{
				cc->cvt = iconv_open("", "utf");
				cc->tmp = sfstropen();
			}
			else
				cc->cvt = (iconv_t)(-1);
#if DEBUG_trace
sfprintf(sfstderr, "AHA#%d:%s %s %s native %p\n", __LINE__, __FILE__, s, name, cc->cat);
#endif
			return (_ast_nl_catd)cc;
		}
	}
#endif

	/*
	 * loser
	 */

	return (_ast_nl_catd)(-1);
}

char*
_ast_catgets(_ast_nl_catd cat, int set, int num, const char* msg)
{
	if (cat == (_ast_nl_catd)(-1))
		return (char*)msg;
#if _lib_catopen
	if (!((Cc_t*)cat)->set)
	{
		char*	s;
		size_t	n;

		msg = (char*)catgets(((Cc_t*)cat)->cat, set, num, msg);
		if (((Cc_t*)cat)->cvt != (iconv_t)(-1))
		{
			s = (char*)msg;
			n = strlen(s);
			iconv_write(((Cc_t*)cat)->cvt, ((Cc_t*)cat)->tmp, &s, &n, NiL);
			return sfstruse(((Cc_t*)cat)->tmp);
		}
		return (char*)msg;
	}
#endif
	return mcget((Mc_t*)cat, set, num, msg);
}

int
_ast_catclose(_ast_nl_catd cat)
{
	if (cat == (_ast_nl_catd)(-1))
		return -1;
#if _lib_catopen
	if (!((Cc_t*)cat)->set)
	{
		if (((Cc_t*)cat)->cvt != (iconv_t)(-1))
			iconv_close(((Cc_t*)cat)->cvt);
		if (((Cc_t*)cat)->tmp)
			sfclose(((Cc_t*)cat)->tmp);
		return catclose(((Cc_t*)cat)->cat);
	}
#endif
	return mcclose((Mc_t*)cat);
}
