#ifndef _FishIDE_FishIDE_h
#define _FishIDE_FishIDE_h

#include <CtrlLib/CtrlLib.h>


//extern "C" { FILE _iob[3] = {__iob_func()[0], __iob_func()[1], __iob_func()[2]}; }

#include "ProjectsCtrl.h"
#include "Controls.h"

#include "AVersion.h"

#define KEYGROUPNAME "Ide"
#define KEYNAMESPACE IdeKeys
#define KEYFILE      <FishIDE/FishIDE.key>
#include             <CtrlLib/key_header.h>

#include "Splash.h"
extern Splash &splash(void);

extern AVersion VERSION;

using namespace Upp;

class FishIDE : public TopWindow
{
	private:
		// jobs tabbed control
		ProjectsCtrl projectsCtrl;
		
		// statusbar
		StatusBar statusBar;
		
		MenuBar menu;
		ToolBar toolBar;
		MenuBar toolBarPopup;
		
		// board selector
		BoardCtrl boardSelector;

		// device selector
		DeviceCtrl deviceSelector;
		
		bool find_pick_sel;
		bool find_pick_text;
		
		// propagate theme application
		void themeApplyCb(Theme const *t);
		
		// examples management
		VectorMap<String, Vector<String>> GatherLibrariesExamples(String const &librariesRoot);
		VectorMap<String, Vector<String>> GatherManagedExamples(void);
		
		void OpenExample(String const &path, bool inPlace);
		
	protected:

		bool ProjectsAvail(void);
			
		void ProjectNewCb();
		void ProjectOpenCb();
		
		void ProjectOpenLibExampleCb(Bar &bar, String const &libsRoot, bool inPlace);
		
		void ProjectOpenManagedExampleCb(Bar &bar, bool inPlace);
		void ProjectOpenPlatformLibExampleCb(Bar &bar, bool inPlace);
		void ProjectOpenSystemLibExampleCb(Bar &bar, bool inPlace);
		void ProjectOpenUserLibExampleCb(Bar &bar, bool inPlace);

		void ProjectOpenExampleMenuCb(Bar &bar, bool inPlace);
		void ProjectOpenExampleToolbarCb(Bar &bar);
		
		void ProjectSaveCb();
		void ProjectSaveAsCb();
		void ProjectPropertiesCb();
		void ProjectExitCb();
		
		void BuildBuildCb();
		void BuildUploadCb();
		void BuildRemoveSketchOutputCb();
		void BuildRemoveBoardOutputCb();
		void BuildRemoveAllOutputCb();
		void BuildShowDisassemblyCb();
		
		void ToolsBoardManagerCb();
		void ToolsExampleManagerCb();
		void ToolsLibraryManagerCb();
		void ToolsLibraryZipInstallCb();
		void ToolsSettingsCb();

		void HelpAboutCb(void);

		void ProjectMenu(Bar &bar);

		void EditMenu(Bar &bar);

			void SearchMenu(Bar& bar);
				void  EditFind();
				void  EditReplace();
				void  EditFindReplacePickText();
				void  EditFindNext();
				void  EditFindPrevious();
				void  EditFindInFiles();
				void  EditReplaceInFiles();
				void  EditPaste();

				void  EditFormatCode(void);
			
/*
			void      EditSpecial(Bar& menu);
				void  TranslateString();
				void  SwapChars()               { editor.SwapChars(); }
				void  CopyWord()                { editor.CopyWord(); }
				void  DuplicateLine()           { editor.DuplicateLine(); }
				void  AlterText(WString (*op)(const WString& in));
				void  TextToUpper();
				void  TextToLower();
				void  TextToAscii();
				void  TextInitCaps();
				void  SwapCase();
				void  ToCString();
				void  ToComment();
				void  CommentLines();
				void  UnComment();
*/

		void BuildMenu(Bar &bar);

		void ToolsMenu(Bar &bar);
			void AKEditor();
			void DoEditKeys();



		void HelpMenu(Bar &bar);
		void MainMenu(Bar &bar);

		void ToolBarMenu(Bar &bar);

		// board selection callback
		void selectBoardCb(String board);
	
		// device selection callback
		void selectDeviceCb(String device);
		
		// update menus functions -- triggered on projects changes
		void updateMenuCb(void);
		
		// triggered by changes in settings
		void settingsChangedCb(void);
	
		// triggered by changes in libraries
		void librariesChangedCb(void);
	
		// triggered by changes in themes
		void themeChangedCb(Theme const *t);
		
		// mdns loop -- checks periodically for network ports changes
		void mdnsLoopCb(void);
	
		// called when a mdns service appears
		void mdnsCb(void);

		enum {
			TIMEID_MENU = ParentCtrl::TIMEID_COUNT,
			TIMEID_MDNS,
			TIMEID_COUNT
		};


	public:
		typedef FishIDE CLASSNAME;
		
		// constructor
		FishIDE();
		
		// destructor
		~FishIDE();
		
		// serialization support -- just serializes placement
		void Serialize(Stream &s)
		{
			// serialize windows positions and size
			SerializePlacement(s);
			
			// serialize splitters
			projectsCtrl.Serialize(s);
		}

		// get active project
		Project *GetCurrentProject(void) { return projectsCtrl.GetCurrentProject(); }
		
		// store/loads last opened projects
		void RestoreOpenedProjects(void);
		void SaveOpenedProjects(void);
		
		// start MDNS
		void StartMDNS(void);
		
		// auto setup
		bool AutoSetup(void);
};

#endif
