/**************************************************************************
 **                                                                      **
 ** Copyright (C) 2011-2026 Lukas Spies                                  **
 ** Contact: https://photoqt.org                                         **
 **                                                                      **
 ** This file is part of PhotoQt.                                        **
 **                                                                      **
 ** PhotoQt is free software: you can redistribute it and/or modify      **
 ** it under the terms of the GNU General Public License as published by **
 ** the Free Software Foundation, either version 2 of the License, or    **
 ** (at your option) any later version.                                  **
 **                                                                      **
 ** PhotoQt is distributed in the hope that it will be useful,           **
 ** but WITHOUT ANY WARRANTY; without even the implied warranty of       **
 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        **
 ** GNU General Public License for more details.                         **
 **                                                                      **
 ** You should have received a copy of the GNU General Public License    **
 ** along with PhotoQt. If not, see <http://www.gnu.org/licenses/>.      **
 **                                                                      **
 **************************************************************************/
pragma ComponentBehavior: Bound

import QtQuick
import PhotoQt
import "../other/PQCommonFunctions.js" as PQF

PQTemplate {

    id: filter_top

    title: qsTranslate("filter", "Filter images in current directory")
    elementId: "Filter"

    Component.onCompleted: {

        //: Written on a clickable button - please keep short
        button1.text = qsTranslate("filter", "Filter")
        button1.enabled = Qt.binding(function() { return !filter_top.attemptToSetFilter })

        button2.visible = true
        button2.text = button2.genericStringCancel

        button3.visible = true
        //: Written on a clickable button - please keep short
        button3.text = qsTranslate("filter", "Remove filter")
        button3.fontWeight = PQCLook.fontWeightNormal
    }

    // when setting a new filter we wait until we get some feedback
    // this boolean stores that this is what we are doing
    property bool attemptToSetFilter: false

    // When nothing was found, we remove the filter again
    // But in that case we want to ignore the "new data!" signal
    // as this would be taken as "successfull filter application" and close the filter window
    property bool ignoreFilterRemoval: false

    Connections {
        target: filter_top.button1
        function onClicked() {
            if(!filenamecheck.checked && !rescheck.checked && !filesizecheck.checked && !ratingscheck.checked) {
                filter_top.removeFilter()
                filter_top.hide()
            } else {
                filter_top.attemptToSetFilter = true
                filter_top.setFilter()
            }
        }
    }
    Connections {
        target: filter_top.button2
        function onClicked() {
            filter_top.hide()
            filter_top.removeFilter()
        }
    }
    Connections {
        target: filter_top.button3
        function onClicked() {
            filter_top.hide()
            filter_top.removeFilter()
        }
    }

    Connections {
        target: PQCFileFolderModel
        // if the data changed and we were expecting it, react to it
        function onNewDataLoadedMainView() {

            if(filter_top.ignoreFilterRemoval) {
                filter_top.ignoreFilterRemoval = false
                return
            }

            if(filter_top.visible && filter_top.attemptToSetFilter) {
                if(PQCFileFolderModel.countMainView > 0) {
                    doingFilter.showSuccess()
                    doingFilter.hide()
                    filter_top.hide()
                } else {
                    doingFilter.showFailure()
                    filter_top.attemptToSetFilter = false
                                                      //: The matches here refer to matches to some filter criteria
                    PQCNotify.showNotificationMessage(qsTranslate("filter", "No matches found"),
                                                      qsTranslate("filter", "No files match the requested filter."))
                    filter_top.ignoreFilterRemoval = true
                    PQCFileFolderModel.removeAllUserFilter()
                }
            }
        }
    }

    property int countOpenSpin: 0
    signal closeAllSpinExcept(var senderid)

    content: [

        Column {

            x: (filter_top.width-width)/2
            y: (filter_top.availableHeight-height)/2

            spacing: 10
            enabled: !filter_top.attemptToSetFilter

            PQTextL {

                id: introtxt

                width: Math.max(col.width, Math.min(filter_top.width*0.8, 800))
                wrapMode: Text.WrapAtWordBoundaryOrAnywhere

                text: qsTranslate("filter", "To filter by file extension, start the term with a dot. Setting the width or height of the resolution to 0 ignores that dimension.")

            }

            Item {

                width: introtxt.width
                height: col.height

                Column {

                    id: col

                    x: (parent.width-width)/2

                    spacing: 10

                    Row {

                        id: filenameextrow

                        spacing: 10

                        PQCheckBox {

                            id: filenamecheck

                            y: (filenameedit.height-height)/2

                            text: qsTranslate("filter", "File name/extension:")

                            onCheckedChanged: {
                                if(checked)
                                    filenameedit.setFocus()
                            }
                        }

                        PQLineEdit {

                            id: filenameedit

                            enabled: filenamecheck.checked&&filter_top.opacity>0

                            width: 300
                            height: 40

                            placeholderText: qsTranslate("filter", "Enter terms")
                        }

                    }

                    Row {

                        id: imageresrow

                        spacing: 10

                        PQCheckBox {
                            id: rescheck
                            y: (reswidth.height-height)/2
                            text: qsTranslate("filter", "Image Resolution")
                            onCheckedChanged: {
                                if(rescheck.checked)
                                    reswidth.forceActiveFocus()
                            }
                        }

                        PQButton {
                            id: resgreaterless
                            y: (filesize.height-height)/2
                            width: height
                            enabled: rescheck.checked
                            property bool greater: true
                            text: greater ? ">" : "<"
                            fontWeight: PQCLook.fontWeightBold
                            fontPointSize: PQCLook.fontSizeL
                            tooltip: greater ?
                                         //: used as tooltip in the sense of 'image resolution GREATER THAN 123x123'
                                         qsTranslate("filter", "greater than") :
                                         //: used as tooltip in the sense of 'image resolution LESS THAN 123x123'
                                         qsTranslate("filter", "less than")
                            onClicked: {
                                reswidth.forceActiveFocus()
                                greater = !greater
                            }
                        }

                        PQAdvancedSpinBox {
                            id: reswidth
                            enabled: rescheck.checked
                            minval: 0
                            maxval: 99999999
                            onEditModeChanged: {
                                if(editMode) {
                                    filter_top.countOpenSpin += 1
                                    filter_top.closeAllSpinExcept("reswidth")
                                } else
                                    filter_top.countOpenSpin -= 1
                            }
                            Connections {
                                target: filter_top
                                function onCloseAllSpinExcept(senderid : string) {
                                    if(senderid !== "reswidth")
                                        reswidth.acceptValue()
                                }
                            }
                        }
                        PQText {
                            y: (resheight.height-height)/2
                            enabled: rescheck.checked
                            font.weight: PQCLook.fontWeightBold
                            text: "x"
                        }
                        PQAdvancedSpinBox {
                            id: resheight
                            enabled: rescheck.checked
                            minval: 0
                            maxval: 99999999
                            onEditModeChanged: {
                                if(editMode) {
                                    filter_top.countOpenSpin += 1
                                    filter_top.closeAllSpinExcept("resheight")
                                } else
                                    filter_top.countOpenSpin -= 1
                            }
                            Connections {
                                target: filter_top
                                function onCloseAllSpinExcept(senderid : string) {
                                    if(senderid !== "resheight")
                                        resheight.acceptValue()
                                }
                            }
                        }

                    }

                    Row {

                        id: filesizerow

                        spacing: 10

                        PQCheckBox {
                            id: filesizecheck
                            y: (filesize.height-height)/2
                            text: qsTranslate("filter", "File size")
                            onCheckedChanged: {
                                if(filesizecheck.checked)
                                    filesize.forceActiveFocus()
                            }
                        }

                        PQButton {
                            id: filesizegreaterless
                            y: (filesize.height-height)/2
                            enabled: filesizecheck.checked
                            property bool greater: true
                            text: greater ? ">" : "<"
                            fontWeight: PQCLook.fontWeightBold
                            fontPointSize: PQCLook.fontSizeL
                            extraextraSmall: true
                            smallerVersion: true
                            tooltip: greater ?
                                         //: used as tooltip in the sense of 'file size GREATER THAN 123 KB/MB'
                                         qsTranslate("filter", "greater than") :
                                         //: used as tooltip in the sense of 'file size LESS THAN 123 KB/MB'
                                         qsTranslate("filter", "less than")
                            onClicked: {
                                greater = !greater
                                filesize.forceActiveFocus()
                            }
                        }

                        PQAdvancedSpinBox {
                            id: filesize
                            enabled: filesizecheck.checked
                            minval: 0
                            maxval: 99999999
                            onEditModeChanged: {
                                if(editMode) {
                                    filter_top.countOpenSpin += 1
                                    filter_top.closeAllSpinExcept("filesize")
                                } else
                                    filter_top.countOpenSpin -= 1
                            }
                            Connections {
                                target: filter_top
                                function onCloseAllSpinExcept(senderid : string) {
                                    if(senderid !== "filesize")
                                        filesize.acceptValue()
                                }
                            }
                        }

                        PQRadioButton {
                            id: filesizekb
                            y: (filesize.height-height)/2
                            text: "KB"
                            checked: true
                            enabled: filesizecheck.checked
                        }
                        PQRadioButton {
                            id: filesizemb
                            y: (filesize.height-height)/2
                            text: "MB"
                            enabled: filesizecheck.checked
                        }

                    }

                    Row {

                        id: ratingsrow

                        spacing: 10

                        PQCheckBox {
                            id: ratingscheck
                            y: (ratingsgreaterless.height-height)/2
                            text: qsTranslate("filter", "Rating")
                        }

                        PQButton {
                            id: ratingsgreaterless
                            enabled: ratingscheck.checked && !noratingscheck.checked
                            property bool greater: true
                            text: greater ? "≥" : "≤"
                            fontWeight: PQCLook.fontWeightBold
                            fontPointSize: PQCLook.fontSizeL
                            extraextraSmall: true
                            smallerVersion: true
                            tooltip: greater ?
                                         //: used as tooltip in the sense of 'rating AT LEAST x stars'
                                         qsTranslate("filter", "at least") :
                                         //: used as tooltip in the sense of 'rating AT MOST x stars'
                                         qsTranslate("filter", "at most")
                            onClicked: {
                                greater = !greater
                            }
                        }

                        Row {

                            id: starrow
                            spacing: 5
                            y: (ratingsgreaterless.height-height)/2
                            property int rating: 1
                            property int cacheRating: 1
                            enabled: ratingscheck.checked && !noratingscheck.checked

                            Repeater {
                                model: 5
                                Image {
                                    id: stardeleg
                                    required property int modelData
                                    width: 20
                                    height: 20
                                    sourceSize: Qt.size(width, height)
                                    opacity: enabled ? 1 : 0.5
                                    source: "image://svg/:/" + PQCLook.iconShade + (modelData<starrow.rating ? "/star.svg" : "/star_empty.svg")
                                    PQMouseArea {
                                        anchors.fill: parent
                                        anchors.leftMargin: -starrow.spacing/2
                                        anchors.rightMargin: -starrow.spacing/2
                                        hoverEnabled: true
                                        enabled: starrow.enabled
                                        onEntered: {
                                            resetRating.stop()
                                            starrow.rating = stardeleg.modelData+1
                                        }
                                        onExited: {
                                            resetRating.startedBy = stardeleg.modelData+1
                                            resetRating.restart()
                                        }
                                        onClicked: {
                                            starrow.cacheRating = starrow.rating
                                        }
                                    }
                                }
                            }

                            Timer {
                                id: resetRating
                                interval: 500
                                property int startedBy
                                onTriggered: {
                                    if(starrow.rating == startedBy)
                                        starrow.rating = starrow.cacheRating
                                }
                            }

                        }

                        PQCheckBox {
                            id: noratingscheck
                            y: (parent.height-height)/2
                            enabled: ratingscheck.checked
                            text: qsTranslate("filter", "not rated")
                        }

                    }

                    Item {

                        width: parent.width

                        height: rescheck.checked ? infotxt.height : 0
                        Behavior on height { enabled: !PQCSettings.generalDisableAllAnimations; NumberAnimation { duration: 250 } }

                        clip: true

                        PQText {
                            id: infotxt
                            width: parent.width
                            horizontalAlignment: Text.AlignHCenter
                            wrapMode: Text.WordWrap

                            text: qsTranslate("filter", "Please note that filtering by image resolution can take a little while, depending on the number of images in the folder.")

                        }

                    }

                }

            }

        }

    ]

    PQWorking {
        id: doingFilter
    }

    Connections {

        target: PQCNotify

        function onLoaderPassOn(what : string, param : list<var>) {

            if(filter_top.visible) {

                if(what === "removeFilter") {

                    filter_top.button3.clicked()

                } else if(what === "keyEvent") {

                    if(param[0] === Qt.Key_Escape) {

                        if(filter_top.attemptToSetFilter) {

                            filter_top.ignoreFilterRemoval = true
                            PQCFileFolderModel.removeAllUserFilter()

                        } else {

                            if(reswidth.editMode || resheight.editMode || filesize.editMode)
                                filter_top.closePopupMenuSpin()
                            else
                                filter_top.button2.clicked()

                        }

                    } else if(param[0] === Qt.Key_Enter || param[0] === Qt.Key_Return)
                        if(!filter_top.attemptToSetFilter)
                            filter_top.button1.clicked()
                    else if(param[0] === Qt.Key_Tab) {
                        if(filter_top.attemptToSetFilter) return
                        if(reswidth.activeFocus)
                            resheight.forceActiveFocus()
                        else if(resheight.activeFocus)
                            reswidth.forceActiveFocus()
                    }

                }
            }
        }
    }

    function closePopupMenuSpin() {
        reswidth.acceptValue()
        resheight.acceptValue()
        filesize.acceptValue()
    }

    function showing() {
        if((PQCFileFolderModel.currentIndex === -1 || PQCFileFolderModel.countMainView === 0) && !PQCFileFolderModel.filterCurrentlyActive) {
            return false
        }
        doingFilter.hide()
        ignoreFilterRemoval = false
        attemptToSetFilter = false
        opacity = 1
        PQCConstants.modalFilterOpen = true

        // we explicitely load the data below to pre-load it even when switching between popout and not

        // load filename filter data
        var txt1 = PQCFileFolderModel.nameFilters.join(" ")
        var txt2 = PQCFileFolderModel.filenameFilters.join(" .")
        if(txt1 !== "") txt1 = "."+txt1

        if(txt1 !== "" || txt2 !== "") {
            filenamecheck.checked = true
            filenameedit.text = txt1 + (txt1==="" ? "" : " ") + txt2
        } else {
            filenamecheck.checked = false
            filenameedit.text = ""
        }

        // load image resolution filter data
        var w = PQCFileFolderModel.imageResolutionFilter.width
        var h = PQCFileFolderModel.imageResolutionFilter.height
        if(w > 0 || h > 0) {
            resgreaterless.greater = true
            rescheck.checked = true
            reswidth.loadAndSetDefault(w)
            resheight.loadAndSetDefault(h)
        } else if(w < 0 || h < 0) {
            resgreaterless.greater = false
            rescheck.checked = true
            reswidth.loadAndSetDefault(-1*w)
            resheight.loadAndSetDefault(-1*h)
        } else {
            resgreaterless.greater = true
            rescheck.checked = false
            reswidth.loadAndSetDefault(0)
            resheight.loadAndSetDefault(0)
        }

        // load file size filter data
        var s = PQCFileFolderModel.fileSizeFilter
        if(s !== 0) {
            filesizecheck.checked = true
            filesizegreaterless.greater = (s > 0)

            if(s < 0) s *= -1

            var mb = Math.round(s/(1024*1024))
            var kb = Math.round(s/1024)
            if(mb*1024*1024 === s) {
                filesizemb.checked = true
                filesize.loadAndSetDefault(mb)
            } else {
                filesizekb.checked = true
                filesize.loadAndSetDefault(kb)
            }

        }

        return true

    }

    function hiding() {
        closePopupMenuSpin()
        PQCConstants.modalFilterOpen = false
        return true
    }

    function setFilter() {

        var fileNameFilter = []
        var fileEndingFilter = []

        // filter out search terms and search suffixes
        if(filenamecheck.checked) {
            var spl = filenameedit.text.split(" ")
            for(var iSpl = 0; iSpl < spl.length; ++iSpl) {
                if(spl[iSpl][0] === ".")
                    fileEndingFilter.push(spl[iSpl].slice(1))
                else {
                    fileNameFilter.push(spl[iSpl])
                }
            }
        }

        // if the filter hasn't changed, nothing will happen
        // in that case we need to remove the filter window as we're done
        var willReload = false

        if(!PQF.areTwoListsEqual(PQCFileFolderModel.nameFilters, fileEndingFilter)) willReload = true
        PQCFileFolderModel.nameFilters = fileEndingFilter

        if(!PQF.areTwoListsEqual(PQCFileFolderModel.filenameFilters, fileNameFilter)) willReload = true
        PQCFileFolderModel.filenameFilters = fileNameFilter

        if(ratingscheck.checked) {
            var toSetStars = (ratingsgreaterless.greater ? 1 : -1) * starrow.cacheRating
            if(noratingscheck.checked) toSetStars = 100
            if(PQCFileFolderModel.ratingsFilter !== toSetStars) willReload = true
            PQCFileFolderModel.ratingsFilter = toSetStars
        } else {
            if(PQCFileFolderModel.ratingsFilter !== 0) willReload = true
            PQCFileFolderModel.ratingsFilter = 0
        }

        if(rescheck.checked) {
            var toSet = Qt.size((resgreaterless.greater ? 1 : -1)*reswidth.value, (resgreaterless.greater ? 1 : -1)*resheight.value)
            if(PQCFileFolderModel.imageResolutionFilter !== toSet) willReload = true
            PQCFileFolderModel.imageResolutionFilter = toSet
        } else {
            if(PQCFileFolderModel.imageResolutionFilter !== Qt.size(0,0)) willReload = true
            PQCFileFolderModel.imageResolutionFilter = Qt.size(0,0)
        }

        if(filesizecheck.checked) {
            var toSetFS = (filesizegreaterless.greater ? 1 : -1)*filesize.value*(filesizekb.checked ? 1024 : (1024*1024))
            if(PQCFileFolderModel.fileSizeFilter !== toSetFS) willReload = true
            PQCFileFolderModel.fileSizeFilter = toSetFS
        } else {
            if(PQCFileFolderModel.fileSizeFilter !== 0) willReload = true
            PQCFileFolderModel.fileSizeFilter = 0
        }

        if(willReload)
            doingFilter.showBusy()
        else if(PQCConstants.currentFilterString !== "")
            filter_top.hide()

    }

    function removeFilter() {

        filenamecheck.checked = false
        rescheck.checked = false
        filesizecheck.checked = false
        ratingscheck.checked = false

        PQCFileFolderModel.removeAllUserFilter()

    }

}
