/*
* Copyright © 2004-2012 Jens Oknelid, paskharen@gmail.com
* Copyright © 2011-2025 BMDC
* This file is part of BMDC.
* BMDC is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version.
*
* BMDC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Xfce-nameday-plugin. If not, see <https://www.gnu.org/licenses/>.
*/

#ifndef _FUNC_HH
#define _FUNC_HH

class FuncBase
{
	public:
		FuncBase() {}
		virtual ~FuncBase() {}
		static gboolean call_(gpointer d) {
			((FuncBase*)d)->call();
                        return FALSE;
		};
		virtual void call() = 0;
		virtual const std::string& getID() = 0;
};

template<class c>
class Func0: public FuncBase
{
	public:
		Func0(c *obj, void (c::*func)())
		{
			this->obj = obj;
			this->func = func;
		}

		void call() {
			(*obj.*func)();
		}

		const std::string& getID()
		{
			return obj->getID();
		}

	private:
		c *obj;
		void (c::*func)();
};

template<class c, typename p1>
class Func1: public FuncBase
{
	public:
		Func1(c *obj, void (c::*func)(p1), p1 param1):
			_param1(param1)
		{
			this->obj = obj;
			this->func = func;
		}

		void call() {
			(*obj.*func)(_param1);
		}

		const std::string& getID()
		{
			return obj->getID();
		}

	private:
		c *obj;
		void (c::*func)(p1);
		p1 _param1;
};

template<class c, typename p1, typename p2>
class Func2: public FuncBase
{
	public:
		Func2(c *obj, void (c::*func)(p1, p2), p1 param1, p2 param2):
			_param1(param1),
			_param2(param2)
		{
			this->obj = obj;
			this->func = func;
		}

		void call() {
			(*obj.*func)(_param1, _param2);
		}

		const std::string& getID()
		{
			return obj->getID();
		}

	private:
		c *obj;
		void (c::*func)(p1, p2);
		p1 _param1;
		p2 _param2;
};

template<class c, typename p1, typename p2, typename p3>
class Func3: public FuncBase
{
	public:
		Func3(c *obj, void (c::*func)(p1, p2, p3), p1 param1, p2 param2, p3 param3):
			_param1(param1),
			_param2(param2),
			_param3(param3)
		{
			this->obj = obj;
			this->func = func;
		}

		void call() {
			(*obj.*func)(_param1, _param2, _param3);
		}

		const std::string& getID()
		{
			return obj->getID();
		}

	private:
		c *obj;
		void (c::*func)(p1, p2, p3);
		p1 _param1;
		p2 _param2;
		p3 _param3;
};

template<class c, typename p1, typename p2, typename p3, typename p4>
class Func4: public FuncBase
{
	public:
		Func4(c *obj, void (c::*func)(p1, p2, p3, p4),
			p1 param1, p2 param2, p3 param3, p4 param4):
			_param1(param1),
			_param2(param2),
			_param3(param3),
			_param4(param4)
		{
			this->obj = obj;
			this->func = func;
		}

		void call() {
			(*obj.*func)(_param1, _param2, _param3, _param4);
		}

		const std::string& getID()
		{
			return obj->getID();
		}

	private:
		c *obj;
		void (c::*func)(p1, p2, p3, p4);
		p1 _param1;
		p2 _param2;
		p3 _param3;
		p4 _param4;
};

template<class c, typename p1, typename p2, typename p3, typename p4, typename p5>
class Func5: public FuncBase
{
	public:
		Func5(c *obj, void (c::*func)(p1, p2, p3, p4, p5),
			p1 param1, p2 param2, p3 param3, p4 param4, p5 param5):
			_param1(param1),
			_param2(param2),
			_param3(param3),
			_param4(param4),
			_param5(param5)
		{
			this->obj = obj;
			this->func = func;
		}

		void call() {
			(*obj.*func)(_param1, _param2, _param3, _param4, _param5);
		}

		const std::string& getID()
		{
			return obj->getID();
		}

	private:
		c *obj;
		void (c::*func)(p1, p2, p3, p4, p5);
		p1 _param1;
		p2 _param2;
		p3 _param3;
		p4 _param4;
		p5 _param5;
};

template<class c, typename p1, typename p2, typename p3, typename p4, typename p5, typename p6>
class Func6: public FuncBase
{
	public:
		Func6(c *obj, void (c::*func)(p1, p2, p3, p4, p5, p6),
			p1 param1, p2 param2, p3 param3, p4 param4, p5 param5, p6 param6):
			_param1(param1),
			_param2(param2),
			_param3(param3),
			_param4(param4),
			_param5(param5),
			_param6(param6)
		{
			this->obj = obj;
			this->func = func;
		}

