모듈:Weather box/row

local w = {}
local math_mod = require('Module:Math')
local wbc = require('Module:Weather box/colors')
local traceText
local Value
Value = {
	lang = mw.getContentLanguage(),
	getDisplay = function (self, second)
		if not self:isValid() then
			return nil
		end
		local display = self.string
		if display == 'trace' then
			if second then
				-- If a cell displays "cm (inch)", show "trace" not "trace (trace)".
				return nil
			end
			return traceText or 'trace'
		end
		if math.abs(self.number) >= 1000 then
			display = self.lang:formatNum(math.abs(self.number))
			if self.number  0 then
			local adjust = math.log10(1/convert.factor) + math.log10(2)
			local p1 = math.floor(precision + adjust)
			local p2 = 1 - math.floor(math.log10(outnum))
			if convert.p2max then
				p2 = math.min(p2, convert.p2max)
			end
			precision = math.max(p1, p2)
		end
		self:setNumberRounded(outnum, precision)
	end,
	setNumberRounded = function (self, number, precision)
		if precision > 2 then
			precision = 2
		end
		self.number = math_mod._round(number, precision)
		if precision (" .. display .. ")" )
				end
			end
		else
			table.insert( result, '—' )
		end
		table.insert( result, "\n" )
	end
	return table.concat( result )
end
local function getInputs( frame, group_name, suffix, include_space )
	local month_names = { 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
		'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'year' }
	local str
	local values = {}
	if suffix == nil then
		for i, mon in ipairs( month_names ) do
			if include_space then
				str = frame.args mon .. ' ' .. group_name  or 
			else
				str = frame.args mon .. group_name  or 
			end
			valuesi = Value.new(str)
		end
	else
		for i, mon in ipairs( month_names ) do
			local value, updated
			for var, suf in ipairs( suffix ) do
				if include_space then
					str = frame.args mon .. ' ' .. group_name .. ' ' .. suf 
				else
					str = frame.args mon .. group_name .. ' ' .. suf 
				end
				if str ~= nil and str ~=  then
					value = Value.new(str)
					value.variant = var
					updated = true
					break
				end
			end
			if not updated then
				value = Value.new()
				value.variant = 0
			end
			valuesi = value
		end
	end
	return values
end
local function getAnnualValue( values, mode )
	if mode == 'avg' or mode == 'sum' then
		local total = 0
		local p1, p2, variant
		p1 = 0
		for i = 1, 12 do
			if not valuesi:isValid() then
				return Value.new()
			end
			if not variant then
				local var = valuesi.variant
				if var and var ~= 0 then
					variant = var
				end
			end
			p2 = valuesi:getPrecision()
			if p2 > p1 then
				p1 = p2
			end
			total = total + valuesi.number
		end
		local value = Value.new(total)
		if mode == 'avg' then
			value:setNumberRounded( total / 12, p1 )
		end
		value.variant = variant
		return value
	elseif mode == 'min' then
		local target
		for i = 1, 12 do
			if valuesi:isValid() then
				if target == nil or valuesi.number  target.number then
					target = valuesi
				end
			end
		end
		return target or Value.new()
	else
		error( 'Unrecognized Annual Mode' )
	end
end
local function reconcileTemperature( C_values, F_values )
	for i = 1,13 do
		local p
		if C_valuesi.string ==  then
			if F_valuesi:isValid() then
				p = F_valuesi:getPrecision()
				C_valuesi:setNumberRounded( (F_valuesi.number - 32)*5/9, p )
			end
		elseif F_valuesi.string ==  then
			if C_valuesi:isValid() then
				p = C_valuesi:getPrecision()
				F_valuesi:setNumberRounded( C_valuesi.number*9/5 + 32, p )
			end
		end
	end
end
local function reconcilePrecipitation( M_values, I_values, prefer_cm )
	local v_class = 0
	for i = 1,13 do
		if M_valuesi.variant == 1 then
			v_class = 1
		elseif M_valuesi.variant == 2 then
			v_class = 2
		end
	end
	if v_class == 0 then
		if prefer_cm then
			v_class = 1
		else
			v_class = 2
		end
	end
	for i = 1,13 do
		local units
		if M_valuesi.string ==  then
			if I_valuesi:isValid() then
				if v_class == 1 then
					units = 'in2cm'
				else
					units = 'in2mm'
				end
				M_valuesi:setConvert( I_valuesi, units )
				M_valuesi.variant = v_class
			end
		elseif I_valuesi.string ==  then
			if M_valuesi:isValid() then
				if M_valuesi.variant == 1 then
					units = 'cm2in'
				else
					units = 'mm2in'
				end
				I_valuesi:setConvert( M_valuesi, units )
			end
		end
	end
end
function w.buildRow( frame )
	local mode = (frame.args.mode or 'basic'):lower()
	local group_name = frame.args.group_name
	local first_values, second_values
	local color_values
	local color_scheme = frame.args.color_scheme or 't'
	local scale_factor = math_mod._cleanNumber( frame.args.scale_factor) or 1
	local date_mode = checkFlag( frame.args.date_mode, false )
	local label = frame.args.label or 
	local annual_mode = (frame.args.annual_mode or 'avg'):lower()
	local include_space = checkFlag( frame.args.include_space, true )
	local second_line = checkFlag( frame.args.second_line, false )
	local prefer_cm = checkFlag( frame.args.prefer_cm, false )
	local pframe = frame:getParent()
	local imperial_first = checkFlag( frame.args'imperial first' or pframe.args'imperial first' )
	local metric_first = checkFlag( frame.args'metric first' or pframe.args'metric first' )
	local single_line = checkFlag( frame.args'single line' or pframe.args'single line' )
	local trace = pframe.args.trace
	if trace and trace ~=  then
		traceText = trace
	end
	if imperial_first == nil then
		imperial_first = metric_first == nil and true or not metric_first
	end
	if mode == 'basic' then
		first_values = getInputs( pframe, group_name, nil, include_space )
		second_values = nil
	elseif mode == 'temperature' then
		first_values = getInputs( pframe, group_name, {'C'}, include_space )
		second_values = getInputs( pframe, group_name, {'F'}, include_space )
		reconcileTemperature( first_values, second_values )
	elseif mode == "precipitation" then
		first_values = getInputs( pframe, group_name, {'cm', 'mm'}, include_space )
		second_values = getInputs( pframe, group_name, {'inch'}, include_space )
		reconcilePrecipitation( first_values, second_values, prefer_cm )
	else
		error( 'Requested mode not recognized' )
	end
	local good = false
	for i = 1,13 do
		if first_valuesi.string ~=  then
			good = true
			break
		end
	end
	if not good then
		return 
	end
	if first_values13.string ==  then
		first_values13 = getAnnualValue( first_values, annual_mode )
	end
	if second_values ~= nil then
		if second_values13.string ==  then
			second_values13 = getAnnualValue( second_values, annual_mode )
		end
	end
	color_scheme = wbc.interpret_color_code( color_scheme )
	color_values = {}
	local month_adj = { 31/30, 28.25/30, 31/30, 1, 31/30, 1,
		31/30, 31/30, 1, 31/30, 1, 31/30, 365.25/30 }
	for i = 1,13 do
		if first_valuesi:isValid() then
			local adj = scale_factor
			if date_mode then
				adj = adj / month_adji
			end
			if mode == "precipitation" then
				if first_valuesi.variant == 1 then
					adj = adj * 10
				end
			end
			table.insert( color_values, color_scheme( first_valuesi.number * adj ) )
		else
			table.insert( color_values, color_scheme( nil ) )
		end
	end
	if imperial_first and second_values ~= nil then
		first_values, second_values = second_values, first_values
	end
	if not single_line then
		if second_line and second_values ~= nil then
			first_values = second_values
		end
		second_values = nil
	end
	return makeLine( label, first_values, second_values, color_values )
end
return w