#include <u.h>

#define Point OSXPoint
#define Rect OSXRect
#define Cursor OSXCursor
#include <Carbon/Carbon.h>
#undef Rect
#undef Point
#undef Cursor
#undef offsetof
#undef nil

#include <libc.h>
#include <draw.h>
#include <memdraw.h>
#include "a.h"


extern void CGFontGetGlyphsForUnichars(CGFontRef, const UniChar[], const CGGlyph[], size_t);

char*
mac2c(CFStringRef s)
{
	char *p;
	int n;

	n = CFStringGetLength(s)*8;	
	p = malloc(n);
	CFStringGetCString(s, p, n, kCFStringEncodingUTF8);
	return p;
}

CFStringRef
c2mac(char *p)
{
	return CFStringCreateWithBytes(nil, (uchar*)p, strlen(p), kCFStringEncodingUTF8, false);
}

Rectangle
mac2r(CGRect r, int size, int unit)
{
	Rectangle rr;

	rr.min.x = r.origin.x*size/unit;
	rr.min.y = r.origin.y*size/unit;
	rr.max.x = (r.origin.x+r.size.width)*size/unit + 0.99999999;
	rr.max.y = (r.origin.x+r.size.width)*size/unit + 0.99999999;
	return rr;
}

void
loadfonts(void)
{
	int i, n;
	CTFontCollectionRef allc;
	CFArrayRef array;
	CFStringRef s;
	CTFontDescriptorRef f;

	allc = CTFontCollectionCreateFromAvailableFonts(0);
	array = CTFontCollectionCreateMatchingFontDescriptors(allc);
	n = CFArrayGetCount(array);
	xfont = emalloc9p(n*sizeof xfont[0]);
	for(i=0; i<n; i++) {
		f = (void*)CFArrayGetValueAtIndex(array, i);
		if(f == nil)
			continue;
		s = CTFontDescriptorCopyAttribute(f, kCTFontNameAttribute);
		xfont[nxfont].name = mac2c(s);		
		CFRelease(s);
		nxfont++;
	}
}

CGRect
subfontbbox(CGFontRef font, int lo, int hi)
{
	int i, first;
	CGRect bbox;

	bbox.origin.x = 0;
	bbox.origin.y = 0;
	bbox.size.height = 0;
	bbox.size.width = 0;

	first = 1;
	for(i=lo; i<=hi; i++) {
		UniChar u;
		CGGlyph g;
		CGRect r;

		u = i;
		CGFontGetGlyphsForUnichars(font, &u, &g, 1);
		if(g == 0 || !CGFontGetGlyphBBoxes(font, &g, 1, &r))
			continue;

		r.size.width += r.origin.x;
		r.size.height += r.origin.y;
		if(first) {
			bbox = r;
			first = 0;
			continue;
		}
		if(bbox.origin.x > r.origin.x)
			bbox.origin.x = r.origin.x;	
		if(bbox.origin.y > r.origin.y)
			bbox.origin.y = r.origin.y;	
		if(bbox.size.width < r.size.width)
			bbox.size.width = r.size.width;
		if(bbox.size.height < r.size.height)
			bbox.size.height = r.size.height;
	}
	
	bbox.size.width -= bbox.origin.x;
	bbox.size.height -= bbox.origin.y;
	return bbox;
}

void
load(XFont *f)
{
	int i, j;
	CGFontRef font;
	CFStringRef s;
	UniChar u[256];
	CGGlyph g[256];
	CGRect bbox;

	if(f->loaded)
		return;
	f->loaded = 1;
	s = c2mac(f->name);
	font = CGFontCreateWithFontName(s);
	CFRelease(s);
	if(font == nil)
		return;
	
	// assume bbox gives latin1 is height/ascent for all
	bbox = subfontbbox(font, 0x00, 0xff);
	f->unit = CGFontGetUnitsPerEm(font);
	f->height = bbox.size.height;
	f->originy = bbox.origin.y;

	// figure out where the letters are
	for(i=0; i<0xffff; i+=0x100) {
		for(j=0; j<0x100; j++) {
			u[j] = i+j;
			g[j] = 0;
		}
		CGFontGetGlyphsForUnichars(font, u, g, 256);
		for(j=0; j<0x100; j++) {
			if(g[j] != 0) {
				f->range[i>>8] = 1;
				f->nrange++;
				break;
			}
		}
	}
	CFRelease(font);
}

