#include <Interviews\X11\painterrep.h>
#include <InterViews\X11\palette.h>

PainterRep::PainterRep() {
    foreground = nil;
    background = nil;
    font = nil;
    pattern = solid;
    fillbg = true;
    xor = false;
    fill_next_primitive = false;
    clip = false;
    holdBrush = NULL;
    holdPen = NULL;
    holdFont = NULL;
    holdRgn = NULL;
    hBrush = NULL;
    hFont = NULL;
    hRgn = NULL;
};

PainterRep::~PainterRep() {
    if (hRgn != NULL) {
	 DeleteObject(hRgn);
    }
};

void PainterRep::Copy (PainterRep* copy) {
    foreground = copy->foreground;
    background = copy->background;
    font = copy->font;
    pattern = copy->pattern;
    clip_rect = copy->clip_rect;
    hRgn = CreateRectRgn(
	       clip_rect.left,
	       clip_rect.bottom,
	       clip_rect.right,
	       clip_rect.top
	   );
    fillbg = copy->fillbg;
    xor = copy->xor;
    clip = copy->clip;
}

void PainterRep::Get_DC(Canvas* c) {
    hDC = GetDC((HWND)c->Id());
    SetDCAttributes(hDC);
}

void PainterRep::Release_DC(Canvas* c) {
    if (holdBrush != NULL) {
	SelectObject(hDC, holdBrush);
	holdBrush = NULL;
    }
    if (holdPen != NULL) {
	SelectObject(hDC, holdPen);
	holdPen = NULL;
    }
    if (holdFont != NULL) {
	SelectObject(hDC, holdFont);
	holdFont = NULL;
    }
    if (holdRgn != NULL) {
	SelectObject(hDC, holdRgn);
	holdRgn = NULL;
    }
    if (hBrush != NULL) {
	DeleteObject(hBrush);
	hBrush = NULL;
    }
    DeleteObject(hPen);
    ReleaseDC((HWND)c->Id(), hDC);
    fill_next_primitive = false;
}

void PainterRep::SetDCAttributes(HDC hDC) {
    COLORREF fg, bg;

    SelectPalette(hDC, _palette->GetPalette(), 0);
    RealizePalette(hDC);

    if (foreground != nil && background != nil) {
	fg = PALETTEINDEX(foreground->PixelValue());
	bg = PALETTEINDEX(background->PixelValue());
	SetBkColor(hDC, bg);
	SetTextColor (hDC, fg);
	hPen = CreatePen(PS_SOLID, 1, fg);
	holdPen = SelectObject(hDC, hPen);
    }
    if (!fillbg) {
	SetBkMode(hDC, TRANSPARENT);
    }
    holdBrush = SelectObject(hDC, GetStockObject(NULL_BRUSH));
    if (fill_next_primitive) {
	if (pattern == solid && foreground != nil) {
	    hBrush = CreateSolidBrush(fg);
	    holdBrush = SelectObject(hDC, hBrush);
	} else if (pattern != nil && pattern->info != nil) {
	    holdBrush = SelectObject(hDC, (HBRUSH)pattern->info);
	}
	SelectObject(hDC, GetStockObject(NULL_PEN));
    }
    if ((font != nil) && font->Valid()) {
	holdFont = SelectObject(hDC, (HFONT)font->Id());
    }
    if (xor) {
	SetROP2(hDC, R2_XORPEN);
	SelectObject(hDC, GetStockObject(WHITE_PEN));
    }
    if (clip) {
	holdRgn = SelectObject(hDC, hRgn);
    }
}

void PainterRep::SetClipOrigin (Coord x, Coord y) {
};

void PainterRep::SetClipRectangle (
    Coord left, Coord bottom, Coord right, Coord top
) {
    clip_rect.left = left;
    clip_rect.bottom = bottom;
    clip_rect.right = right + 1;
    clip_rect.top = top + 1;
    if (hRgn != NULL) {
	DeleteObject(hRgn);
    }
    hRgn = CreateRectRgn(
	clip_rect.left, clip_rect.bottom, clip_rect.right, clip_rect.top
    );
    clip = true;
};

void PainterRep::SetClipAll () {
    if (hRgn != NULL) {
	DeleteObject(hRgn);
	hRgn = NULL;
    }
    clip = false;
}
