/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * 
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: uieffect.cxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/


#include "soole.h"

namespace binfilter {

	void DrawHandle(HDC hDC, int x, int y, UINT cSize, BOOL fInvert
	, BOOL fDraw);

//Hatch pattern brush bits
static WORD g_wHatchBmp[]={0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88};


/*
 * UIDrawHandles
 *
 * Purpose:
 *  Draw handles or/and boundary around Container Object when selected
 *
 * Parameters:
 *  pRect           Dimensions of Container Object
 *  hDC             HDC of the site
 *  dwFlags         DWORD specifying how to draw the handles.
 *  cSize           UINT size of handle box
 *  fDraw           BOOL draw if TRUE, erase if FALSE
 *
 * Return Value:
 *  None
 */

STDAPI_(void) UIDrawHandles(LPRECT pRect, HDC hDC, DWORD dwFlags, UINT cSize
	, BOOL fDraw)
	{
	HBRUSH  hBR;
	RECT    rc;
	int     bkmodeOld;
	BOOL    fInvert=(BOOL)(dwFlags & UI_HANDLES_USEINVERSE);

	CopyRect((LPRECT)&rc, pRect);

	bkmodeOld=SetBkMode(hDC, TRANSPARENT);

	if (dwFlags & UI_HANDLES_OUTSIDE)
		InflateRect((LPRECT)&rc, cSize - 1, cSize - 1);

	//Draw the handles inside the rectangle boundary
	DrawHandle(hDC, rc.left, rc.top, cSize, fInvert, fDraw);
	DrawHandle(hDC, rc.left, rc.top+(rc.bottom-rc.top-cSize)/2, cSize, fInvert, fDraw);
	DrawHandle(hDC, rc.left, rc.bottom-cSize, cSize, fInvert, fDraw);
	DrawHandle(hDC, rc.left+(rc.right-rc.left-cSize)/2, rc.top, cSize, fInvert, fDraw);
	DrawHandle(hDC, rc.left+(rc.right-rc.left-cSize)/2, rc.bottom-cSize, cSize, fInvert, fDraw);
	DrawHandle(hDC, rc.right-cSize, rc.top, cSize, fInvert, fDraw);
	DrawHandle(hDC, rc.right-cSize, rc.top+(rc.bottom-rc.top-cSize)/2, cSize, fInvert, fDraw);
	DrawHandle(hDC, rc.right-cSize, rc.bottom-cSize, cSize, fInvert, fDraw);

	if (!(dwFlags & UI_HANDLES_NOBORDER))
		{
		if (fDraw)
			hBR=(HBRUSH)GetStockObject(BLACK_BRUSH);
		else
			hBR=(HBRUSH)GetStockObject(WHITE_BRUSH);

		FrameRect(hDC, pRect, hBR);
		}

	SetBkMode(hDC, bkmodeOld);
	}



/*
 * DrawHandle
 *
 * Purpose:
 *  Draw a handle box at the specified coordinate
 *
 * Parameters:
 *  hDC             HDC to be drawn into
 *  x, y            int upper left corner coordinate of the handle box
 *  cSize           UINT size of handle box
 *  fInvert         BOOL indicating to invert the rect or fill it
 *  fDraw           BOOL draw if TRUE, erase if FALSE,
 *                  ignored if fInvert is TRUE
 *
 * Return Value:
 *  None
 */

void DrawHandle(HDC hDC, int x, int y, UINT cSize, BOOL fInvert
	, BOOL fDraw)
	{
	HBRUSH  hBR;
	HBRUSH  hBROld;
	HPEN    hPen;
	HPEN    hPenOld;
	RECT    rc;

	if (!fInvert)
		{
		if (fDraw)
			{
			hPen=(HPEN)GetStockObject(BLACK_PEN);
			hBR=(HBRUSH)GetStockObject(BLACK_BRUSH);
			}
		else
			{
			hPen=(HPEN)GetStockObject(WHITE_PEN);
			hBR=(HBRUSH)GetStockObject(WHITE_PEN);
			}

		hPenOld=(HPEN)SelectObject(hDC, hPen);
		hBROld=(HBRUSH)SelectObject(hDC, hBR);
		Rectangle(hDC, x, y, x+cSize, y+cSize);
		SelectObject(hDC, hPenOld);
		SelectObject(hDC, hBROld);
		}
	else
		{
		rc.left=x;
		rc.top=y;
		rc.right=x + cSize;
		rc.bottom=y + cSize;
		InvertRect(hDC, (LPRECT)&rc);
		}

	return;
	}



/*
 * UIDrawShading
 *
 * Purpose:
 *  Draw a hatching across a rectangle, inside a rectangle, or
 *  outside a rectangle.
 *
 * Parameters:
 *  prc             LPRECT containing the rectangle.
 *  hDC             HDC on which to draw.
 *  dwFlags         DWORD specifying how to draw the shading.
 *  cWidth          UINT width of the border to draw.  Ignored
 *                  if dwFlags has UI_SHADE_FULLRECT.
 *
 * Return Value:
 *  None
 */

STDAPI_(void) UIDrawShading(LPRECT prc, HDC hDC, DWORD dwFlags, UINT cWidth)
	{
	HBRUSH      hBR;
	HBRUSH      hBROld;
	HBITMAP     hBM;
	RECT        rc;
	UINT        cx, cy;
	COLORREF    crText;
	COLORREF    crBk;
	const DWORD dwROP=0x00A000C9L;  //DPa

	if (NULL==prc || NULL==hDC)
		return;

	hBM=CreateBitmap(8, 8, 1, 1, g_wHatchBmp);
	hBR=CreatePatternBrush(hBM);
	hBROld=(HBRUSH)SelectObject(hDC, hBR);

	rc=*prc;
	cx=rc.right-rc.left;
	cy=rc.bottom-rc.top;

	if (UI_SHADE_FULLRECT==dwFlags)
		{
		crText=SetTextColor(hDC, RGB(255, 255, 255));
		crBk=SetBkColor(hDC, RGB(0, 0, 0));
		PatBlt(hDC, rc.left, rc.top, cx, cy, dwROP);
		}
	else
		{
		if (UI_SHADE_BORDEROUT==dwFlags)
			InflateRect((LPRECT)&rc, cWidth-1, cWidth-1);

		crText=SetTextColor(hDC, RGB(255, 255, 255));
		crBk=SetBkColor(hDC, RGB(0, 0, 0));
		PatBlt(hDC, rc.left, rc.top, cx, cWidth, dwROP);
		PatBlt(hDC, rc.left, rc.top, cWidth, cy, dwROP);
		PatBlt(hDC, rc.right-cWidth, rc.top, cWidth, cy, dwROP);
		PatBlt(hDC, rc.left, rc.bottom-cWidth, cx, cWidth, dwROP);
		}

	SetTextColor(hDC, crText);
	SetBkColor(hDC, crBk);
	SelectObject(hDC, hBROld);
	DeleteObject(hBR);
	DeleteObject(hBM);

	return;
	}




/*
 * UIShowObject
 *
 * Purpose:
 *  Draw the ShowObject effect around an embedded or linked
 *  object.
 *
 * Parameters:
 *  prc             LPRECT to draw around.
 *  hDC             HDC on which to draw.
 *  fLink           BOOL specifying a linked (TRUE) or
 *                  embedded (FALSE) object
 *
 * Return Value:
 *  None
 */

STDAPI_(void) UIShowObject(LPCRECT prc, HDC hDC, BOOL fLink)
	{
	HPEN    hPen;
	HPEN    hPenOld;
	HBRUSH  hBROld;

	if (NULL==prc || NULL==hDC)
		return;

	hPen=fLink ? CreatePen(PS_DASH, 1, RGB(0,0,0))
		: (HPEN)GetStockObject(BLACK_PEN);

	if (!hPen)
		return;

	hPenOld=(HPEN)SelectObject(hDC, hPen);
	hBROld=(HBRUSH)SelectObject(hDC, GetStockObject(NULL_BRUSH));

	Rectangle(hDC, prc->left, prc->top, prc->right, prc->bottom);

	SelectObject(hDC, hPenOld);
	SelectObject(hDC, hBROld);

	if (fLink)
		DeleteObject(hPen);

	return;
	}
}