Memsubfont*
mksubfont(char *name, int lo, int hi, int size, int antialias)
{
	CFStringRef s;
	CGColorSpaceRef color;
	CGContextRef ctxt;
	CGFontRef font;
	CGRect bbox;
	Memimage *m, *mc, *m1;
	int x, y, y0;
	int i, unit;
	Fontchar *fc, *fc0;
	Memsubfont *sf;

	s = c2mac(name);
	font = CGFontCreateWithFontName(s);
	CFRelease(s);
	if(font == nil)
		return nil;
	bbox = subfontbbox(font, lo, hi);
	unit = CGFontGetUnitsPerEm(font);
	x = (int)(bbox.size.width * size / unit + 0.99999999);
	y = bbox.size.height * size/unit + 0.99999999;
	y0 = (int)(-bbox.origin.y * size/unit + 0.99999999);
	m = allocmemimage(Rect(0, 0, x*(hi+1-lo)+1, y+1), GREY8);
	if(m == nil)
		return nil;
	mc = allocmemimage(Rect(0, 0, x+1, y+1), GREY8);
	if(mc == nil)
		return nil;
	memfillcolor(m, DBlack);
	memfillcolor(mc, DBlack);
	fc = malloc((hi+2 - lo) * sizeof fc[0]);
	sf = malloc(sizeof *sf);
	if(fc == nil || sf == nil) {
		freememimage(m);
		freememimage(mc);
		free(fc);
		free(sf);
		return nil;
	}
	fc0 = fc;

	color = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray);
	ctxt = CGBitmapContextCreate(byteaddr(mc, mc->r.min), Dx(mc->r), Dy(mc->r), 8,
		mc->width*sizeof(u32int), color, kCGImageAlphaNone);
	CGColorSpaceRelease(color);
	if(ctxt == nil) {
		freememimage(m);
		freememimage(mc);
		free(fc);
		free(sf);
		return nil;
	}

	CGContextSetFont(ctxt, font);
	CGContextSetFontSize(ctxt, size);
	CGContextSetAllowsAntialiasing(ctxt, antialias);
	CGContextSetRGBFillColor(ctxt, 1, 1, 1, 1);
	CGContextSetTextPosition(ctxt, 0, 0);	// XXX

	x = 0;
	for(i=lo; i<=hi; i++, fc++) {
		UniChar u[2];
		CGGlyph g[2];
		CGRect r[2];
		CGPoint p1;
		int n;

		fc->x = x;
		fc->top = 0;
		fc->bottom = Dy(m->r);

		n = 0;
		u[n++] = i;
		if(0)	// debugging
			u[n++] = '|';
		g[0] = 0;
		CGFontGetGlyphsForUnichars(font, u, g, n);
		if(g[0] == 0 || !CGFontGetGlyphBBoxes(font, g, n, r)) {
		None:
			fc->width = 0;
			if(i == 0) {
				Point p;
				Fontchar *i;
				p = Pt(x, y0);
				// memimagestring(m, p, memwhite, ZP, defont, peterface);
				i = defont->info + 0;
				memdraw(m, Rect(p.x+i->left, p.y+i->top, p.x+i->left+(i[1].x-i[0].x), p.y+i->bottom),
					memwhite, ZP, defont->bits, Pt(i->x, i->top), S);
				p.x += i->width;
				fc->left = i->left;
				fc->width = i->width;
				x = p.x;
			}	
			continue;
		}
		memfillcolor(mc, DBlack);
		CGContextSetTextPosition(ctxt, 0, y0);
		CGContextShowGlyphs(ctxt, g, n);
		p1 = CGContextGetTextPosition(ctxt);
		if(p1.x <= 0)
			goto None;
		memimagedraw(m, Rect(x, 0, x + p1.x, y), mc, ZP, memopaque, ZP, S);
		fc->width = p1.x;
		fc->left = 0;
		x += p1.x;
	}
	fc->x = x;

	// round up to 32-bit boundary
	// so that in-memory data is same
	// layout as in-file data.
	if(x == 0)
		x = 1;
	if(y == 0)
		y = 1;
	if(antialias)
		x += -x & 3;
	else
		x += -x & 31;
	m1 = allocmemimage(Rect(0, 0, x, y), antialias ? GREY8 : GREY1);
	memimagedraw(m1, m1->r, m, m->r.min, memopaque, ZP, S);
	freememimage(m);

	sf->name = nil;
	sf->n = hi+1 - lo;
	sf->height = Dy(m1->r);
	sf->ascent = Dy(m1->r) - y0;
	sf->info = fc0;
	sf->bits = m1;
	
	return sf;
}

