#******************************************************************************
#
# Copyright:   2018-2020 Paul Obermeier (obermeier@poSoft.de)
#
#              See the file "Mawt_License.txt" for information on
#              usage and redistribution of this file, and for a
#              DISCLAIMER OF ALL WARRANTIES.
#
# Description: Tcl module with miscellaneous utility
#              procedures related to the FFMPEG module.
#
#******************************************************************************

namespace eval mawt {
    variable ns [namespace current]

    namespace ensemble create

    namespace export VideoExport
    namespace export VideoImport

    proc VideoExport { movieFile imgFilePattern args } {
        # Export video frames into a series of image files.
        #
        # movieFile      - Movie file name.
        # imgFilePattern - Pattern for image output files.
        #                  Must contain a printf like integer format specifier.
        # args           - Options described below.
        #
        # -start <int> - Start frame. Default: First video frame.
        # -end <int>   - End frame. Default: Last video frame.
        #
        # See also: VideoImport

        set startFrame -1
        set endFrame   -1
        foreach { key value } $args {
            switch -exact $key {
                "-start" {
                    set startFrame [expr {int($value)}]
                }
                "-end" {
                    set endFrame [expr {int($value)}]
                }
            }
        }

        set videoObj [mawt Video new $movieFile "r"]
        set numBytes [$videoObj Start]
        set tx [$videoObj GetWidth]
        set ty [$videoObj GetHeight]
        set vectorObj [mawt Vector new $numBytes]
        image create photo VideoFrame -width $tx -height $ty
        set numFrames [$videoObj GetNumFrames]    
        if { $startFrame < 0 } {
            set startFrame 0
        }
        if { $endFrame < 0 || $endFrame > $numFrames } {
            set endFrame [expr {$numFrames - 1}]
        }

        set fmtStr "PNG"
        set optStr ""

        set numExportedImgs 0
        for { set i $startFrame } { $i <= $endFrame } { incr i } {
            $videoObj Lock
            $videoObj GetNextImage [$vectorObj Get] 0
            $videoObj Unlock
            $vectorObj ToPhoto VideoFrame $tx $ty
            set outFileName [format $imgFilePattern $i]
            set retVal [catch { VideoFrame write $outFileName -format "$fmtStr $optStr" } errMsg]
            if { $retVal != 0 } {
                puts "Error saving image:\n$errMsg"
                return false
            }
            incr numExportedImgs
        }
        $vectorObj destroy
        $videoObj destroy
        return $numExportedImgs
    }

    proc VideoImport { imgFilePattern movieFile args } {
        # Generate a video by importing a series of image files.
        #
        # imgFilePattern - Pattern for image output files.
        #                  Must contain a printf like integer format specifier.
        # movieFile      - Movie file name.
        # args           - Options described below.
        #
        # -start <int>     - Start frame. Default: First video frame.
        # -end <int>       - End frame. Default: Last video frame.
        # -fps <int>       - Frames per second. Default: 25.
        # -bitrate <float> - Bitrate in MBit per second. Default: 4.0.
        # -flip <bool>     - Flip images. Default: false.
        # -verbose <bool>  - Print verbose messages. Default: false.
        #
        # See also: VideoExport

        set startFrame -1
        set endFrame   -1
        set flip        0
        set verbose     0

        foreach { key value } $args {
            switch -exact $key {
                "-start" {
                    set startFrame [expr {int($value)}]
                }
                "-end" {
                    set endFrame [expr {int($value)}]
                }
                "-flip" {
                    set flip [expr {bool($value)}]
                }
                "-verbose" {
                    set verbose [expr {bool($value)}]
                }
            }
        }

        if { $startFrame < 0 } {
            set startFrame 0
        }
        if { $endFrame < 0 } {
            for { set i $startFrame } { true } { incr i } {
                set inFileName [format $imgFilePattern $i]
                if { ! [file exists $inFileName] } {
                    set endFrame [expr {$i -1}]
                    break
                }
            }
        }

        if { $verbose } {
            puts "Input files: $imgFilePattern"
            puts "Output file: $movieFile"
            puts "Start      : $startFrame"
            puts "End        : $endFrame"
        }
        set numImportedImgs 0
        for { set i $startFrame } { $i <= $endFrame } { incr i } {
            set inFileName [format $imgFilePattern $i]
            set phImg [image create photo -file $inFileName]
            set w [image width  $phImg]
            set h [image height $phImg]
            if { ! [info exists videoObj] } {
                set videoObj [mawt Video new $movieFile "w" -width $w -height $h {*}$args]
                set vectorObj [mawt Vector new [expr {$w * $h * 3}]]
            }
            $vectorObj FromPhoto $phImg 3 1 0
            image delete $phImg
            $videoObj WriteNextImage [$vectorObj Get] $w $h $flip
            incr numImportedImgs
        }
        if { $numImportedImgs > 0 } {
            $videoObj Close
            $vectorObj destroy
            $videoObj destroy
        }
        return $numImportedImgs
    }
}
