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

WFCatFormatter_video.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.lua
local WFRatio = require 'WFRatio'

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

	-- WF.oz_client.managed_catalog.video
local WFCatVideoTime = require 'WFCatVideoTime'

local derefOpt = KSTableUtils.derefOpt

local formatters = {
	default_category = 'com.adobe.formatterCategories.video',
}

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

local function add( f )
	formatters[ #formatters + 1 ] = f
end

--==============================================================================
-- @mark	Utilities
--==============================================================================

local optToString = function( value, optNumericMultiplier, optUnit )

	if value then

		if optNumericMultiplier then
			if type( value ) ~= 'number' then
				return
			end
			value = value * optNumericMultiplier
		end

		if optUnit then
			return 'ZSTR', optUnit, value
		else
			return 'literal', value
		end
	end

	return

end

--==============================================================================
-- @mark	Formatters
--==============================================================================

add {

	id = 'com.adobe.audioChannelType',
	title = "$$$/AgLibrary/MetadataFormatters/Video/audioChannelType=Audio Channel Type",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'video', 'audioChannelType' ) )

	end,
}

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

add {
	id = 'com.adobe.audioSampleRate',
	title = "$$$/AgLibrary/MetadataFormatters/Video/audioSampleRate=Audio Sample Rate",

	format_asset = function( self, assetDoc )

		return optToString(
			derefOpt( assetDoc, 'video', 'audioSampleRate' ),
			1 / 1000,
			"$$$/AgLibrary/MetadataFormatters/Video/audioSampleRate/UnitHertz=^1 kHz" )

	end,
}

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

add {
	id = 'com.adobe.audioSampleType',
	title = "$$$/AgLibrary/MetadataFormatters/Video/audioSampleType=Audio Sample Type",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'video', 'audioSampleType' ) )

	end,
}

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

add {
	id = 'com.adobe.videoAlphaMode',
	title = "$$$/AgLibrary/MetadataFormatters/VideoAlphaMode=Video Alpha Mode",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'video', 'videoAlphaMode' ) )

	end,
}

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

add {
	id = 'com.adobe.videoPixelAspectRatio',
	title = "$$$/AgLibrary/MetadataFormatters/VideoPixelAspectRatio=Pixel Aspect Ratio",

	format_asset = function( self, assetDoc )

		local dar = derefOpt( assetDoc, 'video', 'displayAspectRatio' )
		local w = derefOpt( assetDoc, 'video', 'storageWidth' )
		local h = derefOpt( assetDoc, 'video', 'storageHeight' )
		
		if dar and w and h then
			local par = WFRatio.multiply( dar, { h, w } )
			return 'number', par[ 1 ] / par[ 2 ], 1, true
		end
		
	end,
}

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

add {
	id = 'com.adobe.album',
	title = "$$$/AgLibrary/MetadataFormatters/Video/album=Album",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'xmp', 'dm', 'album' ) )

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					album = value
				}
			}
		}
	end,



}

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

add {

	id = 'com.adobe.altTapeName',
	title = "$$$/AgLibrary/MetadataFormatters/Video/altTapeName=Alternate Tape Name",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'xmp', 'dm', 'altTapeName' ) )

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					altTapeName = value
				}
			}
		}
	end,

}

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

add {
	id = 'com.adobe.cameraModel',
	title = "$$$/AgLibrary/MetadataFormatters/Video/cameraModel=Camera Model",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'xmp', 'dm', 'cameraModel' ) )

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					cameraModel = value
				}
			}
		}
	end,

}

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

add {
	id = 'com.adobe.cameraAngle',
	title = "$$$/AgLibrary/MetadataFormatters/Video/cameraAngle=Camera Angle",
	data_type = "enum",
	enum_values = {
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/enum/Unset=Unset",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraAngle/Low Angle=Low Angle",
			value = "Low Angle",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraAngle/Eye Level=Eye Level",
			value = "Eye Level",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraAngle/High Angle=High Angle",
			value = "High Angle",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraAngle/Overhead Shot=Overhead Shot",
			value = "Overhead Shot",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraAngle/Birds Eye Shot=Birds Eye Shot",
			value = "Birds Eye Shot",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraAngle/Dutch Angle=Dutch Angle",
			value = "Dutch Angle",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraAngle/POV=POV",
			value = "POV",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraAngle/Over the Shoulder=Over the Shoulder",
			value = "Over the Shoulder",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraAngle/Reaction Shot=Reaction Shot",
			value = "Reaction Shot",
		},
	},

	format_asset = function( self, assetDoc )

		local value = derefOpt( assetDoc, 'xmp', 'dm', 'cameraAngle' )
		if value and 
			type( value ) == 'number' and 
			value > 0 and 
			value <= #self.enum_values then
				return 'ZSTR', self.enum_values[ value ].title
		end

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					cameraAngle = value
				}
			}
		}
	end,

}

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

