#ifndef _FishIDE_Platform_h_
#define _FishIDE_Platform_h_

#include <Core/Core.h>

using namespace Upp;

#include "Board.h"

class Board;

class PlatformVersion
{
	friend class Platform;
	friend class Package;
	friend class PackagesClass;
	friend class SettingsClass;
	
	public:
		struct ToolDep : Moveable<ToolDep>
		{
			String _packager;
			String _name;
			String _version;
		};

	private:
	
		// platform version
		String _version;
		
		// platform URL
		String _url;
		
		// platform archive file name
		String _archiveName;
		
		// archive checksum and size
		String _checksum;
		uint32_t _size;
		
		// arraymap of strings=value
		VectorMap<String, String> _values;
		
		// provided boards, from json package file
		// used just to display them in board manager
		Vector<String> _providedBoards;
		
		// defined boards
		ArrayMap<String, Board> _boards;
		
		// tools dependencies
		Vector<ToolDep> _toolsDeps;
	
		// owner platform
		Platform *_platform;
	
		// constructor
		PlatformVersion(Platform *platform);
	
		// parse platform data contained in a Value object
		bool ParseJSON(Value const &json);
		
		// check if is installed
		bool CheckInstall(void);
		
		// get local staging archive
		String GetStagingArchivePath(void);
		
		// parse board file
		bool ParseBoardsFile(void);

		// parse a map containing platform file in form ok key=value
		bool ParsePlatformFile();
		
	protected:
	
	public:
	
		// destructor
		~PlatformVersion();
		
		// get local root folder
		String GetLocalFolder(void);
		
		// get owning platform
		Platform const &GetPlatform(void) const { return *_platform; }
		Platform &GetPlatform(void) { return *_platform; }
		
		// get version
		String const &GetVersion(void) const { return _version; }
		
		// get platform URL
		String const &GetUrl(void) const { return _url; }
		
		// get platform archive file name
		String const &GetArchiveName(void) const { return _archiveName; }
		
		// get archive checksum and size
		String const &GetChecksum(void) const { return _checksum; }
		uint32_t GetArchiveSize(void) const { return _size; }
		
		// get provided boards as given by json file
		// useful only for board manager display
		Vector<String> const &GetProvidedBoards(void) const { return _providedBoards; }
		
		// get all available boards
		ArrayMap<String, Board> const &GetBoards(void) const { return _boards; }
		ArrayMap<String, Board> &GetBoards(void) { return _boards; }

		// get tools dependencies
		Vector<ToolDep> const &GetToolsDeps(void) const { return _toolsDeps; }

		// get platform values
		VectorMap<String, String> const &GetValues(void) const { return _values; }
		
		// get dependent tools values
		VectorMap<String, String> GetToolsValues(void) const;
};

class Platform
{
	friend class Package;
	friend class PackagesClass;
	friend class SettingsClass;
	
	private:
	
		// owning package
		Package *_package;
	
		// installed flag
		bool _installed;
		
		// if installed, installed version
		String _installedVersion;
	
		// platform name
		String _name;
		
		// platform architecture
		String _architecture;
		
		// platform cathegory
		String _cathegory;
		
		// the versions available
		ArrayMap<String, PlatformVersion> _versions;
		
		// constructor
		Platform(Package *owner);
	
		// parse platform data contained in a Value object
		bool ParseJSON(Value const &json);
		
	protected:
	
	public:
	
		// destructor
		~Platform();
		
		// install (or reinstall) platform files (and dependencies)
		bool Install(String const &version);
		
		// remove platform files (and dependencies)
		bool Remove(void);
		
		// check if installed
		bool IsInstalled(void) const { return _installed; }
		
		// get installed version
		String const &GetInstalledVersion(void) const { return _installedVersion; }
		PlatformVersion *GetActiveVersion(void) { if(_installed) return &_versions.Get(_installedVersion); else return NULL; }
		PlatformVersion const *GetActiveVersion(void) const { if(_installed) return &_versions.Get(_installedVersion); else return NULL; }
		
		// get latest platform version available
		String GetLastVersion(void) const;
		
		// get name
		String const &GetName(void) const { return _name; }
		
		// get architecture
		String const &GetArchitecture(void) const { return _architecture; }
		
		// get cathegory
		String const &GetCathegory(void) const { return _cathegory; }
		
		// get installed versions
		ArrayMap<String, PlatformVersion> const &GetVersions(void) const { return _versions; }
		ArrayMap<String, PlatformVersion> &GetVersions(void) { return _versions; }
		
		// get owning package
		Package &GetPackage(void) { return *_package; }
};

#endif
