local t = {}

-- FERHENG --
    -- Definite (def) = binavkirî, diyar
    -- Indefinite (indef) = nebinavkirî, nediyar
    -- Singular (s) = Yekjimar / Plural (p) = Pirjimar
    -- Case = Rewş, awa
    
    -- Nominative (nom)= Rewşa (awayê) navkî, netewandî, xwerû
    -- Construct (constr) = Îzafe
    -- Oblique (obl) = Rewşa (awayê) çemandî (tewandî)
    -- Demonstrative oblique (demons_obl) = Rewşa nîşander a çemandî 
    -- Vocativ (voc) = Rewşa bangkirinê

local gsub = mw.ustring.gsub
local find = mw.ustring.find
local g = require('Modul:girêdan').gR

----------------------------------
--    Peyvên Peyvên hevedudanî
---------------------------------
function t.decl_multiword(name)
	local tew = {}
	
	local name_tab = mw.text.split(name, '%s')
	local word1 = name_tab[1]
	local word2 = table.concat(name_tab, ' ', 2)
	
	tew.def_s = name
	tew.def_p = gsub(word1, '(.)$', 'ên').. ' ' .. word2
	
	if find(word1, 'a$') then
		tew.gender ='mê'
		tew.indef_s = gsub(word1, '(.)$', 'eke') .. ' ' .. word2
		tew.indef_p = gsub(word1, '(.)$', 'ine') .. ' ' .. word2
	elseif find(word1, 'ê$') then
		tew.gender ='nêr'
		tew.indef_s = gsub(word1, '(.)$', 'ekî') .. ' ' .. word2
		tew.indef_p = gsub(word1, '(.)$', 'ine') .. ' ' .. word2
	else
		return 'Zayenda peyva yekem nayê zanîn!'
	end
	
	return tew
end

----------------------------------
--     Peyvên nehevedudanî
---------------------------------
function forms_tab(forms, sep)
	local forms = mw.text.split(forms, ';')
	for i, v in ipairs(forms) do
		forms[i] = g(v)
	end
	
	if sep then
		sep = sep
	else
		sep = ', '
	end
	
	return table.concat(forms, sep)
end

function b(bold)
	return '<b>' .. bold .. '</b>'
end -- nivîsa stûr ji bo paşgira navdêr

function CinavCemandi(z)
	if z == 'mê' then return 'wê' end
	if z == 'nêr' then return 'wî' end
end

