/////////////////////////////////////////////////////////////////////////////
// File:        filebrowser.h
// Author:      Cesar Mauri Loba (cesar at crea-si dot com)
// 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/>.
/////////////////////////////////////////////////////////////////////////////
#pragma once

#include "spcore/basictypes.h"
#include "spcore/pinimpl.h"
#include "spcore/component.h"
#include <string>

namespace mod_io {

/**
	file_browser component

	This component allows to list the contents of a directory of the hard disk

	Input pins:
		path (string)	
			Path to explore. If path exists the lists of files is dumped.

		refresh (any)
			Re-scans the contents of the current directory and dumps the result

	Output pins:
		paths (any)		List of file names (full absolute paths)
		files (any)		List of files names (only names of files)

	Command line:
		[-p <path>]		Set initial path
		[-t [d|f] ]		Selects between directories (d) or files (f). Def.: f
		// TODO
		[-w <string>]	Wildcard. Ex: *.jpg;*.png

	Notes:
*/
class FileBrowserComponent : public spcore::CComponentAdapter {
public:
	static const char* getTypeName() { return "file_browser"; };
	virtual const char* GetTypeName() const { return FileBrowserComponent::getTypeName(); };

	//
	// Component methods
	//
	FileBrowserComponent(const char * name, int argc, const char * argv[]);
	
	virtual int DoInitialize();

private:
	//
	// Data members
	//
	bool m_selectDirs;
	SmartPtr<spcore::IOutputPin> m_oPinPaths;
	SmartPtr<spcore::IOutputPin> m_oPinFiles;

	SmartPtr<spcore::CTypeComposite> m_pathNames;
	SmartPtr<spcore::CTypeComposite> m_fileNames;
		
	std::string m_currentPath;
	std::string m_wildcard;

	//
	// Methods
	//

	// Re-scan path and update m_pathNames & m_pathNames. 
	// Return false if an error ocurred in which case members are not updated
	bool ReScanPath (const char* path_name);
	void OnPinPath (const spcore::CTypeString & msg);
	void Refresh ();

	// 
	// Input pins classes
	//
	class InputPinPath
		: public spcore::CInputPinWriteOnly<spcore::CTypeString, FileBrowserComponent> {
	public:
		InputPinPath (FileBrowserComponent & component)
		: spcore::CInputPinWriteOnly<spcore::CTypeString, FileBrowserComponent>("path", component) { }

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

	class InputPinRefresh
		: public spcore::CInputPinWriteOnly<spcore::CTypeAny, FileBrowserComponent> {
	public:
		InputPinRefresh (FileBrowserComponent & component)
		: spcore::CInputPinWriteOnly<spcore::CTypeAny, FileBrowserComponent>("refresh", component) { }

		virtual int DoSend(const spcore::CTypeAny &) {
			m_component->Refresh();
			return 0;
		}
	};
};

// Component factory
typedef spcore::ComponentFactory<FileBrowserComponent> FileBrowserComponentFactory;

} // namespace spcore
