#------------------------------------------------------------------------------
# File:         thinkware.config
#
# Description:  This config file defines Composite tags to decode subtitle text
#               from Thinkware dashcam videos
#
# Usage:        exiftool -config thinkware.config -ee FILE
#
#               Example command to create .gpx log file from Thinkware video
#               (requires gpx.fmt available in the full Exiftool distribution):
#
#               exiftool -config thinkware.config -p gpx.fmt -ee -api QuickTimeUTC FILE
#
# Requires:     ExifTool version 10.75 or later
#
# Revisions:    2019/09/30 - P. Harvey Created
#------------------------------------------------------------------------------

use Time::Local;

#------------------------------------------------------------------------------
# Decode GPS from Thinkware subtitle Text
# Inputs: 0) ExifTool ref, 1) Text value
# Returns: Hash containing GPS tags
sub Image::ExifTool::UserDefined::DecodeGPS($$)
{
    my ($et, $val) = @_;
    unless ($$et{ThinkwareInfo}{Text} and $val eq $$et{ThinkwareInfo}{Text}) {
        my %gps;
        $$et{ThinkwareInfo}{GPS} = \%gps;
        $$et{ThinkwareInfo}{Text} = $val;
#
# Example embedded "Text" from a Thinkware Q800:
#
#   "gsensori,4,512,-67,-12,100;GNRMC,161313.00,A,4529.87489,N,07337.01215,W,6.225,35.34,310819,,,A*52..;
#    CAR,0,0,0,0.0,0,0,0,0,0,0,0,0"
#
        if ($val =~ /[A-Z]{2}RMC,(\d{2})(\d{2})(\d+(\.\d*)?),A?,(\d*?)(\d{1,2}\.\d+),([NS]),(\d*?)(\d{1,2}\.\d+),([EW]),(\d*\.?\d*),(\d*\.?\d*),(\d{2})(\d{2})(\d+)/ and
            # do some basic sanity checks on the date
            $13 <= 31 and $14 <= 12 and $15 <= 99)
        {
            $gps{lat} = (($5 || 0) + $6/60) * ($7 eq 'N' ? 1 : -1);
            $gps{lon} = (($8 || 0) + $9/60) * ($10 eq 'E' ? 1 : -1);
            $gps{speed} = $11 if length $11;
            $gps{track} = $12 if length $12;
            my $year = $15 + ($15 >= 70 ? 1900 : 2000);
            $gps{datetime} = sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2dZ', $year, $14, $13, $1, $2, $3);
        }
    }
    return $$et{ThinkwareInfo}{GPS};
}

# Composite tags to decode information from subtitle Text
%Image::ExifTool::UserDefined = (
    'Image::ExifTool::Composite' => {
        GROUPS => { 2 => 'Location' },
#
# Note: SubDoc flag is set for all these tags so they will be generated for
#       all embedded documents
#
        GPSDateTime => {
            Description => 'GPS Date/Time',
            Groups => { 2 => 'Time' },
            SubDoc => 1,
            Require => 'Text',
            RawConv => q{
                my $gps = Image::ExifTool::UserDefined::DecodeGPS($self, $val[0]);
                return $$gps{datetime};
            },
            PrintConv => '$self->ConvertDateTime($val)',
        },
        GPSLatitude => {
            SubDoc => 1,
            Require => 'Text',
            RawConv => q{
                my $gps = Image::ExifTool::UserDefined::DecodeGPS($self, $val[0]);
                return $$gps{lat};
            },
            PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
        },
        GPSLongitude => {
            SubDoc => 1,
            Require => 'Text',
            RawConv => q{
                my $gps = Image::ExifTool::UserDefined::DecodeGPS($self, $val[0]);
                return $$gps{lon};
            },
            PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
        },
        GPSSpeed => {
            SubDoc => 1,
            Require => 'Text',
            RawConv => q{
                my $gps = Image::ExifTool::UserDefined::DecodeGPS($self, $val[0]);
                # convert from knots to km/hr
                return defined $$gps{speed} ? $$gps{speed} * 1.852 : undef;
            },
        },
        GPSSpeedRef => {
            SubDoc => 1,
            Require => 'Text',
            RawConv => q{
                my $gps = Image::ExifTool::UserDefined::DecodeGPS($self, $val[0]);
                return defined $$gps{speed} ? 'K' : undef;
            },
            PrintConv => { K => 'km/h', M => 'mph', N => 'knots' },
        },
        GPSTrack => {
            SubDoc => 1,
            Require => 'Text',
            RawConv => q{
                my $gps = Image::ExifTool::UserDefined::DecodeGPS($self, $val[0]);
                return $$gps{track};
            },
        },
        GPSTrackRef => {
            SubDoc => 1,
            Require => 'Text',
            RawConv => q{
                my $gps = Image::ExifTool::UserDefined::DecodeGPS($self, $val[0]);
                return defined $$gps{track} ? 'T' : undef;
            },
            PrintConv => { M => 'Magnetic North', T => 'True North' },
        },
        GSensor => {
            SubDoc => 1,
            Require => 'Text',
            RawConv => q{
                return undef unless $val[0] =~ /gsensori,(.*?)(;|$)/;
                return $1;
            },
        },
        Car => {
            SubDoc => 1,
            Require => 'Text',
            RawConv => q{
                return undef unless $val[0] =~ /CAR,(.*?)(;|$)/;
                return $1;
            },
        },
    },
);

1;  #end
