text: /*
  ** FamiTracker - NES/Famicom sound tracker
  ** Copyright (C) 2005-2014  Jonathan Liss
  **
  ** 0CC-FamiTracker is (C) 2014-2018 HertzDevil
  **
  ** This program 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 2 of the License, or
  ** (at your option) any later version.
  **
  ** 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.  See the GNU
  ** Library General Public License for more details.  To obtain a
  ** copy of the GNU Library General Public License, write to the Free
  ** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  **
  ** Any permitted reproduction of these routines, in whole or in part,
  ** must bear this legend.
  */
  
  #pragma once
  
  #include "stdafx.h"		// // //
  #include <memory>		// // //
  
  enum {
  	WM_USER_WAVE_CHANGED = WM_USER,
  };
  
  class CWaveEditor : public CWnd
  {
  public:
  	CWaveEditor(int sx, int sy, int lx, int ly);
  	virtual ~CWaveEditor();
  	DECLARE_DYNAMIC(CWaveEditor)
  
  	void PhaseShift(int x);		// // //
  	void Invert(int x);		// // //
  private:
  	void EditWave(CPoint pt1, CPoint pt2);
  	void EditWave(CPoint point);
  	void DrawLine(CDC *pDC);
  
  protected:
  	virtual int GetSample(int i) const = 0;
  	virtual void SetSample(int i, int s) = 0;
  	virtual int GetMaxSamples() const = 0;
  	virtual void DrawRect(CDC *pDC, int x, int y, int sx, int sy) const = 0;
  	virtual bool GetLineMode() const = 0;
  	virtual void SetLineMode(bool Mode) = 0;
  
  protected:
  	int m_iSX, m_iSY;
  	int m_iLX, m_iLY;
  
  	CPoint m_ptLineStart, m_ptLineEnd;
  
  	bool m_bDrawLine;
  
  //	static virtual bool m_bLineMode;
  
  public:
  	void WaveChanged();
  	virtual afx_msg void OnPaint();
  
  protected:
  	DECLARE_MESSAGE_MAP()
  
  public:
  	BOOL CreateEx(DWORD dwExStyle, LPCWSTR lpszClassName, LPCWSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd);
  	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
  	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
  	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
  	afx_msg void OnMButtonDown(UINT nFlags, CPoint point);
  	afx_msg void OnMButtonUp(UINT nFlags, CPoint point);
  	afx_msg void OnContextMenu(CWnd* /*pWnd*/, CPoint /*point*/);
  };
  
  // Templates would be better but doesn't work well with MFC unfortunately
  
  class CInstrumentFDS;
  class CInstrumentN163;
  
  // FDS wave
  class CWaveEditorFDS : public CWaveEditor
  {
  public:
  	using CWaveEditor::CWaveEditor;		// // //
  	void SetInstrument(std::shared_ptr<CInstrumentFDS> pInst);
  protected:
  	int GetSample(int i) const override;
  	void SetSample(int i, int s) override;
  	int GetMaxSamples() const override;
  	void DrawRect(CDC *pDC, int x, int y, int sx, int sy) const override;
  	bool GetLineMode() const override { return m_bLineMode; }
  	void SetLineMode(bool Mode) override { m_bLineMode = Mode; }
  
  protected:
  	static bool m_bLineMode;
  
  protected:
  	std::shared_ptr<CInstrumentFDS> m_pInstrument;
  };
  
  // N163 wave
  class CWaveEditorN163 : public CWaveEditor
  {
  public:
  	using CWaveEditor::CWaveEditor;		// // //
  	void SetLength(int Length);
  	void SetInstrument(std::shared_ptr<CInstrumentN163> pInst);
  	void SetWave(int i);
  protected:
  	int GetSample(int i) const override;
  	void SetSample(int i, int s) override;
  	int GetMaxSamples() const override;
  	void DrawRect(CDC *pDC, int x, int y, int sx, int sy) const override;
  	bool GetLineMode() const override { return m_bLineMode; }
  	void SetLineMode(bool Mode) override { m_bLineMode = Mode; }
  
  protected:
  	static bool m_bLineMode;
  
  protected:
  	std::shared_ptr<CInstrumentN163> m_pInstrument;
  	int m_iWaveIndex = 0;
  };
  