#include "stdafx.h"
#include "resource.h"

#include "apl_gui.h"
//#include <Windowsx.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CaplToolTip
LPCTSTR CaplToolTip::m_pszWndClass=NULL;

CaplToolTip::CaplToolTip()
{
	m_pFontWnd=0;
	//m_pParentWnd=0;
	m_pFont=0;

	m_iMaxWidth=0;

	m_txt_color=::GetSysColor(COLOR_INFOTEXT);
	m_fon_color=::GetSysColor(COLOR_INFOBK);

	m_text_x_paragr=2;
	m_text_y_paragr=0;

	m_timer_x=0; m_timer_y=0;

	m_delay_time=0;
	m_timer=0;

	if (m_pszWndClass == NULL && afxCurrentInstanceHandle != NULL)
	{
		m_pszWndClass = AfxRegisterWndClass(CS_SAVEBITS | CS_HREDRAW | CS_VREDRAW |CS_DBLCLKS );
	}
}

CaplToolTip::~CaplToolTip()
{
	if(m_tip_dc.m_hDC!=0) m_tip_dc.DeleteDC();
	if(m_tip_bmp.m_hObject!=0) m_tip_bmp.DeleteObject();
	if(m_orig_dc.m_hDC!=0) m_orig_dc.DeleteDC();
	if(m_orig_bmp.m_hObject!=0) m_orig_bmp.DeleteObject();
}


BEGIN_MESSAGE_MAP(CaplToolTip, CWnd)
	//{{AFX_MSG_MAP(CaplToolTip)
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CaplToolTip message handlers

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

/*
bool CaplToolTip::Attach(CWnd *wnd)
{
	Detach();

	m_pParentWnd=wnd;
	return true;
}

bool CaplToolTip::Detach()
{
	if(m_pParentWnd==0) return false;


	return true;
}
*/