add {
	id = 'com.adobe.cameraMove',
	title = "$$$/AgLibrary/MetadataFormatters/Video/cameraMove=Camera Move",
	data_type = "enum",
	enum_values = {
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/enum/Unset=Unset",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraMove/Aerial=Aerial",
			value = "Aerial",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraMove/Boom Up=Boom Up",
			value = "Boom Up",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraMove/Boom Down=Boom Down",
			value = "Boom Down",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraMove/Crane Up=Crane Up",
			value = "Crane Up",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraMove/Crane Down=Crane Down",
			value = "Crane Down",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraMove/Dolly In=Dolly In",
			value = "Dolly In",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraMove/Dolly Out=Dolly Out",
			value = "Dolly Out",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraMove/Pan Left=Pan Left",
			value = "Pan Left",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraMove/Pan Right=Pan Right",
			value = "Pan Right",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraMove/Pedestal Up=Pedestal Up",
			value = "Pedestal Up",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraMove/Pedestal Down=Pedestal Down",
			value = "Pedestal Down",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraMove/Tilt Up=Tilt Up",
			value = "Tilt Up",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraMove/Tilt Down=Tilt Down",
			value = "Tilt Down",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraMove/Tracking=Tracking",
			value = "Tracking",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraMove/Truck Left=Truck Left",
			value = "Truck Left",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraMove/Truck Right=Truck Right",
			value = "Truck Right",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraMove/Zoom In=Zoom In",
			value = "Zoom In",
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/cameraMove/Zoom Out=Zoom Out",
			value = "Zoom Out",
		},
	},


	format_asset = function( self, assetDoc )

		local value = derefOpt( assetDoc, 'xmp', 'dm', 'cameraMove' )
		if value and 
			type( value ) == 'number' and 
			value > 0 and 
			value <= #self.enum_values then
				return 'ZSTR', self.enum_values[ value ].title
		end

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					cameraMove = value
				}
			}
		}
	end,

}

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

add {
	id = 'com.adobe.client',
	title = "$$$/AgLibrary/MetadataFormatters/Video/client=Client",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'xmp', 'dm', 'client' ) )

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					client = value
				}
			}
		}
	end,

}

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

add {
	id = 'com.adobe.comment',
	title = "$$$/AgLibrary/MetadataFormatters/Video/Comment=Comment",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'xmp', 'dm', 'comment' ) )

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					comment = value
				}
			}
		}
	end,

}

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

add {
	id = 'com.adobe.composer',
	title = "$$$/AgLibrary/MetadataFormatters/Video/composer=Composer",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'xmp', 'dm', 'composer' ) )

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					composer = value
				}
			}
		}
	end,

}

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

add {
	id = 'com.adobe.description',
	title = "$$$/AgLibrary/MetadataFormatters/Video/Description=Description",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'xmp', 'dc', 'description' ) )

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dc = {
					description = value,
				},
			},
		}
	end,
}

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

add {
	id = 'com.adobe.director',
	title = "$$$/AgLibrary/MetadataFormatters/Video/director=Director",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'xmp', 'dm', 'director' ) )

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					director = value
				}
			}
		}
	end,

}

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

add {
	id = 'com.adobe.directorPhotography',
	title = "$$$/AgLibrary/MetadataFormatters/Video/directorPhotography=Director of Photography",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'xmp', 'dm', 'directorPhotography' ) )

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					directorPhotography = value
				}
			}
		}
	end,

}

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

add {
	id = 'com.adobe.dm_artist',
	title = "$$$/AgLibrary/MetadataFormatters/Video/dm_artist=Artist",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'xmp', 'dm', 'artist' ) )

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					artist = value
				}
			}
		}
	end,

}

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

add {
	id = 'com.adobe.dm_scene',
	title = "$$$/AgLibrary/MetadataFormatters/Video/dm_scene=Scene",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'xmp', 'dm', 'scene' ) )

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					scene = value
				}
			}
		}
	end,

}

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

