#pragma TextEncoding="UTF-8"
#pragma rtGlobals=3
#pragma moduleName=SIDAMStartExit

#ifndef SIDAMshowProc
#pragma hide = 1
#endif

#include "SIDAM_Config"
#include "SIDAM_Constants"

//******************************************************************************
//	Start SIDAM
//******************************************************************************
Function SIDAMStart()
	printf "\r SIDAM %d.%d.%d\r", SIDAM_VERSION_MAJOR, SIDAM_VERSION_MINOR, SIDAM_VERSION_PATCH

	//	Construct SIDAM_Procedures.ipf and complie
	createProcFile()
	Execute/P "INSERTINCLUDE \"" + SIDAM_FILE_INCLUDE + "\""
	Execute/P "COMPILEPROCEDURES "
	
	SetIgorHook BeforeFileOpenHook = SIDAMFileOpenHook
	SetIgorHook BeforeExperimentSaveHook = SIDAMBeforeExperimentSaveHook
	SetIgorHook AfterCompiledHook = SIDAMAfterCompiledHook
End

#if IgorVersion() >= 9
Function SIDAMSource()
	Execute/P/Q "SIDAMStartExit#createProcFile()"
	Execute/P "RELOAD CHANGED PROCS "
	Execute/P "COMPILEPROCEDURES "
End
#else
Function SIDAMSource()
	Execute/P/Q "SIDAMStartExit#createProcFile()"
	Execute/P "COMPILEPROCEDURES "
End
#endif

Static Function createProcFile()
	//	Make a list of ipf files
	//	The core files
	Make/T/FREE lw = {"SIDAM_Menus.ipf", "SIDAM_Constants.ipf", "SIDAM_Hook.ipf"}
	//	file loaders
	appendIpf(lw, "[loader]")
	//	extensions
	appendIpf(lw, "[extension]")
	
	// Open SIDAM_Procedures.ipf
	Variable refNum
	String pathStr = SpecialDirPath("Igor Pro User Files", 0, 0, 0) + "User Procedures:"
	String pathName = UniqueName("path",12,0)
	NewPath/Q $pathName, pathStr
	Open/P=$pathName/Z refNum, as SIDAM_FILE_INCLUDE+".ipf"
	KillPath $pathName
	if (V_flag)
		return 0
	endif
	
	//	write the hide pragma
	fprintf refNum, "//This file was automatically generated by SIDAM.\r"
	fprintf refNum, "#ifndef SIDAMshowProc\r#pragma hide = 1\r#endif\r"
	//	write #include ...
	int i
	for(i = 0; i < numpnts(lw); i++)
		fprintf refNum, "#include \"%s\"\r", RemoveEnding(lw[i],".ipf")
	endfor
	//	write configurations
	SIDAMConfigToProc(refNum)
	
	Close refNum
End

Static Function appendIpf(Wave/T listw, String tableName)
	String values = StringByKey( \
		"path", SIDAMConfigItems(tableName, usespecial=1), \
		SIDAM_CHAR_KEYSEP, SIDAM_CHAR_ITEMSEP)
	int i
	for (i = 0; i < ItemsInList(values); i++)
		Wave/T/Z w1 = ipfList(StringFromList(i, values))
		if (WaveType(w1,1) == 2)
			Concatenate/NP/T/FREE {w1}, listw
		endif
	endfor
End

//	make a list of ipf files under a folder
Static Function/WAVE ipfList(String folderpath)

	String pathName = UniqueName("tmpPath",12,0)
	//	If the folder path starts with ":", regard it as a relative path
	//	from the folder where the config file is, otherwise an absolute path.
	int isAbs = CmpStr(folderpath[0], ":")
	if (isAbs)
		NewPath/O/Q/Z $pathName, folderpath
	else
		NewPath/O/Q/Z $pathName, SIDAMConfigPath(1) + folderpath[1,strlen(folderpath)-1]
	endif
	if (V_flag)	//	the folder is not found
		print folderpath + " is not found."
		return $""
	endif

	String listStr = IndexedFile($pathName,-1,".ipf")
	Make/FREE/T/N=(ItemsInList(listStr)) w
	if (isAbs)
		w = ParseFilePath(2, folderpath, ":", 0, 0) + StringFromList(p,listStr)
	else
		w = StringFromList(p,listStr)
	endif
	
	String dirListStr = IndexedDir($pathName,-1,0)
	int i, n = ItemsInList(dirListStr)
	for (i = 0; i < n; i++)
		Concatenate/T {ipfList(folderpath+":"+StringFromList(i,dirListStr))}, w
	endfor

	KillPath $pathName

	return w
End


//******************************************************************************
//	Exit SIDAM
//******************************************************************************
Function sidamExit()
	SetIgorHook/K BeforeFileOpenHook = SIDAMFileOpenHook
	SetIgorHook/K AfterCompiledHook = SIDAMAfterCompiledHook
	SetIgorHook/K BeforeExperimentSaveHook = SIDAMBeforeExperimentSaveHook
	Execute/P/Q/Z "DELETEINCLUDE \""+SIDAM_FILE_INCLUDE+"\""
	Execute/P/Q/Z "SetIgorOption poundUndefine=SIDAMshowProc"
	Execute/P/Q/Z "COMPILEPROCEDURES "
	Execute/P/Q/Z "BuildMenu \"All\""
	KillPath/Z KMMain
End
