/* Get the locale settings */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <libraries/locale.h>
#include <libraries/iffparse.h>
#include <libraries/dos.h>
//#include <proto/locale.h>
//#include <proto/iffparse.h>
//#include <proto/dos.h>
#include <prefs/locale.h>
#include <prefs/prefhdr.h>

#include <clib/dos_protos.h>
#include <clib/iffparse_protos.h>

#include <proto/exec.h>
#include <proto/locale.h>
#include <exec/memory.h>

#include "prefs.h"

extern BOOL locale;
extern struct Language *chosen_lang;
extern struct Language *available_lang;
extern struct Catalog *catalog;

extern struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;
extern struct Library *UtilityBase;
extern struct Library *GadToolsBase;
extern struct Library *DiskfontBase;
extern struct Library *AslBase;
extern struct Library *IFFParseBase;
extern struct Library *DOSBase;

extern void msg(char *text);

extern struct Prefs prefs;

short getlocale(void);
void dissupported_languages(struct Language *a);
struct Language *supported_languages(char *dir);

void dissupported_languages(struct Language *a) {
	// The start of the list should be given!

	struct Language *start;
	int number=0;
	int i;

	start=a;

	while(a) {
		a=a->next;
		number++;
	}
	
	for(i=number; i>0; i--) {
		int j;
		a=start;

		for(j=0; j<(i-1); j++) 
			a=a->next;

		FreeVec(a);
	}
}

struct Language *supported_languages(char *dir) {
	/* What langauges are available in path "dir"? */

	char exported_path[400];
	struct FileLock *framelock_p;
	struct FileInfoBlock *fib_p;
	struct Language *start, *current;
	
	if(!(start=AllocVec(sizeof(struct Language),MEMF_CLEAR))) {
		msg(GetCatalogStr(catalog,30,"Major mem probs!"));
		return(0);
	}
	current=start;

	if(!(framelock_p=(struct FileLock *)Lock(dir,ACCESS_READ)))	{
		FreeVec(start);
		return(0);
	}

	if(!(fib_p=(struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock),MEMF_PUBLIC))) {
		UnLock((BPTR)framelock_p);
		FreeVec(start);
		msg(GetCatalogStr(catalog,30,"Err! No mem!\n"));
		return(0);
	}
	if(!(Examine((BPTR)framelock_p,fib_p))) {
		UnLock((BPTR)framelock_p);
		FreeMem(fib_p, sizeof(struct FileInfoBlock));
		FreeVec(start);
		msg(GetCatalogStr(catalog,30,"Err! No framelock!\n"));
		return(0);
	}

	while(ExNext((BPTR)framelock_p,fib_p)) {
		strcpy(exported_path,fib_p->fib_FileName);
		if(fib_p->fib_DirEntryType<0) {
			// Do something with exported path
			if(!(strcmp(&exported_path[strlen(exported_path)-8],".langmod"))) {
				exported_path[strlen(exported_path)-8]=0;
				strcpy(current->name,exported_path);
				if(!(current->next=AllocVec(sizeof(struct Language),MEMF_CLEAR))) {
					msg(GetCatalogStr(catalog,30,"Mem errors!"));
					dissupported_languages(start);
					start=NULL;
					goto zap;
				}
				current=current->next;
			}
		}
		
	}

	// Note that one too many structures will be allocated here
	// 1) Clear the previous next pointer
	// 2) Free the memory

	if(start->next) {		// Only do this if there was >0 entries
		struct Language *f;
		
		f=start;

		while(f->next!=current)
			f=f->next;
		f->next=0;

		FreeVec(current);
	}

	if(!strcmp(start->name,"")) {
		// There wasn't a single language!
		dissupported_languages(start);		// To allow for ".langmod"
		start=NULL;
	}

	zap:
	UnLock((BPTR)framelock_p);
	FreeMem(fib_p, sizeof(struct FileInfoBlock));

	return(start);
	
}

short getlocale(void) {
	int i=0, p=0;
	struct IFFHandle *iffhandle;
	struct ContextNode *cnode;
	struct StoredProperty *hdrsp, *sp;
	LONG ifferror;
	char prefs_languages[10][31];
	
	locale=FALSE;
	
	// Check to get whether plang is set
	
	chosen_lang=&prefs.planguage;

   /* If nothing is found in planguage (such as when a new pref file is
      created) then the first lang is set to the prefs and system */

	// Does that language (p) exist ?

	if(1) {
		struct Language *a;

		a=available_lang;
		while(a) {
			if(!(strcmp(strlwr(chosen_lang->name),strlwr(a->name)))) {
				//printf("Found plang! Chosen = %s\n",chosen_lang->name);
				return(1);
			}
			a=a->next;
		}
		
	}
	
	// Chosen lang is invalid so ask locale.....
	
	locale=TRUE;
	
	IFFParseBase=OpenLibrary("iffparse.library",0);
	if(!IFFParseBase)
		goto skipbit;
	
	if(iffhandle=AllocIFF()) {
		if(iffhandle->iff_Stream=(LONG)Open("env:sys/locale.prefs",MODE_OLDFILE)) {
			InitIFFasDOS(iffhandle);
			if(OpenIFF(iffhandle,IFFF_READ) == 0) {
				PropChunk(iffhandle,ID_PREF,ID_PRHD);
				PropChunk(iffhandle,ID_PREF,ID_LCLE);
				while(1) {
					ifferror=ParseIFF(iffhandle,IFFPARSE_STEP);
					if(ifferror==IFFERR_EOC) continue; else if(ifferror) break;
					if(cnode=CurrentChunk(iffhandle)) {
					   if(cnode->cn_ID == ID_PRHD || cnode->cn_ID == ID_FORM) continue;
					}
					
					hdrsp=FindProp(iffhandle,ID_PREF,ID_PRHD);
					if(sp=FindProp(iffhandle,ID_PREF,ID_LCLE)) {
						for(i=0; i<10; i++) {
							strcpy(prefs_languages[i],((struct LocalePrefs *)sp->sp_Data)->lp_PreferredLanguages[i]);
						}
					}
				}
				CloseIFF(iffhandle);
			}
			Close(iffhandle->iff_Stream);
		}
		FreeIFF(iffhandle);
	}

	CloseLibrary(IFFParseBase);

	/* Additional Processing */
	
	for(p=0; p<10; p++) {
		struct Language *a;

		a=available_lang;
		
		while(a) {
			if(!(strcmp(strlwr(prefs_languages[p]),strlwr(a->name)))) {
				//strcpy(chosen_lang.name,prefs_languages[p]);
				chosen_lang=a;
				//printf("Found locale! Chosen = %s\n",chosen_lang->name);
				return(1);
			}
			a=a->next;
		}

	}			
	
	/* If it gets this far then none of the preferred languages is
       supported.  In this case the built-in system is set */

	skipbit:
	
	locale=FALSE;

	//strcpy(chosen_lang.name,prefs.planguage);
	

	chosen_lang=available_lang;	// This must work!
	
	//printf("Last resort! Chosen = %s\n",chosen_lang->name);

	return(0);	/* Locale did not work */
}
					
