--[[----------------------------------------------------------------------------

WFCatClientMetadataUtils.lua

--------------------------------------------------------------------------------

ADOBE CONFIDENTIAL
------------------
Copyright 2015 Adobe Systems Incorporated
All Rights Reserved.

NOTICE: All information contained herein is, and remains the property of
Adobe Systems Incorporated and its suppliers, if any. The intellectual and
technical concepts contained herein are proprietary to Adobe Systems
Incorporated and its suppliers and are protected by all applicable
intellectual property laws, including trade secret and copyright laws.
Dissemination of this information or reproduction of this material is
strictly forbidden unless prior written permission is obtained from
Adobe Systems Incorporated.

----------------------------------------------------------------------------]]--

	-- WF.core.os
local KSDate = require 'KSDate'
local WFLocalizationUtils = require 'WFLocalizationUtils'

	-- WF.core.string
local KSStringUtils = require 'KSStringUtils'
local WFZString = require 'WFZString'

	-- WF.core.utils
local KSTableUtils = require 'KSTableUtils'

local derefOpt = KSTableUtils.derefOpt
local sf = string.format
local ZSTR = assert( WFZString.fromZString )

local kMetersPerFoot = 0.3048

--==============================================================================

local WFCatClientMetadataUtils = {}

local sLocalizers = {}

--------------------------------------------------------------------------------

function WFCatClientMetadataUtils.localizeValue( value )

	local formatTypeOrValue = derefOpt( value, 1 )
	
	local localizer = derefOpt( sLocalizers, formatTypeOrValue )
	
	if localizer then

		return localizer( unpack( value, 2, value.n or #value ) )

	elseif type( formatTypeOrValue ) == "table" then

		return formatTypeOrValue

	elseif formatTypeOrValue then
	
		-- TODO [arahn 2015-01-28]: This will help fill out the needed
		-- localizers but should probably be removed before we ship.
		return "< cannot_localize : " .. tostring( formatTypeOrValue ) .. " >"
	end

end

--------------------------------------------------------------------------------

function WFCatClientMetadataUtils.formatHarvestedMetadata( harvested )

	for _, field in ipairs( harvested ) do
	
		local value = derefOpt( field, 'value' )
		
		if value then
			field.value = WFCatClientMetadataUtils.localizeValue( value )
		end
		
	end
	
	return harvested
	
end

--------------------------------------------------------------------------------

-- FIXME [jandrew 5/14/2015]: The incoming dates are not guaranteed
-- to be full ISO 8601 timestamps. Valid formats are as follows:
-- 1.) YYYY
-- 2.) YYYY-MM
-- 3.) YYYY-MM-DD
-- 4.) YYYY-MM-DDThh:mmTZD
-- 5.) YYYY-MM-DDThh:mm:ssTZD
-- 6.) YYYY-MM-DDThh:mm:ss.sTZD
-- politeDateFromISO8601DateString only works with formats 4, 5 and 6. We need
-- to create a new politeDate function that works with all formats.
function sLocalizers.longDateTime( iso8601DateStr )
	-- SEE ABOVE FIXME
	return KSDate.politeDateFromISO8601DateString( iso8601DateStr, 'long', 'medium' )
end

--------------------------------------------------------------------------------

function sLocalizers.mediumDateTime( iso8601DateStr )
	-- SEE ABOVE FIXME
	return KSDate.politeDateFromISO8601DateString( iso8601DateStr, 'medium', 'medium' )
end

--------------------------------------------------------------------------------

function sLocalizers.shortDateTime( iso8601DateStr )
	-- SEE ABOVE FIXME
	return KSDate.politeDateFromISO8601DateString( iso8601DateStr, 'short', 'medium' )
end

--------------------------------------------------------------------------------

function sLocalizers.mediumDate( iso8601DateStr )
	-- SEE ABOVE FIXME
	return KSDate.politeDateFromISO8601DateString( iso8601DateStr, 'medium', 'none' )
end

--------------------------------------------------------------------------------

function sLocalizers.mediumTime( iso8601DateStr )
	-- SEE ABOVE FIXME
	return KSDate.politeDateFromISO8601DateString( iso8601DateStr, 'none', 'medium' )
end

--------------------------------------------------------------------------------

function sLocalizers.rawDateTime( iso8601DateStr )
	-- SEE ABOVE FIXME
	return iso8601DateStr
end

--------------------------------------------------------------------------------

sLocalizers.unused = function()end

--------------------------------------------------------------------------------

sLocalizers.literal = tostring

--------------------------------------------------------------------------------

sLocalizers.rating = function( n )
	
	if type( n ) ~= 'number' then
		return nil
	end
	n = math.floor( n )
	if n >= 1 then
		if n > 5 then
			return 5
		end
		return n
	end

end

--------------------------------------------------------------------------------

sLocalizers.number = function( n, ... )

	return KSStringUtils.numberToString( n, ... )

end

--------------------------------------------------------------------------------

sLocalizers.ZSTR = function( z, ... )

	if z == nil then
		return ""
	end

	local converted = {}
	local n = select( '#', ... )
	
	for i = 1, n do
		local v = select( i, ... )
		if type( v ) == 'table' then
			converted[ i ] = WFCatClientMetadataUtils.localizeValue( v )
		else
			converted[ i ] = v
		end
	end
	
	return ZSTR( z, unpack( converted, 1, n ) )

end

--------------------------------------------------------------------------------

sLocalizers.distance = function( distanceInMeters, numDecimalPlaces, convertToPreferredUnits )

	if convertToPreferredUnits then
		if WFLocalizationUtils.useMetric() then
			distanceInMeters = sf( sf( "%%.%dd", numDecimalPlaces ), distanceInMeters )
			return ZSTR( "$$$/AgLibrary/Exif/Altitude/Display/Meters=^1 m", distanceInMeters )
		else
			local distanceInFeet = sf( sf( "%%.%dd", numDecimalPlaces ), distanceInMeters / kMetersPerFoot )
			return ZSTR( "$$$/AgLibrary/Exif/Altitude/Display/Feet=^1 ft", distanceInFeet )
		end
	end

	return KSStringUtils.systemInternationalString( distanceInMeters, "$$$/Units/Distance/meter/prefix=m", numDecimalPlaces or 2 )

end

--------------------------------------------------------------------------------

sLocalizers.bytes = function( bytes )
	-- pclarke 2019-09-26: this string is ultimately shown to the user so convert
	-- it in a platform appropriate way
	return KSStringUtils.platformByteString( bytes )
end

--------------------------------------------------------------------------------

sLocalizers.formattedFraction = function( num, den, preferAscii )
	return KSStringUtils.formattedFraction( num, den, preferAscii )
end

--==============================================================================

return WFCatClientMetadataUtils
