/////////////////////////////////////////////////////////////////////////////
// Name:       puredataconfig.h
// Author:      Cesar Mauri Loba (cesar at crea-si dot com)
// Modified by: 
// Created:     25/02/2010 21:02:14
// Copyright:   (C) 2010 Cesar Mauri Loba - CREA Software Systems
// 
//  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 3 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 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/>.
/////////////////////////////////////////////////////////////////////////////

#ifndef PUREDATACONFIG_H_
#define PUREDATACONFIG_H_


/*!
 * Includes
 */

#include "spcore/component.h"
#include "spcore/pinimpl.h"
#include "spcore/basictypes.h"
 
////@begin includes
#include "wx/spinctrl.h"
////@end includes
#include <wx/wx.h>

#include "puredatawrapper.h"
#include "valuerange.h"
//#include "logexprange.h"
#include "oscinout.h"

/*!
 * Forward declarations
 */

////@begin forward declarations
class wxSpinCtrl;
////@end forward declarations

/*!
 * Control identifiers
 */

////@begin control identifiers
#define ID_PURE_DATA_CONFIG 10039
#define ID_SPINCTRL_DELAY 10040
#define ID_RADIOBUTTON_PLAYSOUND 10041
#define ID_RADIOBUTTON_MIC 10042
#define ID_SLIDER_OUTVOL 10044
#define ID_GAUGE_OUTVOL 10000
#define ID_SLIDER_MICVOL 10043
#define ID_GAUGE_MICINPUT 10049
#define ID_BUTTON_CLOSE 10047
#define SYMBOL_PUREDATACONFIGPANEL_STYLE wxTAB_TRAVERSAL
#define SYMBOL_PUREDATACONFIGPANEL_TITLE _("Pure Data Configuration")
#define SYMBOL_PUREDATACONFIGPANEL_IDNAME ID_PURE_DATA_CONFIG
#define SYMBOL_PUREDATACONFIGPANEL_SIZE wxDefaultSize
#define SYMBOL_PUREDATACONFIGPANEL_POSITION wxDefaultPosition
////@end control identifiers

namespace mod_puredata {

class PureDataConfigComponent;

/*!
 * PureDataConfigPanel class declaration
 */

class PureDataConfigPanel: public wxPanel
{    
    DECLARE_DYNAMIC_CLASS( PureDataConfigPanel )
    DECLARE_EVENT_TABLE()

public:
    /// Constructors
    PureDataConfigPanel();
    PureDataConfigPanel( wxWindow* parent, wxWindowID id = SYMBOL_PUREDATACONFIGPANEL_IDNAME, const wxPoint& pos = SYMBOL_PUREDATACONFIGPANEL_POSITION, const wxSize& size = SYMBOL_PUREDATACONFIGPANEL_SIZE, long style = SYMBOL_PUREDATACONFIGPANEL_STYLE, const wxString& name = SYMBOL_PUREDATACONFIGPANEL_TITLE );

    /// Creation
    bool Create( wxWindow* parent, wxWindowID id = SYMBOL_PUREDATACONFIGPANEL_IDNAME, const wxPoint& pos = SYMBOL_PUREDATACONFIGPANEL_POSITION, const wxSize& size = SYMBOL_PUREDATACONFIGPANEL_SIZE, long style = SYMBOL_PUREDATACONFIGPANEL_STYLE, const wxString& name = SYMBOL_PUREDATACONFIGPANEL_TITLE );

    /// Destructor
    ~PureDataConfigPanel();

	// Set destruction callback. NULL removes.
	void SetComponent(PureDataConfigComponent* component) { m_component= component; }

	// On component updated
	void NotifyComponentUpdate(); 

private:
    /// Initialises member variables
    void Init();

    /// Creates the controls and sizers
    void CreateControls();

////@begin PureDataConfigPanel event handler declarations

    /// wxEVT_CLOSE_WINDOW event handler for ID_PURE_DATA_CONFIG
    void OnCloseWindow( wxCloseEvent& event );

    /// wxEVT_COMMAND_SPINCTRL_UPDATED event handler for ID_SPINCTRL_DELAY
    void OnSpinctrlDelayUpdated( wxSpinEvent& event );

