
function	Texture( data )
	if TEXTURES == nil then
		TEXTURES = {};
	end
	
	local default_texture_id = -1;
	data.id = data.id or default_texture_id;
	
	if type(data.name) ~= "string" then
		error("texture name not specified");
	elseif type(data.file) ~= "string" then
		error("texture file not specified");
	else
		TEXTURES[data.name] = data;
	end
end

HS_CENTER	= 0;
HS_N		= 1;
HS_NE		= 2;
HS_E		= 3;
HS_SE		= 4;
HS_S		= 5;
HS_SW		= 6;
HS_W		= 7;
HS_NW		= 8;

function	Image( data )
	if IMAGES == nil then
		IMAGES = {};
	end
	
	data.tex = data.tex or "null_texture";
	data.x = data.x or 0;
	data.y = data.y or 0;
	data.w = data.w or 50;
	data.h = data.h or 50;
	data.frames = data.frames or 1;
	data.h_flip = data.h_flip or false;
	data.v_flip = data.v_flip or false;
	if data.hot_stop_relative == nil then
		data.hot_stop_relative = false;
	end
	
	if data.texture_bounded then
		data.w = 1;
		data.h = 1;
		if type(data.hot_spot) ~= "table" then
			data.hot_stop_relative = true;
		end
	end
	
	if type(data.hot_spot) == "table"  then
		data.hot_spot[1] = data.hot_spot[1] or 0;
		data.hot_spot[2] = data.hot_spot[2] or 0;
	elseif data.hot_spot == HS_CENTER then
		data.hot_spot = { data.w/2, data.h/2 };
	elseif data.hot_spot == HS_N then
		data.hot_spot = { data.w/2, 0 };
	elseif data.hot_spot == HS_NE then
		data.hot_spot = { data.w, 0 };
	elseif data.hot_spot == HS_E then
		data.hot_spot = { data.w, data.h/2 };
	elseif data.hot_spot == HS_SE then
		data.hot_spot = { data.w, data.h };
	elseif data.hot_spot == HS_S then
		data.hot_spot = { data.w/2, data.h };
	elseif data.hot_spot == HS_SW then
		data.hot_spot = { 0, data.h };
	elseif data.hot_spot == HS_W then
		data.hot_spot = { 0, data.h/2 };
	elseif data.hot_spot == HS_NW then
		data.hot_spot = { 0, 0 };		
	else
		data.hot_spot = { 0, 0 };
	end
	
	if type(data.name) ~= "string" then
		error("image name not specified");
	else
		IMAGES[data.name] = data;
	end
	
	-- automake node with samename
	--SpriteNode{ name = data.name, image = data.name, node_data = NodeData{ x = 0, y = 0 } };
end

function Counter( data )
	
	if COUNTER == nil then
		COUNTER = {};
	end
	
	data.file = CURRENT_FILE;
	
	if type(data.name) ~= "string" then
		error("counter name not specified");
	else
		COUNTER[data.name] = data;
	end
	
end

function CounterToString( countername, data )

	local result = "Counter{ name = \"";
	
	result = result .. countername .. "\", ";
	
	for i,v in ipairs( data ) do
		result = result .. data[i] .. ", ";
	end
	
	if ( data.subcycles ~= nil and #(data.subcycles) > 0) then
		result = result .. "\n subcycles = {\n";
		
		for i,v in ipairs( data.subcycles ) do
			result = result ..  string.format( "{ frame1 = %d, frame2 = %d, repeat_min = %d, repeat_max = %d },\n", v.frame1, v.frame2, v.repeat_min, v.repeat_max ) ;
		end
		
		result = result .. "},\n";
	end
	
	result = result .. " };"
	
	return result;

end

function SaveCounterFile( filename, filefilter )
	
	local ofile = io.open( filename, "w" );
	
	if ofile then
		
		for i,v in pairs( COUNTER ) do
			if v.file == filefilter then
				ofile:write( CounterToString( i, v ) );
				ofile:write( "\n" );
			end
		end
	
	end
	
	ofile:close();
	
end

function SaveCounters()
	
	local filelist = {};
	
	for i,v in pairs( COUNTER ) do
		if v.file ~= nil then
			filelist[v.file] = 1;
		end
	end
	
	for i,v in pairs( filelist ) do
		SaveCounterFile( i, i );
	end
	
	-- save counters w/o files specified
	SaveCounterFile( "counters_without_files.lua", nil );

end

function Cursor( data )
	if CURSOR == nil then
		CURSOR = {};
	end
	
	if type(data.name) ~= "string" then
		error( "cursor name not specified" );
	end
	if type(data.node) ~= "string" then
		error( "cursor node not specified" );
	end
	if type(NODES[data.node]) == nil then
		error( "cursor node [" .. data.node .. "] not exist" );
	end
	
	data.force_custom = data.force_custom or false;
	
	CURSOR[data.name] = data;
end