loader={}
skip={"_controller","smoothed"}

function loader:init()
	lfs.createDirectory( "thumbnails" )
	lfs.createDirectory( "images" )
end


function loader:loadDefs()
	worlds 		= self:loadDef("worlds", 		{})
	dialogue 	= self:loadDef("dialogue", 	{})
	objects 	= self:loadDef("objects", 	{})
	tagNames 	= self:loadDef("tags", 			{})
	library 	= self:loadDef("library", 	{})
	scripts 	= self:loadDef("scripts", 	{})
	global 		= self:loadDef("global", 		{})
end


function loader:preLoad()
	self:loadDefs()
	self:loadScripts()
	levelLoader:preLoad()
	imageLoader:preLoad()
end

function loader:writeFile(dir,data)
	-- print(1,dir)
	-- print(2,q(dir,true))
	local file,e 		= assert(io.open(q(dir,true),"w"))
 	file:write(data)
 	file:close()
end

function loader:loadScripts()
	local file = ""
	for s,script in pairs(scripts) do
		script.filename	= "scripts/"..script.key
		file = LINK_DIR..script.filename..".lua"
		if lfs.exists(file) then 
			if pcall(require,script.filename) then 
				local lines=0
				for line in lfs.lines(file) do
				  lines=lines+1
				end
				script.lines=lines
				script.broken=false
			else
				script.broken=true
			end
		else
			scripts[s]=nil
		end
	end
	self:saveDef  ("scripts",scripts)
end


function loader:loadDef(name,default)
	local rval 
	
	if lfs.exists(LINK_DIR.."definitions/"..name..".lua") then 
		rval = lfs.load(LINK_DIR.."definitions/"..name..".lua" )()
		print("success def "..name)
	else 
		print("failed def "..name)
		rval = self:createDef(name,default)
	end
	return rval
end

function loader:saveDef(name,var)
	if name=="objects" then var = editor.stripObjects(var) end
	
	self:writeFile(PROJ_DIR.."definitions/"..name..".lua","return "..Tserial.pack(var,nil,true,skip))
end

function loader:createDef(name,default)
	self:writeFile(PROJ_DIR.."definitions/"..name..".lua","return "..Tserial.pack(default,nil,true))
	return deepcopy(default)
end

function loader:addLevel(name,world)
	if self:levelExists(name) then  
		namer.nameTaken()
		return 0;
	end 
	
	local newKey 		= uuid()
	local directory 	= PROJ_DIR.."levels/"..newKey..".lua"
	local newLevel 		= levelLoader:getDefault()
	newLevel.key 		= newKey
	newLevel.name 		= name
	self:writeFile 	( directory, "return "..Tserial.pack(newLevel,nil,true))

	table.insert 		(worlds[world].levels , {key=newKey,index=#worlds[world].levels+1})
	levels[newKey] 		= newLevel
	self:saveDef 		("worlds",worlds)

end

function loader:saveLevel(key,name)
	if self:levelExists(name) then  
		namer.nameTaken()
		return 0
	end 
	levels[key].name 	= tostring(name)
	local directory  	= PROJ_DIR.."levels/"..key..".lua"
	self:writeFile 	(directory,"return "..Tserial.pack(levels[key],nil,true,skipKeys))
	self:saveDef 		("worlds",worlds)
end

function loader:levelExists(name)
	return lume.any(levels,function(x) return x.name == name end)
end

function loader:removeFile(b)
	table.remove(blocks,b.id)
	if ZIP_MODE then 
		lfs.remove 					(LINK_DIR.."levels/"..b.key..".lua")
	else 
		os.remove 					(GAME_DIR.."levels/"..b.key..".lua")
	end
	self:saveDef 				("worlds",worlds) 
end

local logo 
function loader:loadGame()
	if not 		levelLoader.loaded 	then levelLoader:loadLoop()  
	elseif not 	imageLoader.loaded 	then imageLoader:loadLoop() end

	logo = logo or {x=0,y=0}
	logo.x = effects.wobble(renderWidth/2,0.5,60)
	logo.y = effects.wobble(renderHeight,0.5,60)

	if  levelLoader.loaded and imageLoader.loaded and not game.loaded then 
		imageLoader:postLoad 		()
		imageLoader:tagImages 		()
		imageLoader:loadController  ()
		game.loaded = true
		initDisplay()
		initGame() 
	end 


	self:drawPreLoader() 
end


function loader:drawPreLoader()
	
	gfx.setShader()
	gfx.setBlendMode('alpha')

	self:drawProgress()

end

function loader:drawProgress()
	gfx.clear(0.1,0.13,0.18)
	gfx.setBlendMode('alpha')
	gfx.setColor(1,1,1,1)
	local v1 = (3*time+3)%(pi*2)
	local v2 = (7*time+7)%(pi*2)
	local v3 = (13*time+13)%(pi*2)
	gfx.arc("line","open",screenWidth/2,screenHeight/2,20,v1,v1+0.5,64)
	gfx.arc("line","open",screenWidth/2,screenHeight/2,20,v2,v2+0.5,64)
	gfx.arc("line","open",screenWidth/2,screenHeight/2,20,v3,v3+0.5,64)
end