// MySliderCtrl.cpp : implementation file
//

#include "stdafx.h"
#include "NetPlayX.h"
#include "MySliderCtrl.h"
#include "NetPlayXCtl.h"

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

/////////////////////////////////////////////////////////////////////////////
// CMySliderCtrl

CMySliderCtrl::CMySliderCtrl()
{
	m_bDragging = FALSE;
	m_bDragChanged = FALSE;
	m_parent  = NULL;
}

CMySliderCtrl::~CMySliderCtrl()
{
}


BEGIN_MESSAGE_MAP(CMySliderCtrl, CSliderCtrl)
	//{{AFX_MSG_MAP(CMySliderCtrl)
	ON_WM_LBUTTONUP()
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
	ON_WM_CREATE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMySliderCtrl message handlers

void CMySliderCtrl::OnLButtonUp(UINT nFlags, CPoint point) 
{
	if(m_bDragging)
	{
		m_bDragging = FALSE;
		::ReleaseCapture();
		if (SetThumb(point))
		{
			PostMessageToParent(TB_THUMBTRACK);
			m_bDragChanged = TRUE;
		}
		if (m_bDragChanged)
		{
			PostMessageToParent(TB_THUMBPOSITION);
			m_bDragChanged = FALSE;
		}
	}
	else
	{
		CSliderCtrl::OnLButtonUp(nFlags, point);
	}	
	RelayEvent(WM_LBUTTONUP, (WPARAM)nFlags,
		MAKELPARAM(LOWORD(point.x), LOWORD(point.y)));	
}

void CMySliderCtrl::OnLButtonDown(UINT nFlags, CPoint point) 
{

	m_bDragging = TRUE;
	m_bDragChanged = FALSE;
	SetCapture();
	SetFocus();
	if (SetThumb(point))
	{
		m_bDragChanged = TRUE;
		PostMessageToParent(TB_THUMBTRACK);
	}	
	RelayEvent(WM_LBUTTONDOWN, (WPARAM)nFlags,
		MAKELPARAM(LOWORD(point.x), LOWORD(point.y)));	
}

void CMySliderCtrl::OnMouseMove(UINT nFlags, CPoint point) 
{
	if (m_bDragging)
	{
		if (SetThumb(point))
		{
			m_bDragChanged = TRUE;
			PostMessageToParent(TB_THUMBTRACK);
		}
	}
	else
	{
		CSliderCtrl::OnMouseMove(nFlags, point);
	}
	RelayEvent(WM_MOUSEMOVE, (WPARAM)nFlags,
		MAKELPARAM(LOWORD(point.x), LOWORD(point.y)));
}
bool CMySliderCtrl::SetThumb(const CPoint& point)
{
	const int nMin = GetRangeMin();
	const int nMax = GetRangeMax()+1;
	CRect rc;
	GetChannelRect(rc);
	double dPos;
	double dCorrectionFactor = 0.0;
	if (GetStyle() & TBS_VERT) 
	{
		// note: there is a bug in GetChannelRect, it gets the orientation of the rectangle mixed up
		dPos = (double)(point.y - rc.left)/(rc.right - rc.left);
	}
	else
	{
		dPos = (double)(point.x - rc.left)/(rc.right - rc.left);
	}
	// This correction factor is needed when you click inbetween tick marks
	// so that the thumb will move to the nearest one
	dCorrectionFactor = 0.5 *(1-dPos) - 0.5 *dPos;
	int nNewPos = (int)(nMin + (nMax-nMin)*dPos + dCorrectionFactor);
	const bool bChanged = (nNewPos != GetPos());
	if(bChanged)
	{
		SetPos(nNewPos);
	}
	return bChanged;
}

void CMySliderCtrl::PostMessageToParent(const int nTBCode) const
{
	if(m_parent)
	{
		m_parent->PostMessage(WM_HSCROLL, (WPARAM)((GetPos()<<16) | nTBCode), (LPARAM)GetSafeHwnd());
	}
}


void CMySliderCtrl::UpdateTipTool(LPCTSTR string)
{
	m_tooltip.UpdateTipText(string,this);
}
void CMySliderCtrl::RelayEvent(UINT message, WPARAM wParam, LPARAM lParam)
{
	if (NULL != m_tooltip.m_hWnd) {
		MSG msg;
		
		msg.hwnd= m_hWnd;
		msg.message= message;
		msg.wParam= wParam;
		msg.lParam= lParam;
		msg.time= 0;
		msg.pt.x= LOWORD (lParam);
		msg.pt.y= HIWORD (lParam);
		
		m_tooltip.RelayEvent(&msg);
	}
}

int CMySliderCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CSliderCtrl::OnCreate(lpCreateStruct) == -1)
		return -1;
	m_tooltip.Create(this);
	m_tooltip.Activate(TRUE);
	m_tooltip.SetDelayTime(250);
	m_tooltip.AddTool(this);	
	return 0;
}