//********************************
void CaplToolTip::CreateTip(CDC *dc, int screen_cx)
{
	if (dc==0) return;

	if (m_tip_dc.m_hDC!=0) m_tip_dc.DeleteDC();
	if (m_tip_dc.m_hAttribDC != 0) m_tip_dc.m_hAttribDC = NULL;
	
	if(m_tip_bmp.m_hObject!=0) m_tip_bmp.DeleteObject();

	m_tip_dc.CreateCompatibleDC(dc); 

	m_tip_dc.SetTextColor(m_txt_color);
	m_tip_dc.SetBkColor(m_fon_color);

	CFont *newFont=m_pFont;
	if(newFont==0) {if(m_pFontWnd!=0) newFont=m_pFontWnd->GetFont();}
	if(newFont==0)  newFont=(CFont*)CFont::FromHandle((HFONT)GetStockObject(ANSI_VAR_FONT));

	CFont *oldFont=m_tip_dc.SelectObject(newFont);

	UINT style=0;

	RECT rect,txt_rect;
	rect.left=0;
	rect.top=0;
	rect.bottom=1000;

	if(m_iMaxWidth==0) rect.right=screen_cx;
	else
	{
		rect.right=m_iMaxWidth;
		style=DT_WORDBREAK;
	}

	m_tip_dc.DrawText(m_txt,&rect,DT_CALCRECT|style);

	txt_rect=rect;

	txt_rect.top+=m_text_y_paragr+1;
	txt_rect.bottom+=(m_text_y_paragr+1)*2;
	txt_rect.left+=m_text_x_paragr+1;
	txt_rect.right+=(m_text_x_paragr+1)*2;

	rect.bottom+=m_text_y_paragr*2+3;
	rect.right+=m_text_x_paragr*2+3;

	m_cx=rect.right-rect.left;
	m_cy=rect.bottom-rect.top;
   
	m_tip_bmp.CreateCompatibleBitmap(dc, m_cx,m_cy);
	m_tip_dc.SelectObject(&m_tip_bmp);

	CBrush brushfon(m_fon_color);
	CBrush* pOldBrush = m_tip_dc.SelectObject(&brushfon);

	CPen penBlack;
	penBlack.CreatePen(PS_SOLID, 1, ::GetSysColor(COLOR_MENUTEXT));
	CPen* pOldPen = m_tip_dc.SelectObject(&penBlack);

	m_tip_dc.Rectangle(&rect);
	m_tip_dc.SelectObject(pOldBrush);
	m_tip_dc.SelectObject(pOldPen);
	brushfon.DeleteObject();
	penBlack.DeleteObject();

	m_tip_dc.DrawText(m_txt,&txt_rect,DT_LEFT|DT_WORDBREAK);

	m_tip_dc.SelectObject(oldFont);
}
//********************************
bool CaplToolTip::Show(int x, int y,LPCTSTR txt, int iMaxWidth)
{
	Hide();
	m_iMaxWidth=iMaxWidth;
	if(m_hWnd==0)
	{
		CreateEx(0, m_pszWndClass, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL);
	}
	if (m_delay_time==0) return MainShow(x,y,txt);

	m_timer_x=x;
	m_timer_y=y;
	m_timer_txt=txt;

	

	m_timer=SetTimer(12345,m_delay_time,0);
	return true;

}
//********************************
bool CaplToolTip::MainShow(int x, int y,LPCTSTR txt)
{
	if(txt==0) return false;
	if(txt[0]==_T('\0')) return false;
	
	if(m_orig_dc.m_hDC!=0) m_orig_dc.DeleteDC();
	if(m_orig_bmp.m_hObject!=0) m_orig_bmp.DeleteObject();

	CDC hdcScreen;
	hdcScreen.CreateDC(_T("DISPLAY"), NULL, NULL, NULL); 
	int scr_cx=GetDeviceCaps(hdcScreen, HORZRES);
	//	int scr_cy=GetDeviceCaps(hdcScreen, VERTRES);

	m_x=x;
	m_y=y;

	if(m_txt!=txt)
	{
		m_txt=txt;
		CreateTip(&hdcScreen,scr_cx);
	}
	if(m_x+m_cx>scr_cx)
	{
		m_x=scr_cx-m_cx;
		if(m_x<0) m_x=0;
	}

	m_orig_dc.CreateCompatibleDC(&hdcScreen); 
	m_orig_bmp.CreateCompatibleBitmap(&hdcScreen, m_cx,m_cy);
	m_orig_dc.SelectObject(&m_orig_bmp);
	m_orig_dc.BitBlt(0,0, m_cx, m_cy, &hdcScreen, m_x,m_y, SRCCOPY);

	hdcScreen.BitBlt(m_x, m_y, m_cx, m_cy, &m_tip_dc, 0,0, SRCCOPY);

	hdcScreen.DeleteDC();

	return true;
}
//********************************
void CaplToolTip::Hide()
{
	if(m_timer!=0) {KillTimer(m_timer); m_timer=0;}
	if(m_orig_dc.m_hDC!=0)
	{
		CDC hdcScreen;
		hdcScreen.CreateDC(_T("DISPLAY"), NULL, NULL, NULL); 
		hdcScreen.BitBlt(m_x,m_y, m_cx, m_cy, &m_orig_dc, 0,0, SRCCOPY);
		m_orig_dc.DeleteDC();
		if(m_orig_bmp.m_hObject!=0) m_orig_bmp.DeleteObject();
		hdcScreen.DeleteDC();
	}
}

bool CaplToolTip::IsShowed()
{
	if(m_orig_dc.m_hDC!=0) return true;
	else return false;
}

bool CaplToolTip::GetRect(RECT &rect)
{
	if(m_orig_dc.m_hDC!=0)
	{
		rect.left=m_x;
		rect.top=m_y;
		rect.right=m_x+m_cx;
		rect.bottom=m_y+m_cy;
		return true;
	}
	rect.left=-1;
	rect.top=-1;
	rect.right=-1;
	rect.bottom=-1;
	return false;
}

void CaplToolTip::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	if(nIDEvent==12345)
	{
		if(m_timer!=0) {KillTimer(m_timer); m_timer=0;}
		MainShow(m_timer_x, m_timer_y, m_timer_txt);
	}
	
	CWnd::OnTimer(nIDEvent);
}

bool CaplToolTip::IsNeedHideOnMessage(UINT msg)
{
	switch (msg)
	{
		case WM_PAINT:
		case WM_MOUSELEAVE:
		case WM_LBUTTONDOWN:
		case WM_LBUTTONDBLCLK:
		case WM_NCLBUTTONDOWN:
		case WM_MBUTTONDOWN:
		case WM_RBUTTONDOWN:
		case WM_KILLFOCUS:
		case WM_DESTROY:
		case WM_HSCROLL:
		case WM_VSCROLL:
		case WM_KEYDOWN:
		case SBM_SETPOS:
		case SBM_SETSCROLLINFO:
		case WM_MOUSEWHEEL:
			return true;
	}

	return false;
}
