/**********************************************************************
 
	Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.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	<windows.h>
#include	<ddeml.h>
#include	<stdio.h>
#include	"v.h"
#include	"gbview.h"
#include	"machine/param_gbview.h"
#include	"machine/msequence.h"
#include	"pri_level.h"

#define min(a, b)  (((a) < (b)) ? (a) : (b)) 

static VDISPLAY *vd;
extern GBVIEW_ENV env;
static int IsFirstTime;
static int IsCaptured;
static int IsMouseMove;

extern void _redraw(VWINDOW * win,int x,int y,int w,int h);
extern void _button(VWINDOW * win,int subtype,int t,int x,int y);

void new_v_loop(VDISPLAY * d)
//void new_v_loop(TKEY tk)
{
	MSG msg;
//	VWINDOW* win;
//	HDC hdc;
//	RECT rt;
//	VDISPLAY *d;

//	d = (VDISPLAY*)GET_TKEY(tk);
	SetWindowLong(NULL, GWL_USERDATA, (int)d);
	while( GetMessage(&msg, NULL, 0, 0) ) 
	{
		vd = d;
		if( msg.message == MYMSG_INVRECT )
		{
			InvalidateRect(ghWnd,NULL,FALSE);
			PostMessage(ghWnd, WM_PAINT, 0, 0);
			continue;
		}

		TranslateMessage( &msg );
		DispatchMessage( &msg );
	}
}

void v_loop(VDISPLAY *d){
	create_task(ms_loop,0,PRI_USER_INTERFACE);
	new_v_loop(d);
	/*
	create_task(new_v_loop,(int)d,PRI_USER_INTERFACE);
	ms_loop();
	*/
}

HDDEDATA CALLBACK ddeCallBackFunc(
  UINT uType,     // トランザクション型
  UINT uFmt,      // クリップボードデータ形式
  HCONV hconv,    // 対話のハンドル
  HSZ hsz1,       // 文字列のハンドル
  HSZ hsz2,       // 文字列のハンドル
  HDDEDATA hdata, // グローバルメモリオブジェクトのハンドル
  DWORD dwData1,  // トランザクション固有データ
  DWORD dwData2   // トランザクション固有データ
  ){
	return (HDDEDATA)0;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	HDC hdc;
	RECT rt;
	int xPos,yPos;
	VWINDOW *win;

	switch( message ) 
	{
		case WM_PAINT:

			hdc = BeginPaint(hWnd, &ps);
			if(IsFirstTime)
			{
				// Sleep(2000);
				win = _get_vwin(vd,hWnd);
				if(env.flame_base)
					_redraw(win,ps.rcPaint.left,ps.rcPaint.top,ps.rcPaint.right-ps.rcPaint.left,ps.rcPaint.bottom-ps.rcPaint.top);
				IsFirstTime = 0;
			}
			BitBlt(hdc, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom, ghBufferDC, ps.rcPaint.left, ps.rcPaint.top, SRCCOPY);
			EndPaint( hWnd, &ps );
			break;

		case WM_LBUTTONDOWN:
			SetCapture(hWnd);
			IsCaptured  = 1;

			xPos = LOWORD(lParam);
			yPos = HIWORD(lParam); 
			IsMouseMove = 0;
			win = _get_vwin(vd,hWnd);
			if (win) 
			{
				hdc = GetDC(hWnd);
				win->gc = hdc;
				_button(win,VES_BUTTON_PRESS,1/*time*/,xPos,yPos);
				win->gc = NULL;
				ReleaseDC(hWnd,hdc);
			}
			break;

		case WM_LBUTTONUP:
			ReleaseCapture();
			IsCaptured = 0;

			xPos = LOWORD(lParam);
			yPos = HIWORD(lParam);
			win = _get_vwin(vd,hWnd);
			if (win)
			{
				if(IsMouseMove)
					_button(win,VES_BUTTON_RELEASE,10000/*time*/,xPos,yPos);
				else
					_button(win,VES_BUTTON_RELEASE,1/*time*/,xPos,yPos);
			}
			IsMouseMove = 0;
			break;

		case WM_MOUSEMOVE:
			IsMouseMove = 1;
			xPos = LOWORD(lParam);
			yPos = HIWORD(lParam);  
			win = _get_vwin(vd,hWnd);
			if (win) 
			{
				VOBJECT *obj;
				hdc = GetDC(hWnd);
				win->gc = hdc;
				_button(win,VES_BUTTON_MOTION,1,xPos,yPos);
				GetClientRect(hWnd,&rt);
				for ( obj = win->obj_list ; obj ; obj = obj->header.next )
				{
					if(obj->header.type == 2)
						(*obj->header.handler)(obj,VE_REDRAW,rt.left,rt.top,rt.right-rt.left,rt.bottom-rt.top);
				}
				BitBlt(hdc,rt.left,rt.top,rt.right,rt.bottom, ghBufferDC,rt.left,rt.top, SRCCOPY);
				win->gc = NULL;	
				ReleaseDC(hWnd,hdc);
			}	

			break;

		case WM_DESTROY:
			{
				DeleteObject(SelectObject(ghBufferDC,ghBufferImageOld));
				DeleteDC(ghBufferDC);

				PostQuitMessage( 0 );
			}
			break;

		case WM_CREATE:
			{
				hdc = GetDC(hWnd);
				ghBufferDC = CreateCompatibleDC(hdc);
				ghBufferImage = CreateCompatibleBitmap(GetDC(hWnd),GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN));
				ghBufferImageOld = SelectObject(ghBufferDC,ghBufferImage);

				ReleaseDC(hWnd,hdc);

				IsFirstTime = 1;
				IsCaptured = 0;
			}
			break;

		case WM_SIZE:
			if(!IsFirstTime)
			{
				win = _get_vwin(vd,hWnd);
				if(win)
				{
					int w = LOWORD(lParam);
					int h = HIWORD(lParam);
					int ow = env.win_width;
					int oh = env.win_height;
					/*
					GetWindowRect(hWnd,&rt);
					if(w < W_OFS)
					{
						w = W_OFS + 100;
						MoveWindow(hWnd,rt.left,rt.top,w,h,FALSE);
					}
					if(h < H_OFS+Z_BOTTOM_MARGIN+Z_TEXT_HEIGHT*6+Z_MARGIN*5)
					{
						h = H_OFS+Z_BOTTOM_MARGIN+Z_TEXT_HEIGHT*6+Z_MARGIN*5;
						MoveWindow(hWnd,rt.left,rt.top,w,h,FALSE);
					}
					*/
					
					//hdc = GetDC(hWnd);
					//win->gc = hdc;
					//BitBlt(hdc,0,0,w,h,ghBufferDC,0,0,SRCCOPY);
					//PatBlt(ghBufferDC,w-W_OFS,h-H_OFS,W_OFS,H_OFS,BLACKNESS);
					//たての黒
					//PatBlt(ghBufferDC,w-W_OFS,0,W_OFS,h,BLACKNESS);
					//横の黒
					//PatBlt(ghBufferDC,0,h-H_OFS,w,H_OFS,BLACKNESS);
//					if(env.flame_base)
						_redraw(win,0,0,w,h);
					//PatBlt(ghBufferDC,0,0,w,h,BLACKNESS);
					//BitBlt(hdc,0,0,w,h,ghBufferDC,0,0,SRCCOPY);
					//win->gc = NULL;
					//ReleaseDC(hWnd,hdc);
				}
			}
			break;
			
		default:
			return DefWindowProc( hWnd, message, wParam, lParam );
   }
   return 0;
}
