# -*- coding: utf-8 -*-
"""
/***************************************************************************
 GroundTrutherDockWidget
                                 A QGIS plugin
 A toolset for Seafloor Caracterization
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                             -------------------
        begin                : 2023-05-09
        git sha              : $Format:%H$
        copyright            : (C) 2023 by epinux
        email                : epiesasha@me.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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
"""

import os

from qgis.PyQt import QtGui, QtWidgets, uic
from qgis.PyQt.QtCore import pyqtSignal, pyqtSlot
from qgis.utils import iface
from qgis.core import QgsPointXY, QgsRectangle, QgsGeometry, QgsWkbTypes, QgsProject
from qgis.gui import QgsVertexMarker, QgsMapToolEmitPoint, QgsRubberBand

from sys import platform

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

import requests
import pandas as pd
from pathlib import Path
import pyqtgraph as pg
from skimage.io import imread
import numpy as np
from scipy import spatial

from groundtruther.configure import get_settings, ConfigDialog, error_message
from groundtruther.ioutils import parse_annotation

from groundtruther.pygui.Ui_groundtruther_dockwidget_base import Ui_GroundTrutherDockWidgetBase  
from groundtruther.pygui.hbc_browser_gui import HBCBrowserGui
from groundtruther.pygui.image_metadata_gui import ImageMetadata
from groundtruther.pygui.app_settings_gui import AppSettings
from groundtruther.pygui.kmlsave_gui import SaveKml
from groundtruther.pygui.querybuilder_gui import QueryBuilder
from groundtruther.pygui.grass_settings_gui import GrassSettings

#from groundtruther.pygui.grass_mdi_gui import GrassMdi

from groundtruther.pygui.grass_mdi_gui import GrassTools

