/*
 * (C) 2003-2006 Gabest
 * (C) 2006-2023 see Authors.txt
 *
 * This file is part of MPC-BE.
 *
 * MPC-BE is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * MPC-BE 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.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#pragma once

#include "controls/WinHotkeyCtrl.h"

#define LVN_DOLABELEDIT (LVN_FIRST+1)

class CInPlaceWinHotkey : public CWinHotkeyCtrl
{
private:
	int m_iItem;
	int m_iSubItem;
	CString m_sInitText;
	BOOL m_bESC; // To indicate whether ESC key was pressed

public:
	CInPlaceWinHotkey(int iItem, int iSubItem, CString sInitText);
	virtual ~CInPlaceWinHotkey();

protected:
	virtual BOOL PreTranslateMessage(MSG* pMsg);

	DECLARE_MESSAGE_MAP()

public:
	afx_msg void OnKillFocus(CWnd* pNewWnd);
	afx_msg void OnNcDestroy();
	afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
};

class CInPlaceEdit : public CEdit
{
protected:
	int m_iItem;
	int m_iSubItem;
	CString m_sInitText;
	BOOL m_bESC; // To indicate whether ESC key was pressed

public:
	CInPlaceEdit(int iItem, int iSubItem, CString sInitText);
	virtual ~CInPlaceEdit();

protected:
	virtual BOOL PreTranslateMessage(MSG* pMsg);

	DECLARE_MESSAGE_MAP()

public:
	afx_msg void OnKillFocus(CWnd* pNewWnd);
	afx_msg void OnNcDestroy();
	afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
};

class CInPlaceFloatEdit : public CInPlaceEdit
{
public:
	CInPlaceFloatEdit(int iItem, int iSubItem, CString sInitText);
	virtual ~CInPlaceFloatEdit();

protected:
	DECLARE_MESSAGE_MAP()

public:
	afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
};

class CInPlaceComboBox : public CComboBox
{
private:
	int m_iItem;
	int m_iSubItem;
	std::list<CString> m_lstItems;
	int m_nSel;
	BOOL m_bESC; // To indicate whether ESC key was pressed

public:
	CInPlaceComboBox(int iItem, int iSubItem, std::list<CString>& plstItems, int nSel);
	virtual ~CInPlaceComboBox();

protected:
	virtual BOOL PreTranslateMessage(MSG* pMsg);

	DECLARE_MESSAGE_MAP()

public:
	afx_msg void OnKillFocus(CWnd* pNewWnd);
	afx_msg void OnNcDestroy();
	afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnCloseup();
};

class CInPlaceListBox : public CListBox
{
private:
	int m_iItem;
	int m_iSubItem;
	std::list<CString> m_lstItems;
	int m_nSel;
	BOOL m_bESC; // To indicate whether ESC key was pressed

public:
	CInPlaceListBox(int iItem, int iSubItem, std::list<CString>& plstItems, int nSel);
	virtual ~CInPlaceListBox();

protected:
	virtual BOOL PreTranslateMessage(MSG* pMsg);

	DECLARE_MESSAGE_MAP()

public:
	afx_msg void OnKillFocus(CWnd* pNewWnd);
	afx_msg void OnNcDestroy();
	afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
};

// CPlayerListCtrl

class CPlayerListCtrl : public CListCtrl
{
	DECLARE_DYNAMIC(CPlayerListCtrl)

private:
	int m_nItemClicked = -1;
	int m_nSubItemClicked = -1;
	int m_tStartEditingDelay;
	UINT_PTR m_nTimerID = 0;

	bool PrepareInPlaceControl(int nRow, int nCol, CRect& rect);

public:
	CPlayerListCtrl(int tStartEditingDelay = 500);
	virtual ~CPlayerListCtrl();

	int HitTestEx(CPoint& point, int* col) const;
	CImageList* CreateDragImageEx(LPPOINT lpPoint);

	int GetBottomIndex() const;

	CWinHotkeyCtrl* ShowInPlaceWinHotkey(int nItem, int nCol);
	CEdit* ShowInPlaceEdit(int nItem, int nCol);
	CEdit* ShowInPlaceFloatEdit(int nItem, int nCol);
	CComboBox* ShowInPlaceComboBox(int nItem, int nCol, std::list<CString>& lstItems, int nSel, bool bShowDropDown=false);
	CListBox* ShowInPlaceListBox(int nItem, int nCol, std::list<CString>& lstItems, int nSel);

	bool m_fInPlaceDirty = false;

protected:
	virtual void PreSubclassWindow();
	virtual INT_PTR OnToolHitTest(CPoint point, TOOLINFO* pTI) const;
	virtual ULONG GetGestureStatus(CPoint) { return 0; };

	DECLARE_MESSAGE_MAP()

public:
	afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
	afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
	afx_msg void OnTimer(UINT_PTR nIDEvent);
	afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
	afx_msg void OnLvnMarqueeBegin(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnLvnInsertitem(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnLvnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnEnChangeEdit1();
	afx_msg void OnEnChangeWinHotkey1();
	afx_msg void OnCbnDropdownCombo1();
	afx_msg void OnCbnSelendokCombo1();
	afx_msg void OnLbnSelChangeList1();
	afx_msg BOOL OnHdnItemchanging(UINT id, NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg BOOL OnToolTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult);

	int InsertColumn(_In_ int nCol, _In_z_ LPCWSTR lpszColumnHeading,
		_In_ int nFormat = LVCFMT_LEFT, _In_ int nWidth = -1, _In_ int nSubItem = -1, _In_ int nMinWidth = 20);
};
