/////////////////////////////////////////////////////////////////////////////
// Name:       instrselect.h
// Purpose:
// Author:      Cesar Mauri Loba (cesar at crea-si dot com)
// Modified by:
// Created:     26/05/2010 11:05:03
// Copyright:   (C) 2010-11 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 INSTRSELECTOR_H
#define INSTRSELECTOR_H

#include "spcore/component.h"
#include "spcore/pinimpl.h"
#include "spcore/basictypes.h"

namespace mod_score_player {

/** *****************************************************************************
	Component: instrument_selector

	Input pins:
		instrument (int)
			Selects the instrument by its number (starting at 0). 
			If no instrument set is given by command line the full general MIDI 
			is available 
			
	Output pins:
		instruments (any)	List of instrument which are part of the set
		name (string)		Localized name of the selected instrument
		midi_number	(int)	MIDI number of the selected instrument

	Command line:
		[-s <list> ]	
			List of instruments numbers to include in the set (range 1..128). 
			If this parameter is not provided the full set of instruments is available.
		[-n ] 	Append the number of the instrument before its name
****************************************************************************** */
class InstrumentSelectorComponent : public spcore::CComponentAdapter {
public:
	static const char* getTypeName() { return "instrument_selector"; };
	virtual const char* GetTypeName() const { return InstrumentSelectorComponent::getTypeName(); };

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

	virtual int DoInitialize();

private:
	//
	// Private types
	//
	struct Name_MIDINum	{
		unsigned char number;
		std::string name;
	};
	
	//
	// Data members
	//
	unsigned char m_instrIdx;	
	std::vector<struct Name_MIDINum> m_instrumentSet;
	SmartPtr<spcore::IOutputPin> m_oPinInstruments;
	SmartPtr<spcore::IOutputPin> m_oPinName;
	SmartPtr<spcore::IOutputPin> m_oPinMIDINumber;
	
	//
	// Private methods
	//	
	void OnPinInstrument (const spcore::CTypeInt & msg);

	// Adds an instrument to the set givent its number (0..127)
	void AddInstrumentToSet(unsigned int num, bool appendNum);

	void SendNameAndMIDINumber();

	//
	// Input pin classes
	//
	class InputPinInstrument : public spcore::CInputPinWriteOnly<spcore::CTypeInt, InstrumentSelectorComponent> {
	public:
		InputPinInstrument (InstrumentSelectorComponent & component)
		: spcore::CInputPinWriteOnly<spcore::CTypeInt, InstrumentSelectorComponent>("instrument", component) { }

		virtual int DoSend(const spcore::CTypeInt & msg) {
			m_component->OnPinInstrument(msg);
			return 0;
		}
	};
};

typedef spcore::ComponentFactory<InstrumentSelectorComponent> InstrumentSelectorFactory;


};

#endif