add {
	id = 'com.adobe.engineer',
	title = "$$$/AgLibrary/MetadataFormatters/Video/engineer=Engineer",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'xmp', 'dm', 'engineer' ) )

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					engineer = value
				}
			}
		}
	end,

}

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

add {
	id = 'com.adobe.genre',
	title = "$$$/AgLibrary/MetadataFormatters/Video/genre=Genre",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'xmp', 'dm', 'genre' ) )

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					genre = value
				}
			}
		}
	end,

}

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

add {
	id = 'com.adobe.good',
	title = "$$$/AgLibrary/MetadataFormatters/Video/Good_label=Good",
	data_type = "enum",
	enum_values = {
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/enum/Unset=Unset",
			value = nil,
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/good=Good",
			value = 'True',
		},
		{
			title = "$$$/AgLibrary/MetadataFormatters/Video/notGood=Not Good",
			value = 'False',
		},
	},


	format_asset = function( self, assetDoc )

		local good = derefOpt( assetDoc, 'xmp', 'dm', 'good' )
		
		if good == true then
			return 'literal', 'True'
		end
		if good == false then
			return 'literal', 'False'
		end

	end,

	asset_overlay = function( self, value )
	
		if value == nil then
			value = { _delete = true }
		end
		if value == 'True' then
			value = true
		end
		if value == 'False' then
			value = false
		end
		return {
			xmp = {
				dm = {
					good = value
				}
			}
		}
	end,

}

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

add {
	id = 'com.adobe.instrument',
	title = "$$$/AgLibrary/MetadataFormatters/Video/instrument=Instrument",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'xmp', 'dm', 'instrument' ) )

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					instrument = value
				}
			}
		}
	end,

}

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

add {
	id = 'com.adobe.logComment',
	title = "$$$/AgLibrary/MetadataFormatters/Video/logComment=Log Comment",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'xmp', 'dm', 'logComment' ) )

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					logComment = value
				}
			}
		}
	end,

}

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

add {
	id = 'com.adobe.projectName',
	title = "$$$/AgLibrary/MetadataFormatters/Video/projectName=Project Name",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'xmp', 'dm', 'projectName' ) )

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					projectName = value
				}
			}
		}
	end,
}

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

add {
	id = 'com.adobe.releaseDate',
	title = "$$$/AgLibrary/MetadataFormatters/Video/releaseDate=Release Date",

	format_asset = function( self, assetDoc )

		local date = derefOpt( assetDoc, 'xmp', 'dm', 'releaseDate' )
		
		if date then
			return 'mediumDateTime', date
		end

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					releaseDate = value
				}
			}
		}
	end,
}

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

add {
	id = 'com.adobe.shotDate',
	title = "$$$/AgLibrary/MetadataFormatters/Video/shotDate=Shot Date",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'xmp', 'dm', 'shotDate' ) )

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					shotDate = value
				}
			}
		}
	end,
}

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

add {
	id = 'com.adobe.shotDay',
	title = "$$$/AgLibrary/MetadataFormatters/Video/shotDay=Day of Shoot",

	format_asset = function( self, assetDoc )

		local date =  derefOpt( assetDoc, 'xmp', 'dm', 'shotDay' )

		if date then
			return 'mediumDateTime', date
		end

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					shotDay = value
				}
			}
		}
	end,
}

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

add {
	id = 'com.adobe.shotLocation',
	title = "$$$/AgLibrary/MetadataFormatters/Video/shotLocation=Shot Location",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'xmp', 'dm', 'shotLocation' ) )

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					shotLocation = value
				}
			}
		}
	end,

}

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

add {
	id = 'com.adobe.shotName',
	title = "$$$/AgLibrary/MetadataFormatters/Video/shotName=Shot Name",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'xmp', 'dm', 'shotName' ) )

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					shotName = value
				}
			}
		}
	end,

}

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

add {
	id = 'com.adobe.speakerPlacement',
	title = "$$$/AgLibrary/MetadataFormatters/Video/speakerPlacement=Speaker Placement",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'xmp', 'dm', 'speakerPlacement' ) )

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					speakerPlacement = value
				}
			}
		}
	end,

}

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

add {
	id = 'com.adobe.tapeName',
	title = "$$$/AgLibrary/MetadataFormatters/Video/tapeName=Tape Name",

	format_asset = function( self, assetDoc )

		return optToString( derefOpt( assetDoc, 'xmp', 'dm', 'tapeName' ) )

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					tapeName = value
				}
			}
		}
	end,

}

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

