local v=require("\097\112\105\047\076\117\115\116")local M=require("\097\112\105\047\114\097\121\108\105\098\095\097\112\105")local O=require("\097\112\105\047\114\108\103\108\095\097\112\105")local U={M;O}local function J(v,M)for v,O in pairs(v)do if O==M then return true end end return false end local function W(v)local M={"\071\085\065\082\068","\077\065\067\082\079","\085\078\075\078\079\087\078";"\070\076\079\065\084\095\077\065\084\072"}return J(M,v)end local K=v({"\064\109\097\112\123 \110\061\097\114\103\076\105\115\116\044 \095\115\101\112\097\114\097\116\111\114\061\"\044 \" \125\058\123\123\036\110\125\125"})local function F(v)local M=(v:gsub("\042","")):gsub(" ","\095")local O={string="\115\116\114\105\110\103";char="\115\116\114\105\110\103",char_="\115\116\114\105\110\103";const_char_="\115\116\114\105\110\103";const_unsigned_char_="\115\116\114\105\110\103",unsigned_char="\115\116\114\105\110\103";unsigned_char_="\115\116\114\105\110\103";unsigned_short_="\115\116\114\105\110\103",float="\110\117\109\098\101\114",float_="\110\117\109\098\101\114",double="\110\117\109\098\101\114";int="\110\117\109\098\101\114",int_="\110\117\109\098\101\114";unsigned="\110\117\109\098\101\114";unsigned_int="\110\117\109\098\101\114";unsigned_int_="\110\117\109\098\101\114",bool="\098\111\111\108\101\097\110",void_="\118\111\105\100";void="\118\111\105\100"}local U="\040\091\037\119\095\093\043\041\037\091\040\037\100\043\041\037\093"local J,W=M:match(U)if J and J=="\099\104\097\114"then return O.char end if J and(W and J~="\099\104\097\114")then local v=O[J]or J:gsub("\042","")local M={}for O=1,tonumber(W),1 do table.insert(M,v)end local U=K:gen({argList=M})return string.format("\037\115\091\093 \123\037\115\125",v,U)end return O[M]or v:gsub("\042","")end local z=assert(io.open("\105\110\105\116\046\108\117\097","\119"),"\067\111\117\108\100 \110\111\116 \108\111\097\100 \105\110\105\116\046\108\117\097")if z==nil then error("\079\117\116\112\117\116 \102\105\108\101 \040\105\110\105\116\046\108\117\097\041 \099\111\117\108\100 \110\111\116 \098\101 \111\112\101\110\101\100")end local s="\108\111\099\097\108 \102\102\105 \061 \114\101\113\117\105\114\101\040\"\102\102\105\"\041\n\108\111\099\097\108 \108\105\098 \061 \102\102\105\046\108\111\097\100\040\"\108\105\098\114\097\121\108\105\098\"\041\n\n\108\111\099\097\108 \103\101\110\101\114\097\116\101\100 \061 \097\115\115\101\114\116\040\105\111\046\111\112\101\110\040\"\114\097\121\108\105\098\047\103\101\110\101\114\097\116\101\100\046\104\"\044 \"\114\"\041\044 \"\067\097\110\110\111\116 \102\105\110\100 \103\101\110\101\114\097\116\101\100\046\104\"\041\n\n\102\102\105\046\099\100\101\102\040\103\101\110\101\114\097\116\101\100\058\114\101\097\100\040\"\042\097\108\108\"\041\041\n\n\108\111\099\097\108 \109\116 \061 \123 \095\095\105\110\100\101\120 \061 \108\105\098 \125\n\108\111\099\097\108 \114\108 \061 \115\101\116\109\101\116\097\116\097\098\108\101\040\123\125\044 \109\116\041\n\n\108\111\099\097\108 \114\097\121\103\117\105 \061 \114\101\113\117\105\114\101\040\"\114\097\121\108\105\098\047\114\097\121\103\117\105\"\041\n\114\108 \061 \114\097\121\103\117\105\040\114\108\041\n"z:write(s)local m=v({"\036\101\110\116\114\121\046\100\101\115\099\114\105\112\116\105\111\110\n  \114\108\046\036\101\110\116\114\121\046\110\097\109\101 \061 \036\101\110\116\114\121\046\118\097\108\117\101\n\n"})for v,M in pairs(U)do for v,M in pairs(M.defines)do if W(M.type)==false and M.value~=""then if M.description~=""then M.description="--- "..M.description end if type(M.value)=="\115\116\114\105\110\103"then M.value=M.value:gsub("\067\076\073\084\069\082\065\076\037\040\067\111\108\111\114\037\041","")end if M.type=="\083\084\082\073\078\071"then M.value=string.format("\037\113",M.value)end local v=m:gen({entry=M})local O=string.format("  \037\115",v)z:write(O)end end end local i=v({"\036\099\108\097\115\115 \036\101\110\116\114\121\046\110\097\109\101\n  \064\109\097\112\123 \110\061\101\110\116\114\121\046\102\105\101\108\100\115 \125\058\123\123\036\102\105\101\108\100 \036\110\046\110\097\109\101 \036\110\046\116\121\112\101 \036\110\101\119\108\105\110\101\125\125"})local A=v({"  --- \036\101\110\116\114\121\046\100\101\115\099\114\105\112\116\105\111\110 \064\109\097\112\123 \110\061\101\110\116\114\121\046\102\105\101\108\100\115 \125\058\123\123\036\110\101\119\108\105\110\101  \036\112\097\114\097\109 \036\110\046\110\097\109\101 \036\110\046\116\121\112\101\125\125\n  \036\114\101\116\117\114\110\115 \036\101\110\116\114\121\046\110\097\109\101\n  \102\117\110\099\116\105\111\110 \114\108\046\036\101\110\116\114\121\046\110\097\109\101\040\064\109\097\112\123 \110\061\101\110\116\114\121\046\102\105\101\108\100\115\044 \095\115\101\112\097\114\097\116\111\114\061\"\044 \" \125\058\123\123\036\110\046\110\097\109\101\125\125\041\n    \114\101\116\117\114\110 \102\102\105\046\110\101\119\040\"\036\101\110\116\114\121\046\110\097\109\101\"\044 \064\109\097\112\123 \110\061\101\110\116\114\121\046\102\105\101\108\100\115\044 \095\115\101\112\097\114\097\116\111\114\061\"\044 \" \125\058\123\123\036\110\046\110\097\109\101\125\125\041\n  \101\110\100"})local Z={}for v,M in pairs(U)do for v,M in pairs(M.structs)do if J(Z,M.name)==false then if M.fields~=nil then for v,O in ipairs(M.fields)do M.fields[v].type=F(M.fields[v].type)end end local v=i:gen({entry=M;class="---\064\099\108\097\115\115";field="---\064\102\105\101\108\100",newline="\n"})local O=A:gen({entry=M;param="---\064\112\097\114\097\109",returns="---\064\114\101\116\117\114\110";newline="\n"})local U=string.format("\n\n  \037\115\n\037\115",v,O)z:write(U)table.insert(Z,M.name)end end end local h=v({"\064\109\097\112\123 \110\061\097\108\105\097\115\101\115 \125\058\123\123  \036\097\108\105\097\115 \036\110\046\110\097\109\101 \036\110\046\116\121\112\101\036\110\101\119\108\105\110\101\125\125"})for v,M in pairs(U)do if#M.aliases>0 then local v=h:gen({aliases=M.aliases,alias="---\064\097\108\105\097\115",newline="\n"})local O=string.format("\n\n\037\115\n",v)z:write(O)end end local f=v({"\064\109\097\112\123 \110\061\101\110\116\114\121\046\118\097\108\117\101\115 \125\058\123\123  --- \036\110\046\100\101\115\099\114\105\112\116\105\111\110\036\110\101\119\108\105\110\101  \114\108\046\036\110\046\110\097\109\101 \061 \036\110\046\118\097\108\117\101\036\110\101\119\108\105\110\101\036\110\101\119\108\105\110\101\125\125"})for v,M in pairs(U)do for v,M in pairs(M.enums)do local O=f:gen({entry=M,newline="\n"})local U=string.format("\037\115",O)z:write(U)end end local V=v({"  --- \036\101\110\116\114\121\046\100\101\115\099\114\105\112\116\105\111\110 \064\109\097\112\123 \110\061\101\110\116\114\121\046\112\097\114\097\109\115 \125\058\123\123\036\110\101\119\108\105\110\101  \036\112\097\114\097\109 \036\110\046\110\097\109\101 \036\110\046\116\121\112\101\125\125\n  \036\114\101\116\117\114\110\115 \036\101\110\116\114\121\046\114\101\116\117\114\110\084\121\112\101\n  \102\117\110\099\116\105\111\110 \114\108\046\036\101\110\116\114\121\046\110\097\109\101\040\064\109\097\112\123 \110\061\101\110\116\114\121\046\112\097\114\097\109\115\044 \095\115\101\112\097\114\097\116\111\114\061\"\044 \" \125\058\123\123\036\110\046\110\097\109\101\125\125\041\n    \114\101\116\117\114\110 \108\105\098\046\036\101\110\116\114\121\046\110\097\109\101\040\064\109\097\112\123 \110\061\101\110\116\114\121\046\112\097\114\097\109\115\044 \095\115\101\112\097\114\097\116\111\114\061\"\044 \" \125\058\123\123\036\110\046\110\097\109\101\125\125\041\n  \101\110\100"})for v,M in pairs(U)do for v,M in pairs(M.functions)do M.returnType=F(M.returnType)if M.params~=nil then for v,O in ipairs(M.params)do M.params[v].name=M.params[v].name=="\101\110\100"and"\101\110\100\105\110\103"or M.params[v].name M.params[v].type=F(M.params[v].type)end end local O=V:gen({entry=M,param="---\064\112\097\114\097\109";returns="---\064\114\101\116\117\114\110",newline="\n"})local U=string.format("\n\037\115\n",O)z:write(U)end end local r="\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\086\101\099\116\111\114\050\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\086\101\099\116\111\114\050\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \086\101\099\116\111\114\050\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\086\101\099\116\111\114\051\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\086\101\099\116\111\114\051\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \086\101\099\116\111\114\051\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\086\101\099\116\111\114\052\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\086\101\099\116\111\114\052\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \086\101\099\116\111\114\052\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\077\097\116\114\105\120\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\077\097\116\114\105\120\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \077\097\116\114\105\120\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\067\111\108\111\114\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\067\111\108\111\114\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \067\111\108\111\114\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\082\101\099\116\097\110\103\108\101\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\082\101\099\116\097\110\103\108\101\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \082\101\099\116\097\110\103\108\101\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\073\109\097\103\101\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\073\109\097\103\101\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \073\109\097\103\101\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\084\101\120\116\117\114\101\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\084\101\120\116\117\114\101\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \084\101\120\116\117\114\101\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\082\101\110\100\101\114\084\101\120\116\117\114\101\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\082\101\110\100\101\114\084\101\120\116\117\114\101\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \082\101\110\100\101\114\084\101\120\116\117\114\101\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \118\097\108 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\078\080\097\116\099\104\073\110\102\111\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\078\080\097\116\099\104\073\110\102\111\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \078\080\097\116\099\104\073\110\102\111\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\071\108\121\112\104\073\110\102\111\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\071\108\121\112\104\073\110\102\111\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \071\108\121\112\104\073\110\102\111\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\070\111\110\116\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\070\111\110\116\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \070\111\110\116\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\067\097\109\101\114\097\051\068\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\067\097\109\101\114\097\051\068\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \067\097\109\101\114\097\051\068\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\067\097\109\101\114\097\050\068\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\067\097\109\101\114\097\050\068\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \067\097\109\101\114\097\050\068\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\077\101\115\104\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\077\101\115\104\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \077\101\115\104\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\083\104\097\100\101\114\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\083\104\097\100\101\114\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \083\104\097\100\101\114\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\077\097\116\101\114\105\097\108\077\097\112\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\077\097\116\101\114\105\097\108\077\097\112\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \077\097\116\101\114\105\097\108\077\097\112\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\077\097\116\101\114\105\097\108\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\077\097\116\101\114\105\097\108\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \077\097\116\101\114\105\097\108\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\084\114\097\110\115\102\111\114\109\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\084\114\097\110\115\102\111\114\109\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \084\114\097\110\115\102\111\114\109\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\066\111\110\101\073\110\102\111\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\066\111\110\101\073\110\102\111\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \066\111\110\101\073\110\102\111\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\077\111\100\101\108\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\077\111\100\101\108\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \077\111\100\101\108\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\077\111\100\101\108\065\110\105\109\097\116\105\111\110\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\077\111\100\101\108\065\110\105\109\097\116\105\111\110\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \077\111\100\101\108\065\110\105\109\097\116\105\111\110\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\082\097\121\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\082\097\121\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \082\097\121\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\082\097\121\067\111\108\108\105\115\105\111\110\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\082\097\121\067\111\108\108\105\115\105\111\110\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \082\097\121\067\111\108\108\105\115\105\111\110\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\066\111\117\110\100\105\110\103\066\111\120\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\066\111\117\110\100\105\110\103\066\111\120\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \066\111\117\110\100\105\110\103\066\111\120\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\087\097\118\101\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\087\097\118\101\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \087\097\118\101\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\114\065\117\100\105\111\066\117\102\102\101\114\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\114\065\117\100\105\111\066\117\102\102\101\114\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \114\065\117\100\105\111\066\117\102\102\101\114\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\114\065\117\100\105\111\080\114\111\099\101\115\115\111\114\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\114\065\117\100\105\111\080\114\111\099\101\115\115\111\114\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \114\065\117\100\105\111\080\114\111\099\101\115\115\111\114\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\065\117\100\105\111\083\116\114\101\097\109\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\065\117\100\105\111\083\116\114\101\097\109\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \065\117\100\105\111\083\116\114\101\097\109\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\083\111\117\110\100\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\083\111\117\110\100\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \083\111\117\110\100\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\077\117\115\105\099\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\077\117\115\105\099\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \077\117\115\105\099\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\086\114\068\101\118\105\099\101\073\110\102\111\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\086\114\068\101\118\105\099\101\073\110\102\111\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \086\114\068\101\118\105\099\101\073\110\102\111\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\086\114\083\116\101\114\101\111\067\111\110\102\105\103\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\086\114\083\116\101\114\101\111\067\111\110\102\105\103\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \086\114\083\116\101\114\101\111\067\111\110\102\105\103\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\070\105\108\101\080\097\116\104\076\105\115\116\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\070\105\108\101\080\097\116\104\076\105\115\116\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \070\105\108\101\080\097\116\104\076\105\115\116\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\065\117\116\111\109\097\116\105\111\110\069\118\101\110\116\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\065\117\116\111\109\097\116\105\111\110\069\118\101\110\116\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \065\117\116\111\109\097\116\105\111\110\069\118\101\110\116\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n  --- \099\104\101\099\107 \105\102 \116\104\101 \103\105\118\101\110 \118\097\108\117\101 \105\115 \111\102 \116\121\112\101 \"\065\117\116\111\109\097\116\105\111\110\069\118\101\110\116\076\105\115\116\"\n  ---\064\112\097\114\097\109 \099\104\101\099\107 \097\110\121 \116\104\101 \118\097\108\117\101 \116\111 \099\111\109\112\097\114\101\n  ---\064\114\101\116\117\114\110 \098\111\111\108\101\097\110\n  \102\117\110\099\116\105\111\110 \114\108\046\073\115\065\117\116\111\109\097\116\105\111\110\069\118\101\110\116\076\105\115\116\040\099\104\101\099\107\041\n    \114\101\116\117\114\110 \116\121\112\101\040\099\104\101\099\107\041 \061\061 \"\099\100\097\116\097\" \097\110\100 \102\102\105\046\105\115\116\121\112\101\040\"\115\116\114\117\099\116 \065\117\116\111\109\097\116\105\111\110\069\118\101\110\116\076\105\115\116\"\044 \102\102\105\046\116\121\112\101\111\102\040\099\104\101\099\107\041\041\n  \101\110\100\n\n\n  \114\101\116\117\114\110 \114\108\n"z:write(r)z:close()
local Lust = require("api/Lust")

