/**********************************************************************
 
	Copyright (C) 2003 -
	Hirohisa MORI <joshua@nichibun.ac.jp>
 	Tomoki SEKIYAMA <sekiyama@yahoo.co.jp>

	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	This program is distributed in the hope that it will be 
	useful, but WITHOUT ANY WARRANTY; without even the 
	implied warranty of MERCHANTABILITY or FITNESS FOR A 
	PARTICULAR PURPOSE.

**********************************************************************/



#include	"utils.h"
#include	"machine/v_types.h"
#include	"lc_encode.h"
#include	"memory_debug.h"
#include	"encoding_tables.h"
#include	<Fonts.h>
#include	<UnicodeConverter.h>

void v_font_make_list();


typedef struct VFONT_LIST {
    L_CHAR *			lname;
	VFONT *				vfont;
	struct VFONT_LIST *	next;
} VFONT_LIST;

VFONT_LIST *	v_font_list = 0;

CODE_SCRIPT_TABLE * sc_tbl[256];



void
v_font_make_list()
{
FMFontFamily family;
FMFontFamilyIterator fi;
TextEncoding encoding;
TextToUnicodeInfo t2u;
ByteCount  ulen;
UniChar uniname[1024];
int i;
	
printf("Making Font Table...");
fflush(stdout);

	FMCreateFontFamilyIterator(NULL, NULL, 0, &fi);
	while ( FMGetNextFontFamily(&fi, &family) != kFMIterationCompleted ) {
		VFONT_LIST *list = d_alloc(sizeof(VFONT_LIST));
		VFONT *vfont = list->vfont = d_alloc(sizeof(VFONT));
		vfont->id = family;
		list->next = v_font_list;
		v_font_list = list;
		
		FMGetFontFamilyName(family, vfont->fontname);
		FMGetFontFamilyTextEncoding(family, &encoding);
		RevertTextEncodingToScriptInfo(encoding, &vfont->script, 0, 0);
		
		CreateTextToUnicodeInfoByEncoding(encoding, &t2u);
		ConvertFromPStringToUnicode(t2u, vfont->fontname, 1024, &ulen, uniname);
		ulen /= 2;
		DisposeTextToUnicodeInfo(&t2u);
		
		list->lname = d_alloc(sizeof(L_CHAR)*(ulen+1));
		for ( i = 0 ; i < ulen ; i++ )
			list->lname[i] = uniname[i];
		list->lname[ulen] = 0;
	}
	FMDisposeFontFamilyIterator(&fi);
	for ( i = 0 ; mac_script_tbl[i].script != -1 ; i ++ )
		sc_tbl[mac_script_tbl[i].script] = &mac_script_tbl[i];
printf("done\n");
}

int
v_get_font(LC_FONT * f,LC_FONT_ENGINE * fe)
{
int len, i, size = 0;
VFONT * vf;
VFONT_LIST *list;
L_CHAR *fontname;
LC_FONT_SIZE_LIST sl;
CODE_SCRIPT_TABLE * dt;
char buffer[256];
LCZ_SET set[] = {
	{0,LCZM_2B_TYPE},
	{LCC_ERROR,0}
};

LCZ_SET sjis_code[] = {
	{LCZ_2BC_JISX0208_1990,0},
	{LCZ_1BC_ASCII,LCZM_7b_TYPE},
	{LCC_ERROR,0}
};

force_scheduling();

	if ( v_font_list == 0 )
		v_font_make_list();
	len = l_strlen(f->fontname);
fontname = code_convert_with_combine(f->fontname, len, sjis_code, 0);
printf("***** v_get_font ; %s\n", n_string(std_cm,fontname));
d_f_ree(fontname);
	fontname = code_convert_with_combine(f->fontname, len, set, 0);
	for ( i = len-1 ; i ; i-- ) {
		if ( fontname[i] == ' ' ) {
			size = atoi(n_string(&ascii_cm, fontname+i+1));
			if ( size ) {
				fontname[i] = 0;
				break;
			}
			break;
		}
	}
	
	for ( list = v_font_list ; list ; list = list->next ) {
		if ( l_strcmp(fontname, list->lname) == 0 )
			break;
	}
	if ( list == 0 ) {
		d_f_ree(fontname);	
		return -1;
	}
	vf = list->vfont;
	vf->default_size = size;
	
	dt = sc_tbl[vf->script];
	if ( dt ) {
		if ( dt->lcz[0] == LCC_ERROR )
			return -1;
		if ( f->mask[0] != LCZM_ALL && f->mask[0] != 0  ) {
			if ( dt->mask[0] & (~f->mask[0]) )
				goto next;
			if ( (dt->lcz[0] & dt->mask[0])
				!= (f->lcz[0] & dt->mask[0]) )
				goto next;
		}
		f->mask[0] = dt->mask[0];
		f->lcz[0] = dt->lcz[0];
	next:
		f->mask[1] = dt->mask[1];
		f->lcz[1] = dt->lcz[1];
	}
	else	return -1;
	sl.from = f->lcz[0] | dt->from;
	sl.to =   f->lcz[0] | dt->to;
	sl.size = -1;
	_insert_lc_font_size_list(f,&sl);
	
	if ( f->lcz[1] != LCC_ERROR ) {
		sl.from = f->lcz[1] | dt->from;
		sl.to = f->lcz[1] | dt->to;
		sl.size = -1;
		_insert_lc_font_size_list(f,&sl);
	}
	
	d_f_ree(fontname);
	
p2cstrcpy(buffer, vf->fontname);
printf("FONT = ID:%d  Script:%d  Name:%s\n",vf->id, vf->script, buffer);
	insert_font_work(f,fe,vf);
	return 0;
}