		void call() {
			(*obj.*func)(_param1, _param2, _param3, _param4, _param5, _param6);
		}

		const std::string& getID()
		{
			return obj->getID();
		}

	private:
		c *obj;
		void (c::*func)(p1, p2, p3, p4, p5, p6);
		p1 _param1;
		p2 _param2;
		p3 _param3;
		p4 _param4;
		p5 _param5;
		p6 _param6;
};

template<class c, typename p1, typename p2, typename p3, typename p4, typename p5, typename p6, typename p7>
class Func7: public FuncBase
{
	public:
		Func7(c *obj, void (c::*func)(p1, p2, p3, p4, p5, p6, p7),
			p1 param1, p2 param2, p3 param3, p4 param4, p5 param5, p6 param6, p7 param7):
			_param1(param1),
			_param2(param2),
			_param3(param3),
			_param4(param4),
			_param5(param5),
			_param6(param6),
			_param7(param7)
		{
			this->obj = obj;
			this->func = func;
		}

		void call() {
			(*obj.*func)(_param1, _param2, _param3, _param4, _param5, _param6, _param7);
		}

		const std::string& getID()
		{
			return obj->getID();
		}

	private:
		c *obj;
		void (c::*func)(p1, p2, p3, p4, p5, p6, p7);
		p1 _param1;
		p2 _param2;
		p3 _param3;
		p4 _param4;
		p5 _param5;
		p6 _param6;
		p7 _param7;
};

template<class c, typename p1, typename p2, typename p3, typename p4,
	typename p5, typename p6, typename p7, typename p8>
class Func8: public FuncBase
{
	public:
		Func8(c *obj, void (c::*func)(p1, p2, p3, p4, p5, p6, p7, p8),
			p1 param1, p2 param2, p3 param3, p4 param4, p5 param5, p6 param6,
			p7 param7, p8 param8):
			_param1(param1),
			_param2(param2),
			_param3(param3),
			_param4(param4),
			_param5(param5),
			_param6(param6),
			_param7(param7),
			_param8(param8)
		{
			this->obj = obj;
			this->func = func;
		}

		void call() {
			(*obj.*func)(_param1, _param2, _param3, _param4, _param5, _param6,
				_param7, _param8);
			
		}

		const std::string& getID()
		{
			return obj->getID();
		}

	private:
		c *obj;
		void (c::*func)(p1, p2, p3, p4, p5, p6, p7, p8);
		p1 _param1;
		p2 _param2;
		p3 _param3;
		p4 _param4;
		p5 _param5;
		p6 _param6;
		p7 _param7;
		p8 _param8;
};

template<class c, typename p1, typename p2, typename p3, typename p4,
	typename p5, typename p6, typename p7, typename p8, typename p9>
class Func9: public FuncBase
{
	public:
		Func9(c *obj, void (c::*func)(p1, p2, p3, p4, p5, p6, p7, p8, p9),
			p1 param1, p2 param2, p3 param3, p4 param4, p5 param5, p6 param6,
			p7 param7, p8 param8, p9 param9):
			_param1(param1),
			_param2(param2),
			_param3(param3),
			_param4(param4),
			_param5(param5),
			_param6(param6),
			_param7(param7),
			_param8(param8),
			_param9(param9)
		{
			this->obj = obj;
			this->func = func;
		}

		void call() {
			(*obj.*func)(_param1, _param2, _param3, _param4, _param5, _param6,
				_param7, _param8, _param9);
		}

		const std::string& getID()
		{
			return obj->getID();
		}

	private:
		c *obj;
		void (c::*func)(p1, p2, p3, p4, p5, p6, p7, p8, p9);
		p1 _param1;
		p2 _param2;
		p3 _param3;
		p4 _param4;
		p5 _param5;
		p6 _param6;
		p7 _param7;
		p8 _param8;
		p9 _param9;
};

#else
template<class c>
class Func0;
template<class c, class p1>
class Func1;
template<class c, class p1, class p2>
class Func2;
template<class c, class p1, class p2, class p3>
class Func3;
template<class c, class p1, class p2, class p3, class p4, class p5, class p6>
class Func6;
template<class c, class p1, class p2, class p3, class p4, class p5, class p6, class p7>
class Func7;
template<class c, class p1, class p2, class p3, class p4, class p5, class p6,
	class p7, class p8>
class Func8;
template<class c, class p1, class p2, class p3, class p4, class p5, class p6,
	class p7, class p8, class p9>
class Func9;
#endif