-- the list of API files to load
local raylibApi = require("api/raylib_api")
local rlglApi = require("api/rlgl_api")
-- right now, the raylib_parser does not output the full raygui code
-- local rayguiApi = require("api/raygui_api")

local apiFiles = {
  raylibApi,
  rlglApi,
  -- rayguiApi,
}

local function table_contains(table, value)
  for _, v in pairs(table) do
    if v == value then
      return true
    end
  end
  return false
end

local function skipped_types(check)
  local t = {
    "GUARD",
    "MACRO",
    "UNKNOWN",
    "FLOAT_MATH",
  }

  return table_contains(t, check)
end

local tableReturnTemplate = Lust({ [[@map{ n=argList, _separator=", " }:{{$n}}]] })

local function type_map(check)
  local key = check:gsub("*", ""):gsub(" ", "_")

  local typemap = {
    string = "string",
    char = "string",
    char_ = "string",
    const_char_ = "string",
    const_unsigned_char_ = "string",
    unsigned_char = "string",
    unsigned_char_ = "string",
    unsigned_short_ = "string",
    float = "number",
    float_ = "number",
    double = "number",
    int = "number",
    int_ = "number",
    unsigned = "number",
    unsigned_int = "number",
    unsigned_int_ = "number",
    bool = "boolean",
    void_ = "void",
    void = "void",
  }

  -- match array values
  local pattern = "([%w_]+)%[(%d+)%]"
  local word, number = key:match(pattern)

  if word and word == "char" then
    return typemap["char"]
  end

  if word and number and word ~= "char" then
    local mapped = typemap[word] or word:gsub("*", "")
    local argList = {}
    for i = 1, tonumber(number) do
      table.insert(argList, mapped)
    end

    local output = tableReturnTemplate:gen({ argList = argList })

    return string.format("%s[] {%s}", mapped, output)
  end

  return typemap[key] or check:gsub("*", "")