    /// wxEVT_COMMAND_RADIOBUTTON_SELECTED event handler for ID_RADIOBUTTON_PLAYSOUND
    void OnRadiobuttonPlaysoundSelected( wxCommandEvent& event );

    /// wxEVT_COMMAND_RADIOBUTTON_SELECTED event handler for ID_RADIOBUTTON_MIC
    void OnRadiobuttonMicSelected( wxCommandEvent& event );

    /// wxEVT_COMMAND_SLIDER_UPDATED event handler for ID_SLIDER_OUTVOL
    void OnSliderOutvolUpdated( wxCommandEvent& event );

    /// wxEVT_COMMAND_SLIDER_UPDATED event handler for ID_SLIDER_MICVOL
    void OnSliderMicvolUpdated( wxCommandEvent& event );

    /// wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON_CLOSE
    void OnButtonCloseClick( wxCommandEvent& event );

////@end PureDataConfigPanel event handler declarations

	void OnComponentUpdated( wxCommandEvent& event );

////@begin PureDataConfigPanel member function declarations

    /// Retrieves bitmap resources
    wxBitmap GetBitmapResource( const wxString& name );

    /// Retrieves icon resources
    wxIcon GetIconResource( const wxString& name );
////@end PureDataConfigPanel member function declarations

    /// Should we show tooltips?
    static bool ShowToolTips();

private:
////@begin PureDataConfigPanel member variables
    wxSpinCtrl* m_spinDelay;
    wxSlider* m_sldOutVol;
    wxGauge* m_gaugeOutput;
    wxStaticText* m_txtMicVol;
    wxSlider* m_sldMicVol;
    wxGauge* m_gaugeMicInput;
////@end PureDataConfigPanel member variables

	bool m_micTest;
	PureDataConfigComponent* m_component;
};

/* ******************************************************************************
****************************************************************************** */
/**
	puredata_config component

	Allows to interactively configure pure data

	Input pins:		

	Output pins:

	Command line:
		[--data-dir <path>] path where pd scripts reside
*/
class PureDataConfigComponent 
	: public spcore::CComponentAdapter, public IPdPatch, public osc::OscPacketListener {

public:
	static const char* getTypeName() { return "puredata_config"; };
	virtual const char* GetTypeName() const { return PureDataConfigComponent::getTypeName(); };

	PureDataConfigComponent(const char * name, int argc, const char * argv[]);

	//	void OnChangedValue (float v);
	virtual wxWindow* GetGUI(wxWindow * parent);
	void OnPanelDestroyed ();
	
	virtual int DoInitialize();
    virtual void DoFinish();
		
	//
	//
	//
	enum EPDTestType { TEST_PLAY_SOUND= 0, TEST_MICROPHONE };

	// An error ocurred with PD?
	bool GetError() const { return m_pdError; }

	// Input volume and signal
	void SetMicInputControl(int v);
	const CValueRangeI& GetMicInputControl() { return m_micInputControl; }
	float GetMicInputEnvelope() const { return m_micInputEnvelope; }

	// Output volume and signal
	void SetOutputControl(int v);
	const CValueRangeI GetOutputControl() { return m_outputControl; }
	float GetOutputEnvelope() const { return m_outputEnvelope; }

	// Test type
	void SetTestType (EPDTestType tt);


	// Delays
	unsigned int GetDelay();
	void SetDelay(unsigned int d);

	void SaveSettings();

	//
	// IPdPatch methods
	//
	virtual void NotifyStatus (PDStatus e);
	virtual const char* GetPatchFileName() const;
	
private:
	virtual void ProcessMessage( const osc::ReceivedMessage& m, const IpEndpointName& remoteEndpoint );

	virtual ~PureDataConfigComponent();
	
	bool m_pdError;
	PureDataConfigPanel* m_panel;

	COscIn m_oscIn;
	COscOut m_oscOut;

	CValueRangeI m_micInputControl;
	float m_micInputEnvelope;

	CValueRangeI m_outputControl;
	float m_outputEnvelope;

	std::string m_patchPath;
};

typedef spcore::SingletonComponentFactory<PureDataConfigComponent> PureDataConfigFactory;


}; // namespace end

#endif
    // PUREDATACONFIG_H_
