/*
 * Copyright (C) 2022-2023 Savoir-faire Linux Inc.
 * Author: Nicolas Vengeon <nicolas.vengeon@savoirfairelinux.com>
 *
 * This program 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 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
 */

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Qt5Compat.GraphicalEffects
import QtWebEngine

import net.jami.Models 1.1
import net.jami.Adapters 1.1
import net.jami.Enums 1.1
import net.jami.Constants 1.1

import "../../commoncomponents"

Item {
    id: root

    property bool isUnpin: false
    property real maxWidth
    property real maxHeight
    property string attachedAccountId
    property string currentAccountId: CurrentAccount.id
    property string currentConvId: CurrentConversation.id
    property bool isSharing: (PositionManager.positionShareConvIdsCount !== 0)
    property bool isSharingToCurrentConversation

    function closeMapPosition() {
        root.destroy()
    }

    Connections {
        target: PositionManager

        function onPinMapSignal(key) {
            if (key === attachedAccountId) {
                isUnpin = false
                mapObject.state = "pin"
                windowUnpin.close()
            }
        }

        function onCloseMap(key) {
            if (key === attachedAccountId )
                closeMapPosition()
        }

        function onUnPinMapSignal(key) {
            if (key === attachedAccountId ) {
                isUnpin = true
                mapObject.state = "unpin"
                windowUnpin.show()
            }
        }
    }

    Window {
        id: windowUnpin

        width: parentPin.width
        height: parentPin.height
        visible: false
        title: PositionManager.getmapTitle(attachedAccountId)

        Item {
            id: parentUnPin

            width: mapObject.width
            height: mapObject.height
        }

        onClosing: {
            if (isUnpin) {
                PositionManager.setMapInactive(attachedAccountId)
            }
        }
    }

    Item {
        id: parentPin

        width: mapObject.width
        height: mapObject.height

        Rectangle {
            id: mapObject

            x: xPos
            y: yPos
            width: root.isUnpin
                   ? windowUnpin.width
                   : isFullScreen ? root.maxWidth : windowSize
            height: root.isUnpin
                    ? windowUnpin.height
                    : isFullScreen ? root.maxHeight - yPos : windowSize

            property bool isFullScreen: false
            property real windowSize: windowPreferedSize > JamiTheme.minimumMapWidth
                                      ? windowPreferedSize
                                      : JamiTheme.minimumMapWidth
            property real windowPreferedSize: root.maxWidth > root.maxHeight
                                              ? root.maxHeight / 3
                                              : root.maxWidth / 3
            property real xPos: 0
            property real yPos: root.isUnpin ? 0 : JamiTheme.chatViewHeaderPreferredHeight

            states: [ State {
                    name: "unpin"
                    ParentChange { target: mapObject; parent: parentUnPin; x:0; y:0 }
                },
                State {
                    name: "pin"
                    ParentChange { target: mapObject; parent: parentPin; x:xPos; y:JamiTheme.chatViewHeaderPreferredHeight }
                }
            ]
            property alias webView: webView

            WebEngineView {
                id: webView

                layer.enabled: !isFullScreen
                layer.effect: OpacityMask {
                    maskSource:
                        Rectangle {
                            width: webView.width
                            height: webView.height
                            radius: 10
                    }
                }

                width: parent.width
                height: parent.height

                property string mapHtml: ":/webengine/map/map.html"
                property string olCss: ":/webengine/map/ol.css"
                property string mapJs: "../../webengine/map/map.js"
                property string olJs: "../../webengine/map/ol.js"
                property bool isLoaded: false
                property var positionList: PositionManager.positionList;
                property var avatarPositionList: PositionManager.avatarPositionList;

                function loadScripts () {
                    var scriptMapJs = {
                        sourceUrl: Qt.resolvedUrl(mapJs),
                        injectionPoint: WebEngineScript.DocumentReady,
                        worldId: WebEngineScript.MainWorld
                    }

                    var scriptOlJs = {
                        sourceUrl: Qt.resolvedUrl(olJs),
                        injectionPoint: WebEngineScript.DocumentReady,
                        worldId: WebEngineScript.MainWorld
                    }

                    userScripts.collection = [ scriptOlJs, scriptMapJs ]
                }
                Connections {
                    target: PositionManager

                    function onPositionShareAdded(shareInfo) {
                        if(webView.isLoaded) {
                            if (shareInfo.account === attachedAccountId) {
                                var curLong = shareInfo.long
                                var curLat = shareInfo.lat
                                webView.runJavaScript("newPosition([" + curLong + "," + curLat  + "], '" +
                                                      shareInfo.author + "', '" + shareInfo.avatar + "', '" + shareInfo.authorName + "' )" );
                                webView.runJavaScript("zoomTolayersExtent()" );
                            }
                        }
                    }

                    function onPositionShareUpdated(shareInfo) {
                        if(webView.isLoaded) {
                            if (shareInfo.account === attachedAccountId) {
                                var curLong = shareInfo.long
                                var curLat = shareInfo.lat
                                webView.runJavaScript("updatePosition([" + curLong + "," + curLat  + "], '" + shareInfo.author + "' )" );
                            }
                        }
                    }

                    function onPositionShareRemoved(author, accountId) {
                        if(webView.isLoaded) {
                            if (accountId === attachedAccountId) {
                                webView.runJavaScript("removePosition( '" + author + "' )" );
                                webView.runJavaScript("zoomTolayersExtent()" );
                            }
                        }
                    }
                }

                Component.onCompleted: {
                    loadHtml(UtilsAdapter.qStringFromFile(mapHtml), mapHtml)
                    loadScripts()
                }

                onLoadingChanged: function (loadingInfo) {
                    if (loadingInfo.status === WebEngineView.LoadSucceededStatus) {
                        attachedAccountId = CurrentAccount.id
                        runJavaScript(UtilsAdapter.getStyleSheet("olcss",UtilsAdapter.qStringFromFile(olCss)))
                        webView.isLoaded = true
                        webView.runJavaScript("setMapView([" + 0 + ","+ 0  + "], " + 1 + " );" );
                        PositionManager.startPositioning()
                        //load locations that were received before this conversation was opened
                        PositionManager.loadPreviousLocations(attachedAccountId);
                        isSharingToCurrentConversation = PositionManager.isPositionSharedToConv(attachedAccountId, currentConvId)
                    }
                }
            }

            MapPositionSharingControl {}

            MapPositionOverlay {}

            StopSharingPositionPopup {
                id: stopSharingPositionPopup

            }
        }
    }
}