end

-- Open the file in write mode
local file = assert(io.open("init.lua", "w"), "Could not load init.lua")

-- Check if the file was successfully opened
if file == nil then
  error("Output file (init.lua) could not be opened")
end

local header = [[
local ffi = require("ffi")
local lib = ffi.load("libraylib")

local generated = assert(io.open("raylib/generated.h", "r"), "Cannot find generated.h")

ffi.cdef(generated:read("*all"))

local mt = { __index = lib }
local rl = setmetatable({}, mt)

local raygui = require("raylib/raygui")
rl = raygui(rl)
]]

file:write(header)

-- defines
local definesTemplate = Lust({ [[$entry.description
  rl.$entry.name = $entry.value

]] })

for _, targetApi in pairs(apiFiles) do
  for _, entry in pairs(targetApi.defines) do
    if skipped_types(entry.type) == false and entry.value ~= "" then
      if entry.description ~= "" then
        entry.description = "--- " .. entry.description
      end

      if type(entry.value) == "string" then
        entry.value = entry.value:gsub("CLITERAL%(Color%)", "")
      end

      if entry.type == "STRING" then
        entry.value = string.format("%q", entry.value)
      end

      local output = definesTemplate:gen({ entry = entry })

      local formattedOutput = string.format("  %s", output)

      -- print(formattedOutput)

      file:write(formattedOutput)
    end
  end
