#pragma TextEncoding = "UTF-8"
#pragma rtGlobals=3		// Use modern global access method and strict wave access.
#pragma version = 1.00
#pragma IgorVersion = 6.2
#pragma ModuleName = PearlTools
#include "pearl-gui-tools"

// general programming tools for Igor

// $Id$
// author: matthias.muntwiler@psi.ch
// Copyright (c) 2009-14 Paul Scherrer Institut

// Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//   http://www.apache.org/licenses/LICENSE-2.0

function DefaultWaveIterator(w, sdata)
// function prototype for IterateWaves
	wave w // wave which the iterator is supposed to work on
	string &sdata // string with additional data, shared between calls
		// this is a pass-by-reference argument,
		// the function may modify the string
end

function AppendToGraphIterator(w, sdata)
// append iterated waves to the current graph
	wave w // wave to be displayed
	string &sdata // not used
	
	appendtograph w
end

function SumWavesIterator(w, sdata)
// sum waves into one result wave
	wave w // wave which the iterator is supposed to work on
	string &sdata // name of the result wave, can include absolute path
		// the wave must exist and compatible with the summands
		// the caller is responsible for initialization of the wave
		
	wave result = $sdata
	result += w
end

function/s IterateWaves(matchStr, iterator, sdata)
// iterate over all waves matching a specified pattern (see built-in WaveList function),
// passing each wave to a user-defined iterator function
	string matchStr // matchStr as for WaveList
	funcref DefaultWaveIterator iterator // iterator function
		// use the DefaultWaveIterator function as a template
	string sdata // data string passed to iterator function
		// the iterator may modify the string
		// the function returns the string at the end
	
	string wlist = WaveList(matchStr, ";", "")
	variable n = ItemsInList(wlist, ";")
	variable i
	for (i = 0; i < n; i += 1)
		wave w = $(StringFromList(i, wlist, ";"))
		iterator(w, sdata)
	endfor
	return sdata
end

function DefaultFolderIterator(df, sdata)
// function prototype for IterateWaves
	dfref df // data folder reference which the iterator is supposed to work on
	string &sdata // string with additional data, shared between calls
		// this is a pass-by-reference argument,
		// the function may modify the string
		
	// switch to requested data folder
	setdatafolder df
	// for testing
	print getdatafolder(1)
	// no need to switch back to original folder
end

function/s IterateDataFolders(matchStr, iterator, sdata, [progress_title])
// iterate over all data folders matching a specified pattern in the current data folder,
// passing each folder to a user-defined iterator function
	string matchStr // matchStr as for the built-in stringmatch function
	funcref DefaultFolderIterator iterator // iterator function
		// use the DefaultFolderIterator function as a template
	string sdata // data string passed to iterator function
		// the iterator may modify the string
		// the function returns the string at the end
	string progress_title // title of the progress window (optional)
		// if not specified or empty, the progress window will not be shown.
		// if the progress window is show, the user can abort the iteration.
		// the function result does not indicate whether the iteration was completed or aborted.
		// the iterator and caller must take care of leaving the data in a consistent state.
	
	if (ParamIsDefault(progress_title))
		progress_title = ""
	endif
	variable show_progress = strlen(progress_title) > 0
	
	dfref origdf = GetDataFolderDFR()
	dfref curdf
	variable index = 0
	variable abort_req = 0
	string objName
	
	variable ndf = CountObjectsDFR(origdf, 4)
	if (show_progress)
		display_progress_panel(progress_title, "", ndf)
	endif
		
	do
		objName = GetIndexedObjNameDFR(origdf, 4, index)
		if (strlen(objName) == 0)
			break
		endif
		if (stringmatch(objname, matchstr))
			if (show_progress)
				abort_req = update_progress_panel(index, message=objName)
				if (abort_req)
					break
				endif
			endif
			setdatafolder origdf
			curdf = $(":" + objname)
			iterator(curdf, sdata)
		endif
		index += 1
	while(1)
	
	if (show_progress)
		kill_progress_panel()
	endif
	
	setdatafolder origdf
	return sdata
end
