x_func_version	= 6;

--[[
	Minor version history:

	v5 -----------
	- Added Bisqwit's 'clone table' function.
	
	v6 -----------
	- added pairs by keys
	- added hitbox functions



]]




-- Draws a line from x1,y1 to x2,y2 using color

function line(x1,y1,x2,y2,color)
	if (x1 >= 0 and x1 <= 255 and x2 >= 0 and x2 <= 255 and y1 >= 0 and y1 <= 244 and y2 >= 0 and y2 <= 244) then
		local success = pcall(function() gui.drawline(x1,y1,x2,y2,color) end);
		if not success then 
			text(60, 224, "ERROR: ".. x1 ..",".. y1 .." ".. x2 ..",".. y2);
		end;
	end;
end;


-- Puts text on-screen (duh)
function text(x,y,str)
	if str == nil then
		str = "nil";
	end;
	if (x >= 0 and x <= 255 and y >= 0 and y <= 240) then
		gui.text(x,y,str);
	end;
end;

-- Sets the pixel at x, y to color
function pixel(x,y,color)
	if (x >= 0 and x <= 255 and y >= 0 and y <= 240) then
		gui.drawpixel(x,y,color);
	end;
end;


-- Draws a rectangle from x1,y1 to x2, y2
function box(x1,y1,x2,y2,color)
	if (x1 >= 0 and x1 <= 255 and x2 >= 0 and x2 <= 255 and y1 >= 0 and y1 <= 244 and y2 >= 0 and y2 <= 244) then
--[[	local success = pcall(function() gui.drawbox(x1,y1,x2,y2,color); end);
		if not success then 
			text(60, 150, string.format("%3d %3d %3d %3d", x1, y1, x2, y2));
			FCEU.pause();
		end;
]]		gui.drawbox(x1,y1,x2,y2,color);
	end;
end;


-- Draws a filled box from x1, y1 to x2, y2 (warning: can be slow if drawing large boxes)
function filledbox(x1,y1,x2,y2,color)
	for i = 0, math.abs(y1 - y2) do
		line(x1,y1 + i,x2,y1 + i,color);
	end;
end;



-- Draws a life-bar.
-- x, y: position of top-right
-- sx, sy: width and height of ACTUAL BAR (0 is the smallest height (1px))
-- a1, a2: Amounts (a1/a2*100 = % of bar filled)
-- oncolor, offcolor: "bar", "background"
-- noborder: set to "true" if you just want a black outline without the white

function lifebar(x, y, sx, sy, a1, a2, oncolor, offcolor, outerborder, innerborder)
	-- this function will have the effect of drawing an HP bar
	-- keep in mind xs and ys are 2px larger to account for borders
	
	x1	= x;
	x2	= x + sx + 4;
	y1	= y;
	y2	= y + sy + 4;
	w	= math.floor(a1 / math.max(1, a1, a2) * sx);
	if not a2 then w = 0 end;

	outer	= outerborder;
	inner	= innerborder;

	if (outer == true or outer == false) and (inner == nil) then
		-- legacy
		outer	= nil;
		inner	= "#000000";

	elseif outer == nil and inner == nil then
		outer	= "#000000";
		inner	= "#ffffff";

	elseif inner == nil then
		inner	= "#ffffff";
	end;
	
	if (inner) then 
		box(x1 + 1, y1 + 1, x2 - 1, y2 - 1, inner);
	end;
	if (outer) then
		box(x1    , y1    , x2    , y2    , outer);
	end; 

	if (w < sx) then
		filledbox(x1 + w + 2, y1 + 2, x2 - 2, y2 - 2, offcolor);
	end;		

	if (w > 0) then
		filledbox(x1 + 2, y1 + 2, x1 + 2 + w, y2 - 2, oncolor);
	end;		

end;



function graph(x, y, sx, sy, minx, miny, maxx, maxy, xval, yval, color, border, filled)


	if (filled ~= nil) then
		filledbox(x + 1, y + 1, x+sx, y+sy, "#000000");
	end;
	if (border ~= nil) then
		box(x, y, x+sx+1, y+sy+1, color);
	end;
	

	xp	= (xval - minx) / (maxx - minx) * sx;
	yp	= (yval - miny) / (maxy - miny) * sy;

	line(x + 1     , yp + y + 1, x + sx + 1, yp + y + 1, color);
	line(xp + x + 1, y + 1     , xp + x + 1, y + sy + 1, color);

	return true;
end;


-- Bisqwit's clone table feature.
table.clone = function(table)
  local res = {}
  for k,v in pairs(table)do
    res[k]=v
  end
  return res
end

spairs		= function (t, f)
	local a = {}
	for n in pairs(t) do table.insert(a, n) end
	table.sort(a, f)
	local i = 0      -- iterator variable
	local iter = function ()   -- iterator function
		i = i + 1
		if a[i] == nil then return nil
		else return a[i], t[a[i]]
		end
	end
	return iter
end


-- ****************************************************************************
-- * hitbox( coords1, coords2, con, coff )
-- * Checks if any point of coords1 is within coords2. 
-- * con/coff determine what colors of box to draw.
-- ****************************************************************************
function hitbox(b1x1, b1y1, b1x2, b1y2, b2x1, b2y1, b2x2, b2y2, con, coff)

	if not b1x1 then
		text(0, 8, "ERROR!!!!");
		return;
	end;

	local noboxes	= false;
	if con == nil and coff == nil then
		noboxes	= true;
	else
		if coff == nil then
			coff = "#00ff00"
		end;

		if con == nil then
			con	= "#dd0000";
		end;
		if coff == nil then
			coff = "#00ff00"
		end;
	end;

	boxes	= {{
			x	= {b1x1, b1x2},
			y	= {b1y1, b1y2},
		}, {
			x	= {b2x1, b2x2},
			y	= {b2y1, b2y2},
		}};

	hit	= false;

	for xc = 1, 2 do
		for yc = 1, 2 do

			if	(boxes[1]['x'][xc] >= boxes[2]['x'][1]) and
				(boxes[1]['y'][yc] >= boxes[2]['y'][1]) and
				(boxes[1]['x'][xc] <= boxes[2]['x'][2]) and
				(boxes[1]['y'][yc] <= boxes[2]['y'][2]) then

				hit	= true;
				-- TODO: make this break out of the for loop? might not be worth it
			end;
		end;
	end;

	if hit == true then
		if not noboxes then box(b2x1, b2y1, b2x2, b2y2, con); end;
		return true;
	else
		if not noboxes then box(b2x1, b2y1, b2x2, b2y2, coff); end;
		return false;
	end;

	return true;

end;



function x_requires(required)
	-- Sanity check. If they require a newer version, let them know.
	timer	= 1;
	if x_func_version < required then

		while (true) do
			timer = timer + 1;

			for i = 0, 32 do
				box( 6, 28 + i, 250, 92 - i, "#000000");
			end;

			text( 10, 32, string.format("This Lua script requires version %02d or greater.", required));
			text( 43, 42, string.format("Your x_functions.lua is version %02d.", x_func_version));
			text( 29, 58, "Please check for an updated version at");
			text( 14, 69, "http://xkeeper.shacknet.nu:5/");
			text(114, 78, "emu/nes/lua/x_functions.lua");

			warningboxcolor	= string.format("%02X", math.floor(math.abs(30 - math.fmod(timer, 60)) / 30 * 0xFF));
			box(7, 29, 249, 91, "#ff" .. warningboxcolor .. warningboxcolor);

			FCEU.frameadvance();
		end;

	end;
end;