end

-- structs
local structsClassTemplate =
  Lust({ [[$class $entry.name
  @map{ n=entry.fields }:{{$field $n.name $n.type $newline}}]] })

local structsFunctionTemplate = Lust({
  [[  --- $entry.description @map{ n=entry.fields }:{{$newline  $param $n.name $n.type}}
  $returns $entry.name
  function rl.$entry.name(@map{ n=entry.fields, _separator=", " }:{{$n.name}})
    return ffi.new("$entry.name", @map{ n=entry.fields, _separator=", " }:{{$n.name}})
  end]],
})

-- bucket to make sure structs aren't doubled
local loadedStructs = {}

for _, targetApi in pairs(apiFiles) do
  for _, entry in pairs(targetApi.structs) do
    if table_contains(loadedStructs, entry.name) == false then
      if entry.fields ~= nil then
        for i, v in ipairs(entry.fields) do
          entry.fields[i].type = type_map(entry.fields[i].type)
        end
      end

      local classOutput = structsClassTemplate:gen({
        entry = entry,
        class = "---@class",
        field = "---@field",
        newline = "\n",
      })

      local functionOutput = structsFunctionTemplate:gen({
        entry = entry,
        param = "---@param",
        returns = "---@return",
        newline = "\n",
      })

      local formattedOutput = string.format("\n\n  %s\n%s", classOutput, functionOutput)

      -- print(formattedOutput)

      file:write(formattedOutput)

      table.insert(loadedStructs, entry.name)
    end
  end
