# Module:         poWinPreview
# Copyright:      Paul Obermeier 2014-2025 / paul@poSoft.de
# First Version:  2014 / 10 / 26
#
# Distributed under BSD license.

namespace eval poWinPreview {
    variable ns [namespace current]

    namespace ensemble create

    namespace export Init
    namespace export Create Clear
    namespace export SetTitle Update
    namespace export GetMaxBytes SetMaxBytes

    # Init is called at package load time.
    proc Init {} {
        SetMaxBytes 2048
    }

    proc GetMaxBytes {} {
        variable sett

        return $sett(maxBytes)
    }

    proc SetMaxBytes { maxBytes } {
        variable sett

        set sett(maxBytes) $maxBytes
    }

    # Create a megawidget for previewing file or image data.
    # "masterFr" is the frame, where the components of the megawidgets are placed.
    # "title" is an optional string displayed as title of the preview widget.
    # Return an identifier for the new preview widget.
 
    proc Create { masterFr { title "Preview" } } {
        variable sett

        set previewId $masterFr.fr
        ttk::frame $previewId
        pack $previewId -expand 1 -fill both

        set textId [poExtProg ShowSimpleTextEdit $title $previewId false \
                    -width 1 -height 1 -wrap none -exportselection false \
                    -undo false -font [poWin GetFixedFont]]
        set sett($previewId,previewTxt) $textId
        $textId configure -state disabled

        return $previewId
    }

    proc SetTitle { w title } {
        variable sett

        poExtProg SetTitle $sett($w,previewTxt) $title
    }

    proc Update { w fileName { forceUpdate false } } {
        variable sett

        set fileName [file normalize [poMisc QuoteTilde $fileName]]
        # If the preview information of fileName is already displayed, return immediately.
        if { [info exists sett($w,previewFile)] && $sett($w,previewFile) eq $fileName && ! $forceUpdate } {
            return
        }

        # Delete the content already stored in the preview label.
        Clear $w

        $sett($w,previewTxt) configure -state normal
        $sett($w,previewTxt) configure -background [poImgAppearance GetCanvasResetColor]
        if { [poImgMisc IsImageFile $fileName] } {
            set sw [expr { [winfo width  $sett($w,previewTxt)] - 5 }]
            set sh [expr { [winfo height $sett($w,previewTxt)] - 5 }]
            if { $sw <= 0 } {
                set sw 1
            }
            if { $sh <= 0 } {
                set sh 1
            }
            set retVal [catch { poImgMisc LoadImgScaled $fileName $sw $sh } imgDict]
            if { $retVal == 0 } {
                set phImg [dict get $imgDict phImg]
                $sett($w,previewTxt) configure -background [poImgAppearance GetCanvasBackgroundColor]
                $sett($w,previewTxt) image create 1.0 -image $phImg -align center
                set sett($w,phImg) $phImg
            } else {
                poExtProg DumpFileIntoTextWidget $sett($w,previewTxt) $fileName -maxbytes [GetMaxBytes] -update true
            }
        } elseif { [poType IsCompressed $fileName] } {
            set zipList [poCompress List $fileName]
            if { [llength $zipList] == 0 } {
                # Unsupported compression format. 
                poExtProg DumpFileIntoTextWidget $sett($w,previewTxt) $fileName -maxbytes [GetMaxBytes] -update true
            } else {
                set zipFileNames ""
                foreach zipFile $zipList {
                    set name [dict get $zipFile "name"]
                    append zipFileNames $name "\n"
                }
                poExtProg LoadStringIntoTextWidget $sett($w,previewTxt) $zipFileNames -maxbytes [GetMaxBytes] -linenumbers true
            }
        } elseif { [poType IsBinary $fileName] } {
            poExtProg DumpFileIntoTextWidget $sett($w,previewTxt) $fileName -maxbytes [GetMaxBytes] -update true
        } else {
            set catchVal [catch { poExtProg LoadFileIntoTextWidget $sett($w,previewTxt) $fileName -maxbytes [GetMaxBytes] }]
            if { $catchVal } {
                $sett($w,previewTxt) insert end [lindex [split "$::errorInfo" "\n"] 0]
            }
        }
        $sett($w,previewTxt) configure -state disabled
        set sett($w,previewFile) $fileName
        update
        SetTitle $w [file tail $fileName]
    }

    proc Clear { w } {
        variable sett

        $sett($w,previewTxt) configure -state normal
        $sett($w,previewTxt) delete 1.0 end
        poExtProg ShowLineNumbers $sett($w,previewTxt) false
        $sett($w,previewTxt) configure -state disabled
        if { [info exists sett($w,phImg)] } {
            image delete $sett($w,phImg)
            unset sett($w,phImg)
        }
        catch { unset sett($w,previewFile) }
    }
}

poWinPreview Init