function t.tew(navder, zayend, guherto, bold)
	local tew = {}
	
		    tew.def_nom_s = navder
	        tew.def_nom_p = navder
	
	if (find(navder, '[bcçdfghjklmnpqrsştvwxyz]$')) then
		if (zayend == 'nêr') then
	        tew.def_constr_s = gsub(navder, '(.)$', '%1' .. b('ê'))
	        tew.def_constr_p = gsub(navder, '(.)$', '%1' .. b('ên'))
	        tew.def_obl_s = gsub(navder, '(.)$', '%1' .. b('î'))
	        tew.def_obl_p = gsub(navder, '(.)$', '%1' .. b('an'))
	        tew.indef_nom_s = gsub(navder, '(.)$', '%1' .. b('ek'))
	        tew.indef_nom_p = gsub(navder, '(.)$', '%1' .. b('in'))
	        tew.indef_constr_s = gsub(navder, '(.)$', '%1' .. b('ekî'))
	        tew.indef_constr_p = gsub(navder, '(.)$', '%1' .. b('ine'))
	        tew.indef_obl_s = gsub(navder, '(.)$', '%1' .. b('ekî'))
	        tew.indef_obl_p = gsub(navder, '(.)$', '%1' .. b('inan'))
	        tew.voc_s = gsub(navder, '(.)$', '%1' .. b('o'))
	        tew.voc_p = gsub(navder, '(.)$', '%1' .. b('ino'))
	        
	    elseif (zayend == 'mê') then
	        tew.def_constr_s = gsub(navder, '(.)$', '%1' .. b('a'))
	        tew.def_constr_p = gsub(navder, '(.)$', '%1' .. b('ên'))
	        tew.def_obl_s = gsub(navder, '(.)$', '%1' .. b('ê'))
	        tew.def_obl_p = gsub(navder, '(.)$', '%1' .. b('an'))
	        tew.indef_nom_s = gsub(navder, '(.)$', '%1' .. b('ek'))
	        tew.indef_nom_p = gsub(navder, '(.)$', '%1' .. b('in'))
	        tew.indef_constr_s = gsub(navder, '(.)$', '%1' .. b('eke'))
	        tew.indef_constr_p = gsub(navder, '(.)$', '%1' .. b('ine'))
	        tew.indef_obl_s = gsub(navder, '(.)$', '%1' .. b('ekê'))
	        tew.indef_obl_p = gsub(navder, '(.)$', '%1' .. b('inan'))
	        tew.voc_s = gsub(navder, '(.)$', '%1' .. b('ê'))
	        tew.voc_p = gsub(navder, '(.)$', '%1' .. b('ino'))
	    end

    elseif (find(navder, '[aêiîouû]$') and guherto == '2') then
    	if (zayend == 'nêr') then
	        tew.def_constr_s = gsub(navder, '(.)$', '%1' .. b('yê'))
	        tew.def_constr_p = gsub(navder, '(.)$', '%1' .. b('yên'))
	        if (find(navder, '[î]$')) then
	        	tew.def_obl_s = navder
	        else
	        	tew.def_obl_s = gsub(navder, '(.)$', '%1' .. b('yî'))
	        end
	        tew.def_obl_p = gsub(navder, '(.)$', '%1' .. b('yan'))
	        tew.indef_nom_s = gsub(navder, '(.)$', '%1' .. b('yek'))
	        tew.indef_nom_p = gsub(navder, '(.)$', '%1' .. b('yin'))
	        tew.indef_constr_s = gsub(navder, '(.)$', '%1' .. b('yekî'))
	        tew.indef_constr_p = gsub(navder, '(.)$', '%1' .. b('yine'))
	        tew.indef_obl_s = gsub(navder, '(.)$', '%1' .. b('yekî'))
	        tew.indef_obl_p = gsub(navder, '(.)$', '%1' .. b('yinan'))
	        tew.voc_s = gsub(navder, '(.)$', '%1' .. b('yo'))
	        tew.voc_p = gsub(navder, '(.)$', '%1' .. b('yino'))
	        
	    elseif (zayend == 'mê') then
	        tew.def_constr_s = gsub(navder, '(.)$', '%1' .. b('ya'))
	        tew.def_constr_p = gsub(navder, '(.)$', '%1' .. b('yên'))
	        if (find(navder, '[ê]$')) then
	        	tew.def_obl_s = navder
	        else
	        	tew.def_obl_s = gsub(navder, '(.)$', '%1' .. b('yê'))
	        end
	        tew.def_obl_p = gsub(navder, '(.)$', '%1' .. b('yan'))
	        tew.indef_nom_s = gsub(navder, '(.)$', '%1' .. b('yek'))
	        tew.indef_nom_p = gsub(navder, '(.)$', '%1' .. b('yin'))
	        tew.indef_constr_s = gsub(navder, '(.)$', '%1' .. b('yeke'))
	        tew.indef_constr_p = gsub(navder, '(.)$', '%1' .. b('yine'))
	        tew.indef_obl_s = gsub(navder, '(.)$', '%1' .. b('yekê'))
	        tew.indef_obl_p = gsub(navder, '(.)$', '%1' .. b('yinan'))
	        tew.voc_s = gsub(navder, '(.)$', '%1' .. b('yê'))
	        tew.voc_p = gsub(navder, '(.)$', '%1' .. b('yino'))
	    end
	    
    elseif (find(navder, '[e]$') and guherto == '2') then
        if (zayend == 'nêr') then
	        tew.def_constr_s = gsub(navder, '(.)$', b('ê'))
	        tew.def_constr_p = gsub(navder, '(.)$', b('ên'))
	        tew.def_obl_s = gsub(navder, '(.)$', b('î'))
	        tew.def_obl_p = gsub(navder, '(.)$', b('an'))
	        tew.indef_nom_s = gsub(navder, '(.)$', 'e' .. b('k'))
	        tew.indef_nom_p = gsub(navder, '(.)$', b('in'))
	        tew.indef_constr_s = gsub(navder, '(.)$', 'e' .. b('kî'))
	        tew.indef_constr_p = gsub(navder, '(.)$', b('ine'))
	        tew.indef_obl_s = gsub(navder, '(.)$', 'e' .. b('kî'))
	        tew.indef_obl_p = gsub(navder, '(.)$', b('inan'))
	        tew.voc_s = gsub(navder, '(.)$', b('o'))
	        tew.voc_p = gsub(navder, '(.)$', b('ino'))
	        
	    elseif (zayend == 'mê') then
	        tew.def_constr_s = gsub(navder, '(.)$', b('a'))
	        tew.def_constr_p = gsub(navder, '(.)$', b('ên'))
	        tew.def_obl_s = gsub(navder, '(.)$', b('ê'))
	        tew.def_obl_p = gsub(navder, '(.)$', b('an'))
	        tew.indef_nom_s = gsub(navder, '(.)$', 'e' .. b('k'))
	        tew.indef_nom_p = gsub(navder, '(.)$', b('in'))
	        tew.indef_constr_s = gsub(navder, '(.)$', 'e' .. b('ke'))
	        tew.indef_constr_p = gsub(navder, '(.)$', b('ine'))
	        tew.indef_obl_s = gsub(navder, '(.)$', 'e' .. b('kê'))
	        tew.indef_obl_p = gsub(navder, '(.)$', b('inan'))
	        tew.voc_s = gsub(navder, '(.)$', b('ê'))
	        tew.voc_p = gsub(navder, '(.)$', b('ino'))
	    end
	    
    elseif (find(navder, '[aeîoû]$')) then
        if (zayend == 'nêr') then
	        tew.def_constr_s = gsub(navder, '(.)$', '%1' .. b('yê'))
	        tew.def_constr_p = gsub(navder, '(.)$', '%1' .. b('yên'))
	        if (find(navder, '[î]$')) then
	        	tew.def_obl_s = navder
	        else
	        	tew.def_obl_s = gsub(navder, '(.)$', '%1' .. b('yî'))
	        end
	        tew.def_obl_p = gsub(navder, '(.)$', '%1' .. b('yan'))
	        tew.indef_nom_s = gsub(navder, '(.)$', '%1' .. b('yek'))
	        tew.indef_nom_p = gsub(navder, '(.)$', '%1' .. b('yin'))
	        tew.indef_constr_s = gsub(navder, '(.)$', '%1' .. b('yekî'))
	        tew.indef_constr_p = gsub(navder, '(.)$', '%1' .. b('yine'))
	        tew.indef_obl_s = gsub(navder, '(.)$', '%1' .. b('yekî'))
	        tew.indef_obl_p = gsub(navder, '(.)$', '%1' .. b('yinan'))
	        tew.voc_s = gsub(navder, '(.)$', '%1' .. b('yo'))
	        tew.voc_p = gsub(navder, '(.)$', '%1' .. b('yino'))
	        
	    elseif (zayend == 'mê') then
	        tew.def_constr_s = gsub(navder, '(.)$', '%1' .. b('ya'))
	        tew.def_constr_p = gsub(navder, '(.)$', '%1' .. b('yên'))
	        tew.def_obl_s = gsub(navder, '(.)$', '%1' .. b('yê'))
	        tew.def_obl_p = gsub(navder, '(.)$', '%1' .. b('yan'))
	        tew.indef_nom_s = gsub(navder, '(.)$', '%1' .. b('yek'))
	        tew.indef_nom_p = gsub(navder, '(.)$', '%1' .. b('yin'))
	        tew.indef_constr_s = gsub(navder, '(.)$', '%1' .. b('yeke'))
	        tew.indef_constr_p = gsub(navder, '(.)$', '%1' .. b('yine'))
	        tew.indef_obl_s = gsub(navder, '(.)$', '%1' .. b('yekê'))
	        tew.indef_obl_p = gsub(navder, '(.)$', '%1' .. b('yinan'))
	        tew.voc_s = gsub(navder, '(.)$', '%1' .. b('yê'))
	        tew.voc_p = gsub(navder, '(.)$', '%1' .. b('yino'))
	    end
   	
    elseif (find(navder, '[ê]$')) then
        if (zayend == 'nêr') then
	        tew.def_constr_s = gsub(navder, '(.)$', b('iyê'))
	        tew.def_constr_p = gsub(navder, '(.)$', b('iyên'))
	        tew.def_obl_s = gsub(navder, '(.)$', b('iyî'))
	        tew.def_obl_p = gsub(navder, '(.)$', b('iyan'))
	        tew.indef_nom_s = gsub(navder, '(.)$', b('iyek'))
	        tew.indef_nom_p = gsub(navder, '(.)$', b('iyin'))
	        tew.indef_constr_s = gsub(navder, '(.)$', b('iyekî'))
	        tew.indef_constr_p = gsub(navder, '(.)$', b('iyine'))
	        tew.indef_obl_s = gsub(navder, '(.)$', b('iyekî'))
	        tew.indef_obl_p = gsub(navder, '(.)$', b('iyinan'))
	        tew.voc_s = gsub(navder, '(.)$', b('iyo'))
	        tew.voc_p = gsub(navder, '(.)$', b('iyino'))
	        
	    elseif (zayend == 'mê') then
	        tew.def_constr_s = gsub(navder, '(.)$', b('iya'))
	        tew.def_constr_p = gsub(navder, '(.)$', b('iyên'))
	        if (find(navder, '[ê]$')) then
	        	tew.def_obl_s = navder
	        else
	        	tew.def_obl_s = gsub(navder, '(.)$', b('iyê'))
	        end
	        tew.def_obl_p = gsub(navder, '(.)$', b('iyan'))
	        tew.indef_nom_s = gsub(navder, '(.)$', b('iyek'))
	        tew.indef_nom_p = gsub(navder, '(.)$', b('iyin'))
	        tew.indef_constr_s = gsub(navder, '(.)$', b('iyeke'))
	        tew.indef_constr_p = gsub(navder, '(.)$', b('iyine'))
	        tew.indef_obl_s = gsub(navder, '(.)$', b('iyekê'))
	        tew.indef_obl_p = gsub(navder, '(.)$', b('iyinan'))
	        tew.voc_s = gsub(navder, '(.)$', b('iyê'))
	        tew.voc_p = gsub(navder, '(.)$', b('iyino'))
	    end
	end
	
	-- îy --> iy + girêdan
	for i, v in pairs(tew) do
		tew[i] = gsub(tew[i], 'î<b>y', '<b>iy')
		
		if bold == 'na' then
			tew[i] = gsub(tew[i], '<b>', '')
			tew[i] = gsub(tew[i], '</b>', '')
		else
			local ziman = require("Modul:ziman").getByCode("ku")
			local alt = tew[i]
			tew[i] = gsub(tew[i], '<b>', '')
			tew[i] = gsub(tew[i], '</b>', '')
			local peyv =tew[i]
			local form = gsub(i, '_', '|')
			local a_zayend = ""
			if zayend == "mê" then
				a_zayend = "m"
			elseif zayend == "nêr" then
				a_zayend = "n"
			elseif zayend == "mê û nêr" then
				a_zayend = "mê û nêr"
			end
			tew[i] = require("Modul:links").full_link(
				{
					lang = ziman,
					term = peyv,
					alt = alt,
					accel = {form = form, gender = a_zayend}
				})
		end
	end
	
	-- zêdekirina cînavên wê/wî/wan
	tew.def_demons_obl_s = g(CinavCemandi(zayend)) .. ' ' .. tew.def_obl_s
	tew.def_demons_obl_p = g('wan') .. ' ' .. tew.def_obl_p
	
	return  tew
