// i3csstatus - Alternative generator of i3 status bar written in c#
// (c)   2022 Jiri Kalvoda <jirikalvoda@kam.mff.cuni.cz>

// This program 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 3 of the License, or
// any later version.

// This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.

#nullable enable
using System;
using System.Collections.Generic;
using System.Text;

using System.IO;
using System.Linq;

using Color = System.Drawing.Color;
using Process = System.Diagnostics.Process;

using Config;

namespace i3csstatus;


abstract partial class StatusBar
{
	protected static Module addStandardModuleWrappers(ConfigSection section, Module module, ModuleParent parrent)
	{
		if(section.Contains("_default_color"))
			module  = new WrapperDefaultColor(module, section.Mandatory("_default_color").AsColor());

		if(section.Contains("_color"))
			module  = new WrapperColor(module, section.Mandatory("_color").AsColor());

		module.Init(parrent, section);
		return module;
	}
}

#nullable disable
class ModuleWrapper: Module, ModuleParent
{
	protected Module child;
	protected ModuleParent parent;

	public ModuleWrapper(Module _child)
	{
		child = _child;
	}

	virtual public IEnumerable<Block> Get()
		=> child.Get();
	virtual public void Init(ModuleParent _parent, ConfigSection section)
	{
		parent = _parent;
		child.Init(this, section);
	}
	virtual public T GetGlobal<T>() where T: GlobalModuleResource, new()
		=> parent.GetGlobal<T>();
	virtual public void Schedule(int in_ms)
		=> parent.Schedule(in_ms);
}

class WrapperDefaultColor: ModuleWrapper
{
	Color defaultColor;
	public WrapperDefaultColor(Module _child, Color _defaultColor):base(_child)
	{
		defaultColor = _defaultColor;
	}
	override public IEnumerable<Block> Get()
		=> child.Get().Select(x => x with {
					Color = x.Color==null ? defaultColor : x.Color
				}).ToArray();
}

class WrapperColor: ModuleWrapper
{
	Color color;
	public WrapperColor(Module _child, Color _color):base(_child)
	{
		color = _color;
	}
	override public IEnumerable<Block> Get()
		=> child.Get().Select(x => x with {
					Color = color
				}).ToArray();
}

class WrapperExec: ModuleWrapper
{
	string cmd;
	MouseButton button;
	Modifiers modifiers;
	public WrapperExec(Module _child, string _cmd, MouseButton _button, Modifiers _modifiers):base(_child)
	{
		cmd = _cmd;
		button = _button;
		modifiers = _modifiers;
	}
	override public IEnumerable<Block> Get()
		=> child.Get().Select(x => x with {
					OnClick = ev =>
						{
							if(ev.Button == button && ev.Modifiers == modifiers)
								POSIX.Bash(cmd);
							else if(x.OnClick != null)
								x.OnClick(ev);
						}
				}).ToArray();
}