-- Custom Speed Mods v1.3
-- by AJ 187 of KKI Labs
-- http://kki.ajworld.net/

--[[
changelog:

v1.3
* strip whitespace out of file in case people use it.
	(I don't think it really works but SM seems to think the mods are legal)
* fixed an error related to using the fallback return value.

v1.2
* small fixes
* more comments

v1.1
* Cleaned up code some, I think.
]]

-- This code allows end users to add their own speed mods to the list.

-- Caveats:
--  * Unsure if this will work if the theme is installed as a package.

function SpeedMods()
	-- GetSpeedMods() - read all the speed mods from a file.
	local function GetSpeedMods()
		local s = { };
		local file = RageFileUtil.CreateRageFile();
		
		-- the file is located at Data/SpeedMods.txt, meaning any other theme
		-- that reads custom speed mods in this location will use them.
		-- the root is the StepMania install directory.
		
		-- Currently unknown if you can get this to read from a memory card
		-- profile directory, much less a local profile directory.
		local path = "Data/SpeedMods.txt"
		
		if file:Open(path, 1) then
			-- add each mod to the table. split by a comma.
			local a = file:Read();
			s = split(',',a);
			
			-- whitespace stripping
			-- I'm hoping this works for all spaces
			for i=1,#s do
				string.gsub(s[i], "%s", "");
			end
			
			file:destroy();
			return s;
		else
			-- couldn't be read for whatever reasons; write & return fallback
			Trace("[CustomSpeedMods]: Could not read SpeedMods; writing out fallback!");
			file:Open(path, 2);
			file:Write("0.5x,1x,1.5x,2x,3x,4x,8x,C200,C400");
			file:destroy();
			return {"0.5x","1x","1.5x","2x","3x","4x","8x","C200","C400"};
		end;
		-- this is unlikely but I am coding defensively
		Trace("[CustomSpeedMods]: unexpected jump location; using fallback!");
		return {"0.5x","1x","1.5x","2x","3x","4x","8x","C200","C400"};
	end;
	
	-- here we see the option menu itself.
	local t = {
		Name = "Speed",
		LayoutType = "ShowAllInRow",
		SelectType = "SelectOne",
		OneChoiceForAllPlayers = false,
		ExportOnChange = false,
		Choices = GetSpeedMods(),
		
		LoadSelections = function(self, list, pn)
			local pMods = GAMESTATE:GetPlayerState(pn):GetPlayerOptions("ModsLevel_Preferred");
			for i = 1,table.getn(self.Choices) do
				if string.find(pMods, self.Choices[i]) then
					list[i] = true;
					return;
				end;
			end;
			list[1] = true -- depends on what they have set.
		end,
		SaveSelections = function(self, list, pn)
			for i = 1,table.getn(self.Choices) do
				if list[i] then
					local PlayerState = GAMESTATE:GetPlayerState(pn);
					PlayerState:SetPlayerOptions("ModsLevel_Preferred",self.Choices[i]);
					return
				end
			end
		end
	};
	setmetatable( t, t );
	return t;
end;

--[[
Copyright © 2008 AJ Kelly/KKI Labs
All rights reserved.

This code is licensed under AJ's Generic Use of Code License.
An up to date copy can be found at the following address:
http://kki.ajworld.net/wiki/AJ%27s_Generic_Use_of_Code_License
However, keep in mind that the code in this file is bound to the exact
specifications found in this file.
That is to say, changes are not retroactive.

When using this code in your theme, you agree to the following points:

1. Redistributions of anything that uses this code must retain the above
copyright notice and this list of conditions.

2. Not hide/require registration for any theme that uses the code from the
public IF there is a public release. (This means private themes and themes for
commercial games can use the code without worry.)

3. Not compile the code down to bytecode (if the code is Lua) in a public
theme. (Yes, it can be reversed, but regardless, this hinders openness and
sharing.)

4. This code is a unique/nontrivial creation, therefore, credit should be
given to the creator of the code if used in another theme.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
]]