end

local function zayendTablo(zayend)
 	if (zayend == 'nêr') then return ' Zayenda nêr a'
 	elseif  (zayend == 'mê') then return ' Zayenda mê ya'
    end
end

function t.tewandin(frame)
   local args = frame:getParent().args
   local navder = args[1]
   local zayend = args[2]
   local yekjimar = args[3]
   local guherto = args['guherto']
   -- Parametre ji bo formên ne standard
   local voc_s = args['bang_y']
   local voc_p = args['bang_p']
   local def_obl_s = args['çemandî_y']
   local def_obl_p = args['çemandî_p']
   
   tew_mn = require('Modul:ku-tewîn-nav/mê û nêr').mn
   tew_yekjimar = require('Modul:ku-tewîn-nav/yekjimar').yekjimar

   if (zayend == 'mê û nêr') then
       return tew_mn(navder, guherto)
   elseif (yekjimar == 'y') then
       return tew_yekjimar(navder, zayend, guherto)
   elseif zayend == '-' then
	   flex_tab = t.decl_multiword(navder, zayend)
       return 
  '{| class="wikitable" style="float:right; margin:0.5em 0 0.5em 0.5em; background-color:white; clear: right;"'
   ..'\n|-'
   ..'\n! colspan="3" align="center" | Zayenda ' .. flex_tab['gender']
   ..'\n|-'
   ..'\n! style="background-color:#FFFFE0; text-align:left;" | Rewş'
   ..'\n! style="background-color:#FFFFE0;" | Yekjimar'
   ..'\n! style="background-color:#FFFFE0;" | Pirjimar'
   ..'\n|-'
   ..'\n| style="background-color:#f8f9fa; text-align:left;" | Binavkirî'
   ..'\n|' .. g(flex_tab["def_s"])
   ..'\n|' .. g(flex_tab["def_p"])
   ..'\n|-'
   ..'\n| style="background-color:#f8f9fa; text-align:left;" | Nebinavkirî'
   ..'\n|' .. g(flex_tab["indef_s"])
   ..'\n|' .. g(flex_tab["indef_p"])
   ..'\n|-'
   ..'\n| colspan="3" align="center" style="background-color:#f8f9fa; font-size:x-small;" | <b style="color:green">Agahdarî</b>: Di peyvên <u>hevedudanî</u> de tenê peyva<br>yekem li gor diyarîtiyê  û li gor hejmarê diguhere.'
   ..'\n|}'
   else
	   flex_tab_g1 = t.tew(navder, zayend, '1')
	   flex_tab_g2 = t.tew(navder, zayend, '2')
	   -- Formên "Nîşandera çemandî" li gorî formên çemandî yên standard tên çêkirin:
	   -- Bo mînak "wî bajarî" rast e feqet "wî bajêr" nayê bikaranîn
	   -- Binêre gotûbêja [[Wîkîferheng:Dîwan/2023#dayê/diyê]]
	   if voc_s then 
	   		flex_tab_g1["voc_s"]  = forms_tab(args['bang_y'])
	   		flex_tab_g2["voc_s"]  = forms_tab(args['bang_y'])
	   end
	   if voc_p then 
	   		flex_tab_g1["voc_p"] = forms_tab(args['bang_p'])
	   		flex_tab_g2["voc_p"] = forms_tab(args['bang_p'])
	   end
	   if def_obl_s then
	   		flex_tab_g1["def_obl_s"] = forms_tab(args['çemandî_y'])
	   		flex_tab_g2["def_obl_s"] = forms_tab(args['çemandî_y'])
	   end
	   if def_obl_p then
	   		flex_tab_g1["def_obl_p"] = forms_tab(args['çemandî_p'])
	   		flex_tab_g2["def_obl_p"] = forms_tab(args['çemandî_p'])
	   end
	   
   		function flex_tab(case)
   			if guherto == 'hemû' then
   				if (voc_s ~= nil or voc_p ~= nil or def_obl_s ~= nil or def_obl_p ~= nil) then
   					return flex_tab_g1[case]
   				else
   					return flex_tab_g1[case] .. '<br>' .. flex_tab_g2[case]
   				end
   			elseif guherto == '2' then
   				return flex_tab_g2[case]
   			else
   				return flex_tab_g1[case]
   			end
   		end
   
       return 
  '{| class="wikitable" style="float:right; margin:0.5em 0 0.5em 0.5em; background-color:white; clear:right;"'
   ..'\n|-'
   ..'\n! colspan="3" align="center" |' .. zayendTablo(zayend) .. ' binavkirî'
   ..'\n|-'
   ..'\n! style="background-color:#FFFFE0;  text-align:left;" | Rewş'
   ..'\n! style="background-color:#FFFFE0;" | Yekjimar'
   ..'\n! style="background-color:#FFFFE0;" | Pirjimar'
   ..'\n|-'
   ..'\n| style="background-color:#f8f9fa; text-align:left;" | Navkî'
   ..'\n|' .. flex_tab_g1["def_nom_s"]
   ..'\n|' .. flex_tab_g1["def_nom_p"]
   ..'\n|-'
   ..'\n| style="background-color:#f8f9fa; text-align:left;" | Îzafe'
   ..'\n|' .. flex_tab("def_constr_s")
   ..'\n|' .. flex_tab("def_constr_p")
   ..'\n|-'
   ..'\n| style="background-color:#f8f9fa; text-align:left;" | Çemandî'
   ..'\n|' .. flex_tab("def_obl_s")
   ..'\n|' .. flex_tab("def_obl_p")
   ..'\n|-'
   ..'\n| style="background-color:#f8f9fa; text-align:left;" | Nîşandera çemandî'
   ..'\n|' .. 	flex_tab("def_demons_obl_s")
   ..'\n|' .. 	flex_tab("def_demons_obl_p")
   ..'\n|-'
   ..'\n| style="background-color:#f8f9fa; text-align:left;" | Bangkirin'
   ..'\n|' .. flex_tab("voc_s")
   ..'\n|' .. flex_tab("voc_p")
   ..'\n|-'
   ..'\n! colspan="3" align="center" |' .. zayendTablo(zayend) .. ' nebinavkirî'
   ..'\n|-'
   ..'\n! style="background-color:#FFFFE0; text-align:left;" | Rewş'
   ..'\n! style="background-color:#FFFFE0;" | Yekjimar'
   ..'\n! style="background-color:#FFFFE0;" | Pirjimar'
   ..'\n|-'
   ..'\n| style="background-color:#f8f9fa; text-align:left;" | Navkî'
   ..'\n|' .. flex_tab("indef_nom_s")
   ..'\n|' .. flex_tab("indef_nom_p")
   ..'\n|-'
   ..'\n| style="background-color:#f8f9fa; text-align:left;" | Îzafe'
   ..'\n|' .. flex_tab("indef_constr_s")
   ..'\n|' .. flex_tab("indef_constr_p")
   ..'\n|-'
   ..'\n| style="background-color:#f8f9fa; text-align:left;" | Çemandî'
   ..'\n|' .. flex_tab("indef_obl_s")
   ..'\n|' .. flex_tab("indef_obl_p")
   ..'\n|}'
      end   
end

---------------------------------------------------------------------------
-- Bo tabloyên formên navdêran.
-- Binêre: [[Şablon:tew-nav-ku]]
---------------------------------------------------------------------------
function t.tew_nobold(navder, zayend, pos, guherto)
   return t.tew(navder, zayend, guherto, 'na')[pos]
end

function t.tew2(frame)
   local args = frame:getParent().args
   local pos = frame.args['pos']
   local navder = args[1]
   local zayend = args[2]
   local guherto = args['guherto']
   
   if guherto == 'hemû' then
      	tew_hemu = t.tew(navder, zayend, '1')[pos] .. '<br>' .. t.tew(navder, zayend, '2')[pos]
      	return tew_hemu
   else
      return t.tew(navder, zayend, guherto)[pos]
   end
end

function t.tew3(frame)
   local args = frame:getParent().args
   local pos = frame.args['pos']
   local zayend = frame.args[1]
   local navder = args[1]
   local guherto = args['guherto']
   
   return t.tew(navder, zayend, guherto)[pos]
end

function t.get_comma_separated_forms(frame)
   local args = frame:getParent().args
   local navder = frame.args[1]
   local zayend = frame.args[2]
   
   local tew_results = {}
   local forms = {}
   
   function removeTags(tag)
		tag = mw.ustring.gsub(tag, '%[%[(.+)%|(.+)%]%]', '%2')
		tag = mw.ustring.gsub(tag, '<b>(.+)</b>', '%1')
		tag = mw.ustring.gsub(tag, '<span(.*)>(.*)</span>', '%2')
		return tag
   end
   
   if zayend == "mê û nêr" then
   		tew_results = t.tew(navder, 'nêr', 'hemû')
   		tew_results_2 = t.tew(navder, 'mê', 'hemû')
    	for k, v in pairs(tew_results_2) do
			v = removeTags(v)
    		table.insert(forms, v)
    	end
   	else
   		tew_results = t.tew(navder, zayend, '2')
   	end

	for k, v in pairs(tew_results) do
		v = removeTags(v)
		table.insert(forms, v)
	end
	
	-- Remove duplicate elements
	local newForms = {}
	local checkForms = {}
	
	for _, v in ipairs(forms) do
		if not checkForms[v] then
			checkForms[v] = true
			table.insert(newForms, v)
		end
	end
	
	return table.concat(newForms, ',') 
end

return t