end

-- aliases
local aliasesTemplate = Lust({ [[@map{ n=aliases }:{{  $alias $n.name $n.type$newline}}]] })

for _, targetApi in pairs(apiFiles) do
  if #targetApi.aliases > 0 then
    local output = aliasesTemplate:gen({
      aliases = targetApi.aliases,
      alias = "---@alias",
      newline = "\n",
    })

    local formattedOutput = string.format("\n\n%s\n", output)

    -- print(formattedOutput)

    file:write(formattedOutput)
  end
end

-- enums
local enumsTemplate =
  Lust({ [[@map{ n=entry.values }:{{  --- $n.description$newline  rl.$n.name = $n.value$newline$newline}}]] })

for _, targetApi in pairs(apiFiles) do
  for _, entry in pairs(targetApi.enums) do
    local output = enumsTemplate:gen({
      entry = entry,
      newline = "\n",
    })

    local formattedOutput = string.format("%s", output)

    -- print(formattedOutput)

    file:write(formattedOutput)
  end
end

---@todo callbacks?

-- functions
local functionsTemplate = Lust({
  [[  --- $entry.description @map{ n=entry.params }:{{$newline  $param $n.name $n.type}}
  $returns $entry.returnType
  function rl.$entry.name(@map{ n=entry.params, _separator=", " }:{{$n.name}})
    return lib.$entry.name(@map{ n=entry.params, _separator=", " }:{{$n.name}})
  end]],
})