add {
	id = 'com.adobe.trackNumber',
	title = "$$$/AgLibrary/MetadataFormatters/Video/trackNumber=Track Number",

	format_asset = function( self, assetDoc )

		local trackNumber = derefOpt( assetDoc, 'xmp', 'dm', 'trackNumber' )
		if type( trackNumber ) == 'number' then
			return 'number', trackNumber
		end

	end,

	asset_overlay = function( self, value )
		if value == nil then
			value = { _delete = true }
		end
		return {
			xmp = {
				dm = {
					trackNumber = value
				}
			}
		}
	end,

}


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

add {
	id = 'com.adobe.videoFrameSize',
	title = "$$$/AgLibrary/MetadataFormatters/VideoFrameSize=Video Dimensions",

	format_asset = function( self, assetDoc )

		local w, h = derefOpt( assetDoc, 'video', 'storageWidth' ), derefOpt( assetDoc, 'video', 'storageHeight' )

		if w and h then

			return optToString( string.format( "%d x %d", w, h ) )

		end

	end,

}

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

local function formatVideoTime( tt )

	if not tt or tt == "" then

		return "--:--.--"

	end

	local t = tonumber( tt )

	if type( t ) ~= 'number' then

		return tostring( tt )

	end

	local m = math.floor( t / 60 )
	local s = math.floor( t - m * 60 )
	local ms = ( t - m * 60 - s ) * 10
	return string.format( "%02d:%02d.%01d", m, s, ms )
end

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

local function userTimeFormat( tt, fr, display_mode )

	if not tt or not type( tt ) == table then return end

	tt = tt[ 1 ] / tt[ 2 ]

	if display_mode == 'smpte' then

		return 'literal', WFCatVideoTime.formatSmpteVideoTime( tt, fr )
	else
		return 'literal', formatVideoTime( tt )

	end

end

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

add {
	id = 'com.adobe.duration',
	title = "$$$/AgLibrary/MetadataFormatters/Duration=Duration",

	format_asset = function( self, assetDoc, options )

		local duration = derefOpt( assetDoc, 'video', 'duration' )
		local frame_rate = derefOpt( assetDoc, 'video', 'frameRate' )

		return userTimeFormat( duration, frame_rate, options and options.VideoPlayer_timeDisplay or nil )

	end,
}

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

add {
	id = 'com.adobe.videoFrameRate',
	title = "$$$/AgLibrary/MetadataFormatters/VideoFrameRate=Video Frame Rate",

	format_asset = function( self, assetDoc )

		local frame_rate = derefOpt( assetDoc, 'video', 'frameRate' )
		local hat1

		if frame_rate then

			hat1 = { 'number', frame_rate[ 1 ] / frame_rate[ 2 ], 3, false }

		end

		if not hat1 then return end

		return 'ZSTR', "$$$/AgLibrary/MetadataFormatters/Video/VideoFrameRate/UnitFramesPerSecopnd=^1 fps", hat1

	end,

}

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

add {
	id = 'com.adobe.duration.combined.optional',
	title = "$$$/AgLibrary/MetadataFormatters/Duration=Duration",

	format_asset = function( self, assetDoc, options )
		
		local duration = derefOpt( assetDoc, 'video', 'duration' )
		local frame_rate = derefOpt( assetDoc, 'video', 'frameRate' )

		if duration then

			return userTimeFormat( duration, frame_rate, options and options.VideoPlayer_timeDisplay or nil )

		end

	end,
}

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

add {
	id = 'com.adobe.trimmed_duration.optional',
	title = "$$$/AgLibrary/MetadataFormatters/TrimmedDuration=Trimmed Duration",

	format_asset = function( self, assetDoc, options )

		local frame_rate = derefOpt( assetDoc, 'video', 'frameRate' )
		local clips = derefOpt( assetDoc, 'video', 'clips' )

		if clips and next( clips ) then
			local duration = { 0, 1 }
			for _, clip in pairs( clips ) do
				duration = WFRatio.add( duration, clip[ 'end' ] )
				duration = WFRatio.add( duration, WFRatio.multiply( clip.start, { -1, 1 } ) )
			end

			return userTimeFormat( duration, frame_rate, options and options.VideoPlayer_timeDisplay or nil )

		end

	end,

}

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

return formatters

