/*
 * GraphApp - Cross-Platform Graphics Programming Library.
 *
 * File: context.c -- internal functions for manipulating DCs.
 * Platform: Windows  Version: 2.35  Date: 1998/04/04
 *
 * Version: 1.00  Changes: Original version by Lachlan Patrick.
 * Version: 1.05  Changes: Added drawstate information.
 * Version: 1.50  Changes: New colour system, dithered grey.
 * Version: 2.00  Changes: New object class and context sub-system.
 * Version: 2.01  Changes: get_context is now more bulletproof.
 * Version: 2.02  Changes: drawto and setwinrgb have been updated.
 * Version: 2.20  Changes: Added currentrgb, currentfont etc.
 * Version: 2.35  Changes: New reference count technique.
 */

/* Copyright (C) 1993-1998 Lachlan Patrick

   This file is part of GraphApp, a cross-platform C graphics library.

   GraphApp is free software; you can redistribute it and/or modify it
   under the terms of the GNU Library General Public License.
   GraphApp is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY.

   See the file COPYLIB.TXT for details.
*/

/* Copyright (C) 2004	The R Foundation

      Changes for R:  allow 32 contexts not 4
      Remove assumption that current->dest is non-NULL
*/

#include "internal.h"

/*
 *  Private library variables.
 */

PROTECTED drawstruct app_drawstate =
{
    NULL,	/* drawing destination */
    Black,	/* colour */
    S,	/* drawing mode */
    {0,0},	/* point */
    1,	/* line width */
    NULL,	/* font */
    NULL,	/* cursor */
};

PROTECTED drawstate current = & app_drawstate;
PROTECTED HDC       dc;	/* shared DC variable */
PROTECTED HPEN      the_pen   = 0;
PROTECTED HBRUSH    the_brush = 0;

PROTECTED COLORREF win_rgb  = 0L;

/*
 *  Private drawing context variables.
 */

static	rgb	prev_pixval	= Black;
static	int	prev_width	= 1;

static	bitmap	grey_bitmap	= NULL;

static rgb grey_cmap [] = {
    0x00000000UL,
    0x00FFFFFFUL,
};
static byte grey_pixels [] = {
    0, 1, 0, 1, 0, 1, 0, 1,
    1, 0, 1, 0, 1, 0, 1, 0,
    0, 1, 0, 1, 0, 1, 0, 1,
    1, 0, 1, 0, 1, 0, 1, 0,
    0, 1, 0, 1, 0, 1, 0, 1,
    1, 0, 1, 0, 1, 0, 1, 0,
    0, 1, 0, 1, 0, 1, 0, 1,
    1, 0, 1, 0, 1, 0, 1, 0,
};
static imagedata grey_imagedata = {
    8,	/* depth */
    8,	/* width */
    8,	/* height */
    2,	/* cmapsize */
    grey_cmap,
    grey_pixels
};
static image grey_image = & grey_imagedata;

/*
 *  Private context list structure
 */
typedef struct contextinfo  contextinfo;

struct contextinfo
{
    object	obj;	/* back pointer to drawing object */
    HDC	dc;	/* handle to DC used when drawing */
    HGDIOBJ old_bitmap; /* bitmap returned by SelectObject() */
};

/*
 *  The constant MAX_CONTEXTS controls how large the
 *  circular array of contexts is, and thus how many
 *  concurrently active contexts there can be.  This
 *  number should be at least 2,  since bitblt needs
 *  two contexts for source and destination bitmaps.
 */
#define MAX_CONTEXTS 32

static contextinfo context[MAX_CONTEXTS];
static int num_contexts = 0;
static int empty_slot = 0;

/*
 *  Create a pen and a brush for use in drawing.
 */
static void create_pen_and_brush(rgb c, unsigned long winrgb,
		int width, int depth)
{
    the_pen = CreatePen(PS_INSIDEFRAME, width, winrgb);

    if ((depth == 1) && (c == Grey))
	the_brush = CreatePatternBrush(grey_bitmap->handle);
    else
	the_brush = CreateSolidBrush(winrgb);
}

/*
 *  Delete any created pens and brushes.
 *  Assumes they are not selected into any valid DC.
 */
static void delete_pen_and_brush(void)
{
    DeleteObject(the_pen);
    DeleteObject(the_brush);
}

/*
 *  Set Windows drawing globals up.
 */
PROTECTED
void init_contexts(void)
{
    grey_bitmap = imagetobitmap(grey_image);
    grey_bitmap->text = new_string("grey_bitmap");

    current = & app_drawstate;
    app_drawstate.fnt = SystemFont;
    app_drawstate.crsr = ArrowCursor;

    create_pen_and_brush(Black, Black, 1, 0);
}

