local EXP_INC = 1 			// The experience gained every second of sprinting
local EXP_STOPATMAX = 1		// Whether or not player's stop gaining exp at the maximum level (1 for they do)
local EXP_USETXT = 0		// Whether or not to use SQL or .txt files to store the data (1 using .txt)

sql.Query("CREATE TABLE IF NOT EXISTS exp_pdata('steam' TEXT NOT NULL, 'exp' INTEGER NOT NULL, 'curlevel' INTEGER NOT NULL, 'nextlevel' INTEGER NOT NULL, 'levelnum' INTEGER NOT NULL, PRIMARY KEY('steam'));")
if not file.Exists("exp_store.txt") and EXP_USETXT == 1 then file.Write("exp_store.txt","") end

local function PrintAll(msg) for _,v in ipairs(player.GetAll()) do v:ChatPrint(msg) end end

local function WriteData(ply) 
	local lines = string.Explode("\n",file.Read("exp_store.txt"))
	local towrite = ""
	for k,v in ipairs(lines) do 
		local values = string.Explode(" ",v)
		if values[1] != ply:SteamID() then towrite = towrite..v
		else end
	end
	file.Write("exp_store.txt",
	file.Read("exp_store.txt")..ply:SteamID().." "..ply:GetNWInt("Exp").." "..ply:GetNWInt("CurLevel").." "..ply:GetNWInt("NextLevel").." "..ply:GetNWInt("LevelNum").."\n")
end

local function LoadData(ply)
	local lines = string.Explode("\n",file.Read("exp_store.txt"))
	for _,v in ipairs(lines) do
		local values = string.Explode(" ",v)
		if values[1] == ply:SteamID() then
			ply:SetNWInt("Exp",values[2])
			ply:SetNWInt("CurLevel",values[3])
			ply:SetNWInt("NextLevel",values[4])
			ply:SetNWInt("LevelNum",values[5])
		end
	end
end

levelups = {
0,
2500,
5000,
10000,
25000,
50000,
100000,
200000,
500000,
600000,
700000,
800000}

function AddEXP(ply)
if ply:IsPlayer() then
	if (ply:KeyDown(131072)) then
		if( ply:GetNWFloat("sprint") > 10) then 
			if(math.Round((ply:GetVelocity():Length())) > 1) then
			ply:SetNWInt("Exp",ply:GetNWInt("Exp")+EXP_INC)
	
			if table.HasValue(levelups,ply:GetNWInt("Exp")) then
			local leveln = 1
			for k,v in pairs(levelups) do if v == ply:GetNWInt("Exp") then leveln = k end end
			if leveln == table.Count(levelups) then PrintAll(ply:Name().." has reached the maximum level!") 
			else PrintAll(ply:GetName().." has now reached level "..leveln.."!") end
			ply:SetNWInt("NextLevel",levelups[leveln+1])
			ply:SetNWInt("CurLevel",levelups[leveln])
			ply:SetNWInt("LevelNum",leveln)
			--ply:SendLua("surface.PlaySound(\"achievements/achievement_earned.mp3\")")
			end
		end
	end
end
end
end
hook.Add("Move","ExpAdd",AddEXP)

hook.Add("PlayerInitialSpawn","RegisterEXP",function(ply)
	if not tonumber(sql.QueryValue("SELECT exp FROM exp_pdata WHERE steam =  "..sql.SQLStr(ply:SteamID())..";")) then
		sql.Query("INSERT INTO exp_pdata VALUES("..sql.SQLStr(ply:SteamID())..",".. 0 ..",".. 0 ..","..levelups[2]..",".. 1 ..");")
		ply:SetNWInt("Exp",0)
		ply:SetNWInt("CurLevel",0)
		ply:SetNWInt("NextLevel",levelups[2])
		ply:SetNWInt("LevelNum",1)
	else
	sql.Begin()
	ply:SetNWInt("Exp",tonumber(sql.QueryValue("SELECT exp FROM exp_pdata WHERE steam =  "..sql.SQLStr(ply:SteamID())..";")))
	ply:SetNWInt("CurLevel",tonumber(sql.QueryValue("SELECT curlevel FROM exp_pdata WHERE steam =  "..sql.SQLStr(ply:SteamID())..";")))
	ply:SetNWInt("NextLevel",tonumber(sql.QueryValue("SELECT nextlevel FROM exp_pdata WHERE steam =  "..sql.SQLStr(ply:SteamID())..";")))
	ply:SetNWInt("LevelNum",tonumber(sql.QueryValue("SELECT levelnum FROM exp_pdata WHERE steam =  "..sql.SQLStr(ply:SteamID())..";")))
	sql.Commit()
	end
end)

