// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
 
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#ifndef _PWL_SCROLLBAR_H_
#define _PWL_SCROLLBAR_H_

class CPWL_SBButton;
class CPWL_ScrollBar;

struct PWL_SCROLL_INFO
{
public:
	PWL_SCROLL_INFO() : fContentMin(0.0f), fContentMax(0.0f), fPlateWidth(0.0f), fBigStep(0.0f), fSmallStep(0.0f)
	{
	}
	FX_FLOAT					fContentMin;
	FX_FLOAT					fContentMax;	
	FX_FLOAT					fPlateWidth;	
	FX_FLOAT					fBigStep;
	FX_FLOAT					fSmallStep;
};

enum PWL_SCROLLBAR_TYPE
{
	SBT_HSCROLL,
	SBT_VSCROLL
};

enum PWL_SBBUTTON_TYPE
{
	PSBT_MIN,
	PSBT_MAX,
	PSBT_POS
};

class CPWL_SBButton : public CPWL_Wnd  
{
public:
	CPWL_SBButton(PWL_SCROLLBAR_TYPE eScrollBarType,PWL_SBBUTTON_TYPE eButtonType);
	virtual ~CPWL_SBButton();

public:
	virtual CFX_ByteString		GetClassName() const;
	virtual void				OnCreate(PWL_CREATEPARAM & cp);
	virtual void				GetThisAppearanceStream(CFX_ByteTextBuf & sAppStream);
	virtual void				DrawThisAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device);
	virtual FX_BOOL				OnLButtonDown(const CPDF_Point & point, FX_DWORD nFlag);
	virtual FX_BOOL				OnLButtonUp(const CPDF_Point & point, FX_DWORD nFlag);
	virtual FX_BOOL				OnMouseMove(const CPDF_Point & point, FX_DWORD nFlag);

protected:
	PWL_SCROLLBAR_TYPE			m_eScrollBarType;
	PWL_SBBUTTON_TYPE			m_eSBButtonType;

	FX_BOOL						m_bMouseDown;
};

struct PWL_FLOATRANGE
{
public:
	PWL_FLOATRANGE();
	PWL_FLOATRANGE(FX_FLOAT min,FX_FLOAT max);
	void Default();
	void Set(FX_FLOAT min,FX_FLOAT max);
	FX_BOOL	In(FX_FLOAT x) const;
	FX_FLOAT GetWidth() const;

	FX_FLOAT fMin,fMax;
};

struct PWL_SCROLL_PRIVATEDATA
{
public:
	PWL_SCROLL_PRIVATEDATA();

	void Default();
	void SetScrollRange(FX_FLOAT min,FX_FLOAT max);
	void SetClientWidth(FX_FLOAT width);
	void SetSmallStep(FX_FLOAT step);
	void SetBigStep(FX_FLOAT step);
	FX_BOOL SetPos(FX_FLOAT pos);

	void AddSmall();
	void SubSmall();
	void AddBig();
	void SubBig();

	PWL_FLOATRANGE				ScrollRange;
	FX_FLOAT					fClientWidth;
	FX_FLOAT					fScrollPos;
	FX_FLOAT					fBigStep;
	FX_FLOAT					fSmallStep;
};

class CPWL_ScrollBar : public CPWL_Wnd  
{
public:
	CPWL_ScrollBar(PWL_SCROLLBAR_TYPE sbType = SBT_HSCROLL);
	virtual ~CPWL_ScrollBar();

public:
	virtual CFX_ByteString		GetClassName() const;
	virtual void				OnCreate(PWL_CREATEPARAM & cp);
	virtual void				RePosChildWnd();
	virtual void				GetThisAppearanceStream(CFX_ByteTextBuf & sAppStream);
	virtual void				DrawThisAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device);

	virtual FX_BOOL				OnLButtonDown(const CPDF_Point & point, FX_DWORD nFlag);
	virtual FX_BOOL				OnLButtonUp(const CPDF_Point & point, FX_DWORD nFlag);
	virtual void				OnNotify(CPWL_Wnd* pWnd, FX_DWORD msg, FX_INTPTR wParam = 0, FX_INTPTR lParam = 0);

	virtual void				CreateChildWnd(const PWL_CREATEPARAM & cp);
	
	FX_FLOAT					GetScrollBarWidth() const;	
	PWL_SCROLLBAR_TYPE			GetScrollBarType() const {return m_sbType;};

	void						SetNotifyForever(FX_BOOL bForever) {m_bNotifyForever = bForever;}

protected:			
	void						SetScrollRange(FX_FLOAT fMin,FX_FLOAT fMax,FX_FLOAT fClientWidth);
	void						SetScrollPos(FX_FLOAT fPos);
	void						MovePosButton(FX_BOOL bRefresh);
	void						SetScrollStep(FX_FLOAT fBigStep,FX_FLOAT fSmallStep);
	void						NotifyScrollWindow();
	CPDF_Rect					GetScrollArea() const;

private:
	void						CreateButtons(const PWL_CREATEPARAM & cp);

	void						OnMinButtonLBDown(const CPDF_Point & point);
	void						OnMinButtonLBUp(const CPDF_Point & point);
	void						OnMinButtonMouseMove(const CPDF_Point & point);

	void						OnMaxButtonLBDown(const CPDF_Point & point);
	void						OnMaxButtonLBUp(const CPDF_Point & point);
	void						OnMaxButtonMouseMove(const CPDF_Point & point);

	void						OnPosButtonLBDown(const CPDF_Point & point);
	void						OnPosButtonLBUp(const CPDF_Point & point);
	void						OnPosButtonMouseMove(const CPDF_Point & point);

	FX_FLOAT					TrueToFace(FX_FLOAT);
	FX_FLOAT					FaceToTrue(FX_FLOAT);

	virtual	void				TimerProc();

private:
	PWL_SCROLLBAR_TYPE			m_sbType;
	PWL_SCROLL_INFO				m_OriginInfo;
	CPWL_SBButton*				m_pMinButton;
	CPWL_SBButton*				m_pMaxButton;
	CPWL_SBButton*				m_pPosButton;
	PWL_SCROLL_PRIVATEDATA		m_sData;
	FX_BOOL						m_bMouseDown;	
	FX_BOOL						m_bMinOrMax;
	FX_BOOL						m_bNotifyForever;
	FX_FLOAT					m_nOldPos;
	FX_FLOAT					m_fOldPosButton;
};

#endif // !defined(AFX_PWL_SCROLLBAR_H__DCFEC082_2651_48A4_B8F3_63F1B3CC5E10__INCLUDED_)


