-- lua script for drawing a grid
-- some basic constants
local w_mid = width / 2
local h_mid = height / 2
local radius = math.sqrt((w_mid * w_mid) + (h_mid * h_mid)) * 2
local r2d =  180 / math.pi
local r, g, b

-- ------------------------------
-- note: functions must be defined BEFORE the calling logic calls them
-- ------------------------------

function plot(pointx,pointy)
     if (pointx > 0) and (pointy > 0) and (pointx < width) and (pointy < height) then  
    	set_rgba(pointx, pointy, r, g, b, 1)
    end 
end

function round(x)
    local xf = math.floor(x)
    if (x - xf) <= 0.5 then 
        return xf
    else
        return math.ceil(x)
    end 
end

-- Line Clipping Algorithm -- Liang-Barsky
function Liang_Barsky_clipTest(p, q, u1, u2)
local r
   if (p < 0) then 
        r = q / p
        if (r > u2) then 
            return 0, u1, u2
        elseif (r > u1) then 
            return 1, r, u2
        end
   elseif (p > 0) then 
      r = q / p
      if (r < u1) then 
         return 0, u1, u2
      elseif (r < u2) then 
            return 1, u1, r
      end
   elseif (q < 0) then 
      return 0, u1, u2
   end
   return 1, u1, u2
end

function Liang_Barsky_clipping(x0, y0, x1, y1)
local XS_MIN = 0
local XS_MAX = width
local YS_MIN = 0
local YS_MAX = height
local dx = x1 - x0
local dy = y1 - y0
local u1 = 0
local u2 = 1
local t1, t2, t3, t4 

t1, u1, u2 = Liang_Barsky_clipTest(-dx, x0-XS_MIN, u1, u2)
t2, u1, u2 = Liang_Barsky_clipTest( dx, XS_MAX-x0, u1, u2)
t3, u1, u2 = Liang_Barsky_clipTest(-dy, y0-YS_MIN, u1, u2)
t4, u1, u2 = Liang_Barsky_clipTest( dy, YS_MAX-y0, u1, u2)
    
   if (t1 == 1) and (t2 == 1) and (t3 == 1) and (t4 == 1)  then 
        if (u2 < 1) then 
            x1 = x0 + round(u2 * dx)
            y1 = y0 + round(u2 * dy)
        end
        if (u1 > 0) then 
            x0 = x0 + round(u1 * dx)
            y0 = y0 + round(u1 * dy)
        end
    end
    return x0, y0, x1, y1
end

-- Line Gen using a choice of two algorithms. 
-- Line Generating Algorithm using Digital Differential Analyzer 
function line_dda( x0, y0, x1, y1)  
    local x, y
    local delta
    x0, y0, x1, y1 = Liang_Barsky_clipping(x0, y0, x1, y1)
    if math.abs(x0-x1) > math.abs(y0-y1) then -- draw using X axis for greatest resolution
        delta =  (y1 - y0) /  (x1 - x0)
        y = y0
        if x0 > x1 then 
            t = x0; x0 = x1; x1 = t
            -- delta = -delta
            y = y1
        end
        for x = x0, x1 do
            plot(x, y)
            y = y + delta
        end
    else        -- draw using Y axis for greatest resolution
        delta =  (x1 - x0) /  (y1 - y0)
        x = x0
        if y0 > y1 then 
            t = y0; y0 = y1; y1 = t
            x = x1
        end
        for y = y0, y1 do
            plot(x, y)
            x = x + delta
        end
    end
end

-- Line Generating Algorithm using Bresenham's technique
function line_bres(x0, y0, x1, y1)
   x0, y0, x1, y1 = Liang_Barsky_clipping(x0, y0, x1, y1)
    local steep, t
    if (math.abs(y1 - y0) > math.abs(x1 - x0)) then 
        steep = 1 
    else 
        steep = 0 
    end 

    if steep == 1 then
        t = x0; x0 = y0; y0 = t
        t = x1; x1 = y1; y1 = t
    end
    if x0 > x1 then
        t = x0; x0 = x1; x1 = t
        t = y0; y0 = y1; y1 = t
    end 

    local deltax = x1 - x0
    local deltay = math.abs(y1 - y0)
    local error = round(deltax / 2)
    local ystep
    local y = y0
    if y0 < y1 then ystep = 1 else ystep = -1 end
    
    for x = x0, x1 do
         if (steep == 1) then plot(y,x) else plot(x,y) end 
         error = error - deltay
         if error < 0 then
             y = y + ystep
             error = error + deltax
         end
    end
end


function DrawGrid(uGridSize)
	local row,col = 0,0
	for col = 0, width, uGridSize do
		line_bres(col, 0, col, height)
	end
	for row = 0, height, uGridSize do
		line_bres(0,row, width, row)
	end
end

r, g, b = 0.7,0.7,0.7
DrawGrid(50)
r, g, b = 0,0,0
DrawGrid(100)