#ifndef _FishIDE_Builder_h_
#define _FishIDE_Builder_h_

#include "IdeEnvironment.h"
#include "Depend.h"
#include "SourceTools.h"

#include "LibraryInfo.h"

class BuilderClass : public IdeEnvironment
{
	friend BuilderClass &__GetBuilder(void);
	
	public:
	
		struct ErrorLine : Moveable<ErrorLine>
		{
			String file;
			int line;
			int pos;
			String message;
			Vector<String> extra;
			bool isError;
		};
		
		typedef BuilderClass CLASSNAME;

	private:
	
		// error flag
		bool _isError;
		
		// error stream contents
		String _errorStream;

		// parsed error messages	
		Vector<ErrorLine> _parsedMessages;
		
		// command strings used to call various builder apps
		String _recipe_c_o;
		String _recipe_cpp_o;
		String _recipe_S_o;
		String _recipe_ar;
		String _recipe_combine;
		String _recipe_objcopy_eep;
		String _recipe_objcopy_hex;
		String _recipe_output_tmp_file;
		String _recipe_output_save_file;

		String _recipe_size;
		String _recipe_size_regex;
		String _recipe_size_regex_data;
		String _recipe_size_regex_eeprom;
		
		String _recipe_preproc_includes;
		String _recipe_preproc_macros;
		String _recipe_elf_lst;
		
		// command strings for upload
		String _upload_recipe;
		String _upload_network_recipe;
		
		// dependency data
		Depend _depend;
		
		// library list
		Vector<Ptr<LibraryInfo>> _libraries;
		
		// include path string
		String _includes;
		
		// preprocessed ino file path
		String _preprocessedINO;
		
		// set error flag and return !_isError
		void SetError(void) { _isError = true; }
		void ClearError(void) { _isError = false; }

		// constructor
		BuilderClass();
		
		// get includes
		void GetIncludes();
		
		// create recipes
		bool CreateRecipes();
		
		// various compile commands
		bool Compile(String const &src, String const &obj);
		bool Archive(String const &archive, String const &obj);
		bool Archive(String const &archive, Vector<String> const &objects);
		bool Combine(void);
		bool ObjCopy_HEX(void);
		
		// pre-build stuffs
		// (prepare for building)
		bool PrepareBuild(Project *project);
		
		// build core files
		bool BuildCore(void);
		
		// build a library
		bool BuildLib(Ptr<LibraryInfo> lib);
		
		// build used libraries
		bool BuildLibs(void);
		
		// preprocess the sketch
		bool PreprocessSketch(void);

		// build the sketch
		bool BuildSketch(void);
		
		// calculate sketch size
		bool CalcSize(void);
		
		// parse error messages
		bool ParseMessages(void);
		
		// show upload progress callback
		bool showUploadProgressCb(String const &o, String const &e);
		
	protected:
	
	public:
	
		// destructor
		~BuilderClass();
		
		// build command
		bool Build(Project *project);
		
		// upload command
		bool Upload(Project *project);

		// show hex disassembly
		String ShowDisasm(Project *project);
		
		// build (compile) a single file
		// (output discarded, just for speed tests)
		bool CompileFile(Project *project, String path);
};

extern BuilderClass &__GetBuilder(void);

#define Builder __GetBuilder()

#endif
