--[[ Countdown
هذه الوحدة تعمل عبر قالب {{عد تنازلي}}
أصل الوحدة منقول عن الإنجليزية ولكن طورت هنا لتقوم بوظائف أحسن 
لذا أحذر عند تحديثها من نص الإنجليزية
]]
-- هذه الوحدة مترتبط بالإضافة [[ميدياويكي:Gadget-countdown-timer.js]]

require 'strict'
local p = {}
string = mw.ustring
-- Constants
local lang = mw.language.getContentLanguage()
local getArgs = require('Module:Arguments with aliases').getArgs
local alltimeparts = {'years', 'weeks', 'days', 'hours', 'minutes', 'seconds'}
local timeFormat
local timeparts = 2
local color ='#F00'



local function formatMessage(text, secondsLeft)
	local maj = mw.ustring.find( text, '@مدة مجرورة@', 1, true ) and true or false

    local function getTableKeys(table,limit)
        local keyset = {}
        local n=0
        for _,v in pairs(alltimeparts) do
            if table[v] then
            	n=n+1
            	keyset[n] = v
	            if n>=limit then
	            	break
	        	end
            end
        end
        return keyset
    end
    local mytimeformat = timeFormat or (timeparts and getTableKeys(lang:getDurationIntervals(secondsLeft, alltimeparts),timeparts)) or alltimeparts
    local timeLeft = lang:formatDuration(secondsLeft, mytimeformat)
    -- Color and bold the numbers, because it makes them look important.
	timeLeft = string.gsub(timeLeft, '(%d+)', '<span style="color: ' .. color .. '; font-weight: bold;">%1</span>')
	if maj then
		timeLeft=string.gsub(timeLeft,'ان و ', 'ين و');
		timeLeft=string.gsub(timeLeft,'ان، ', 'ين و');
        if string.sub(timeLeft,-2) == 'ان' then
        	timeLeft = string.sub(timeLeft,1,-3) .. 'ين'
    	end
    end
    timeLeft = string.gsub(timeLeft,'، ',' و');
	timeLeft = string.gsub(timeLeft,'%(','');
	timeLeft = string.gsub(timeLeft,'%)','');

    if text and text ~= '' then
        timeLeft = string.gsub(text,maj and '@مدة مجرورة@' or '@مدة@', timeLeft)
    end
    return timeLeft
end

local function  formatDurationList(_timeFormat)
	local allowedIntervals = {}
	for _,v in ipairs(alltimeparts) do
		if string.find( _timeFormat,string.sub(v,1,1)) then 
			table.insert(allowedIntervals, v) 
		end
	end
	return allowedIntervals
end

local function  process(args)
	local eventTime
	if type(args.date1) ~= 'nil' then 
		eventTime= tonumber(lang:formatDate('U',args.date1))
		args.date1 = lang:formatDate('c',args.date1)
	else
        if (tonumber(args.year) and tonumber(args.month) and tonumber(args.day)) then 
        	eventTime = os.time({year=args.year, month=args.month, day=args.day
        		, hour=args.hour, min=args.minute, sec=args.second})
			args.date1 = lang:formatDate('c','@' .. eventTime)
		-- else
        -- 	error(  '<strong class="error">خطأ: يجب تحديد السنة، والشهر، واليوم.</strong>')
        end
	end
	
	local timeToStart = eventTime and os.difftime(eventTime, os.time()) or nil -- (future time - current time)

	local timeToEnd
	if args.date2 then
		timeToEnd = tonumber(lang:formatDate('U',args.date2))
		if timeToEnd % 86400 == 0 and not string.find(args.date2,':') and not string.find(args.date2,'hours') then
			timeToEnd=timeToEnd+86400
		end
        args.date2 = lang:formatDate('c','@' .. tostring(timeToEnd))
        timeToEnd = os.difftime(timeToEnd , os.time())
	elseif tonumber(args.duration) and eventTime then
		if args['duration unit'] then
			-- Duration is in unit other than seconds, use formatDate to add
			timeToEnd = tonumber(lang:formatDate('U', '@' .. tostring(timeToStart) 
				.. ' +' .. tostring(args.duration) .. ' ' .. args['duration unit']))
			args.date2 = lang:formatDate('c', '@' .. tostring(eventTime) 
			.. ' +' .. tostring(args.duration) .. ' ' .. args['duration unit'])
		else 
			timeToEnd = timeToStart + (tonumber(args.duration) 
				or error('args.duration should be a number of seconds', 0))
			args.date2 = lang:formatDate('c', '@' .. tostring(eventTime+ args.duration))
		end
	end

	if (timeToStart or timeToEnd) == nil then
		error(  '<strong class="error">خطأ: يجب تحديد تاريخ .</strong>')
	elseif timeToEnd ~= nil and timeToStart == nil then
		timeToStart = 0
	end

	return timeToStart,timeToEnd