static void free_context(contextinfo *c)
{
    if (! c->dc)
	return; /* already been deleted */

    SelectObject(c->dc, GetStockObject(NULL_PEN));
    SelectObject(c->dc, GetStockObject(NULL_BRUSH));

    if (c->obj->kind & ControlObject)
	ReleaseDC(c->obj->handle, c->dc);
    else if (c->obj->kind == BitmapObject) {
	SelectObject(c->dc, c->old_bitmap);
	DeleteDC(c->dc);
    }

    if (dc == c->dc)
	dc = 0;

    c->dc = 0;
    c->obj = NULL;
    c->old_bitmap = 0;
}

/*
 *  Add a new DC into our list of DCs.  This is kind of ugly:  num_contexts just keeps growing, unless
 *  del_all_contexts is called, when it is set to 0.  The free ones will be scattered through the list.
 */
PROTECTED
void add_context(object obj, HDC dc, HGDIOBJ old)
{
    contextinfo *c;

    /* Search for or clear a spot for the new DC if the array is full. */
    if (num_contexts == MAX_CONTEXTS) {
        int i = empty_slot;
        while ( context[i].dc ) {
             i = (i+1) % MAX_CONTEXTS;
             if (i == empty_slot) {
		 free_context(&context[i]);
		 break;
	     }
	}
        c = & context[i];
	empty_slot = (i+1) % MAX_CONTEXTS;
    } else {
	c = & context[num_contexts];
	num_contexts++;
    }
    /* Add this context to the list. */
    c->obj = obj;
    c->dc = dc;
    c->old_bitmap = old;
}

/*
 *  Find and return a DC for a window or a bitmap.
 *  Also keep track of which DCs have been created.
 */
PROTECTED
HDC get_context(object obj)
{
    int i;
    HDC dc;
    HGDIOBJ old;

    /* Determine if a DC for this object already exists. */
    for (i = 0; i < num_contexts; i++) {
	if (context[i].obj == obj)
	    return context[i].dc;
    }

    /* Use GetDC or CreateCompatibleDC to return a DC. */
    if (obj->kind & ControlObject) {
	dc = GetDC(obj->handle);
	add_context(obj, dc, 0);
    }
    else if (obj->kind == BitmapObject) {
	dc = CreateCompatibleDC(0);
	old = SelectObject(dc, obj->handle);
	add_context(obj, dc, old);
    }
    else {
	return NULL;
	/* apperror("Cannot find DC for non-drawable object."); */
    }

    /* We only select in the brush or pen we need, when we
     * need it. Thus at all other times, they are NULL.
     * This ensures we can delete objects when we want, and
     * also makes correct context possible. */
    SelectObject(dc, GetStockObject(NULL_PEN));
    SelectObject(dc, GetStockObject(NULL_BRUSH));

    return dc;
}

/*
 *  Remove the context from the list by blanking its fields.
 *  It is assumed that the DC has previously been released,
 *  for example by EndPaint() in the events.c file.
 */
PROTECTED
void remove_context(object obj)
{
    int i;
    contextinfo *c;

    for (i = 0; i < num_contexts; i++) {
	c = & context[i];
	if (c->obj == obj) {
	    c->obj = NULL;
	    c->dc = 0;
	    c->old_bitmap = 0;
	    /* If we delete the last one, reduce the count:  avoid 
	       a search next time. */
	    if (i == num_contexts - 1)
	    	num_contexts--;
	    else
	    	empty_slot = i;
	}
    }
}

/*
 *  Free the DC associated with a given object.
 */
PROTECTED
void del_context(object obj)
{
    int i;
    contextinfo *c;

    for (i = 0; i < num_contexts; i++) {
	c = & context[i];
	if (c->obj == obj) {
	    free_context(c);
	    c->obj = NULL;
	    c->dc = 0;
	    c->old_bitmap = 0;
	    /* If we delete the last one, reduce the count:  avoid 
	       a search next time. */
	    if (i == num_contexts - 1)
	    	num_contexts--;
	    else
	    	empty_slot = i;

	}
    }
}

/*
 *  Get rid of all DCs.
 */
PROTECTED
void del_all_contexts(void)
{
    int i;
    contextinfo *c;

    for (i = 0; i < num_contexts; i++) {
	c = & context[i];
	free_context(c);
	c->obj = NULL;
	c->dc = 0;
	c->old_bitmap = 0;
    }
    num_contexts = 0;
    empty_slot = 0;
}

/*
 *  De-initialise drawing variables.
 */
PROTECTED
void finish_contexts(void)
{
    del_all_contexts();
    DeleteObject(the_pen);
    DeleteObject(the_brush);
}

