#ifndef _FishIDE_Examples_h_
#define _FishIDE_Examples_h_

#include "AVersion.h"

using namespace Upp;

class ExampleVersion : Moveable<ExampleVersion>
{
	friend class ExamplesClass;
	friend class Example;
	
	private:
	
		// library properties
		bool			_anyArchitecture;
		String			_name;
		AVersion		_version;
		String			_author;
		String			_maintainer;
		String			_sentence;
		String			_paragraph;
		String			_website;
		String			_category;
		String			_url;
		String			_archiveFileName;
		int				_size;
		String			_checksum;
		Vector<String>	_architectures;
		Vector<String>	_requires;
		
		// clear info data
		void ClearInfo(void);
		
		// read properties file
		void ReadPropertiesFile(String const &path);
		
		// write properties file
		void WritePropertiesFile(String const &path) const;

	protected:
	
	public:
	
		// constructor
		ExampleVersion();
		
		// pick constructor
		ExampleVersion(ExampleVersion &&) = default;
		
		// destructor
		~ExampleVersion();
		
		// move operator
		ExampleVersion &operator=(ExampleVersion &&lib) = default;
	

		String const&	GetName(void) const					{ return _name;				}
		AVersion const&	GetVersion(void) const				{ return _version;			}
		String const &	GetAuthor(void) const				{ return _author;			}
		String const &	GetMaintainer(void) const			{ return _maintainer;		}
		String const &	GetSentence(void) const				{ return _sentence;			}
		String const &	GetParagraph(void) const			{ return _paragraph;		}
		String const &	GetWebsite(void) const				{ return _website;			}
		String const &	GetCategory(void) const				{ return _category;			}
		String const &	GetUrl(void) const					{ return _url;				}
		String const &	GetArchiveFileName(void) const		{ return _archiveFileName;	}
		int				GetSize(void) const					{ return _size;				}
		String const &	GetChecksum(void) const				{ return _checksum;			}
		
		Vector<String>	const &GetArchitectures(void) const	{ return _architectures; }
		
		// get the staging archive
		String GetStagingArchivePath(void) const;

		// get example local folder
		String GetLocalFolder(void) const;
};

class Example : Moveable<Example>
{
	friend class ExamplesClass;
	
	private:
	
		// available versions
		VectorMap<MaintainerVersion, ExampleVersion> _versions;
		
		// name
		String _name;
		
		// installed flag
		bool _installed;
		
		// installed version
		MaintainerVersion _installedVersion;
	
	protected:
	
	public:
	
		// constructor
		Example();
		
		// pick constructor
		Example(Example &&lib) = default;
		
		// destructor
		~Example();
		
		Example &operator=(Example &&lib) = default;
		
		// install or update a example
		bool Install(MaintainerVersion const &ver);
		
		// uninstall the example
		bool Remove(void);
		
		// check if installed and installed version
		bool IsInstalled(void) const { return _installed; }
		MaintainerVersion const &GetInstalledVersion(void) const { return _installedVersion; }
		
		// get available versions
		VectorMap<MaintainerVersion, ExampleVersion> const &GetVersions(void) const { return _versions; }
		VectorMap<MaintainerVersion, ExampleVersion> &GetVersions(void) { return _versions; }
		
		// get example name
		String const &GetName(void) const { return _name; }

		// get latest version available
		MaintainerVersion GetLatestVersion(void) const;
};

class ExamplesClass
{
	friend ExamplesClass &__GetExamples(void);
	
	private:
	
		// available/installed examples
		VectorMap<String, Example> _examples;
		
		// constructor
		ExamplesClass();
		
	protected:
	
	public:
	
		// destructor
		~ExamplesClass();
		
		// clear data
		void Clear(void);

		// read from json file
		bool ParseJSON(String const &json);
		
		// scan from installed on disk
		bool ScanLocal(void);
		
		// refresh examples
		bool Refresh(void);
		
		int GetCount(void) const { return _examples.GetCount(); }
		Example &operator[](int i) { return _examples[i]; }
		Example const &operator[](int i) const { return _examples[i]; }
		String const &GetKey(int i) const { return _examples.GetKey(i); }

		// find an example by name
		Example const *Find(String const &name) const;
		Example *Find(String const &name);
};

extern ExamplesClass &__GetExamples(void);

#define Examples __GetExamples()

#endif
