/**********************************************************************

	Copyright (C) 2003-2004
	Hirohisa MORI <joshua@nichibun.ac.jp>
	Tomohito Nakajima <nakajima@zeta.co.jp>
	Tomoki Sekiyama <sekiyama@yahoo.co.jp>

	This program is free software; you can redistribute it
	and/or modify it under the terms of the GLOBALBASE
	Library General Public License (G-LGPL) as published by

	http://www.globalbase.org/

	This program 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.

**********************************************************************/


#include "v/VAlignView.h"
#include "machine/gb_windows.h"
#include "VApplication.h"
#include "vwin_error.h"

extern "C" int is_theme_active();
extern "C" HRESULT enable_theme_dialog_texture(HWND hwnd, DWORD dwFlags);


class VTabPageInfo : public VContainerInfo
{
public:
	VTabPageInfo(VObject *o, HWND h, int id) : VContainerInfo(o,h,id,0,1,1),hBrush(NULL) {}
	static BOOL CALLBACK TabPageProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
protected:
	virtual LRESULT dispatch_message(MSG *msg);
	void	update_bkgnd_brush();
private:
	HBRUSH hBrush;
	BOOL isDirty;
};

BOOL CALLBACK VTabPageInfo::TabPageProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	extern DWORD current_time;
	VTabPageInfo *info = dynamic_cast<VTabPageInfo *>(VInfo::get_from_hwnd(hWnd));
	if(!info)
		return FALSE;
	MSG msg;
	memset(&msg, 0, sizeof(msg));
	msg.hwnd = hWnd;
	msg.message = message;
	msg.lParam = lParam;
	msg.wParam = wParam;
	msg.time = current_time;

	return info->dispatch_message(&msg);
}

LRESULT
VTabPageInfo::dispatch_message(MSG *msg)
{
	RECT rc;

	switch ( msg->message ) {
	case WM_INITDIALOG:
	case WM_SIZE:
		isDirty = TRUE;
		break;
	case WM_DESTROY:
		if ( hBrush )
			DeleteObject(hBrush);
		hBrush = NULL;
		break;
	case WM_CTLCOLORSTATIC:
		int f;
		f = is_theme_active();
		if ( ! f ) {
			VContainerInfo *parent;
			parent = dynamic_cast<VContainerInfo*>(
					get_from_hwnd(GetParent(get_hwnd())));
			while ( parent && parent->get_bkgnd_parent() )
				parent = dynamic_cast<VContainerInfo*>(
					get_from_hwnd(GetParent(parent->get_hwnd())));
			if ( parent ) {
				msg->hwnd = parent->get_hwnd();
				return SendMessage(msg->hwnd, msg->message, msg->wParam, msg->lParam);
			}
			break;
		}
		
		if ( isDirty ) {
			update_bkgnd_brush();
			isDirty = FALSE;
		}

		::SetBkMode((HDC)(msg->wParam), TRANSPARENT);

		::GetWindowRect((HWND)(msg->lParam), &rc);
		::MapWindowPoints(NULL, get_hwnd(), (LPPOINT)(&rc), 2);
		// Adjust the position of the brush for this control
		::SetBrushOrgEx((HDC)(msg->wParam), -rc.left, -rc.top, NULL);

		return (LRESULT)hBrush;
	}
	return VContainerInfo::dispatch_message(msg);
}

void
VTabPageInfo::update_bkgnd_brush()
{
	if ( hBrush )
		DeleteObject(hBrush);
	hBrush = NULL;

	if ( ! is_theme_active() )
		return;

	RECT rc;

	GetWindowRect(get_hwnd(), &rc);
	HDC hDC = GetDC(get_hwnd());

	// Create a compatible DC
	HDC hDCMem = ::CreateCompatibleDC(hDC);
	HBITMAP hBmp = ::CreateCompatibleBitmap(hDC, 
		rc.right - rc.left, rc.bottom - rc.top);
	HBITMAP hBmpOld = (HBITMAP)(::SelectObject(hDCMem, hBmp));

	// Tell the tab control to paint in our DC
	SendMessage(get_hwnd(), WM_PRINTCLIENT, (WPARAM)(hDCMem), 
	   (LPARAM)(PRF_ERASEBKGND | PRF_CLIENT | PRF_NONCLIENT));

	// Create a pattern brush from the bitmap selected in our DC
	hBrush = ::CreatePatternBrush(hBmp);

	// Restore the bitmap
	::SelectObject(hDCMem, hBmpOld);

	// Cleanup
	::DeleteObject(hBmp);
	::DeleteDC(hDCMem);
	ReleaseDC(get_hwnd(), hDC);
}


static HWND v_create_tabpage_dialog(DWORD style, HWND parent)
{
	struct {
		DLGTEMPLATE	h;
		USHORT		menu;
		USHORT		cls;
		USHORT		title;
	} tmp;
	tmp.h.style = style;
	tmp.h.dwExtendedStyle = 0;
	tmp.h.cdit = 0;
	tmp.h.x = 0;
	tmp.h.y = 0;
	tmp.h.cx = 10;
	tmp.h.cy = 10;
	tmp.menu = 0;
	tmp.cls = 0;
	tmp.title = 0;
	return CreateDialogIndirect(GetModuleHandle(NULL),
		(DLGTEMPLATE*)&tmp, parent, VTabPageInfo::TabPageProc);
}

VInfo* make_TabPageDialog(
	const VObjectStatus *s, VObject* obj, VContainerInfo *parent_info, int id)
{
	DWORD style=WS_CHILD|DS_CONTROL;
	if(!s->enabled)
		style |= WS_DISABLED;
	if(s->visible)
		style |= WS_VISIBLE;

	VContainerInfo *p;
	p = dynamic_cast<VContainerInfo*>(
			VInfo::get_from_hwnd(GetParent(parent_info->get_hwnd())));

	HWND hwnd = v_serialized_exec_func(v_create_tabpage_dialog, style, p->get_hwnd());
	v_serialized_exec_sub(enable_theme_dialog_texture, hwnd, 6/*ETDT_ENABLETAB*/);
	VTabPageInfo *info = new VTabPageInfo(obj, hwnd, id);
	if(info->get_hwnd()==NULL){
		VWinError();
		er_panic("make_AlignView");
	}

	return info;
}