/*
 *  Set up a pen and a brush for use in colouring things, and return
 *  the Windows RGB value equivalent to the library rgb value.
 */
static unsigned long set_win_rgb(rgb c, int width)
{
    int r, g, b;
    long luminance;
    int depth;
    unsigned long winrgb;

    if (current->mode == Ones)
	c = White;
    else if (current->mode == Zeros)
	c = Black;

    r = (int) ((c >> 16) & 0x000000FFL);
    g = (int) ((c >>  8) & 0x000000FFL);
    b = (int) ((c >>  0) & 0x000000FFL);

    if (current->dest) depth = getdepth(current->dest);
    else depth = 2;  /* set default minimal depth if no current window */

    if (depth <= 2)	/* map to black or white, or grey if c == Grey */
    {
	luminance = (r*3 + g*5 + b) / 9;
	if (luminance > 0x0087)		r = g = b = 0x00FF;
	else if (luminance <= 0x0077)	r = g = b = 0x0000;
	else				r = g = b = 0x0080;
	c = rgb(r,g,b);
    }

    winrgb = RGB(r, g, b);

    /* Has a colour or width change occured? */
    if ((c != prev_pixval) || (width != prev_width))
    {
	prev_pixval = c;
	prev_width = width;

	/* delete any old objects */
	delete_pen_and_brush();

	/* set up new objects */
	create_pen_and_brush(c, winrgb, width, depth);
    }
    return winrgb;
}

void setcursor(cursor c)
{
    decrease_refcount(current->crsr);
    current->crsr = c;
    if (c) SetCursor((HCURSOR) c->handle);
    increase_refcount(c);
}

void setfont(font f)
{
    decrease_refcount(current->fnt);
    current->fnt = f;
    increase_refcount(f);
}

/*
 *  Set the way that source and destination pixels are combined
 *  when drawing.
 */
void setdrawmode(int mode)
{
    current->mode = mode & 0x0F; /* must be between 0x00 and 0x0F */
}

/*
 *  Set the colour.
 */
void setrgb(rgb hue)
{
    current->hue = hue;
    win_rgb = set_win_rgb(hue, current->linewidth);
}

/*
 *  Set the line width.
 */
void setlinewidth(int width)
{
    if (width < 1)
	width = 1;
    current->linewidth = width;
    win_rgb = set_win_rgb(current->hue, current->linewidth);
}

/*
 *  Set which window/menubar/menu to add new objects too.
 */
void addto(object obj)
{
    if (! obj)
	return;
    switch (obj->kind) {
    case WindowObject:	current_window = obj;	break;
    case MenubarObject:	current_menubar = obj;	break;
    case MenuObject:	current_menu = obj;	break;
    }
}

/*
 *  Set which bitmap or window to draw to; allocate a DC too.
 */
void drawto(drawing d)
{
    if (! d) {
	current = & app_drawstate;
	current->dest = NULL;
	return;
    }

    dc = get_context(d);

    if (d->drawstate) {
	/* Change the current drawing state to this one. */
	current = d->drawstate;
	current->dest = d;
	win_rgb = set_win_rgb(current->hue, current->linewidth);
    }
    else {
	/* Otherwise just use the current drawing state. */
	current->dest = d;
    }
}

/*
 *  Ensure drawing variables are set up.
 */
void setdrawstate(drawstate s)
{
    if (! s)
	return;
    moveto(s->p);
    setdrawmode(s->mode);
    setcursor(s->crsr);
    setfont(s->fnt);
    setlinewidth(s->linewidth);
    setrgb(s->hue);
}

/*
 *  Change the current drawstate to the specified one.
 */
void restoredrawstate(drawstate s)
{
    if (! s)
	return;
    setdrawstate(s);
    discard(s);
}

/*
 *  Reset drawing variables to initial values.
 */
void resetdrawstate(void)
{
    setrgb(Black);
    setlinewidth(1);
    setcursor(ArrowCursor);
    moveto(pt(0,0));
    setfont(SystemFont);
    setdrawmode(S);
}

/*
 *  Return a new copy of the current drawing state.
 */
drawstate copydrawstate(void)
{
    drawstate s = NULL;

    if (current) {
	s = create(drawstruct);
	if (s)
	    *s = *current;
    }
    return s;
}

/*
 *  Return drawing state information.
 */

drawing	currentdrawing(void)    { return current->dest; }
rgb	currentrgb(void)        { return current->hue; }
int	currentmode(void)       { return current->mode; }
point	currentpoint(void)      { return current->p; }
int	currentlinewidth(void)  { return current->linewidth; }
font	currentfont(void)       { return current->fnt; }
cursor	currentcursor(void)     { return current->crsr; }

int	getkeystate(void)       { return keystate; }
