 /*
 *  MS Windows - dependent cursors
 */

#include <Interviews\bitmap.h>
#include <Interviews\color.h>
#include <Interviews\cursor.h>
#include <Interviews\font.h>
#include <Interviews\X11\worldrep.h>
#include <mem.h>


void MakeWinFormat (
    int* pat, int* mask, unsigned* andmask, unsigned* xormask, boolean bitmapbits
) {
    memset(andmask, 0xff, 128);
    memset(xormask, '\0', 128);
    for (int j = 0, i = 0; i < 16; i++, j += 2) {
	andmask[j] = ~mask[i];
	xormask[j] = mask[i] & pat[i];

    }

    if (!bitmapbits) {
	BYTE highbyte;

	for (i = 0; i < 32; i += 2) {
	    highbyte = HIBYTE(andmask[i]);
	    andmask[i] <<= 8;
	    andmask[i] += highbyte;

	    highbyte = HIBYTE(xormask[i]);
	    xormask[i] <<= 8;
	    xormask[i] += highbyte;
	}
    } else {
	for (i = 0; i < 32; i += 2) {
	    xormask[i] = ~(xormask[i] | andmask[i]);
	}
    }
}

Cursor::Cursor (Bitmap* p, Bitmap* m, Color* fg, Color* bg) {
    int bitmap_pattern[16];
    int bitmap_mask[16];
    unsigned andmask[64];
    unsigned xormask[64];

    GetBitmapBits((HBITMAP)p->Map(), 32, (LPSTR)bitmap_pattern);
    GetBitmapBits((HBITMAP)m->Map(), 32, (LPSTR)bitmap_mask);

    x = -p->Left();
    y = p->Height() -1 -(-p->Bottom());
    foreground = fg;
    background = bg;

    MakeWinFormat(
	bitmap_pattern, bitmap_mask, andmask, xormask, true
    );

    id = (void*)CreateCursor(
		    _world->hinstance(), x, y, 32, 32,
		    (LPSTR)andmask, (LPSTR)xormask
		);
    is_stock_cursor = false;
}

Cursor::Cursor (Font* font, int pattern, int mask, Color* fg, Color* bg) {
    Bitmap* p = new Bitmap(font, pattern);
    Bitmap* m = new Bitmap(font, mask);

    Cursor(p, m, fg, bg);

    delete p;
    delete m;
    is_stock_cursor = false;
}

Cursor::Cursor (long int c, Color* fg, Color* bg) {
    id = (void*)LoadCursor(NULL, MAKEINTRESOURCE(c));
    is_stock_cursor = true;
}

void* Cursor::Id () {
    if (id == nil && pat != nil && mask != nil) {
	unsigned andmask[64];
	unsigned xormask[64];

	MakeWinFormat(pat, mask, andmask, xormask, false);
	id = (void*)CreateCursor(
			_world->hinstance(), x, y, 32, 32,
			(LPSTR)andmask, (LPSTR)xormask
		    );
        is_stock_cursor = false;
    }
    return id;
}

Cursor::~Cursor () {
    if (id != nil && !is_stock_cursor) {
	DestroyCursor((HCURSOR)id);
    }
}

