// MariFX menu code

// preset save functions
Class MFXPresetUtility
{
	static clearscope void SavePreset( int slot )
	{
		let lmp = Wads.CheckNumForFullname("cvarinfo.marifx");
		String dat = Wads.ReadLump(lmp);
		// fucking Windows
		dat.Substitute("\r","");
		Array<String> list, ln;
		list.Clear();
		dat.Split(list,"\n");
		let dct = Dictionary.Create();
		bool dosave = false;
		CVar v;
		String pn = "";
		for ( int i=0; i<list.Size(); i++ )
		{
			if ( list[i].Mid(3,17) == "BEGIN PRESET VARS" ) dosave = true;
			else if ( list[i].Mid(3,15) == "END PRESET VARS" ) dosave = false;
			if ( !dosave || (list[i].Length() == 0) || (list[i].Left(2) == "//") || (list[i].Left(1) == "") )
				continue;
			int eq = list[i].IndexOf("=");
			if ( eq == -1 ) continue;
			list[i].Truncate(eq);
			ln.Clear();
			list[i].Split(ln," ",0);
			for ( int j=0; j<ln.Size(); j++ )
			{
				if ( (ln[j].Left(4) != "mfx_") ) continue;
				v = CVar.FindCVar(ln[j]);
				if ( !v ) continue;
				String str = v.GetString();
				dct.Insert(ln[j],str);
				if ( ln[j] == "mfx_presetname" ) pn = str;
			}
		}
		v = CVar.FindCVar("mfx_preset"..slot);
		if ( v ) v.SetString(dct.ToString());
		Console.Printf(StringTable.Localize("$MFX_PRESETSAVED"),slot,pn);
	}

	static clearscope void LoadPreset( int slot )
	{
		CVar v = CVar.FindCVar("mfx_preset"..slot);
		if ( !v ) return;
		String str = v.GetString();
		if ( str == "" )
		{
			Console.Printf(StringTable.Localize("$MFX_PRESETEMPTY"),slot);
			return;
		}
		let dct = Dictionary.FromString(str);
		let di = DictionaryIterator.Create(dct);
		String pn = "";
		while ( di.Next() )
		{
			String k = di.Key();
			v = CVar.FindCVar(k);
			if ( !v ) continue;
			String str = di.Value();
			v.SetString(str);
			if ( k == "mfx_presetname" ) pn = str;
		}
		Console.Printf(StringTable.Localize("$MFX_PRESETLOADED"),slot,pn);
	}

	static clearscope String GetPresetName( int slot )
	{
		CVar v = CVar.FindCVar("mfx_preset"..slot);
		if ( !v ) return "Error";
		String str = v.GetString();
		if ( str == "" ) return "Empty";
		let dct = Dictionary.FromString(str);
		return dct.At("mfx_presetname");
	}
}

// for preset listing
Class OptionMenuItemMFXPresetList : OptionMenuItemOptionBase
{
	CVar mCVar;
	String names[MFX_NUMPRESETS];

	OptionMenuItemMFXPresetList Init( String label, Name command, CVar graycheck = null, int center = 0 )
	{
		Super.Init(label,command,'',graycheck,center);
		mCVar = CVar.FindCVar(mAction);
		UpdateNames();
		return self;
	}

	void UpdateNames()
	{
		for ( int i=0; i<MFX_NUMPRESETS; i++ )
			names[i] = MFXPresetUtility.GetPresetName(i);
	}

	override int GetSelection()
	{
		return clamp(mCVar.GetInt(),0,MFX_NUMPRESETS-1);
	}

	override void SetSelection( int Selection )
	{
		mCVar.SetInt(clamp(Selection,0,MFX_NUMPRESETS-1));
	}

	override int Draw( OptionMenuDescriptor desc, int y, int indent, bool selected )
	{
		if ( mCenter ) indent = (screen.GetWidth()/2);
		drawLabel(indent,y,selected?OptionMenuSettings.mFontColorSelection:OptionMenuSettings.mFontColor,isGrayed());
		int sel = GetSelection();
		drawValue(indent,y,OptionMenuSettings.mFontColorValue,String.Format("%d - %s",sel,names[sel]),isGrayed());
		return indent;
	}

	override bool MenuEvent( int mkey, bool fromcontroller )
	{
		int Selection = GetSelection();
		if ( mkey == Menu.MKEY_Left )
		{
			if ( --Selection < 0 ) Selection = MFX_NUMPRESETS-1;
		}
		else if ( (mkey == Menu.MKEY_Right) || (mkey == Menu.MKEY_Enter) )
		{
			if ( ++Selection >= MFX_NUMPRESETS ) Selection = 0;
		}
		else return OptionMenuItem.MenuEvent(mkey,fromcontroller);
		SetSelection(Selection);
		Menu.MenuSound("menu/change");
		return true;
	}
}

// keyboard input snaps to increment
// holding shift increments by ten steps
Class OptionMenuItemMFXSlider : OptionMenuItemSlider
{
	bool bShift, bAlt;

	override bool MenuEvent ( int mkey, bool fromcontroller )
	{
		double value = GetSliderValue();
		double step = bShift?(mStep*10):bAlt?(mStep*5):mStep;
		if ( mkey == Menu.MKEY_Left ) value -= step;
		else if ( mkey == Menu.MKEY_Right ) value += step;
		else return OptionMenuItem.MenuEvent(mkey,fromcontroller);
		if ( value ~== 0 ) value = 0;	// This is to prevent formatting anomalies with very small values
		value = round(value/step)*step;	// truncate to step
		SetSliderValue(clamp(value,mMin,mMax));
		Menu.MenuSound("menu/change");
		return true;
	}

	override bool isGrayed()
	{
		// HACK
		if ( (mAction == 'mfx_paldepth') && mfx_palnaive ) return true;
		if ( (mAction == 'mfx_palspread') && !mfx_palnaive ) return true;
		return Super.isGrayed();
	}
}

// passes shift/alt presses to MFXSliders
Class MFXOptionMenu : OptionMenu
{
	private void UpdatePresetNames()
	{
		for ( int i=0; i<mDesc.mItems.size(); i++ )
		{
			if ( !(mDesc.mItems[i] is 'OptionMenuItemMFXPresetList') )
				continue;
			OptionMenuItemMFXPresetList(mDesc.mItems[i]).UpdateNames();
		}
	}

	override void Init( Menu parent, OptionMenuDescriptor desc )
	{
		Super.init(parent,desc);
		DontDim = true;
		DontBlur = true;
		Animated = true;
		UpdatePresetNames();
	}

	override bool OnUIEvent( UIEvent ev )
	{
		for ( int i=0; i<mDesc.mItems.size(); i++ )
		{
			if ( !(mDesc.mItems[i] is 'OptionMenuItemMFXSlider') )
				continue;
			OptionMenuItemMFXSlider(mDesc.mItems[i]).bShift = ev.IsShift;
			OptionMenuItemMFXSlider(mDesc.mItems[i]).bAlt = ev.IsAlt;
		}
		return Super.OnUIEvent(ev);
	}

	override void OnReturn()
	{
		Super.OnReturn();
		UpdatePresetNames();
	}
}
