/********************************************************************/
/* Copyright (c) 2019 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/********************************************************************/
#pragma once

#include "mg/Group.h"

namespace groupfunc
{
	/// MGGelPosition というクラスが公式に存在するが、ここでは利用できない。
	struct GelLocation
	{
		MGGroup::iterator pos;
		MGGroup* group;

		GelLocation(MGGroup::iterator p, MGGroup* g)
			 : pos(p), group(g)
		{
		}
	};

	/// 汎用 Group ツリー探索アルゴリズム。深さ優先。
	template <typename F>
	GelLocation SearchGroup(MGGroup& g, F func)
	{
		MGGroup::iterator first = g.begin(), last = g.end();
		for(; first != last; ++first){
			MGGel* node = first->get();
			MGGroup* g2 = dynamic_cast<MGGroup*>(node);
			if(g2){
				return SearchGroup(*g2, func);
			}else if(func(node)){
				return GelLocation(first, &g);
			}
		}
		return GelLocation(g.end(), 0);
	}

	/// 汎用 Group ツリー全走査アルゴリズム。深さ優先。
	template <typename F>
	void WalkGroup(MGGroup& g, F func)
	{
		MGGroup::iterator first = g.begin(), last = g.end();
		for(; first != last; ++first){
			MGGel* node = first->get();
			MGGroup* g2 = dynamic_cast<MGGroup*>(node);
			if(g2){
				WalkGroup(*g2, func);
			}else{
				func(node);
			}
		}
	}
}