concommand.Add("rp_curlevel",function(ply,cmd,args)
	for k,v in ipairs(levelups) do if ply:GetNWInt("CurLevel") == v then ply:ChatPrint("You are on level "..k..".") end end
end)

concommand.Add("exp_printsql",function(ply,cmd,args)
	ply:ChatPrint("Data from previous save...")
	ply:ChatPrint("Experience: "..tonumber(sql.QueryValue("SELECT exp FROM exp_pdata WHERE steam =  "..sql.SQLStr(ply:SteamID())..";")))
	ply:ChatPrint("Base Level Experience: "..tonumber(sql.QueryValue("SELECT curlevel FROM exp_pdata WHERE steam =  "..sql.SQLStr(ply:SteamID())..";")))
	ply:ChatPrint("Next Level: "..tonumber(sql.QueryValue("SELECT nextlevel FROM exp_pdata WHERE steam =  "..sql.SQLStr(ply:SteamID())..";")))
	ply:ChatPrint("Level Number: "..tonumber(sql.QueryValue("SELECT levelnum FROM exp_pdata WHERE steam =  "..sql.SQLStr(ply:SteamID())..";")))
end)
--table.insert(chatcommands,{"printsql","exp_printsql"})

concommand.Add("exp_savedata",function(ply,cmd,args)
	if ply:IsAdmin() then
		sql.Begin()
		for _,v in pairs(player.GetAll()) do
			local exp = v:GetNWInt("Exp") 
			local cur = v:GetNWInt("CurLevel")
			local new = v:GetNWInt("NextLevel")
			local lvl = v:GetNWInt("LevelNum")
			if EXP_USETXT == 1 then WriteData(v)
			else
				sql.Query("UPDATE exp_pdata SET exp = "..exp.." WHERE steam = "..sql.SQLStr(ply:SteamID())..";") 
				sql.Query("UPDATE exp_pdata SET curlevel = "..cur.." WHERE STEAM = "..sql.SQLStr(ply:SteamID())..";")
				sql.Query("UPDATE exp_pdata SET nextlevel = "..new.." WHERE STEAM = "..sql.SQLStr(ply:SteamID())..";")
				sql.Query("UPDATE exp_pdata SET levelnum = "..lvl.." WHERE STEAM = "..sql.SQLStr(ply:SteamID())..";")
			end
		end
		sql.Commit()
		ply:ChatPrint("Data saved!")
	end
end)
--table.insert(chatcommands,{"savedata","exp_savedata"})


hook.Add("PlayerDisconnected","UpdateEXP",function(ply)
	local exp = ply:GetNWInt("Exp") 
	local cur = ply:GetNWInt("CurLevel")
	local new = ply:GetNWInt("NextLevel")
	local lvl = ply:GetNWInt("LevelNum")
	if EXP_USETXT == 1 then WriteData(ply)
	else
		sql.Begin()
		sql.Query("UPDATE exp_pdata SET exp = "..exp.." WHERE steam = "..sql.SQLStr(ply:SteamID())..";") 
		sql.Query("UPDATE exp_pdata SET curlevel = "..cur.." WHERE STEAM = "..sql.SQLStr(ply:SteamID())..";")
		sql.Query("UPDATE exp_pdata SET nextlevel = "..new.." WHERE STEAM = "..sql.SQLStr(ply:SteamID())..";")
		sql.Query("UPDATE exp_pdata SET levelnum = "..lvl.." WHERE STEAM = "..sql.SQLStr(ply:SteamID())..";")
		sql.Commit()
	end
end)

hook.Add("PlayerSpawn","EXP_PowerupsSpawn",function(ply) 
	
	// Get the player's current level
	local lvl = ply:GetNWInt("CurLevel")
	
	// Enhance their run/walk/jump speed
	if UP_RUN == 1 then ply:SetRunSpeed(230+(lvl*10)) end
	if UP_WALK == 1 then ply:SetWalkSpeed(155+(lvl*10)) end
	if UP_JUMP == 1 then ply:SetJumpPower(200+(lvl*5)) end
	--if UP_ARMOR == 1 then ply:SetArmor(0+lvl*10) end
	if UP_HP == 1 then ply:SetHealth(100+lvl*10) end
	
end) 

