/*
 * Copyright (C) 1992 by Software Research Associates, Inc.
 *      Author: Y. Kawabe <kawabe@sra.co.jp>
 *
 * Permission to use, copy, modify, and distribute, and sell this software
 * and its documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notice appear in all copies and that
 * both that copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Software Research Associates not be
 * used in advertising or publicity pertaining to distribution of the software
 * without specific, written prior permission.  Software Research Associates
 * makes no representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 *
 */

#include <NLS/locale.h>
#include <NLS/nlsfile.h>
#include <hyperg/OS/table.h>
#include <hyperg/OS/ustring.h>
//#include <strings.h>
#include <stdlib.h>

#ifndef IV_LOCALE_PATH
#define IV_LOCALE_PATH         "Locale"
#endif

LocaleRep::LocaleRep () {
    name_ = nil;
    codeset_ = nil;
}

LocaleRep::~LocaleRep () {
    delete name_;
    delete codeset_;
}

/*
 * class LocaleTable
 */

inline unsigned long key_to_hash(String &s) {
    return (unsigned long) s.hash();
}

declareTable(LocaleRepTable, String, LocaleRep*);
implementTable(LocaleRepTable, String, LocaleRep*);

/*
 * class Locale
 */

Locale*			Locale::default_;
LocaleRepTable*		Locale::table_;

Locale::Locale (const char* locale) {
    rep_ = rep(String(locale));
}
    
Locale::Locale (const String& locale) {
    rep_ = rep(locale);
}

Locale::Locale (const Locale& locale) {
    rep_ = locale.rep_;
}

const Locale& Locale::setlocale () {
    if (default_ == nil) {
	default_ = new Locale ("C");
    }
    return *default_;
}

const Locale& Locale::setlocale (const char* locale) {
    return setlocale(Locale(locale));
}

const Locale& Locale::setlocale (const String& locale) {
    return setlocale(Locale(locale));
}

const Locale& Locale::setlocale (const Locale& locale) {
    if (default_ == nil) {
        default_ = new Locale (locale);
    } else {
	default_->rep_ = locale.rep_;
    }
    return *default_;
}

static char* defaultlocales[][2]=
{
  {"C","CTEXT"},
  {"en_US.88591","ISO8859-1"},
  {"en_UK.88591","ISO8859-1"},
  {"fr_FR.88591","ISO8859-1"},
  {"ja_JP.jis8","ja_JP.JIS"},
  {"ja_JP.EUC","ja_JP.EUC"},
  {"ja_JP.ujis","ja_JP.EUC"},
  {"ja_JP.SJIS","ja_JP.SJIS"},
  {"ja_JP.mscode","ja_JP.SJIS"},
  {"ko_KR.EUC","ko_KR.EUC"},
  {"zh_CN.EUC","zh_CN.EUC"},
  {"zh_TW.BIG5","zh_TW.BIG5"},
  {"zh_TW.big5","zh_TW.BIG5"},
  {0,0}
};

LocaleRep* Locale::rep (const String& locale) {
    if (table_ == nil) {
	// Initialization of LocaleRepTable;
	
	table_ = new LocaleRepTable(16);

	LocaleRep *def=new LocaleRep();;
        def->name_ = new UniqueString("C");
	table_->insert(*def->name_, def);
        int i=0;
	LocaleRep	*rep = nil;

        while(defaultlocales[i][0])
        {
          rep = new LocaleRep();
          rep->name_ = new UniqueString(defaultlocales[i][0]);
          rep->codeset_ = new UniqueString(defaultlocales[i][1]);
          if (rep && rep->name_) {
            LocaleRep		*oldrep;
            if (table_->find_and_remove(oldrep, *rep->name_)) {
              delete oldrep;
            }
            table_->insert(*rep->name_, rep);
          }
          rep = nil;
          i++;
        }

	int		argc;
	const int	argsize = 64;
	char		*argv[argsize];
	nlsFile		file (IV_LOCALE_PATH);

	while ((argc = file.getline (argv, argsize)) >= 0) {
	    if (argc == 0) {
		continue;
	    } else if (strcmp(argv[0], "BEGIN") == 0) {
		rep = new LocaleRep();
	    } else if (strcmp(argv[0], "END") == 0) {
		if (rep && rep->name_) {
		    LocaleRep		*oldrep;
		    if (table_->find_and_remove(oldrep, *rep->name_)) {
			delete oldrep;
		    }
		    table_->insert(*rep->name_, rep);
		}
		rep = nil;
	    } else if (rep && argc == 2) {
		if (strcmp(argv[0], "NAME") == 0) {
		    rep->name_ = new UniqueString(argv[1]);
		} else if (strcmp(argv[0], "CODESET") == 0) {
		    rep->codeset_ = new UniqueString(argv[1]);
		}
	    }
	}
    }
    LocaleRep* rep;
    if (!table_->find(rep, locale)) {
	rep = new LocaleRep();
	rep->name_ = new UniqueString(locale);
	table_->insert(*rep->name_, rep);
    }
    return rep;
}