end

local function  _shortMain(args)
	local timeToStart,timeToEnd = process(args)
	
	if timeToStart > 0 then
		-- Event has not begun yet
		return formatMessage(timeToStart, args.color)
	elseif timeToEnd then
		if timeToEnd > 0 then 	-- Event is in progress
			return  formatMessage(timeToEnd,  args.color)
		else 			-- Event had a duration and has now ended
			return  ''
		end
	else
		-- Event had no duration and has begun
		return  ''
	end
	
end

local function _addparam(var,varkey)
	return ' data-' .. varkey .. '="' .. string.gsub(var, '"', '&quot;') .. '"'
end

local function  _Main(args)
	local timeToStart,timeToEnd = process(args)
	local params = ''
	local otherparam = ''
	local text
	local active = (timeToStart and timeToStart > 0) or (timeToEnd and timeToEnd > 0)
    local retSpan = mw.html.create( 'span' ):addClass('countdown-timer')

    if active then
        local paramargs={'date2', 'eventstart', 'eventstart2', 'eventend', 'event'}
        retSpan:attr('data-color', color)
        for _,v in pairs(paramargs) do
            if args[v] then retSpan:attr('data-' .. v, args[v]) end
        end
        if timeparts then otherparam = otherparam .. timeparts end
        if otherparam ~= '' then retSpan:attr('data-other', otherparam) end
        if timeToStart > 0 then
            retSpan:attr('data-date1', args.date1)
			if args.eventbefore then retSpan:attr('data-eventbefore', args.eventbefore) end
        end
    end


	if timeToStart > 0 then
		-- Event has not begun yet
        text = formatMessage(args.eventbefore or args.event and ('بقي @مدة@ على بداية «' .. args.event  .. "».") or '', timeToStart)
	elseif timeToEnd then
		if timeToEnd > 0 then 	-- Event is in progress
            text = formatMessage(args.eventstart2 or args.event and ("بداية «" .. args.event .. "» وستكون النهاية بعد @مدة مجرورة@")  or '', timeToEnd)
		else 			-- Event had a duration and has now ended
			text = args.eventend or args.event and ("انتهاء «" .. args.event .. "».") or ''
		end
	else
		-- Event had no duration and has begun
		text = args.eventstart or args.event and ("بداية «" .. args.event .. '».') or ''
	end

	local refreshLink
	if  not active or args.refresh == 'no' or args.refresh == 'لا' then
		refreshLink = ''
	else
		refreshLink = mw.title.getCurrentTitle():fullUrl({action = 'purge'})
		refreshLink = string.format('<span class="plainlinks cdt-refreshLink"><small>([%s تحديث])</small></span>', refreshLink)
	end

    if active then
		text = tostring(retSpan:wikitext(text .. refreshLink)) .. '[[تصنيف:Gadget-Countdown]]'
    end

    return  text
end

function p.main(frame)
	local aliases = {
		['duration unit'] = 'duration unit',
		date1 = {'date1', 'بداية', 'البداية'},
		date2 = {'date2', 'نهاية', 'النهاية'},
		day = {'day', 'يوم', 'اليوم'},
		duration = {'duration', 'مدة', 'المدة'},
		event = {'event', 'حدث', 'الحدث'},
		eventbefore = {'eventbefore', 'قبل الحدث'},
		eventend = {'eventend', 'نهاية الحدث'},
		eventstart = {'eventstart', 'بداية الحدث'},
		eventstart2 = {'eventstart2', 'بداية الحدث 2', 'بداية الحدث2'},
		hour = {'hour', 'ساعة', 'الساعة'},
		min = {'minute', 'دقيقة', 'الدقيقة'},
		month = {'month', 'شهر', 'الشهر'},
		refresh = {'refresh', 'تحديث', 'التحديث'},
		sec = {'second', 'ثانية', 'الثانية'},
		year = {'year', 'سنة', 'السنة'},
		timeparts = {'timeparts', 'أجزاء الوقت'},
		color = {'color', 'لون', 'اللون'}
	}
	local args = getArgs(frame, {aliases=aliases})
	
	if type(args.timeFormat) == 'string' then
		timeFormat = formatDurationList(args.timeFormat)
	end
	
	timeparts = tonumber(args.timeparts) or timeparts
    color = args.color or color
	if args.format == 'short' then
		args.refresh = 'no'
		args.event = nil
		args.eventbefore = nil
		args.eventstart = nil
		args.eventstart2 = nil
		args.eventend= nil
	end
    return _Main(args)
end

return p