for _, targetApi in pairs(apiFiles) do
  for _, entry in pairs(targetApi.functions) do
    entry.returnType = type_map(entry.returnType)

    if entry.params ~= nil then
      for i, v in ipairs(entry.params) do
        entry.params[i].name = entry.params[i].name == "end" and "ending" or entry.params[i].name
        entry.params[i].type = type_map(entry.params[i].type)
      end
    end

    local output = functionsTemplate:gen({
      entry = entry,
      param = "---@param",
      returns = "---@return",
      newline = "\n",
    })

    local formattedOutput = string.format("\n%s\n", output)

    -- print(formattedOutput)

    file:write(formattedOutput)
  end
end

local footer = [[

  --- check if the given value is of type "Vector2"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsVector2(check)
    return type(check) == "cdata" and ffi.istype("struct Vector2", ffi.typeof(check))
  end

  --- check if the given value is of type "Vector3"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsVector3(check)
    return type(check) == "cdata" and ffi.istype("struct Vector3", ffi.typeof(check))
  end

  --- check if the given value is of type "Vector4"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsVector4(check)
    return type(check) == "cdata" and ffi.istype("struct Vector4", ffi.typeof(check))
  end

  --- check if the given value is of type "Matrix"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsMatrix(check)
    return type(check) == "cdata" and ffi.istype("struct Matrix", ffi.typeof(check))
  end

  --- check if the given value is of type "Color"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsColor(check)
    return type(check) == "cdata" and ffi.istype("struct Color", ffi.typeof(check))
  end

  --- check if the given value is of type "Rectangle"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsRectangle(check)
    return type(check) == "cdata" and ffi.istype("struct Rectangle", ffi.typeof(check))
  end

  --- check if the given value is of type "Image"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsImage(check)
    return type(check) == "cdata" and ffi.istype("struct Image", ffi.typeof(check))
  end

  --- check if the given value is of type "Texture"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsTexture(check)
    return type(check) == "cdata" and ffi.istype("struct Texture", ffi.typeof(check))
  end

  --- check if the given value is of type "RenderTexture"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsRenderTexture(check)
    return type(check) == "cdata" and ffi.istype("struct RenderTexture", ffi.typeof(check))
  end

  --- val if the given value is of type "NPatchInfo"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsNPatchInfo(check)
    return type(check) == "cdata" and ffi.istype("struct NPatchInfo", ffi.typeof(check))
  end

  --- check if the given value is of type "GlyphInfo"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsGlyphInfo(check)
    return type(check) == "cdata" and ffi.istype("struct GlyphInfo", ffi.typeof(check))
  end

  --- check if the given value is of type "Font"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsFont(check)
    return type(check) == "cdata" and ffi.istype("struct Font", ffi.typeof(check))
  end

  --- check if the given value is of type "Camera3D"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsCamera3D(check)
    return type(check) == "cdata" and ffi.istype("struct Camera3D", ffi.typeof(check))
  end

  --- check if the given value is of type "Camera2D"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsCamera2D(check)
    return type(check) == "cdata" and ffi.istype("struct Camera2D", ffi.typeof(check))
  end

  --- check if the given value is of type "Mesh"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsMesh(check)
    return type(check) == "cdata" and ffi.istype("struct Mesh", ffi.typeof(check))
  end

  --- check if the given value is of type "Shader"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsShader(check)
    return type(check) == "cdata" and ffi.istype("struct Shader", ffi.typeof(check))
  end

  --- check if the given value is of type "MaterialMap"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsMaterialMap(check)
    return type(check) == "cdata" and ffi.istype("struct MaterialMap", ffi.typeof(check))
  end

  --- check if the given value is of type "Material"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsMaterial(check)
    return type(check) == "cdata" and ffi.istype("struct Material", ffi.typeof(check))
  end

  --- check if the given value is of type "Transform"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsTransform(check)
    return type(check) == "cdata" and ffi.istype("struct Transform", ffi.typeof(check))
  end

  --- check if the given value is of type "BoneInfo"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsBoneInfo(check)
    return type(check) == "cdata" and ffi.istype("struct BoneInfo", ffi.typeof(check))
  end

  --- check if the given value is of type "Model"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsModel(check)
    return type(check) == "cdata" and ffi.istype("struct Model", ffi.typeof(check))
  end

  --- check if the given value is of type "ModelAnimation"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsModelAnimation(check)
    return type(check) == "cdata" and ffi.istype("struct ModelAnimation", ffi.typeof(check))
  end

  --- check if the given value is of type "Ray"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsRay(check)
    return type(check) == "cdata" and ffi.istype("struct Ray", ffi.typeof(check))
  end

  --- check if the given value is of type "RayCollision"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsRayCollision(check)
    return type(check) == "cdata" and ffi.istype("struct RayCollision", ffi.typeof(check))
  end

  --- check if the given value is of type "BoundingBox"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsBoundingBox(check)
    return type(check) == "cdata" and ffi.istype("struct BoundingBox", ffi.typeof(check))
  end

  --- check if the given value is of type "Wave"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsWave(check)
    return type(check) == "cdata" and ffi.istype("struct Wave", ffi.typeof(check))
  end

  --- check if the given value is of type "rAudioBuffer"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsrAudioBuffer(check)
    return type(check) == "cdata" and ffi.istype("struct rAudioBuffer", ffi.typeof(check))
  end

  --- check if the given value is of type "rAudioProcessor"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsrAudioProcessor(check)
    return type(check) == "cdata" and ffi.istype("struct rAudioProcessor", ffi.typeof(check))
  end

  --- check if the given value is of type "AudioStream"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsAudioStream(check)
    return type(check) == "cdata" and ffi.istype("struct AudioStream", ffi.typeof(check))
  end

  --- check if the given value is of type "Sound"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsSound(check)
    return type(check) == "cdata" and ffi.istype("struct Sound", ffi.typeof(check))
  end

  --- check if the given value is of type "Music"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsMusic(check)
    return type(check) == "cdata" and ffi.istype("struct Music", ffi.typeof(check))
  end

  --- check if the given value is of type "VrDeviceInfo"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsVrDeviceInfo(check)
    return type(check) == "cdata" and ffi.istype("struct VrDeviceInfo", ffi.typeof(check))
  end

  --- check if the given value is of type "VrStereoConfig"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsVrStereoConfig(check)
    return type(check) == "cdata" and ffi.istype("struct VrStereoConfig", ffi.typeof(check))
  end

  --- check if the given value is of type "FilePathList"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsFilePathList(check)
    return type(check) == "cdata" and ffi.istype("struct FilePathList", ffi.typeof(check))
  end

  --- check if the given value is of type "AutomationEvent"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsAutomationEvent(check)
    return type(check) == "cdata" and ffi.istype("struct AutomationEvent", ffi.typeof(check))
  end

  --- check if the given value is of type "AutomationEventList"
  ---@param check any the value to compare
  ---@return boolean
  function rl.IsAutomationEventList(check)
    return type(check) == "cdata" and ffi.istype("struct AutomationEventList", ffi.typeof(check))
  end


  return rl
]]

file:write(footer)

file:close()