from groundtruther.grassconfig import GrassConfigDialog
from groundtruther.run_geomorphon_mdi import GeoMorphonWidget
from groundtruther.run_paramscale_mdi import ParamScaleWidget
from groundtruther.run_grm_lsi_mdi import GrmLsiWidget
import groundtruther.resources_rc

 
class GroundTrutherDockWidget(QtWidgets.QDockWidget, Ui_GroundTrutherDockWidgetBase):

    closingPlugin = pyqtSignal()
    send_image_path = pyqtSignal(str)
    send_imagemetadata_string = pyqtSignal(str)

    def __init__(self, parent=None):
        """Constructor."""
        super(GroundTrutherDockWidget, self).__init__(parent)
        # Set up the user interface from Designer.
        # After setupUI you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://doc.qt.io/qt-5/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.canvas = iface.mapCanvas()
        self.project = QgsProject.instance()
        self.w = HBCBrowserGui()
        self.setupUi(self)
        self.setWidget(self.w)
        #self.config = os.environ.get('HBC_CONFIG')
        self.config = os.path.join(os.path.dirname(__file__), 'config/config.yaml')
        self.dialog = ConfigDialog()
        self.grass_dialog = GrassConfigDialog()
        self.settings = get_settings(self.config)
        if not self.settings:
            self.show_dialog()
            self.settings = get_settings(self.config)
        self.imagelist = []
        self.imageindex = 1
        self.rangevalue = self.w.range.value()
        self.dirname = self.settings["HabCam"]["imagepath"]
        self.metadatafile = self.settings["HabCam"]["imagemetadata"]
        self.imageannotationfile = self.settings["HabCam"]["imageannotation"]
        self.grass_api_endpoint = self.settings["Processing"]["grass_api_endpoint"]
        self.annotation_confidence_treshold = (
            self.w.annotation_confidence_spinBox.value()
        )
        self.projection = "+proj=utm +no_defs +zone=19 +a=6378137 +rf=298.257223563 +towgs84=0.000,0.000,0.000 +to_meter=1"
        self.graph_items = []
        self.m1 = None
        self.image_point_built = False
        self.parsed_query = None
        self.init_ui()
        # hide for QGIS PlugIn
        self.w.gisTools.hide()
        self.w.gisTools_logger.hide()
        self.w.actionGisTools.setVisible(True)
        self.w.actionQuit.setVisible(False)
        # print(self.parent.plugin_dir) # = os.path.dirname(__file__))
        self.grassenabled = False
        self.r = None
        print(self.actions)
        print(iface)



    def init_ui(self):
        """docstring"""
        self.region_response = None
        self.imv = pg.ImageView(self.w)
        self.w.setCentralWidget(self.imv)
        self.appsettings = AppSettings()
        self.grass_config_widget = GrassSettings()
        self.w.toolWidget.hide()
        # TODO: remove gistools
        self.w.gisTools.hide()
        self.w.fwd.clicked.connect(self.increaseimageindex)
        self.w.rwd.clicked.connect(self.decreaseimageindex)
        # Image Index
        self.w.ImageIndexSlider.valueChanged.connect(
            self.setValueImageIndexspinBox)
        self.w.ImageIndexspinBox.valueChanged.connect(
            self.setValueImageIndexSlider)
        self.w.ImageStepspinBox.valueChanged.connect(
            self.setImageIndexStepValue)
        self.w.ImageIndexSlider.valueChanged.connect(self.add_image)

        self.image = QLabel()

        self.w.latitude = QLineEdit()
        self.w.longitude = QLineEdit()
        self.w.longitude.setFocusPolicy(Qt.NoFocus)
        self.w.latitude.setFocusPolicy(Qt.NoFocus)
        self.w.latitude.setFixedWidth(90)
        self.w.longitude.setFixedWidth(90)
        self.w.longitude.setText("0")
        self.w.latitude.setText("0")
        self.w.statusbar.addPermanentWidget(self.w.latitude, stretch=0)
        self.w.statusbar.addPermanentWidget(self.w.longitude, stretch=0)
        

        # self.myProj = pyproj.Proj("+proj=utm +no_defs +zone=19 +a=6378137 +rf=298.257223563 +towgs84=0.000,0.000,0.000 +to_meter=1")
        self.myProj = self.projection
        self.w.range.valueChanged.connect(self.setValuerangeSpinBox)
        # self.getImageMetadata_hard()
        self.w.actionTools.triggered.connect(self.showTools)
        self.w.actionGisTools.triggered.connect(self.showGisTools)
        #self.w.actionImageBrowser.triggered.connect(self.showImageBrowser)
        self.w.actionImageBrowser.triggered.connect(self.showImageViewer)
        # self.w.actionWizard.triggered.connect(self.showPreferences)
        self.w.actionWizard.triggered.connect(self.show_dialog)
        # self.w.refresh.clicked.connect(self.on_send)
        if platform == "darwin":
            self.w.fwd.hide()
            self.w.rwd.hide()
        # self.w.refresh.hide()
        #
        #
        self.imagemetadata_gui = ImageMetadata()
        self.w.tools.insertTab(0, self.imagemetadata_gui, "Image Metadata")
        self.savekml = SaveKml()
        # emit image path to savekml widget
        self.send_image_path.connect(self.savekml.from_main_imagepath_signal)
        # self.send_image_path.connect(self.savekml.from_main_imagepath_signal)
        self.send_imagemetadata_string.connect(
            self.savekml.from_main_imagemetadata_signal)
        #
        #
        self.w.tools.insertTab(1, self.savekml, "Report Builder")
        self.querybuilder = QueryBuilder()
        self.w.tools.insertTab(2, self.querybuilder, "Query Builder")
        #

        # self.qgis_widget_gui = myMainClass(self)

        # self.w.gisToolSplitter.insertWidget(0, self.qgis_widget_gui)

        # self.w.actionQuit.triggered.connect(self.quitAll)
        self.set_settings()
        #
        self.querybuilder.send_2dgraph_path.connect(
            self.savekml.from_querybuilder_2dplot_signal
        )
        self.querybuilder.send_3dgraph_path.connect(
            self.savekml.from_querybuilder_3dplot_signal
        )
        #
        self.querybuilder.send_selected_points_path.connect(
            self.savekml.from_querybuilder_selected_points_signal
        )
        #
        # self.w.refresh.clicked.connect(self.close_pyqtgraph)
        self.w.annotation_confidence_spinBox.valueChanged.connect(
            self.setValue_annotation_confidence
        )
        self.w.actionAnnotation.triggered.connect(self.showAnnotationThreshold)
        self.w.annotation_confidence_spinBox.hide()
        self.w.annotation_confidence_spinBox_label.hide()

        self.init_grass_ui()
        self.init_grass_toolbar()
        # self.region_response = None
        self.w.show()


    def init_grass_toolbar(self):
        self.w.actiongrass_settings.triggered.connect(self.show_grass_dialog)

    def show_grass_dialog(self):
        """docstring"""
        self.grass_dialog.exec_()
        print(self.grass_dialog.grassenabled)        

    def init_grass_ui(self):
        # create the widget for grass which goes into the splitter
        self.grassWidgetContents = GrassTools(self) #QtWidgets.QWidget()
        self.grassWidgetContents.setObjectName("grassDockWidgetContents")
        # assign a vertical lyout to the grass widget
        #self.grass_tool_layout = QtWidgets.QVBoxLayout(
        #    self.grassWidgetContents)
        #
        #self.grass_tool_layout.setObjectName("grass_tool_layout")
        # create text editor to add query results
        
        #self.gis_tool_report = QtWidgets.QTextEdit()
        #self.gis_tool_report.setObjectName("gis_tool_report")
        
        
        # self.grass_mdi = GrassMdi()
        # layout1 = QHBoxLayout()
        # #layout2 = QVBoxLayout()
        # #layout2.addWidget(self.gis_tool_report)
        # layout1.addWidget(self.grass_mdi)
        # #layout1.addLayout( layout2 )
        # self.grass_widget = QWidget()
        # self.grass_widget.setLayout(layout1)
        
        # #self.grassWidgetContents.setCentralWidget(self.gis_tool_report)
        # self.grassWidgetContents.setCentralWidget(self.grass_widget)

        # self.moduleToolBar = self.grassWidgetContents.addToolBar("GrassModules")
        # self.moduleToolBar.toggleViewAction().setEnabled(False)
        
        # self.mdi_view = QtWidgets.QComboBox()
        # self.moduleToolBar.addWidget(self.mdi_view)
        # self.mdi_view.insertItems(1,["Tiled","Cascade","Minimize", "Close"])
        # self.mdi_view.currentIndexChanged.connect(self.set_mdi_view)



        # self.r_gemorphon = GeoMorphonWidget(self)    
        # self.r_gemorphon_window = QMdiSubWindow()
        # self.r_gemorphon_window.setWindowTitle("r.geomorphon")
        # self.r_gemorphon_window.setWidget(self.r_gemorphon)
        # self.grass_mdi.grassTools.addSubWindow(self.r_gemorphon_window)
        # self.r_gemorphon_window.setWindowFlags(Qt.WindowMinimizeButtonHint|Qt.WindowMaximizeButtonHint)
        # self.r_gemorphon_window.hide()
        # self.r_gemorphon.exit.clicked.connect(self.view_r_gemorphon)
        # gemorphon_icon_path = ':/icons/qtui/icons/element-cell.gif'
        # gemorphon_icon = QIcon(gemorphon_icon_path)
        # gemorphon_action = QAction(gemorphon_icon, self.tr(u'r.gemorphon'), self.grassWidgetContents)
        # #
        # gemorphon_action.triggered.connect(self.view_r_gemorphon)
        # gemorphon_action.setEnabled(True)
        # gemorphon_action.setCheckable(True)
        # #
        # self.moduleToolBar.addAction(gemorphon_action)
        
        
        
        # self.r_paramscale = ParamScaleWidget(self)    
        # self.r_paramscale_window = QMdiSubWindow()
        # self.r_paramscale_window.setWindowTitle("r.param.scale")
        # self.r_paramscale_window.setWidget(self.r_paramscale)
        # self.grass_mdi.grassTools.addSubWindow(self.r_paramscale_window)
        # self.r_paramscale_window.setWindowFlags(Qt.WindowMinimizeButtonHint|Qt.WindowMaximizeButtonHint)
        # self.r_paramscale_window.hide()
        # self.r_paramscale.exit.clicked.connect(self.view_r_paramscale)
        # paramscale_icon_path = ':/icons/qtui/icons/element-cell.gif'
        # paramscale_icon = QIcon(paramscale_icon_path)
        # paramscale_action = QAction(paramscale_icon, self.tr(u'r.param.scale'), self.grassWidgetContents)
        # #
        # paramscale_action.triggered.connect(self.view_r_paramscale)
        # paramscale_action.setEnabled(True)
        # paramscale_action.setCheckable(True)
        
        
        
        # self.r_grm_lsi = GrmLsiWidget(self)    
        # self.r_grm_lsi_window = QMdiSubWindow()
        # self.r_grm_lsi_window.setWindowTitle("r.grm.lsi")
        # self.r_grm_lsi_window.setWidget(self.r_grm_lsi)
        # self.grass_mdi.grassTools.addSubWindow(self.r_grm_lsi_window)
        # #self.r_grm_lsi_window.setWindowTitle("r.grm.lsi")
        # self.r_grm_lsi_window.setWindowFlags(Qt.WindowMinimizeButtonHint|Qt.WindowMaximizeButtonHint)
        # self.r_grm_lsi_window.hide()
        # self.r_grm_lsi.exit.clicked.connect(self.view_r_grm_lsi)
        # grm_lsi_icon_path = ':/icons/qtui/icons/element-cell.gif'
        # grm_lsi_icon = QIcon(grm_lsi_icon_path)
        # grm_lsi_action = QAction(grm_lsi_icon, self.tr(u'r.grm.lsi'), self.grassWidgetContents)
        # #
        # grm_lsi_action.triggered.connect(self.view_r_grm_lsi)
        # grm_lsi_action.setEnabled(True)
        # grm_lsi_action.setCheckable(True)

        # #
        # self.moduleToolBar.addAction(gemorphon_action)
        # self.moduleToolBar.addAction(paramscale_action)
        # self.moduleToolBar.addAction(grm_lsi_action)
        
        # # Using a QToolBar object
        # # editToolBar = QToolBar("Edit", self.grassWidgetContents)
        # # self.grassWidgetContents.addToolBar(editToolBar)
        # # Using a QToolBar object and a toolbar area
        # # helpToolBar = QToolBar("Help", self.grassWidgetContents)
        # # self.grassWidgetContents.addToolBar(Qt.LeftToolBarArea, helpToolBar)
        
        # #
        # # self.geomorphon_dialog = GeoMorphonDialog(self)
        # self.grass_mdi.zoom_in.clicked.connect(self.onZoomInClicked)
        # self.grass_mdi.zoom_out.clicked.connect(self.onZoomOutClicked)
        # self.grass_mdi.copy.clicked.connect(self.grass_mdi.gis_tool_report.copy)
        # self.grass_mdi.selectAll.clicked.connect(self.grass_mdi.gis_tool_report.selectAll)
        
        # self.grass_mdi.clear.clicked.connect(self.onClearClicked)
        
        self.w.gisToolSplitter.insertWidget(0, self.grassWidgetContents)

    def onZoomInClicked(self):
        self.grass_mdi.gis_tool_report.zoomIn(1)

    def onZoomOutClicked(self):
        self.grass_mdi.gis_tool_report.zoomOut(1)
    
    def onClearClicked(self):
        self.grass_mdi.gis_tool_report.clear()

    def view_r_gemorphon(self, module):
        if self.r_gemorphon_window.isVisible():
            self.r_gemorphon_window.hide()
        else:
            self.r_gemorphon.get_rvr_list()
            self.r_gemorphon_window.show()

    def view_r_paramscale(self, module):
        if self.r_paramscale_window.isVisible():
            self.r_paramscale_window.hide()
        else:
            self.r_paramscale.get_rvr_list()
            self.r_paramscale_window.show()
             
    def view_r_grm_lsi(self, module):
        if self.r_grm_lsi_window.isVisible():
            self.r_grm_lsi_window.hide()
        else:
            self.r_grm_lsi.get_rvr_list()
            self.r_grm_lsi_window.show()
            
    
        
    def set_mdi_view(self, index):
        if self.mdi_view.itemText(index) == 'Cascade':
            self.grass_mdi.grassTools.cascadeSubWindows()
        if self.mdi_view.itemText(index) == 'Tiled':
            self.grass_mdi.grassTools.tileSubWindows()
        if self.mdi_view.itemText(index) == 'Minimize':
            for i in self.grass_mdi.grassTools.subWindowList():
                print(i)
                if i.isVisible():
                    #i.hide()
                    i.showMinimized()
        if self.mdi_view.itemText(index) == 'Close':
            for i in self.grass_mdi.grassTools.subWindowList():
                print(i)
                if i.isVisible():
                    i.hide()
                    #i.close()
            
    # def show_module(self):
    #     print('show module')

    # def show_geomorphon(self):
    #     """docstring"""
    #     self.geomorphon_dialog.get_rvr_list()
    #     self.geomorphon_dialog.exec_()

    def set_settings(self):
        """docstring"""
        # self.dialog.exec_()
        self.settings = get_settings(self.config)
        self.host = self.settings["Broadcast"]["ip"]
        self.port = self.settings["Broadcast"]["port"]
        self.dirname = self.settings["HabCam"]["imagepath"]
        self.metadatafile = self.settings["HabCam"]["imagemetadata"]
        self.imageannotationfile = self.settings["HabCam"]["imageannotation"]
        self.grass_api_endpoint = self.settings["Processing"]["grass_api_endpoint"]
        # self.annotation_confidence_treshold = 0.5  #

        #
        # self.imagelist = os.listdir(self.dirname)
        # self.imagelist.sort()
        # self.w.ImageIndexspinBox.setMaximum(len(self.imagelist) - 1)
        # self.w.ImageIndexSlider.setMaximum(len(self.imagelist) - 1)
        #
        try:
            self.imagemetadata_gui
        except AttributeError:
            self.imagemetadata_gui = ImageMetadata()
        if Path(self.metadatafile).is_file():
            try:
                self.imageMetadata = pd.read_parquet(self.metadatafile)
                # self.imageMetadata.index = pd.to_datetime(
                #    self.imageMetadata["index"])
                # self.imageMetadata = self.imageMetadata.loc[
                #    self.imageMetadata["Imagename"].isin(
                #        (i.replace(".jpg", "") for i in self.imagelist)
                #    )
                # ]

                self.w.ImageIndexspinBox.setMaximum(
                    len(self.imageMetadata) - 1)
                self.w.ImageIndexSlider.setMaximum(len(self.imageMetadata) - 1)

                if os.getenv("HBC_DEBUG") and os.getenv("HBC_DEBUG") == 'VERBOSE':
                    print("image metadata columns")
                    print(self.imageMetadata.columns)
                self.imagemetadata_gui.metadata_scroll_area.setEnabled(True)
                if Path(self.imageannotationfile).is_file():
                    # check the annotation file
                    # merge the info in the metadata and
                    # enable annotation tool
                    print("Annotation file loaded")
                    self.w.actionAnnotation.setEnabled(True)
                    annotations_by_image = parse_annotation(
                        self.imageannotationfile)
                    self.imageMetadata["Annotation"] = self.imageMetadata.Imagename.map(
                        annotations_by_image
                    )
                else:
                    self.w.actionAnnotation.setEnabled(False)
                self.kdt = spatial.KDTree(
                    self.imageMetadata[["habcam_lon", "habcam_lat"]].values)
            except OSError:
                print("OS error reading metadata")
            except pyarrow.lib.ArrowInvalid as message:
                error_message(
                    f"error reading {self.metadatafile}: \n" + str(message))
                self.imageMetadata = None
                # self.show_dialog()
        else:
            self.show_dialog()
            print(f"ther new path is {self.dialog.image_path.text()}")

    # def get_vquey_position(self, lat: float, lon: float):
    #     print("vquery at", lat, lon)
    #     index = self.getImageIndex(lon, lat)
    #     self.w.ImageIndexSlider.setValue(index)
    #     self.w.gisTools_logger.setText(
    #         f'Zoom to nearest Image: index # {index}')
    
    def set_grass_cpr(self, minlat, maxlat, minlon, maxlon):
        print('set_grass_cpr: ', minlat, maxlat, minlon, maxlon)
        print(self.set_grass_region(float(minlat), float(maxlat), float(minlon), float(maxlon)).json())
        self.region_response = self.set_grass_region(float(minlat), float(maxlat), float(minlon), float(maxlon)).json()['data']['region']
        print(self.region_response)
        if self.r:
            self.canvas.scene().removeItem(self.r)
        self.r = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry)  # polygon
        points = [[QgsPointXY(maxlon, maxlat), QgsPointXY(minlon, maxlat), QgsPointXY(minlon, minlat), QgsPointXY(maxlon, minlat)]]
        self.r.setToGeometry(QgsGeometry.fromPolygonXY(points), None)
        self.r.setWidth(3)
        
    
    def get_query_message(self, stringa):
        print('stringa', stringa)
        self.grass_mdi.gis_tool_report.setHtml(stringa)
        
    def get_query_position(self, lat, lon):
        print('position', lat, lon)
        self.set_image_index(lat, lon)
        
    def set_image_index(self, lat: float, lon: float):
        print("vquery at", lat, lon)
        index = self.getImageIndex(lon, lat)
        self.w.ImageIndexSlider.setValue(index)
        # self.w.gisTools_logger.setText(
        #     f'Zoom to nearest Image: index # {index}')

    def get_grass_query_data(self, lat:float, lon: float):
        grass_settings = self.grass_dialog.set_grass_location()
        if grass_settings['status'] == 'SUCCESS':
            grass_gisenv = grass_settings['data']['gisenv']
        if int(grass_settings['data']['region']['projection'].split(' ')[0]) == 1:
            # corner = [[minlon, maxlat], [maxlon, minlat]]
            headers = {
                'accept': 'application/json',
                'Content-Type': 'application/json',
            }

            json_data = {
                'location': {
                    'location_name': grass_gisenv['LOCATION_NAME'],
                    'mapset_name': grass_gisenv['MAPSET'],
                    'gisdb': grass_gisenv['GISDBASE'],
                },
                'coors': [[lon, lat]],
            }

            response = requests.post(
                f'{self.grass_api_endpoint}/api/m_proj', headers=headers, json=json_data, timeout=60)
            point = response.json()['data']
        else:
            point = [[lon, lat]]
        print(point)
        self.grass_mdi.gis_tool_report.setHtml(str(point))


    def set_grass_region(self, minlat: float, maxlat: float, minlon: float, maxlon: float):
        grass_settings = self.grass_dialog.set_grass_location()
        if grass_settings['status'] == 'SUCCESS':
            grass_gisenv = grass_settings['data']['gisenv']
        print(grass_settings['data']['region']['projection'])
        if int(grass_settings['data']['region']['projection'].split(' ')[0]) == 1:
            # corner = [[minlon, maxlat], [maxlon, minlat]]
            headers = {
                'accept': 'application/json',
                'Content-Type': 'application/json',
            }

            json_data = {
                'location': {
                    'location_name': grass_gisenv['LOCATION_NAME'],
                    'mapset_name': grass_gisenv['MAPSET'],
                    'gisdb': grass_gisenv['GISDBASE'],
                },
                'coors': [[minlon, maxlat], [maxlon, minlat]],
            }

            response = requests.post(
                f'{self.grass_api_endpoint}/api/m_proj', headers=headers, json=json_data, timeout=60)
            corners = response.json()['data']
        else:
            corners = [[minlon, maxlat], [maxlon, minlat]]
        print('corners: ', corners)
        headers = {
                'accept': 'application/json',
                'Content-Type': 'application/json',
            }
        json_data = {
            'location': {
                'location_name': grass_gisenv['LOCATION_NAME'],
                'mapset_name': grass_gisenv['MAPSET'],
                'gisdb': grass_gisenv['GISDBASE'],
            },
            'bounds': {
                'n': corners[0][1],
                's': corners[1][1],
                'e': corners[1][0],
                'w': corners[0][0],
            },
            'resolution': {
                'resolution': 0,
            },
        }
        response = requests.post(
            f'{self.grass_api_endpoint}/api/set_region_bounds', headers=headers, json=json_data, timeout=60)
        return response
        # headers = {
        #     'accept': 'application/json',
        # }

        # params = {
        #     'location_name': grass_gisenv['LOCATION_NAME'],
        #     'mapset_name': grass_gisenv['MAPSET'],
        #     'gisdb': grass_gisenv['GISDBASE'],
        # }

        # response = requests.get(
        #     'http://localhost/api/get_current_region', params=params, headers=headers, timeout=60)
        # data = response.content
        
        # self.grass_region_bounds =  os.path.join(os.path.dirname(__file__), 'data' 'grass_region.geojson')
        
        # with open(self.grass_region_bounds, 'wb') as s:
        #     s.write(data)
        
        
        # self.w.gisToolSplitter.widget(1).remove_vector(
        #     self.grass_region_bounds, 'grass_region')
        # self.w.gisToolSplitter.widget(1).add_vector(
        #     self.grass_region_bounds, 'grass_region')
        # self.w.gisToolSplitter.widget(0).refresh()

        # self.w.gisToolSplitter.widget(2).show()
        # self.w.gisToolSplitter.widget(
        #     2).children()[0].itemAt(0).widget().setPlainText(f"{min_lon}, {min_lat}, {max_lon}, {max_lat}")


    def getImageIndex(self, lon, lat):
        distance, index = self.kdt.query([lon, lat])
        return index

    def clear_image_annotation(self):
        for i in self.graph_items:
            i.setData(
                pos=[],
                adj=[],
                pen=[],
                size=1,
                pxMode=False,
            )
            del i
        self.graph_items = []
        
    def decreaseimageindex(self):
        """docstring"""
        self.imageindex = self.imageindex - self.w.ImageStepspinBox.value()
        self.w.ImageIndexSlider.setValue(self.imageindex)
        self.w.ImageIndexspinBox.setValue(self.imageindex)
        self.w.ImageIndexspinBox.update()

    def increaseimageindex(self):
        """docstring"""
        self.imageindex = self.imageindex + self.w.ImageStepspinBox.value()
        self.w.ImageIndexSlider.setValue(self.imageindex)
        self.w.ImageIndexspinBox.setValue(self.imageindex)
        self.w.ImageIndexspinBox.update()

    def setValueImageIndexspinBox(self, z):
        """docstring"""
        self.imageindex = int(z)
        self.w.ImageIndexspinBox.setSingleStep(self.w.ImageStepspinBox.value())
        self.w.ImageIndexspinBox.setValue(self.imageindex)

    def setValueImageIndexSlider(self, z):
        """docstring"""
        self.imageindex = int(z)
        self.w.ImageIndexSlider.setSingleStep(self.w.ImageStepspinBox.value())
        self.w.ImageIndexSlider.setValue(self.imageindex)

    def setValuerangeSpinBox(self, r):
        """docstring"""
        self.rangevalue = int(r)
        self.w.range.setSingleStep(1)
        self.w.range.setValue(self.rangevalue)
        if self.w.zoomto.isChecked():
            self.zoom_to()

    def setImageIndexStepValue(self):
        """docstring"""
        self.w.ImageIndexspinBox.setSingleStep(self.w.ImageStepspinBox.value())
        self.w.ImageIndexSlider.setSingleStep(self.w.ImageStepspinBox.value())

    def close_pyqtgraph(self):
        self.querybuilder.close()
        
    def zoom_to(self):
        """docstring"""
        lon = float(self.w.longitude.text())
        lat = float(self.w.latitude.text())
        distance = float(self.rangevalue)
        # print(lon, lat, distance)
        

        self.w.statusbar.showMessage("System Status | Normal")

        distance = distance/10000
        rect = QgsRectangle(
            (float(lon)) - float(distance), 
            (float(lat)) - float(distance), 
            (float(lon)) + float(distance), 
            (float(lat)) + float(distance)
            )
        # # Get the map canvas
        # # del self.m1
        # # try:
        self.canvas.scene().removeItem(self.m1)
        self.m1 = QgsVertexMarker(self.canvas)
        self.m1.setCenter(QgsPointXY(float(lon), float(lat)))
        self.m1.setColor(QColor(255, 0, 0))  # (R,G,B)
        self.m1.setIconSize(10)
        self.m1.setIconType(QgsVertexMarker.ICON_X)
        self.m1.setPenWidth(3)
        self.canvas.setExtent(rect)
        self.canvas.refresh()
        
        
        # self.w.gisToolSplitter.widget(1).canvas.scene().removeItem(self.m1)
        # self.m1 = qgis_gui.QgsVertexMarker(
        #     self.w.gisToolSplitter.widget(1).canvas)
        # self.m1.setCenter(qgis_core.QgsPointXY(float(lon), float(lat)))
        # self.m1.setColor(QtGui.QColor(255, 0, 0))  # (R,G,B)
        # self.m1.setIconSize(10)
        # self.m1.setIconType(qgis_gui.QgsVertexMarker.ICON_X)
        # self.m1.setPenWidth(3)
        # self.w.gisToolSplitter.widget(1).canvas.setExtent(rect)
        # self.w.gisToolSplitter.widget(1).canvas.refresh()

    def build_box(self, bbox):
        pos = np.array(
            [
                [bbox[0], bbox[1]],
                [bbox[2], bbox[3]],
                [bbox[4], bbox[5]],
                [bbox[6], bbox[7]],
            ]
        )
        adj = np.array(
            [
                [0, 1],
                [1, 2],
                [2, 3],
                [3, 0],
            ]
        )
        symbols = ["o", "o", "o", "o"]
        lines = np.array(
            [
                (255, 0, 0, 255, 3),
                (255, 0, 0, 255, 3),
                (255, 0, 0, 255, 3),
                (255, 0, 0, 255, 3),
            ],
            dtype=[
                ("red", np.ubyte),
                ("green", np.ubyte),
                ("blue", np.ubyte),
                ("alpha", np.ubyte),
                ("width", float),
            ],
        )
        return pos, adj, lines, symbols

    def add_image_annotation(self):
        # annotation = self.imageMetadata[
        #     self.imageMetadata["Imagename"] == self.imagelist[self.imageindex][:-4]
        # ]["Annotation"]

        annotation = self.imageMetadata["Annotation"].iloc[self.imageindex]

        # print(annotation, type(annotation.values))
        # add treshold check for annotation confidence
        # if not annotation.isnull().values.any():
        if annotation is not np.nan:
            # print(annotation.values[0]["bbox"])
            # print(annotation.values[0]["Species"])
            # print(annotation.values[0]["Confidence"])
            # print(len(annotation.values[0]["bbox"]), len(annotation.values))
            self.clear_image_annotation()
            # for i, v in enumerate(annotation.values[0]["bbox"]):
            for i, bbox in enumerate(annotation["bbox"]):

                print("annotation_confidence_treshold: ",
                      self.annotation_confidence_treshold)
                if (
                    annotation["Confidence"][i]
                    >= self.annotation_confidence_treshold
                ):
                    print("annotation bbox", bbox)
                    print("annotation label", annotation["Species"][i])
                    print("annotation confidence treshold",
                          annotation["Confidence"][i])
                    self.g = pg.GraphItem()
                    pos, adj, lines, symbols = self.build_box(
                        bbox["bbox"]
                    )
                    self.g.setData(
                        pos=pos,
                        adj=adj,
                        pen=lines,
                        size=15,
                        symbol=symbols,
                        pxMode=False,
                    )
                    self.imv.addItem(self.g)
                    # print(self.imv.getImageItem())
                    self.g.setZValue(10)  # make sure ROI is drawn above image
                    self.graph_items.append(self.g)
        else:
            print("no annotation found")
            self.clear_image_annotation()

    def add_image(self):
        
        """docstring"""
        self.imv.clear()
        if any(self.imagelist) is not None:
            path = Path(os.path.join(
                self.dirname, self.imageMetadata["Imagename"].iloc[self.imageindex]+".jpg"))
            self.pixmap = QPixmap(
                os.path.join(
                    self.dirname, self.imageMetadata["Imagename"].iloc[self.imageindex]+".jpg")
            )
            self.imv.imageItem.axisOrder = "row-major"
            # check if the imageviewer is hidden or not
            if self.w.actionImageBrowser.isChecked():
                self.imv.show()

            self.imv.setImage(
                imread(os.path.join(
                    self.dirname, self.imageMetadata["Imagename"].iloc[self.imageindex]+".jpg"))
            )

            if self.w.actionAnnotation.isChecked():
                self.add_image_annotation()
            else:
                self.clear_image_annotation()
            #
            # self.imageeast = str(self.imageMetadata['Xutm'].values[0])
            # self.imagenorth = str(self.imageMetadata['Yutm'].values[0])
            # self.w.statusbar.showMessage("Image %s" % self.imageMetadata.index[0])
            
            if self.imageMetadata is not None:
                
                # try:
                # record = self.imageMetadata[
                #     self.imageMetadata["Imagename"]
                #     == self.imagelist[self.imageindex][:-4]
                # ]

                record = self.imageMetadata.iloc[self.imageindex]
                if len(record) != 0:
                    self.w.longitude.setText(
                        str(round(record["habcam_lon"], 8))
                    )
                    self.w.latitude.setText(
                        str(round(record["habcam_lat"], 8))
                    )

                    # METADATA
                    self.imagemetadata_gui.imageeast.setText(
                        str(round(record["Xutm_adj"], 2))
                    )
                    self.imagemetadata_gui.imagenorth.setText(
                        str(round(record["Yutm_adj"], 2))
                    )
                    self.imagemetadata_gui.hbcdepth.setText(
                        str(record["V_Depth"])
                    )
                    self.imagemetadata_gui.waterdepth.setText(
                        str(record["Water_Depth"])
                    )
                    self.imagemetadata_gui.altimeter.setText(
                        str(record["Altimeter"])
                    )
                    self.imagemetadata_gui.salinity.setText(
                        str(record["Salinity"])
                    )
                    self.imagemetadata_gui.temperature.setText(
                        str(record["Temp"])
                    )
                    self.imagemetadata_gui.O2.setText(
                        str(record["O2"]))
                    self.imagemetadata_gui.CDOM.setText(
                        str(record["Cdom"])
                    )
                    self.imagemetadata_gui.chlorophyll.setText(
                        str(record["Chlorophyll"])
                    )
                    self.imagemetadata_gui.turbidity.setText(
                        str(record["Turb"])
                    )
                    # test QtDateTime

                    self.imagemetadata_gui.dateTimeEdit.setDateTime(
                        record.name)
                    self.imagemetadata_gui.linklabel.setText(
                        '<a href="file://%s">%s</a>'
                        % (
                            os.path.join(
                                self.dirname, self.imageMetadata["Imagename"].iloc[self.imageindex]+".jpg"),
                            str(record["Imagename"]),
                        )
                    )
                    self.imagemetadata_gui.linklabel.setOpenExternalLinks(
                        True)

                    self.w.statusbar.showMessage(
                        "Image : %s" % self.imageindex)

                    if self.w.zoomto.isChecked():
                        self.zoom_to()
                    self.on_send()
                else:
                    print(
                        "record lenght:",
                        len(record),
                        "for image index: ",
                        self.imageindex,
                        self.imageMetadata["Imagename"].iloc[self.imageindex],
                    )
                    #
                # except:
                #     error_message(
                #         f"image metadata not set properly- check settings \n \n image metadata widget will be disabled"
                #     )
                #     self.imageMetadata = None
                #     self.imagemetadata_gui.metadata_scroll_area.setEnabled(
                #         False)
            else:
                print("image metadata disabled - reconfigure the settings")
                self.imagemetadata_gui.metadata_scroll_area.setEnabled(False)

        else:
            print("both image path not be set")
            print(" --- ")

    @pyqtSlot()
    def on_send(self):
        """docstring"""
        image_path = os.path.join(
            self.dirname, self.imageMetadata["Imagename"].iloc[self.imageindex]+".jpg")
        self.send_image_path.emit(image_path)
        md_str = pd.DataFrame(
            [self.imageMetadata[['Longitude',
                                 'Latitude',
                                 'V_Depth',
                                 'Water_Depth',
                                 'Altimeter',
                                 'Salinity',
                                 'Temp',
                                 'O2',
                                 'Cdom',
                                 'Chlorophyll',
                                 'Turb']].iloc[self.imageindex]]).to_html()
        self.send_imagemetadata_string.emit(md_str)
        if not self.savekml.lock_location.isChecked():
            self.savekml.longitude.setText(self.w.longitude.text())
            self.savekml.latitude.setText(self.w.latitude.text())
        # update query builder widgets
        if not self.querybuilder.lock_location.isChecked():
            self.querybuilder.qb_longitude.setText(self.w.longitude.text())
            self.querybuilder.qb_latitude.setText(self.w.latitude.text())
            
    def show_dialog(self):
        """docstring"""
        self.dialog.exec_()
        self.settings = get_settings(self.config)
        self.host = self.settings["Broadcast"]["ip"]
        self.port = self.settings["Broadcast"]["port"]
        self.dirname = self.settings["HabCam"]["imagepath"]
        self.metadatafile = self.settings["HabCam"]["imagemetadata"]
        self.imageannotationfile = self.settings["HabCam"]["imageannotation"]
        self.grass_api_endpoint = self.settings["Processing"]["grass_api_endpoint"]
        #
        # self.imagelist = os.listdir(self.dirname)
        # self.imagelist.sort()
        # self.w.ImageIndexspinBox.setMaximum(len(self.imagelist) - 1)
        # self.w.ImageIndexSlider.setMaximum(len(self.imagelist) - 1)
        #
        try:
            self.imagemetadata_gui
        except AttributeError:
            self.imagemetadata_gui = ImageMetadata()
        if Path(self.metadatafile).is_file():
            try:
                self.imageMetadata = pd.read_parquet(self.metadatafile)
                self.w.ImageIndexspinBox.setMaximum(
                    len(self.imageMetadata) - 1)
                self.w.ImageIndexSlider.setMaximum(len(self.imageMetadata) - 1)
                # self.imageMetadata.index = pd.to_datetime(
                #     self.imageMetadata["index"])
                # self.imageMetadata = self.imageMetadata.loc[
                #     self.imageMetadata["Imagename"].isin(
                #         (i.replace(".jpg", "") for i in self.imagelist)
                #     )
                # ]
                if os.getenv("HBC_DEBUG") and os.getenv("HBC_DEBUG") == 'VERBOSE':
                    print("image metadata columns")
                    print(self.imageMetadata.columns)
                self.imagemetadata_gui.metadata_scroll_area.setEnabled(True)
                if Path(self.imageannotationfile).is_file():
                    # check the annotation file
                    # merge the info in the metadata and
                    # enable annotation tool
                    print("Annotation file loaded")
                    self.w.actionAnnotation.setEnabled(True)
                    annotations_by_image = parse_annotation(
                        self.imageannotationfile)
                    self.imageMetadata["Annotation"] = self.imageMetadata.Imagename.map(
                        annotations_by_image
                    )
                else:
                    self.w.actionAnnotation.setEnabled(False)
                self.kdt = spatial.KDTree(
                    self.imageMetadata[["habcam_lon", "habcam_lat"]].values)
            except OSError:
                print("OS error reading metadata")
            except pyarrow.lib.ArrowInvalid as message:
                error_message(
                    f"error reading {self.metadatafile}: \n" + str(message))
                self.imageMetadata = None
                # self.show_dialog()
        else:
            self.show_dialog()
            print(f"ther new path is {self.dialog.image_path.text()}")

    def showTools(self):
        """docstring"""
        if self.w.toolWidget.isVisible():
            self.w.toolWidget.hide()
        else:
            self.w.toolWidget.show()

    def showGisTools(self):
        """docstring"""
        if self.w.gisTools.isVisible():
            self.w.gisTools.hide()
            self.w.gisTools_logger.hide()
        else:
            self.w.gisTools.show()
            #self.w.gisTools_logger.show()

    def showImageViewer(self):
        """docstring"""
        if self.imv.isVisible():
            self.imv.hide()
            self.imageviewer_is_hidden = True
            if self.w.link_to_image_viewer.isChecked():
                self.w.imageBrowsing.hide()
        else:
            self.imv.show()
            self.imageviewer_is_hidden = False
            if self.w.link_to_image_viewer.isChecked():
                self.w.imageBrowsing.show()

    def showImageBrowser(self):
        """docstring"""
        if self.imv.isVisible():
            #self.imv.hide()
            self.w.imageBrowsing.hide()
            self.imageviewer_is_hidden = True
        else:
            #self.imv.show()
            self.w.imageBrowsing.show()
            self.imageviewer_is_hidden = False


    def setValue_annotation_confidence(self):
        self.annotation_confidence_treshold = (
            self.w.annotation_confidence_spinBox.value()
        )

    def showAnnotationThreshold(self):
        """docstring"""
        if self.w.annotation_confidence_spinBox.isVisible():
            self.w.annotation_confidence_spinBox.hide()
            self.w.annotation_confidence_spinBox_label.hide()
        else:
            self.w.annotation_confidence_spinBox.show()
            self.w.annotation_confidence_spinBox_label.show()
            
    # def quitAll(self):
    #     """docstring"""
    #     self.querybuilder.close()
    #     qApp.quit()
        
        
    def closeEvent(self, event):
        if self.r is not None:
            self.canvas.scene().removeItem(self.r)
        self.closingPlugin.emit()
        event.accept()
