 # -*- coding: utf-8 -*-
"""
/***************************************************************************
 Atlas
                                 A QGIS plugin
 Atlas
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2019-02-15
        git sha              : $Format:%H$
        copyright            : (C) 2019 by jan vrobel
        email                : vrobel.jan@seznam.cz
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/
"""
from PyQt5.QtCore import QSettings, QTranslator, qVersion, QCoreApplication, Qt, QFileSystemWatcher, QRegExp,QDir
from PyQt5.QtGui import QIcon, QPixmap, QRegExpValidator, QDoubleValidator
from PyQt5.QtWidgets import QAction, QTreeWidget, QTreeWidgetItem, QMessageBox, QLabel, QProgressDialog, QDialog, QProgressBar,QListWidgetItem
# Initialize Qt resources from file resources.py
from .resources import *
import re
#from .flaskServer import *
from multiprocessing import Process
from pathlib import Path 
# Import the code for the DockWidget
from builtins import str
from builtins import range
from builtins import object
import json
import zipfile
import tempfile
import configparser
import shutil
import uuid
import copy
import webbrowser
from .Atlas_dockwidget import AtlasDockWidget
import os.path
import tempfile
import qgis.core
from qgis.core import *
import platform
import os
import qgis.utils
import qgis.gui
from qgis.gui import QgsMapCanvas
from qgis.core import QgsApplication
from qgis.utils import iface
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox, QWidget, QInputDialog, QLineEdit, QFileDialog
import requests
import tempfile
import time
from urllib.request import urlopen
import subprocess
import threading
#from flask import Flask, request, jsonify
import base64
import hashlib
import html
import re
import urllib.parse
from .ogr2ogr import main
## forms
from .dlg_GetLayers import GetLayersDialog
from .dlg_importMap import ImportMapDialog
from .dlg_deleteMap import DeleteMapDialog
from .dlg_importLayer import ImportLayerDialog
from .dlg_addLayer import AddLayerDialog
from .dlg_addMap import AddMapDialog
from .dlg_createComposite import CreateCompositeDialog
from .dlg_deleteLayerFromMap import DeleteLayerFromMapDialog
from .dlg_editMap import EditMapDialog
from .dlg_ConnectionManager import ConnectionManagerDialog
from .dlg_userInfo import UserInfoDialog



class Atlas:
    """QGIS Plugin Implementation."""

    def __init__(self, iface):
        """Constructor.
        
        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface

        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__) 
        
        ## init global variables
      #  global filename 
        self.client_id = None
        self.filename = None
        self.layerName = None
        self.username = 'browser'
        self.EPSG = 'EPSG:3857'
        self.composite = None
        self.thread1 = None
        self.compositeList = []
        self.compositeListOld = []
        self.CHUNK_SIZE = 1048576 ## s touto hodnotou pracuje layman klient (cca 1MB soubor)
        self.URI = "http://layman.lesprojekt.cz"
        self.access_token = None
        self.expires_in = None
        self.refresh_token = None
        self.laymanUsername = ""
        self.authHeader = None
        self.code_verifier = None
        self.code_challenge = None
        self.Agrimail = None
        self.loadedInMemory = False
        self.liferayServer = None
        self.laymanServer = None
        self.uri = 'http://layman.lesprojekt.cz/rest/'
        self.iface.layerTreeView().currentLayerChanged.connect(lambda: self.layerChanged())
        
        
     #   global dlgGetLayers 
        self.dlgGetLayers= GetLayersDialog()
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(
            self.plugin_dir,
            'i18n',
            'Atlas_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&Layman')
        # TODO: We are going to let the user set this up in a future iteration
        self.toolbar = self.iface.addToolBar(u'Layman')
        self.toolbar.setObjectName(u'Layman')

        #print "** INITIALIZING Atlas"

        self.pluginIsActive = False
        self.dockwidget = None
        ## prepare temp dir
        tempDir = tempfile.gettempdir() + os.sep + "atlas" 
        try:
            os.mkdir(tempDir)
            print("Directory " , tempDir ,  " Created ") 
        except FileExistsError:
            print("Directory " , tempDir ,  " already exists")


    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('Layman', message)


    def add_action(
        self,
        icon_path,
        text,
        callback,
        enabled_flag=True,
        add_to_menu=True,
        add_to_toolbar=True,
        status_tip=None,
        whats_this=None,
        parent=None):
        

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            self.toolbar.addAction(action)

        if add_to_menu:
            self.iface.addPluginToMenu(
                self.menu,
                action)

        self.actions.append(action)

        return action


    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        #icon_path = ':/plugins/Atlas/icon.png'
        #self.add_action(
        #    icon_path,
        #    text=self.tr(u''),
        #    callback=self.run,
        #    parent=self.iface.mainWindow())
        #self.first_start = True

        ################## user
        self.textbox = QLabel(self.iface.mainWindow())
        # Set width
        self.textbox.setFixedWidth(140)
        # Add textbox to toolbar
        self.txtAction = self.toolbar.addWidget(self.textbox)
        # Set tooltip
        self.txtAction.setToolTip(self.tr(u'Current Row Number'))
        # Set callback
        self.textbox.setText("Layman")

        ################ end usericon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'login.png'
        icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'login.png'
        self.menu_Connection = self.add_action(
            icon_path,
            text=self.tr(u'Login'),
            callback=self.run_login,
            enabled_flag=True,
            parent=self.iface.mainWindow())


        icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'save.png'
        self.menu_saveLocalFile = self.add_action(
            icon_path,
            text=self.tr(u'Save as to JSON and SLD'),
            callback=self.saveLocalFile,
            enabled_flag=False,
            parent=self.iface.mainWindow())

        self.first_start = True
        icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'file.png'
        self.menu_loadJson = self.add_action(
            icon_path,
            text=self.tr(u'Load from JSON'),
            callback=self.loadLocalFile,
            enabled_flag=False,
            parent=self.iface.mainWindow())
        self.first_start = True

        icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'layers-up.png'
        self.menu_ImportLayerDialog = self.add_action(
            icon_path,
            text=self.tr(u'Export layer to server'),
            callback=self.run_ImportLayerDialog,
            enabled_flag=False,
            parent=self.iface.mainWindow())  
        icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'layers-down.png'
        self.menu_AddLayerDialog = self.add_action(
            icon_path,
            text=self.tr(u'Load layer from server'),
            callback=self.run_AddLayerDialog,
            enabled_flag=False,
            parent=self.iface.mainWindow()) 
        icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'upload-map.png'
        self.menu_ImportMapDialog = self.add_action(
            icon_path,
            text=self.tr(u'Manage maps'),
            callback=self.run_ImportMapDialog,
            enabled_flag=False,
            parent=self.iface.mainWindow())  
        icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'download_map.png'
        self.menu_AddMapDialog = self.add_action(
            icon_path,
            text=self.tr(u'Load map from server'),
            callback=self.run_AddMapDialog,
            enabled_flag=False,
            parent=self.iface.mainWindow())   
        
        #icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'delete.png'
        #self.menu_DeleteMapDialog = self.add_action(
        #    icon_path,
        #    text=self.tr(u'Delete map'),
        #    callback=self.run_DeleteMapDialog,
        #    enabled_flag=False,
        #    parent=self.iface.mainWindow())  
        #icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'globus.png'
        #self.menu_CreateCompositeDialog = self.add_action(
        #    icon_path,
        #    text=self.tr(u'Create map'),
        #    callback=self.run_CreateCompositeDialog,
        #    enabled_flag=False,
        #    parent=self.iface.mainWindow())
        icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'account.svg'
        self.menu_UserInfoDialog = self.add_action(
            icon_path,
            text=self.tr(u'User info'),
            callback=self.run_UserInfoDialog,
            enabled_flag=False,
            parent=self.iface.mainWindow())
    #--------------------------------------------------------------------------
    def run_UserInfoDialog(self):
        self.dlg = UserInfoDialog() 
        self.dlg.show()
        self.dlg.pushButton_logout.setStyleSheet("#pushButton_logout {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_logout:hover{background: #66ab27 ;}")
        self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")
        userEndpoint = "http://layman.lesprojekt.cz/rest/current-user"
        r = requests.get(url = userEndpoint,  headers = self.authHeader)
        res = r.text
        res = self.fromByteToJson(r.content)
        self.dlg.pushButton_logout.clicked.connect(lambda: self.logout())
        print(res['claims'])
        self.dlg.label_layman.setText(res['claims']['preferred_username'])
        self.dlg.label_agrihub.setText(res['claims']['email'])
        self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")

    def run_EditMap(self, x):
        self.dlg = EditMapDialog()      
        self.dlg.pushButton_save.setStyleSheet("#pushButton_save {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_save:hover{background: #66ab27 ;}#pushButton_save:disabled{background: #64818b ;}")
        self.dlg.pushButton_close.setStyleSheet("#pushButton_close {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_close:hover{background: #66ab27 ;}")
        self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")
        
       
        self.dlg.lineEdit_name.hide()
        self.dlg.label_2.hide()
        self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
        self.dlg.lineEdit_name.setText(self.compositeList[x]['name'])
        self.dlg.lineEdit_abstract.setText(self.compositeList[x]['abstract'])
        self.dlg.lineEdit_title.setText(self.compositeList[x]['title'])
        self.dlg.lineEdit_units.setText(self.compositeList[x]['units'])
        self.dlg.lineEdit_scale.setText(str(self.compositeList[x]['scale']))
        self.dlg.lineEdit_user.setText(self.compositeList[x]['user']['name'])
        self.dlg.lineEdit_xmin.setText(self.compositeList[x]['extent'][0])
        self.dlg.lineEdit_xmax.setText(self.compositeList[x]['extent'][2])
        self.dlg.lineEdit_ymin.setText(self.compositeList[x]['extent'][1])
        self.dlg.lineEdit_ymax.setText(self.compositeList[x]['extent'][3])
        self.dlg.rejected.connect(lambda: self.afterCloseEditMapDialog()) 
        self.dlg.pushButton_save.clicked.connect(lambda: self.modifyMap(x))
        self.dlg.rejected.connect(lambda: self.afterCloseCompositeDialog())
        self.dlg.show()
        result = self.dlg.exec_()

    def run_DeleteLayerFromMap(self):
        self.dlg = DeleteLayerFromMapDialog()
        self.dlg.pushButton.clicked.connect(lambda: self.deteteLayerFromComposite(self.dlg.listWidget.currentRow(),self.compositeList[self.dlg.listWidget.currentRow()]['layers'][self.dlg.listWidget_listLayers2.currentRow()]['params']['LAYERS']))
        #self.dlg.pushButton.clicked.connect(lambda: print(self.dlg.listWidget_2.currentRow()))
       
        layers = QgsProject.instance().mapLayers().values()
        
        for i in range (0, len(self.compositeList)):
            self.dlg.listWidget.addItem(self.compositeList[i]['name'])
       # self.dlg.pushButton.setEnabled(False)
        self.dlg.listWidget.itemClicked.connect(self.listCompositeLayers)
        self.dlg.listWidget_listLayers2.itemClicked.connect(self.showThumbnail)   
        

       # self.dlg.listWidget_listMaps.itemClicked.connect(self.enableButton)    
        self.dlg.show()
        self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
        result = self.dlg.exec_()

    def run_CreateCompositeDialog(self, fromImport = False):
        self.dlg = CreateCompositeDialog()
        self.dlg.label_info.hide()
        self.dlg.label_2.hide()
        self.dlg.lineEdit.hide()
        self.dlg.pushButton_CreateComposition.clicked.connect(lambda: self.createComposite(self.dlg.lineEdit.text(),self.dlg.lineEdit_2.text()))              
        layers = QgsProject.instance().mapLayers().values()
        self.dlg.treeWidget.itemClicked.connect(self.setExtent)
        for layer in layers:
           # self.dlg.listWidget_listLayers.addItem(layer.name())
            if (layer.type() == QgsMapLayer.VectorLayer):
                item = QTreeWidgetItem([layer.name()]) 
            
                    
                self.dlg.treeWidget.addTopLevelItem(item)
        ext = iface.mapCanvas().extent()
        self.dlg.lineEdit.setValidator(QRegExpValidator(QRegExp("[a-z]{1}[a-z0-9]{1,30}")))      
        self.dlg.lineEdit_2.editingFinished.connect(self.checkNameCreateMap)
        self.dlg.lineEdit_3.setText(str(ext.xMinimum()))
        self.dlg.lineEdit_4.setText(str(ext.xMaximum()))
        self.dlg.lineEdit_5.setText(str(ext.yMinimum()))
        self.dlg.lineEdit_6.setText(str(ext.yMaximum()))
        self.dlg.pushButton_defaultExtent.clicked.connect(lambda: self.setDefaultExtent(ext))              
        self.dlg.pushButton_defaultExtent.setStyleSheet("#pushButton_defaultExtent {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_defaultExtent:hover{background: #66ab27 ;}#pushButton_defaultExtent:disabled{background: #64818b ;}")
        self.dlg.pushButton_CreateComposition.setStyleSheet("#pushButton_CreateComposition {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_CreateComposition:hover{background: #66ab27 ;}#pushButton_CreateComposition:disabled{background: #64818b ;}")
        self.dlg.pushButton_close.setStyleSheet("#pushButton_close {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_close:hover{background: #66ab27 ;}")
        self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")

        self.dlg.show()
        self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
        if (fromImport):
            self.dlg.rejected.connect(lambda: self.afterCloseCompositeDialog())
        result = self.dlg.exec_()


    def run_ImportMapDialog(self):
        self.dlg = ImportMapDialog()
        self.dlg.label_import.hide()
        #self.dlg.listWidget_listLayers2.hide()
        self.dlg.pushButton_deleteMap.setEnabled(False)
        self.dlg.pushButton_editMeta.setEnabled(False)
        self.dlg.pushButton_addRaster.setEnabled(False)
        self.dlg.mMapLayerComboBox.setFilters(QgsMapLayerProxyModel.VectorLayer)
        self.dlg.pushButton.clicked.connect(lambda: self.addLayerToComposite(self.dlg.listWidget.currentRow()))   
        self.dlg.pushButton_deleteMap.clicked.connect(lambda: self.deleteMap(self.dlg.listWidget.currentItem().text(),self.dlg.listWidget.currentRow()))
       # self.dlg.pushButton_deleteMap.clicked.connect(lambda: self.deleteMapFromCanvas(self.dlg.listWidget.currentRow())) 
        self.dlg.pushButton_up.clicked.connect(lambda: self.reorderLayers(self.dlg.listWidget_listLayers.currentRow(), 1, self.dlg.listWidget.currentRow()))
        self.dlg.pushButton_down.clicked.connect(lambda: self.reorderLayers(self.dlg.listWidget_listLayers.currentRow(), -1, self.dlg.listWidget.currentRow()))


        if not self.loadedInMemory:
            self.loadAllComposites()
        self.dlg.pushButton_addMap.clicked.connect(lambda: self.showAddMapDialog())
        layers = QgsProject.instance().mapLayers().values()     
        for i in range (0, len(self.compositeList)):
            print(self.compositeList[i])
            #self.dlg.listWidget.addItem(self.compositeList[i]['name'])
            self.dlg.listWidget.addItem(self.compositeList[i]['title'])
        self.dlg.progressBar.hide()            
        self.dlg.pushButton.setIcon(QIcon(self.plugin_dir + os.sep + 'icons' + os.sep + 'plus.png'))
        self.dlg.pushButton_addMap.setIcon(QIcon(self.plugin_dir + os.sep + 'icons' + os.sep + 'plus.png'))
        self.dlg.pushButton_addRaster.setIcon(QIcon(self.plugin_dir + os.sep + 'icons' + os.sep + 'plus.png'))
        self.dlg.pushButton_deleteLayers.setIcon(QIcon(self.plugin_dir + os.sep + 'icons' + os.sep + 'minus.png'))
        self.dlg.pushButton_deleteMap.setIcon(QIcon(self.plugin_dir + os.sep + 'icons' + os.sep + 'minus.png'))
        self.dlg.pushButton_editMeta.setIcon(QIcon(self.plugin_dir + os.sep + 'icons' + os.sep + 'edit.png'))
        self.dlg.listWidget.itemClicked.connect(self.refreshLayerList)
        self.dlg.listWidget.itemClicked.connect(lambda: self.dlg.pushButton_deleteMap.setEnabled(True))
        self.dlg.listWidget.itemClicked.connect(lambda: self.dlg.pushButton_editMeta.setEnabled(True))
        self.dlg.listWidget.itemClicked.connect(lambda: self.dlg.pushButton_addRaster.setEnabled(True))
        self.dlg.listWidget_listLayers.itemClicked.connect(lambda: self.dlg.pushButton_down.setEnabled(True))
        self.dlg.listWidget_listLayers.itemClicked.connect(lambda: self.dlg.pushButton_up.setEnabled(True))
        
       
        self.dlg.pushButton_editMeta.clicked.connect(lambda: self.showEditMapDialog(self.dlg.listWidget.currentRow()))
     ###########nacitam vrstvy z laymana do comboboxu
        url = self.URI+'/rest/'+self.laymanUsername+'/layers'
        r = requests.get(url = url)
       # print(r.content())
        data = r.json()             
        for row in range(0, len(data)):          
            self.dlg.comboBox_raster.addItem(data[row]['name'])

        self.dlg.pushButton_addRaster.clicked.connect(lambda: self.addExistingLayerToComposite(self.dlg.comboBox_raster.currentText()))
        #### nahrát mapy ze serveru do comboboxu
        url = self.URI+'/rest/'+self.laymanUsername+'/maps'
        r = requests.get(url = url)
        data = r.json()
        for row in range(0, len(data)):            
            self.dlg.comboBox_loadMap.addItem(data[row]['name'])
      
        self.dlg.pushButton_loadMap.clicked.connect(lambda: self.readMapJson(self.dlg.comboBox_loadMap.currentText(), 'WMS'))
        self.dlg.pushButton_loadMapWFS.clicked.connect(lambda: self.readMapJson(self.dlg.comboBox_loadMap.currentText(), 'WFS'))
        self.dlg.pushButton_loadMapWFS.hide()
        self.dlg.pushButton_loadMap.hide()
        self.dlg.comboBox_loadMap.hide()
     #############
        self.dlg.pushButton.setEnabled(False)
        self.dlg.pushButton_deleteLayers.setEnabled(False)
        self.dlg.listWidget_listLayers.itemClicked.connect(self.showSmallThumbnail)
      #  self.dlg.listWidget_listLayers.itemClicked.connect(self.showThumbnail)
        self.dlg.listWidget.itemClicked.connect(self.enableButton)          
        self.dlg.pushButton_deleteLayers.clicked.connect(lambda: self.deteteLayerFromComposite(self.dlg.listWidget.currentRow(),self.dlg.listWidget_listLayers.currentRow(), self.dlg.listWidget_listLayers.currentItem().text()))    
        self.dlg.show()
        self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())

        self.dlg.pushButton_down.setStyleSheet("#pushButton_down {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_down:hover{background: #66ab27 ;}#pushButton_down:disabled{background: #64818b ;}")
        self.dlg.pushButton_up.setStyleSheet("#pushButton_up {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_up:hover{background: #66ab27 ;}#pushButton_up:disabled{background: #64818b ;}")
        self.dlg.pushButton.setStyleSheet("#pushButton {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton:hover{background: #66ab27 ;}#pushButton:disabled{background: #64818b ;}")
        self.dlg.pushButton_close.setStyleSheet("#pushButton_close {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_close:hover{background: #66ab27 ;}#pushButton_close:disabled{background: #64818b ;}")
        self.dlg.pushButton_deleteLayers.setStyleSheet("#pushButton_deleteLayers {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_deleteLayers:hover{background: #66ab27 ;}#pushButton_deleteLayers:disabled{background: #64818b ;}")
        self.dlg.pushButton_deleteMap.setStyleSheet("#pushButton_deleteMap {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_deleteMap:hover{background: #66ab27 ;}#pushButton_deleteMap:disabled{background: #64818b ;}")
        self.dlg.pushButton_addRaster.setStyleSheet("#pushButton_addRaster {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_addRaster:hover{background: #66ab27 ;}#pushButton_addRaster:disabled{background: #64818b ;}")
        self.dlg.pushButton_addMap.setStyleSheet("#pushButton_addMap {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_addMap:hover{background: #66ab27 ;}#pushButton_addMap:disabled{background: #64818b ;}")
        self.dlg.pushButton_editMeta.setStyleSheet("#pushButton_editMeta {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_editMeta:hover{background: #66ab27 ;}#pushButton_editMeta:disabled{background: #64818b ;}")
        self.dlg.pushButton_loadMapWFS.setStyleSheet("#pushButton_loadMapWFS {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_loadMapWFS:hover{background: #66ab27 ;}#pushButton_loadMapWFS:disabled{background: #64818b ;}")
        self.dlg.pushButton_loadMap.setStyleSheet("#pushButton_loadMap {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_loadMap:hover{background: #66ab27 ;}#pushButton_loadMap:disabled{background: #64818b ;}")
        self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")
        


        result = self.dlg.exec_()
    def run_DeleteMapDialog(self):
        self.dlg = DeleteMapDialog()
        self.refreshListWidgetMaps()
        self.dlg.pushButton.setEnabled(False)
        self.dlg.treeWidget.itemClicked.connect(self.enableButton) 
        self.dlg.pushButton.clicked.connect(lambda: self.deleteMapFromServer(self.dlg.treeWidget.selectedItems()[0].text(0)))
        self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
        self.dlg.show()
        result = self.dlg.exec_()
    def run_ImportLayerDialog(self):
        self.dlg = ImportLayerDialog()
        
      #  self.dlg.pushButton.clicked.connect(lambda: self.postRequest(self.dlg.treeWidget.currentItem().text(0)))

        self.dlg.pushButton.clicked.connect(lambda: self.callPostRequest(self.dlg.treeWidget.selectedItems()))
       
        
        self.dlg.pushButton.setEnabled(False)
       # self.dlg.treeWidget.itemClicked.connect(self.enableButton)  
        self.dlg.treeWidget.itemPressed.connect(self.enableButtonImport)
        self.dlg.treeWidget.itemClicked.connect(self.onItemClicked)
        layers = QgsProject.instance().mapLayers().values()
        
        for layer in layers:           
            if (layer.type() == QgsMapLayer.VectorLayer):
                layerType = 'vector layer'
            else:
                layerType = 'raster layer'
            item = QTreeWidgetItem([layer.name(), layerType])    
            if (layerType == 'vector layer'):
                self.dlg.treeWidget.addTopLevelItem(item)
        self.dlg.setWindowModality(Qt.ApplicationModal)

        self.dlg.pushButton_close.setStyleSheet("#pushButton_close {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_close:hover{background: #66ab27 ;}")
        self.dlg.pushButton.setStyleSheet("#pushButton {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton:hover{background: #66ab27 ;}#pushButton:disabled{background: #64818b ;}")
        self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")

        self.dlg.show()
      
        
        self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
        result = self.dlg.exec_()
    def run_login(self):
        self.dlg = ConnectionManagerDialog()
        self.dlg.show()    
        self.dlg.pushButton_Connect.setEnabled(False) 
        if (os.path.isfile(os.getenv("HOME") + os.sep + ".layman" + os.sep +'layman_user.INI')):
            config = self.loadIni()
            if len(config['DEFAULT']['login']) > 0:
                self.Agrimail = config['DEFAULT']['login']
                self.dlg.pushButton_Connect.setEnabled(True) 
            self.dlg.lineEdit_userName.setText(config['DEFAULT']['login'] + "@lesprojekt.cz")  
            try:
                self.dlg.lineEdit_AgriID.setText(config['DEFAULT']['id']) 
                self.dlg.lineEdit_server.setText(config['DEFAULT']['server']) 
                self.dlg.lineEdit_serverLayman.setText(config['DEFAULT']['layman']) 
            except:
                print("udaj v ini nenalezen")
        else:
            try:
                os.makedirs(os.getenv("HOME") + os.sep + ".layman")
            except:
                print("layman directory already exists")
            self.dlg.lineEdit_userName.setText("@lesprojekt.cz")
            self.dlg.pushButton_Connect.setEnabled(True) 
        self.dlg.pushButton_ttt.hide()

        
        self.dlg.lineEdit_userName.textChanged.connect(self.checkUsername)
        self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
        self.dlg.pushButton_Connect.clicked.connect(lambda: self.openAuthLiferayUrl())
        self.dlg.pushButton_Continue.clicked.connect(lambda: self.getToken())
        self.dlg.pushButton_Continue.setEnabled(False)       
        self.dlg.pushButton_ttt.clicked.connect(lambda: self.printVariables())
        self.dlg.pushButton_close.setStyleSheet("#pushButton_close {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_close:hover{background: #66ab27 ;}")
        self.dlg.pushButton_Connect.setStyleSheet("#pushButton_Connect {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_Connect:hover{background: #66ab27 ;}")
        self.dlg.pushButton_Continue.setStyleSheet("#pushButton_Continue {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_Continue:hover{background: #66ab27 ;} #pushButton_Continue:disabled{background: #64818b ;}")
        self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")
        result = self.dlg.exec_()
    def run_AddMapDialog(self):        
        url = self.URI+'/rest/'+self.laymanUsername+'/maps'
        print(url)
        r = requests.get(url = url)
        print(r.content)
        data = r.json()
        self.dlg = AddMapDialog()
        
        for row in range(0, len(data)):
            url = self.URI+'/rest/'+self.laymanUsername+'/maps/'+data[row]['name']+'/file'
            r = requests.get(url = url)
         #   print(r.content)
            d = r.json()
            print(d['title'])
         #   item = QTreeWidgetItem([data[row]['name'], data[row]['url'], data[row]['uuid']])           
            item = QTreeWidgetItem([d['title']])            
            self.dlg.treeWidget.addTopLevelItem(item)
        
        
      
        self.dlg.pushButton.setEnabled(False)
        self.dlg.pushButton_mapWFS.setEnabled(False)
        self.dlg.label_info.hide()
     
        self.dlg.treeWidget.itemClicked.connect(self.showThumbnailMap)
        self.dlg.treeWidget.itemClicked.connect(self.enableButton)
        self.dlg.treeWidget.itemClicked.connect(self.enableLoadMapButtons)
        

        self.dlg.pushButton.clicked.connect(lambda: self.readMapJson(self.dlg.treeWidget.selectedItems()[0].text(0), 'WMS'))
        self.dlg.pushButton_mapWFS.clicked.connect(lambda: self.readMapJson(self.dlg.treeWidget.selectedItems()[0].text(0), 'WFS'))
        

        self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())

        self.dlg.pushButton_mapWFS.setStyleSheet("#pushButton_mapWFS {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_mapWFS:hover{background: #66ab27 ;}#pushButton_mapWFS:disabled{background: #64818b ;}")
        self.dlg.pushButton.setStyleSheet("#pushButton {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton:hover{background: #66ab27 ;}#pushButton:disabled{background: #64818b ;}")
        self.dlg.pushButton_close.setStyleSheet("#pushButton_close {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_close:hover{background: #66ab27 ;}#pushButton_close:disabled{background: #64818b ;}")
        self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")

        self.dlg.show()
        result = self.dlg.exec_()
    def run_AddLayerDialog(self):
        if not self.loadedInMemory:
            self.loadAllComposites()
        url = self.URI+'/rest/'+self.laymanUsername+'/layers'
        r = requests.get(url = url)
        data = r.json()
        self.dlg = AddLayerDialog()
        self.dlg.pushButton_layerRedirect.hide()
        self.dlg.pushButton_layerRedirect.setEnabled(False)
        self.dlg.pushButton.setEnabled(False)
        self.dlg.pushButton_wfs.setEnabled(False)
        self.dlg.pushButton_delete.setEnabled(False)
        
        for row in range(0, len(data)):            
            item = QTreeWidgetItem([self.getLayerTitle(data[row]['name'])])
            self.dlg.treeWidget.addTopLevelItem(item)
        self.dlg.pushButton_delete.clicked.connect(lambda: self.layerDelete(self.dlg.treeWidget.selectedItems()[0].text(0)))    
        self.dlg.pushButton_layerRedirect.clicked.connect(lambda: self.layerInfoRedirect(self.dlg.treeWidget.selectedItems()[0].text(0)))
        self.dlg.pushButton.clicked.connect(lambda: self.readLayerJson(self.dlg.treeWidget.selectedItems()[0].text(0), "WMS"))
        self.dlg.pushButton_wfs.clicked.connect(lambda: self.readLayerJson(self.dlg.treeWidget.selectedItems()[0].text(0), "WFS"))
        self.dlg.treeWidget.itemClicked.connect(self.showThumbnail)  
        self.dlg.treeWidget.itemClicked.connect(self.enableDeleteButton) 
        self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
        self.dlg.setWindowModality(Qt.ApplicationModal)

        self.dlg.pushButton_delete.setStyleSheet("#pushButton_delete {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_delete:hover{background: #66ab27 ;}#pushButton_delete:disabled{background: #64818b ;}")
        self.dlg.pushButton_close.setStyleSheet("#pushButton_close {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_close:hover{background: #66ab27 ;}#pushButton_close:disabled{background: #64818b ;}")
        self.dlg.pushButton_delete.setStyleSheet("#pushButton_delete {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_delete:hover{background: #66ab27 ;}#pushButton_delete:disabled{background: #64818b ;}")
        self.dlg.pushButton.setStyleSheet("#pushButton {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton:hover{background: #66ab27 ;}#pushButton:disabled{background: #64818b ;}")
        self.dlg.pushButton_wfs.setStyleSheet("#pushButton_wfs {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_wfs:hover{background: #66ab27 ;}#pushButton_wfs:disabled{background: #64818b ;}")
        self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")


        self.dlg.show()
        result = self.dlg.exec_()
    def showExistingLayers(self,x):
 
        self.dlg.listWidget_listLayers.clear()    
        for i in range (0,len(self.compositeList[self.dlg.listWidget.currentRow()]['layers'])):         
               
            self.dlg.listWidget_listLayers.addItem(self.compositeList[self.dlg.listWidget.currentRow()]['layers'][i]['params']['LAYERS'])
    #--------------------------- slots---------------------
   # @QtCore.pyqtSlot(QtWidgets.QTreeWidgetItem, int)
    def onItemClicked(self, it, col):     
        if (it.text(1) == 'raster layer'):
            self.dlg.pushButton.setEnabled(False)
        else:
            self.dlg.pushButton.setEnabled(True)
    def setExtent(self, it, col):
        layer = QgsProject.instance().mapLayersByName(it.text(0))
        ext = layer[0].extent()
        xmin = ext.xMinimum()
        xmax = ext.xMaximum()
        ymin = ext.yMinimum()
        ymax = ext.yMaximum()
        self.dlg.lineEdit_3.setText(str(xmin))
        self.dlg.lineEdit_4.setText(str(xmax))
        self.dlg.lineEdit_5.setText(str(ymin))
        self.dlg.lineEdit_6.setText(str(ymax))
        self.dlg.label_4.setText("Extent of canvas: " + it.text(0))

    def enableDeleteButton(self, item, col):
        self.dlg.pushButton.setEnabled(True)
        self.dlg.pushButton_wfs.setEnabled(True)
        self.dlg.pushButton_layerRedirect.setEnabled(True)
        self.dlg.pushButton_delete.setEnabled(True)

    def enableButton(self, item, col):
        
        
        self.dlg.pushButton.setEnabled(True)
        self.dlg.pushButton_mapWFS.setEnabled(True)
        self.dlg.pushButton_deleteLayers.setEnabled(True)
        self.dlg.pushButton_editMeta.setEnabled(True)
        self.dlg.pushButton_addRaster.setEnabled(True)       

            

    def checkUsername(self, name):
        n = name.split("@")
        if(len(n[0]) > 0):
            self.dlg.pushButton_Connect.setEnabled(True) 
            self.Agrimail = n[0]
        else:
            self.dlg.pushButton_Connect.setEnabled(False) 

        
    def checkLoadedMap(self, name):
        print(self.compositeList)
        loaded = False
        for i in range (0, len(self.compositeList)):
            if self.compositeList[i]['name'] == name:
                loaded = True
            
        return loaded 
                   
        
    def logout(self):
        self.menu_saveLocalFile.setEnabled(False)
        self.menu_loadJson.setEnabled(False)
        self.menu_ImportLayerDialog.setEnabled(False)
        self.menu_AddLayerDialog.setEnabled(False) 
        self.menu_AddMapDialog.setEnabled(False)       
        self.menu_ImportLayerDialog.setEnabled(False)
        self.menu_ImportMapDialog.setEnabled(False)    
        self.menu_UserInfoDialog.setEnabled(False)
        self.textbox.setText("Layman")
        self.dlg.close()
       # self.flaskThread.join()
       # self.thread1.join() ## ukončujeme vlákno, které se stará o refresh tokenů OAUTH

    def enableLoadMapButtons(self, item):
        self.dlg.pushButton_mapWFS.setEnabled(True)
    def enableButtonImport(self, item, column):
        if (len(self.dlg.treeWidget.selectedItems()) > 0):
            self.dlg.pushButton.setEnabled(True)
        else:
            self.dlg.pushButton.setEnabled(False)


    def enableButton(self, item):
        try: ## addMap nemá combobox
            if (self.dlg.mMapLayerComboBox.count() > 0):
                self.dlg.pushButton.setEnabled(True) 
                self.dlg.pushButton_mapWFS.setEnabled(True)
            else:
                self.dlg.pushButton.setEnabled(False)
        except:
            self.dlg.pushButton.setEnabled(True) ## addMap nemá combobox nastavujeme funkční tlačítko

        try:
            self.dlg.pushButton_deleteLayers.setEnabled(True) # pro formulář importMap
        except:
            pass
    def listCompositeLayers(self, it):    
         self.dlg.listWidget_listLayers2.clear()    
         for i in range (0,len(self.compositeList[self.dlg.listWidget.currentRow()]['layers'])):    
            
            self.dlg.listWidget_listLayers2.addItem(self.compositeList[self.dlg.listWidget.currentRow()]['layers'][i]['params']['LAYERS'])
    def deleteLayerThrowCompositions(self, name):
        for x in range (0,len(self.compositeList)):
           
            for i in range (0,len(self.compositeList[x]['layers'])): 
                if (name == self.compositeList[x]['layers'][i]['params']['LAYERS']):
                    inComposite = True
                    print(self.compositeList[x]['layers'][i]['params']['LAYERS'])
                    self.deteteLayerFromComposite(x, i, name)
    def checkLayersInComopsitions(self, name):
        inComposite = False
        for x in range (0,len(self.compositeList)):
           
            for i in range (0,len(self.compositeList[x]['layers'])): 
                if (name == self.compositeList[x]['layers'][i]['params']['LAYERS']):
                    inComposite = True
                    print(self.compositeList[x]['layers'][i]['params']['LAYERS'])
        return inComposite


    def refreshCompositeList(self):
        self.dlg.listWidget.clear()
        print (len(self.compositeList))
        
        for i in range (0, len(self.compositeList)):
           # self.dlg.listWidget.addItem(self.compositeList[i]['name'])
           self.dlg.listWidget.addItem(self.compositeList[i]['title'])
 

    def refreshLayerList(self):
        self.dlg.listWidget_listLayers.clear()
        for i in range (0,len(self.compositeList[self.dlg.listWidget.currentRow()]['layers'])):
            self.dlg.listWidget_listLayers.addItem(self.compositeList[self.dlg.listWidget.currentRow()]['layers'][i]['params']['LAYERS'])
            print(self.compositeList[self.dlg.listWidget.currentRow()]['layers'][i]['params']['LAYERS'])



    def refreshListWidgetMaps(self):
        self.dlg.treeWidget.clear()
        url = self.URI+'/rest/'+self.laymanUsername+'/maps'
        print(url)
        r = requests.get(url = url)
        #print(r.content())
        data = r.json()  
       
        for row in range(0, len(data)):                
            item = QTreeWidgetItem([data[row]['name']])           
            self.dlg.treeWidget.addTopLevelItem(item)

    def showAddMapDialog(self):
        self.old_dlg = self.dlg
        self.run_CreateCompositeDialog(True)      
        
       
    ### connect
    def afterCloseCompositeDialog(self):        
        self.dlg = self.old_dlg
        self.refreshCompositeList()

    def afterCloseEditMapDialog(self):
        self.dlg = self.old_dlg

    def showEditMapDialog(self, x):        
        self.old_dlg = self.dlg
        self.run_EditMap(x)
            ############### pravdepodobne půjde smazat
    def refreshItems(self):
  
         self.dlg.listWidget_listLayers.clear()    
         for i in range (0,len(self.compositeList)):            
           # self.dlg.listWidget_listLayers.addItem(self.compositeList[i]['name'])
           self.dlg.listWidget_listLayers.addItem(self.compositeList[i]['title'])

    def saveEditedToComposite(self,x):        
        self.compositeList[x]['abstract'] =  self.dlg.lineEdit_abstract.text()  
        self.compositeList[x]['title'] =  self.dlg.lineEdit_title.text() 

    def layerDelete(self, name):
        if (self.checkLayersInComopsitions(name) == True):
            msgbox = QMessageBox(QMessageBox.Question, "Delete layer", "This layers is included in other compositions. It will be delete from every composition.")
            msgbox.addButton(QMessageBox.Yes)
            msgbox.addButton(QMessageBox.No)
            msgbox.setDefaultButton(QMessageBox.No)
            reply = msgbox.exec()
            if (reply == QMessageBox.Yes):
                url = self.URI+'/rest/'+self.laymanUsername+'/layers/'+name    
                response = requests.delete(url, headers = self.authHeader)
                print(response.content)
                print(response)
                self.addLayerRefresh()
                try:
                    self.deleteLayerThrowCompositions(name)
                except:
                    pass
                
        else:    
            url = self.URI+'/rest/'+self.laymanUsername+'/layers/'+name    
            response = requests.delete(url, headers = self.authHeader)
            print(response.content)
            print(response)
            self.addLayerRefresh()
    def addLayerRefresh(self):
        self.dlg.treeWidget.clear()
        url = self.URI+'/rest/'+self.laymanUsername+'/layers'
        r = requests.get(url = url)
        data = r.json()
        for row in range(0, len(data)):            
            item = QTreeWidgetItem([data[row]['name']])
            self.dlg.treeWidget.addTopLevelItem(item)
    def checkIfMapExist(self, name):
        url = "http://layman.lesprojekt.cz/rest/"+self.laymanUsername+"/maps/"+str(name)+"/file"
        print(url)
        r = requests.get(url)
        print(r.content)
        if (r.status_code == 404):
            return False
        else:
            return True

    def reorderLayers(self, pos, order, x):
        self.compositeList[x]['layers']
        i = 0
        compositeLength = len(self.compositeList[x]['layers'])
       
        if (pos + order < 0):
            QMessageBox.information(None, "Error", "Layer is already on the top level!")
            
        elif( pos + order == compositeLength):
            QMessageBox.information(None, "Error", "Layer is already on the bottom level!")

        else:
            for lay in self.compositeList[x]['layers']:
                #print (lay)
                if i == pos:

                    pom = self.compositeList[x]['layers'][i]
                    self.compositeList[x]['layers'][i] = self.compositeList[x]['layers'][i + order]
                    self.compositeList[x]['layers'][i + order] = pom     

                i = i + 1
            print(self.compositeList[x]['layers'])
            self.importMap(x, 'mod')
            self.refreshLayerList()
            self.dlg.listWidget_listLayers.setCurrentRow(pos + order)

    def showThumbnail(self, it):
        try:
            layer = it.text(0) ##pro QTreeWidget
        except:
            layer = it.text()##pro listWidget
        try:
            url = self.URI+'/rest/' +self.laymanUsername+'/layers/'+str(layer).lower()+'/thumbnail'    
            data = urlopen(url).read()
            pixmap = QPixmap(200, 200)
            pixmap.loadFromData(data)
            smaller_pixmap = pixmap.scaled(200, 200, Qt.KeepAspectRatio, Qt.FastTransformation)
            self.dlg.label_thumbnail.setPixmap(smaller_pixmap)
            self.dlg.label_thumbnail.setAlignment(Qt.AlignCenter)
        except:
            self.dlg.label_thumbnail.setText('  Unable to load thumbnail.')
    def showSmallThumbnail(self, it):
        try:
            layer = it.text(0) ##pro QTreeWidget
        except:
            layer = it.text()##pro listWidget
        try:
            url = self.URI+'/rest/'+self.laymanUsername+'/layers/'+str(layer).lower()+'/thumbnail'    
            data = urlopen(url).read()
            pixmap = QPixmap(170, 170)
            pixmap.loadFromData(data)
            smaller_pixmap = pixmap.scaled(170, 170, Qt.KeepAspectRatio, Qt.FastTransformation)
            self.dlg.label_thumbnail.setPixmap(smaller_pixmap)
            self.dlg.label_thumbnail.setAlignment(Qt.AlignCenter)
        except:
            self.dlg.label_thumbnail.setText('  Unable to load thumbnail.')

    def showThumbnailMap(self, it):
        try:
            map = it.text(0) ##pro QTreeWidget
        except:
            map = it.text()##pro listWidget
        
        try:
            map = self.removeUnacceptableChars(str(map))
            url = self.URI+'/rest/'+self.laymanUsername+'/maps/'+str(map).lower()+'/thumbnail'    
            print(url)
            data = urlopen(url).read()
            pixmap = QPixmap(100, 100)
            pixmap.loadFromData(data)
            smaller_pixmap = pixmap.scaled(100, 100, Qt.KeepAspectRatio, Qt.FastTransformation)
            self.dlg.label_thumbnail.setPixmap(smaller_pixmap)
           # self.dlg.label_thumbnail.setAlignment(Qt.AlignCenter)
        except:
            self.dlg.label_thumbnail.setText('       Unable to load thumbnail.')

    def checkNameCreateMap(self):
        text = self.dlg.lineEdit_2.text()
        text = self.removeUnacceptableChars(text)
        print(text)
        if (self.checkIfMapExist(text)):
            self.dlg.pushButton_CreateComposition.setEnabled(False)
            self.dlg.label_info.show()
            
        else:
            self.dlg.pushButton_CreateComposition.setEnabled(True)
            self.dlg.label_info.hide()
    #----------------------------------------------------------
    def readLayerJson(self,layerName, service):
        if self.checkLayerOnLayman(layerName):
            layerNameTitle =layerName
            layerName = self.removeUnacceptableChars(layerName)
            url = self.URI+'/rest/'+self.laymanUsername+'/layers/'+layerName  
            print (url)
            r = requests.get(url = url)
            data = r.json()
            if (service == "WMS"):
                print("loading WMS")
                print (data['wms']['url'])
                wmsUrl = data['wms']['url']
                format = 'png'
                epsg = 'EPSG:4326' 
                self.loadWms(wmsUrl, layerName,layerNameTitle, format, epsg) 
            if (service == "WFS"):
                wfsUrl = data['wfs']['url']
                print("loading WFS")
                self.loadWfs(wfsUrl, layerName, layerNameTitle) 
        else:
            QMessageBox.information(None, "Layman", "Something went wrong with this layer: "+layerName)
    def loadAllComposites(self):
        url = self.URI+'/rest/' + self.laymanUsername + '/maps'
        try:
            r = requests.get(url = url)
        except:
            QMessageBox.information(None, "Error", "Connection with server failed!.")
        data = r.json()  
        print(data)
        for i in data:
            print(i['name'])
            url = self.URI+'/rest/' + self.laymanUsername + '/maps/'+i['name']+'/file'  
            r = requests.get(url = url)
            map = r.json()
            self.compositeList.append (map)
        self.loadedInMemory = True

    def readMapJson(self,name, service):
        nameWithDiacritics = name        
        name = self.removeUnacceptableChars(name)
        print(name)
        print("readMapJson " + name)
        if not self.checkLoadedMap(name): ## je nactena mapa?
            url = self.URI+'/rest/'+self.laymanUsername+'/maps/'+name   +'/file'     
            r = requests.get(url = url)
            data = r.json()   
            print(data)
        
            self.addComposite(data,service, name)
            try:
                self.refreshCompositeList()        ## pouze pro import Form     
            except:
                pass
        else:
            url = self.URI+'/rest/'+self.laymanUsername+'/maps/'+name   +'/file'     
            r = requests.get(url = url)
            data = r.json()
            self.loadService(data,service, name)

        #    QMessageBox.information(None, "Message", "This map is already loaded in memory. Loading only layers to canvas")
    

    def deleteMapFromServer(self,name):        
        
        url = self.URI+'/rest/'+self.laymanUsername+'/maps/'+name    
        response = requests.delete(url, headers = self.authHeader)
        print(response)
        QMessageBox.information(None, "Message", "Composition deleted sucessfully.")
       # self.refreshMapList()            
        self.refreshListWidgetMaps() ## pro treewidget
        
      
    def deleteMap(self,name, x):      
        name = self.removeUnacceptableChars(name)
        url = self.URI+'/rest/'+self.laymanUsername+'/maps/'+name    
        response = requests.delete(url, headers = self.authHeader)
        print(response)
        print(response.content)
        QMessageBox.information(None, "Message", "Composition deleted sucessfully.")
        del (self.compositeList[x])        
        self.refreshCompositeList()## pro import map form
        self.dlg.listWidget_listLayers.clear()
      
        
        
      
    def deleteMapandLayers(self,name, x):        
        try:
            url = self.URI+'/rest/'+self.laymanUsername+'/maps/'+name    
            response = requests.delete(url, headers = self.authHeader)
            QMessageBox.information(None, "Message", "Composition deleted sucessfully.")
            
            
      
        except:
            QMessageBox.information(None, "Warning", "Deleting composition failed.")
        #self.refreshItems()
        self.deleteMapFromCanvas(x)
        self.dlg.listWidget_listLayers.clear()
        self.dlg.pushButton_deleteLayers.setEnabled(False)
        self.dlg.pushButton.setEnabled(False)
        self.dlg.pushButton_deleteMap.setEnabled(False)
        self.refreshCompositeList()

    def deleteMapFromCanvas(self, x):
        for i in range (0,len(self.compositeList[x]['layers'])):  #[0]['params']['LAYERS']:
            name = self.compositeList[x]['layers'][i]['params']['LAYERS']
            lay = QgsProject.instance().mapLayersByName(name)[0]
            if (lay != None and lay.type() != QgsMapLayer.VectorLayer):
                QgsProject.instance().removeMapLayer(lay.id())
        del (self.compositeList[x])

    def deleteLayerFromCanvas(self, name):        
        lay = QgsProject.instance().mapLayersByName(name)[0]        
        if (lay != None and lay.type() != QgsMapLayer.VectorLayer):
            QgsProject.instance().removeMapLayer(lay.id())
        
        
    def getSelectedLayers(self):
        arr = self.dlg.listWidget_listLayers2.selectedItems()
        layers = []
        for a in arr:
            layer = QgsProject.instance().mapLayersByName(a.text())
            for lay in layer:

                if (lay.type() == QgsMapLayer.VectorLayer):
                    layers.append(lay)
            
        return layers
    def run_getLayer(self):
        """Run method that performs all the real work"""

        # Create the dialog with elements (after translation) and keep reference
        # Only create GUI ONCE in callback, so that it will only load when the plugin is started
        if self.first_start == True:
            self.first_start = False
            
            
        self.dlgGetLayers.items.clear()
        # show the dialog
        self.dlgGetLayers.show()
        data= self.getExistingLayers()
        for x in range(len(data)):
            print(data[x]['name'])
            self.dlgGetLayers.items.addItem(data[x]['name'])
        # Run the dialog event loop
        print (self.dlgGetLayers)
        result = self.dlgGetLayers.exec_()
       
        
        # See if OK was pressed
        if result:
            # Do something useful here - delete the line containing pass and
            # substitute with your code.
           
            print ("test tlacitka")
   
    def onClosePlugin(self):
        """Cleanup necessary items here when plugin dockwidget is closed"""

        #print "** CLOSING Atlas"

        # disconnects
        self.dockwidget.closingPlugin.disconnect(self.onClosePlugin)

        self.flaskThread.terminate() ## killing daemons
        self.thread1.terminate()
        self.pluginIsActive = False


    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""

        #print "** UNLOAD Atlas"

        for action in self.actions:
            self.iface.removePluginMenu(
                self.tr(u'&Atlas'),
                action)
            self.iface.removeToolBarIcon(action)
        # remove the toolbar
        del self.toolbar

    #--------------------------------------------------------------------------
    def bounds(self, layers):

        extent = None
        for layer in layers:
            if layer.type() == 0:
                transform = QgsCoordinateTransform(layer.crs(), QgsCoordinateReferenceSystem('EPSG:4326'), QgsProject.instance()) # WGS 84 / UTM zone 33N
                try:
                    layerExtent = transform.transform(layer.extent())
                except QgsCsException:
                    print("exception in transform layer srs")
                    layerExtent = QgsRectangle(-180, -90, 180, 90)
                if extent is None:
                    extent = layerExtent
                else:
                    extent.combineExtentWith(layerExtent)

        return (extent.xMinimum(), extent.yMinimum(), extent.xMaximum(), extent.yMaximum())
    def copySymbols(self,symbol, tempPath, fileNames):
        for i in range(symbol.symbolLayerCount()):
            sl = symbol.symbolLayer(i)
            if isinstance(sl, QgsSvgMarkerSymbolLayer):
                symbolPath = sl.path();
                shutil.copy(symbolPath, tempPath)
                print("Copying " + str(sl.path()))
                fileNames.append(tempPath + os.sep + os.path.basename(symbolPath))
            else:
                print("Ignoring " + str(sl))

    def setDefaultExtent (self, ext):        
        self.dlg.lineEdit_3.setText(str(ext.xMinimum()))
        self.dlg.lineEdit_4.setText(str(ext.xMaximum()))
        self.dlg.lineEdit_5.setText(str(ext.yMinimum()))
        self.dlg.lineEdit_6.setText(str(ext.yMaximum()))


    def loadJsonLayer(self, fileName):    
        name = (os.path.splitext(os.path.basename(fileName))[0])
        vlayer = QgsVectorLayer(fileName, name,"ogr")
        sldPath = os.path.splitext(fileName[:-4])[0] + ".sld"
        qmlPath = os.path.splitext(fileName[:-4])[0] + ".qml"
        print (sldPath)
        sldExists = os.path.isfile(sldPath)
        qmlExists = os.path.isfile(qmlPath)
        if (qmlExists):
            print("qml loaded")
            vlayer.loadNamedStyle(qmlPath)
        elif (sldExists):
            vlayer.loadSldStyle(os.path.splitext(fileName)[0]+ ".sld")
            print("sld loaded")
        QgsProject.instance().addMapLayer(vlayer)
        vlayer.triggerRepaint()
    def checkLoadedLayer(self):
        layers = iface.layerTreeView().selectedLayers()
        if (len(layers) > 0):
            self.json_export()    
        else:
            QMessageBox.information(None, "Message", "You must load layer first!")
    def getEmptyComposite(self, compositeName, compositeTitle):        
        compositeEPSG  = "epsg:4326"        
        if (self.dlg.lineEdit_3.text() == "" or self.dlg.lineEdit_4.text() == "" or self.dlg.lineEdit_5.text() == "" or self.dlg.lineEdit_6.text() == ""):
           ext = iface.mapCanvas().extent() 
           xmin = ext.xMinimum()
           xmax = ext.xMaximum()
           ymin = ext.yMinimum()
           ymax = ext.yMaximum()
        else:   
           xmin = self.dlg.lineEdit_3.text()
           xmax = self.dlg.lineEdit_4.text()
           ymin = self.dlg.lineEdit_5.text()
           ymax = self.dlg.lineEdit_6.text() 
        
            
        abstract = self.dlg.lineEdit_7.text()        
        comp = {"abstract":abstract,"center":[1672068,6568819],"current_base_layer":{"title":"Composite_base_layer"},"extent":[str(xmin),str(ymin),str(xmax),str(ymax)],"groups":{"guest":"w"},"layers":[],"name":compositeName,"projection":compositeEPSG,"scale":1,"title":compositeTitle,"units":"m","user":{"email":"","name":self.laymanUsername}}
        self.dlg.close()
        iface.messageBar().pushWidget(iface.messageBar().createMessage("Atlas:", " Kompozice  " + compositeName + " byla úspešně vytvořena."), Qgis.Success, duration=3)
        return comp
    def loadLocalFile(self):
        options = QFileDialog.Options()
        dialog = QFileDialog()
        dialog.setStyleSheet("QPushButton {color: #fff !important;text-transform: uppercase;  text-decoration: none;   background: #72c02c;   padding: 20px;  border-radius: 50px;    display: inline-block; border: none;transition: all 0.4s ease 0s;} QPushButton:hover{background: #66ab27 ;}QPushButton:disabled{background: #64818b ;}");
        fileName = dialog.getOpenFileName(None,"Load file", "","GeoJson Files (*.geojson);;Json Files (*.json)", options=options)
        print ("načítám json ze souboru:" + fileName[0])
        self.loadJsonLayer(fileName[0])
    def modifyMap(self, x):        
        name = self.removeUnacceptableChars(self.dlg.lineEdit_title.text())
        #self.compositeList[x]['name'] = self.dlg.lineEdit_name.text()
        self.compositeList[x]['name'] = name
        self.compositeList[x]['abstract'] = self.dlg.lineEdit_abstract.text()
        self.compositeList[x]['title'] = self.dlg.lineEdit_title.text()
        self.compositeList[x]['extent'][0] = self.dlg.lineEdit_xmin.text()
        self.compositeList[x]['extent'][2] = self.dlg.lineEdit_xmax.text()
        self.compositeList[x]['extent'][1] = self.dlg.lineEdit_ymin.text()
        self.compositeList[x]['extent'][3] = self.dlg.lineEdit_ymax.text()
        print(self.compositeList[x]['extent'])
        
        print(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'])       
        oldName = self.dlg.lineEdit_name.text()
        response = requests.delete(self.URI+'/rest/'+self.laymanUsername+'/maps/'+oldName,headers = self.authHeader)
        print(response.content)
        self.dlg.close()
        self.afterCloseEditMapDialog()
        self.importMap(x, 'mod')
        
        try:
            self.refreshCompositeList()
            iface.messageBar().pushWidget(iface.messageBar().createMessage("Import:", " Map metadata was saved successfully."), Qgis.Success, duration=3)
        except:
            pass
        
        
    def saveLocalFile(self):
        
        layer = self.iface.activeLayer() 
        path = iface.activeLayer().dataProvider().dataSourceUri()
        path = path.split("|")[0].replace("'","")
        if (layer == None):
            QMessageBox.information(None, "Message", "You must load layer first!")
        else:
           # defaultDir = QDir().home()
            defaultDir = os.path.dirname(path)
            print(defaultDir)
            print(defaultDir +os.sep+ str(layer.name()) + ".geojson")
            print(QDir().homePath() +os.sep+ str(layer.name()) + ".geojson")
            dialog = QFileDialog()
            dialog.setFileMode(1)
            dialog.setDirectory(defaultDir)
            print(dialog.directory().path())
           # layer_name = dialog.getSaveFileName(None, "Save file", QDir().homePath() +os.sep+ str(layer.name()) + ".geojson", "*.geojson")        
            layer_name = dialog.getSaveFileName(None, "Save file", defaultDir +os.sep+ str(layer.name()) + ".geojson", "*.geojson")        
            self.json_export_local(layer_name[0], layer)

    def json_export_local(self, layer_name, lay):     
        import shutil
        filePath = self.getTempPath(layer_name)  
        ogr_driver_name = "GeoJSON" 
        project = QgsProject.instance()
        fileNames = []
        ## zde musí být zajištěna vektorová vrstva
        layer = lay        
        layerType = layer.type()
        if layerType == QgsMapLayer.VectorLayer:

            renderer = layer.renderer()
            hasIcon = False
            if isinstance(renderer, QgsSingleSymbolRenderer):

                self.copySymbols(renderer.symbol(), tempfile.gettempdir(), fileNames)
                hasIcon = True


            layerCrs = qgis.utils.iface.activeLayer().crs().authid()
            crs = QgsCoordinateReferenceSystem(layerCrs)          
            result2 = qgis.core.QgsVectorFileWriter.writeAsVectorFormat(layer, layer_name, "utf-8", crs, ogr_driver_name) # export jsonu do souboru
            print(result2)
            if(result2[0] == 2): ## testujeme zda není soubor otevřený v jiném procesu / návratový kod 2
                
                tempFile = self.getTempPath(os.path.basename(layer_name.replace(".geojson", "") ))
                print(tempFile)
                #QMessageBox.information(None, "Layman", "It is not possible overwrite this file. File is already open in other process.")  
                sld_temp_filename = tempFile.replace("geojson", "sld") 
                qml_temp_filename = tempFile.replace("geojson", "qml")
                layer.saveSldStyle(sld_temp_filename)
                layer.saveNamedStyle(qml_temp_filename)
                result2 = qgis.core.QgsVectorFileWriter.writeAsVectorFormat(layer, tempFile, "utf-8", crs, ogr_driver_name)
                print(result2)
                if(result2[0] == 2):
                    QMessageBox.information(None, "Layman", "It is not possible overwrite this file. File is already open in other process.")  
                    return
                if os.path.basename(layer_name.replace(".geojson", "")) != '':
                    QgsProject.instance().removeMapLayer(layer.id())
                    print(tempFile, layer_name)
                    shutil.copy(tempFile, layer_name)
                    shutil.copy(sld_temp_filename, layer_name.replace(".geojson", ".sld"))
                    shutil.copy(qml_temp_filename, layer_name.replace(".geojson", ".qml"))
                    self.loadJsonLayer(layer_name)
                
            else:                
                sld_filename = layer_name.replace("geojson", "sld")     
                qml_filename = layer_name.replace("geojson", "qml") 
                result3 = False
                layer.saveSldStyle(sld_filename)
                layer.saveNamedStyle(qml_filename)

    def json_export(self, layer_name):     

        filePath = self.getTempPath(layer_name.lower())  
        ogr_driver_name = "GeoJSON"     
        project = QgsProject.instance()
        fileNames = []      
        layer = QgsProject.instance().mapLayersByName(layer_name)[0]       
        
        layerType = layer.type()
        if layerType == QgsMapLayer.VectorLayer:

            renderer = layer.renderer()
            hasIcon = False
            if isinstance(renderer, QgsSingleSymbolRenderer):

                self.copySymbols(renderer.symbol(), tempfile.gettempdir(), fileNames)
                hasIcon = True


            #layerCrs = qgis.utils.iface.activeLayer().crs().authid()
            layerCrs = layer.crs().authid()
            crs = QgsCoordinateReferenceSystem(layerCrs)# původně bylo
            layer_filename = filePath       
          #  crs = QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
            ##crs = layer.crs().authid()
         #   tempOut = layer_filename.replace(".geojson", "_2.geojson") 
            result2 = qgis.core.QgsVectorFileWriter.writeAsVectorFormat(layer, layer_filename, "utf-8", crs, ogr_driver_name) # export jsonu do souboru
            ##transformace
        #    input = tempOut
        #    out = layer_filename
        #    try:
        #        os.remove(layer_filename)
        #    except:
        #        pass
        ##    print("","-f", "Geojson", "-s_srs", layerCrs, "-t_srs", "epsg:4326", out, input)
        #    print("convert")
        #    print(main(["","-f", ogr_driver_name, "-s_srs", "EPSG:5514", "-t_srs", "EPSG:4326", out, input])) ## ogr2ogr
            ##
            sld_filename = filePath.replace("geojson", "sld").lower()            
            result3 = False
            layer.saveSldStyle(sld_filename)


    def checkValidAttributes(self, layer_name):
        layers = QgsProject.instance().mapLayersByName(layer_name)
        if len(layers) > 1:
            for l in layers:
                if (isinstance(l, QgsVectorLayer)):
                    print("xxx")
                    layers.clear()
                    layers.append(l)
                    break
        isValid = True
        pom =layers[0].getFeature(1)        
        for nam in pom.fields().names():
            if (nam == ''):
                isValid = False
        return isValid


    def checkWgsExtent(self, layer):
        WgsXmax = 180
        WgsXmin = -180
        WgsYmax = 90
        WgsYmin = -90
        extent = layer.extent()
        if (extent.xMaximum() > WgsXmax or extent.xMinimum() < WgsXmin or extent.yMaximum() > WgsYmax or extent.yMinimum() < WgsYmin ):
            return False
        else:
            return True


    def callPostRequest(self, layers):
        
        for item in layers:
            print (item.text(0))
            
            
                

            self.postRequest(item.text(0))
    #def transformLayer2(self, layer):
    #    pass
    def setCurrentLayer(name):
        layers = QgsProject.instance().mapLayersByName(name) 
        if(len(layers) >1):
            layerss = QgsProject.instance().mapLayers().values()    
            i = 0
            for layer in layerss:  
                if layers[0].name == layer.name():
                    if (i == item.currentIndex()):
                        i = i + 1
                        break
                    i = i + 1
        return i
    def transformLayer(self, layer):
        layer = iface.activeLayer()
        crsSrc = layer.crs()
        print(crsSrc.authid())
        crsDest = QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
        print(crsSrc, crsDest)
        xform = QgsCoordinateTransform(crsSrc, crsDest, 5514, 4326)
        feats=[]

        if (layer.geometryType() == 0):
            destLayer = QgsVectorLayer("Point?crs=EPSG:4326","lay","memory")
        if (layer.geometryType() == 1):
            destLayer = QgsVectorLayer("Linestring?crs=EPSG:4326","lay","memory")
        if (layer.geometryType() == 2):
            destLayer = QgsVectorLayer("Polygon?crs=EPSG:4326","lay","memory")

        for f in layer.getFeatures():
            g = f.geometry()
    
            g.transform(xform)
            print(g)
            f.setGeometry(g)
            feats.append(f)
    
        destLayer.dataProvider().addFeatures(feats)
        return destLayer
    def postRequest(self, layer_name):     
        nameCheck = True
        validExtent = True
        layers = QgsProject.instance().mapLayersByName(layer_name)  
       # layer_name = self.removeUnacceptableChars(layer_name)
        layers[0].setName(layer_name)
        if len(layers) > 1:
            for l in layers:
                if (isinstance(l, QgsVectorLayer)):                   
                    layers.clear()
                    layers.append(l)
                    break
     
        #if not (re.match('[a-zA-Z_]{1}', layer_name)): ## nesmí být nesmysl v názvu na prvním místě
        #    QMessageBox.information(None, "Layman", "Diacritics or number in first character is not allowed.")
        #    nameCheck = False
        #if not (re.match('[a-zA-Z0-9]', layer_name)): ## není povolena diakritika
        #    QMessageBox.information(None, "Layman", "Diacritics is not allowed.")
        #    nameCheck = False
        if (re.match('[0-9]{1}', layer_name)): ## nesmí být nesmysl v názvu na prvním místě
            QMessageBox.information(None, "Layman", "Number in first character is not allowed.")
            nameCheck = False
        
        print(layer_name)
        #if (layers[0].crs().authid() != 'EPSG:4323'):
        #    layers[0] = self.transformLayer(layers[0]) 

        if not self.checkWgsExtent(layers[0]):
            QMessageBox.information(None, "Layman", "Extent of layer is out of WGS 84 range. (EPSG: 4326)")
            validExtent = False

        if (nameCheck and validExtent):
                     
            crs = layers[0].crs().authid()
            crs = "EPSG:4326"
            data = { 'name' :  str(layer_name).lower(), 'title' : str(layer_name), 'crs' : str(crs) } 
            
            if (self.checkValidAttributes(layer_name)):
                if (self.checkExistingLayer(layer_name)):
                    print("vrstva již existuje")
                    msgbox = QMessageBox(QMessageBox.Question, "Layman", "Layer "+layer_name+" already exists in server. Do you want overwrite it´s geometry?")
                    msgbox.addButton(QMessageBox.Yes)
                    msgbox.addButton(QMessageBox.No)
                    msgbox.setDefaultButton(QMessageBox.No)
                    reply = msgbox.exec()
                    if (reply == QMessageBox.Yes):
                        print("vrstva již existuje")
                        self.json_export(layer_name)
                        geoPath = self.getTempPath(layer_name)
                        #try:
                        if (os.path.getsize(geoPath) > self.CHUNK_SIZE):
                            self.postInChunks(layer_name, "patch")
                           # iface.messageBar().pushWidget(iface.messageBar().createMessage("Import:", " Layer  " + layer_name + " was imported successfully."), Qgis.Success, duration=3)
                        else:
                            self.patchLayer(layer_name, data)
                            iface.messageBar().pushWidget(iface.messageBar().createMessage("Import:", " Layer  " + layer_name + " was imported successfully."), Qgis.Success, duration=3)
                        #except:
                        #    iface.messageBar().pushWidget(iface.messageBar().createMessage("Import:", " Layer  " + layer_name + " was not imported successfully."), Qgis.Warning, duration=3)
                    else:
                        pass
                else:
            
                    self.layerName = layer_name
                   # if (self.checkEpsg(layer_name)):
                    if(True): ##Pravděpodobně nebude třeba testovat EPSG, pokud se detekuje, je vrstva transformována. 
                      #  print (layer_name)
                        self.json_export(layer_name)
                        sldPath = self.getTempPath(self.layerName).replace("geojson", "sld")
                        geoPath = self.getTempPath(self.layerName)
                        if (os.path.getsize(geoPath) > self.CHUNK_SIZE):
                            self.postInChunks(layer_name, "post")
                        else:
                            if(os.path.isfile(sldPath)): ## existuje sld?
                                files = [('file', open(geoPath, 'rb')), ('sld', open(sldPath, 'rb'))]
                            else:
                                files = {'file': (geoPath, open(geoPath, 'rb')),} 

                            print(files)
                            response = requests.post(self.URI+'/rest/'+self.laymanUsername+'/layers', files=files, data = data, headers = self.authHeader)
                            print(response.content)
                            print(response.status_code)
                            if response.status_code == 200:
                                iface.messageBar().pushWidget(iface.messageBar().createMessage("Import:", " Layer  " + layer_name + " was imported successfully."), Qgis.Success, duration=3)
                            else:
                                iface.messageBar().pushWidget(iface.messageBar().createMessage("Import:", " Layer  " + layer_name + " was not imported."), Qgis.Warning, duration=3)
                    else:
                   #     QMessageBox.information(None, "Atlas", "Vrstva "+layer_name+" nelze nahrát. Použíjte EPSG:4326 nebo EPSG:3857")
                        QMessageBox.information(None, "Layman", "Use EPSG:4326")
            else:
                QMessageBox.information(None, "Layman", "Layer "+layer_name+" does not have attributes!")

    def addExistingLayerToComposite(self, name):
        x = self.dlg.listWidget.currentRow()
        if self.checkLayerOnLayman(name):
            inComposite = name in self.isRasterLayerInComposite(x, name)
            if not(inComposite):
                response = requests.get(self.URI+'/rest/'+self.laymanUsername+'/layers/'+str(name), verify=False)
                res = self.fromByteToJson(response.content)
                print(res)
                wmsUrl = res['wms']['url']
        
            
                self.compositeList[x]['layers'].append({"metadata":{},"visibility":True,"opacity":1,"title":str(name),"className":"HSLayers.Layer.WMS","singleTile":True,"wmsMaxScale":0,"legends":[""],"maxResolution":None,"minResolution":0,"url": wmsUrl ,"params":{"LAYERS": str(name),"INFO_FORMAT":"application/vnd.ogc.gml","FORMAT":"image/png","FROMCRS":"EPSG:3857","VERSION":"1.3.0"},"ratio":1.5,"dimensions":{}})
                self.importMap(x, 'add', 1)
                self.refreshLayerList()
            else:
                QMessageBox.information(None, "Message", "Composition already include layer "+name+"!")
        else:
            QMessageBox.information(None, "Layman", "Something went wrong with this layer: "+name)

    def addExistingMapToMemory(self, name):
        response = requests.get(self.URI+'/rest/'+self.laymanUsername+'/maps/'+str(name), verify=False)
        res = self.fromByteToJson(response.content)
        print(res)
        wmsUrl = res['wms']['url']
        
        x = self.dlg.listWidget.currentRow()


        self.compositeList[x]['layers'].append({"metadata":{},"visibility":True,"opacity":1,"title":str(name),"className":"HSLayers.Layer.WMS","singleTile":True,"wmsMaxScale":0,"legends":[""],"maxResolution":None,"minResolution":0,"url": wmsUrl ,"params":{"LAYERS": str(name),"INFO_FORMAT":"application/vnd.ogc.gml","FORMAT":"image/png","FROMCRS":"EPSG:3857","VERSION":"1.3.0"},"ratio":1.5,"dimensions":{}})
        self.importMap(x, 'add', 1)
        self.refreshLayerList()

    def layerInfoRedirect(self, name):
        url = self.URI+'/rest/'+self.laymanUsername+"/layers/" + name
        print(url)
        response = requests.get(url)
        r = self.fromByteToJson(response.content)
        try:
            url = r['metadata']['record_url']
            webbrowser.open(url, new=2) ## redirect na micku pro více info
        except:
            QMessageBox.information(None, "Layman", "Link is unavailable.")
    def checkLayerOnLayman(self, layer_name):
        url = self.URI+'/rest/'+self.laymanUsername+"/layers/"+layer_name
        r = requests.get(url = url, verify=False)
        #print(r.content)
        data = r.json()
        try:
            if data['wms']['status'] == 'NOT_AVAILABLE' or data['wms']['status'] == 'PENDING':
                return False
            else:
                return True
        except:
            return True # validní vrstva nemá status


    def addLayerToComposite(self,x):
       
        self.compositeListOld = copy.deepcopy(self.compositeList) ## list pred upravou pro vraceni zmen
        #layers = self.getSelectedLayers() #odkomentovat pro zapnuti nacitani vrstev z listwidgetu
        layers = []
        layers.append(self.dlg.mMapLayerComboBox.currentLayer())
        successful = 0
        print (len(layers))
        try:
            step = self.getProgressBarStep(len(layers))
        except:
            QMessageBox.information(None, "Layman", "No layer selected!")
        
        for i in range (0, len(layers)):
            print(type(layers[i]))           
            
            print (self.isLayerInComposite(x))
            print (layers[i].name() in self.isLayerInComposite(x))
            inComposite = layers[i].name() in self.isLayerInComposite(x)
            layerName = self.removeUnacceptableChars(layers[i].name())
            if (self.checkExistingLayer(layers[i].name()) and inComposite):
                j = self.getLayerInCompositePosition(x)
                print("j je: " + str(j))
                
               # QMessageBox.information(None, "Message", "Composition already include layer "+layers[i].name()+"!")
               # self.deteteLayerFromComposite(x, j, layers[i].name())
             
                self.postRequest(layers[i].name())
                layerName = self.removeUnacceptableChars(layers[i].name())
                wmsStatus = 'PENDING'
                j = 0
                while ((wmsStatus == 'PENDING') and (j < 10)):
                    print (self.URI+'/rest/'+self.laymanUsername+'/layers/'+str(layerName))
                    response = requests.get(self.URI+'/rest/'+self.laymanUsername+'/layers/'+str(layerName), verify=False)
                    res = self.fromByteToJson(response.content)
                    try:
                        wmsStatus = res['wms']['status']
                    except:
                        wmsStatus = "done"
                    time.sleep(1)
                    j = j + 1
            

                #print(res)
                #try:
                #    wmsUrl = res['wms']['url']
                #except:
                #    wmsUrl = self.URI+'/geoserver/'+layers[i].name()+'/ows'
                #self.compositeList[x]['layers'].append({"metadata":{},"visibility":True,"opacity":1,"title":str(layers[i].name()),"className":"HSLayers.Layer.WMS","singleTile":True,"wmsMaxScale":0,"legends":[""],"maxResolution":None,"minResolution":0,"url": wmsUrl ,"params":{"LAYERS": str(layers[i].name()),"INFO_FORMAT":"application/vnd.ogc.gml","FORMAT":"image/png","FROMCRS":"EPSG:3857","VERSION":"1.3.0"},"ratio":1.5,"dimensions":{}})
                #successful = successful + 1
                #self.dlg.progressBar.setValue(self.dlg.progressBar.value()+step)
 
                #self.importMap(x, "add", successful) 

              
            else:
                self.postRequest(layers[i].name())
                wmsStatus = 'PENDING'
                j = 0
                while ((wmsStatus == 'PENDING') and (j < 10)):
                    print (self.URI+'/rest/'+self.laymanUsername+'/layers/'+str(layerName))
                    response = requests.get(self.URI+'/rest/'+self.laymanUsername+'/layers/'+str(layerName), verify=False)
                    res = self.fromByteToJson(response.content)
                    try:
                        wmsStatus = res['wms']['status']
                    except:
                        wmsStatus = "done"
                    time.sleep(1)
                    j = j + 1
            

                print(res)
                try:
                    wmsUrl = res['wms']['url']
                except:
                    wmsUrl = self.URI+'/geoserver/'+layerName+'/ows'
                self.compositeList[x]['layers'].append({"metadata":{},"visibility":True,"opacity":1,"title":str(layerName),"className":"HSLayers.Layer.WMS","singleTile":True,"wmsMaxScale":0,"legends":[""],"maxResolution":None,"minResolution":0,"url": wmsUrl ,"params":{"LAYERS": str(layers[i].name()),"INFO_FORMAT":"application/vnd.ogc.gml","FORMAT":"image/png","FROMCRS":"EPSG:3857","VERSION":"1.3.0"},"ratio":1.5,"dimensions":{}})
                successful = successful + 1
                self.dlg.progressBar.setValue(self.dlg.progressBar.value()+step)
 
                self.importMap(x, "add", successful) 
    def getProgressBarStep(self, count):
        return (100/count)

    def deteteLayerFromComposite(self, x, position, name):   ## pro verzi s komboboxem   
        
        previousLayers = self.compositeList[x]['layers']         
        self.compositeList[x]['layers'] = []  
        for i in range (0,len(previousLayers)):
            if (i != position):              
               self.compositeList[x]['layers'].append(previousLayers[i])        
        self.importMap(x, "del")
        done = True
        if (len(self.compositeList[x]['layers']) != 0 and len(self.compositeList[x]['layers']) != None):
            for i in range (0, len(self.compositeList[x]['layers'])):
                if (self.compositeList[x]['layers'][i]['params']['LAYERS'] == name):
                    done = False
        if (done and QgsProject.instance().mapLayersByName(name)):    ## kompozice může mít načtené vrstvy, které nejsou v canvasu
            self.deleteLayerFromCanvas(name)    
        
    def importCleanComposite(self,x):
        tempFile = tempfile.gettempdir() + os.sep + "atlas" + os.sep + "compsite.json"
        with open(tempFile, 'w') as outfile:  
                    json.dump(self.compositeList[x], outfile)
        with open(tempFile, 'rb') as f:
                    d = json.load(f)        
        files = {'file': (tempFile, open(tempFile, 'rb')),} 
        data = { 'name' :  self.compositeList[x]['name'], 'title' : self.compositeList[x]['title'], 'description' : self.compositeList[x]['abstract']} 
        print(self.URI+'/rest/'+self.laymanUsername+'/maps/')
        #response = requests.post(self.URI+'/rest/'+self.laymanUsername+'/maps/', data = data, files=files, headers = self.authHeader, verify=False)
        print(self.authHeader)
        response = requests.post(self.URI+'/rest/'+self.laymanUsername+'/maps', files=files, data = data, headers = self.authHeader, verify=False)
        
        print(response.content)



    def showProgressBar(self, bar):
        bar = QProgressBar() 
        bar.setRange(0,0) ## range 0,0 je nekonečný
        self.showProgressBar(bar)
        bar.show()
        iface.mainWindow().statusBar().addWidget(bar)
    def fromByteToJson(self, res):
        pom = res
        pom = pom.decode('utf_8')
        pom = json.loads(pom)
        return pom

    def importMap(self, x, operation, s = 0): ##s je počet vrstev úspěšně nahraných na server   
        if (s != 0):
            self.dlg.progressBar.show() 
            self.dlg.label_import.show()
        tempFile = tempfile.gettempdir() + os.sep + "atlas" + os.sep + "compsite.json"
        
        try:
            existingLayers = self.isLayerInComposite(x)
        except:
            existingLayers = []        
        successful = s
        with open(tempFile, 'w') as outfile:  
            json.dump(self.compositeList[x], outfile)
        jsonPath = tempfile.gettempdir() + os.sep + "atlas" + os.sep + "compsite.json"
        with open(jsonPath, 'rb') as f:
            d = json.load(f)

        files = {'file': (jsonPath, open(jsonPath, 'rb')),} 
        data = { 'name' :  self.compositeList[x]['name'], 'title' : self.compositeList[x]['title'], 'description' : self.compositeList[x]['abstract']} 
        req = requests.get(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'])
        mapCode = req.status_code ## test jestli vrstva na serveru existuje. Pokud ne = error 404
        if (mapCode == 404):
            if (operation == "add"):                
                msgbox = QMessageBox(QMessageBox.Question, "Import Map", "Chcete přidat do kompozice "+str(successful)+" vrstev?") 
            if (operation == "mod"): 
                #msgbox = QMessageBox(QMessageBox.Question, "Import Map", "Do you want save changes?") 
                
                self.dlg.close()
                self.afterCloseEditMapDialog()
                print(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'])       
              
                response = requests.delete(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'],headers = self.authHeader, verify=False)
                print(response.content)
                response = requests.post(self.URI+'/rest/'+self.laymanUsername+'/maps', files=files, data = data, headers = self.authHeader)
                self.dlg.show()
                return
            if (operation == "del"):
                msgbox = QMessageBox(QMessageBox.Question, "Import Map", "Chcete smazat vybranou vrstvu?")
          
            try: # jedná se o mod pokud je except
                msgbox.addButton(QMessageBox.Yes)
                msgbox.addButton(QMessageBox.No)
                msgbox.setDefaultButton(QMessageBox.No)
                reply = msgbox.exec()
            except:
                pass
                
            if (reply == QMessageBox.Yes):
                response = requests.post(self.URI+'/rest/'+self.laymanUsername+'/maps', files=files, data = data, headers = self.authHeader)
                print(response.content)
                data = response.content
                self.dlg.progressBar.hide() 
               # self.refreshItems()## refresh formuláře
                if (operation != "mod"):
                    self.refreshLayerList()
                
            else:
                if (operation == "add"):
                    self.dlg.progressBar.setValue(0)                
     
        else:
            print(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'])       
            files = {'file': (jsonPath, open(jsonPath, 'rb')),} 
            response = requests.patch(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'], data = data, files=files, headers = self.authHeader, verify=False)
            try:
                self.refreshLayerList()
            except:
                ## nacházíme se v jiném formuláři, není co refreshovat
                pass
            #if (operation == "add"):
            #    print(len(existingLayers))
            #    msgbox = QMessageBox(QMessageBox.Question, "Layman", "Vybraná vrstva bude přidána do kompozice.")
            #    #if(len(existingLayers) == 0):
                    
            #    #    #if (successful != 0):
            #    #    msgbox = QMessageBox(QMessageBox.Question, "Layman", "Vybraná vrstva bude přidána do kompozice.")
            #    #else:
            #    #  #  msgbox = QMessageBox(QMessageBox.Question, "Import Map", "Kompozice již obsauje vrstvy: "+(', '.join(existingLayers))+". Chcete vybrané vrstvy opravdu znovu přidat?.")
            #    #     msgbox = QMessageBox(QMessageBox.Question, "Layman", "Vybraná vrstva bude přidána do kompozice.")
            #if (operation == "del"):
            #    msgbox = QMessageBox(QMessageBox.Question, "Import Map", "Chcete smazat vybranou vrstvu?")
            #if (operation == "mod"):
            #    msgbox = QMessageBox(QMessageBox.Question, "Import Map", "Chcete uložit upravenou mapu?")
            #msgbox.addButton(QMessageBox.Yes)
            #msgbox.addButton(QMessageBox.No)
            #msgbox.setDefaultButton(QMessageBox.No)
            #reply = msgbox.exec()
            #if (reply == QMessageBox.Yes):            
            #    print(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'])       
            #    files = {'file': (jsonPath, open(jsonPath, 'rb')),} 
            #    response = requests.patch(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'], data = data, files=files, headers = self.authHeader, verify=False)
   
            #    try:
            #        self.refreshLayerList()
            #    except:
            #        ## nacházíme se v jiném formuláři, není co refreshovat
            #        pass
            #if (reply == QMessageBox.No):
                
            #    self.compositeList = copy.deepcopy(self.compositeListOld)
            #    #self.refreshItems()##refresh formulare
               # self.refreshLayerList()
        try: ## některé formuláře nemají progress bar
            self.dlg.progressBar.hide() 
            self.dlg.label_import.hide() 
        except:
            pass
    def deleteLayer(self, layerName):
        url = self.URI+'/rest/'+self.laymanUsername+"/layers/" + layerName
        r = requests.delete(url)
        print (r.content)
    def getActiveLayer(self):
        layer = self.iface.activeLayer()
        return layer
    
    def createComposite(self, name, title):
      #  if (name == "" or title == ""):
        if (title == ""):
            QMessageBox.information(None, "Message", "Není vyplněn titulek!")
        else:
            name = self.removeUnacceptableChars(title)
            data = self.getEmptyComposite(name,title)
            print (data)
            self.compositeList.append(data)   
            x = len(self.compositeList) - 1
            self.importCleanComposite(x)
            try:
                self.refreshCompositeList()
            except:
                pass


    def patchLayer(self, layer_name, data):
        self.layerName = layer_name
        self.json_export(layer_name)
        sldPath = self.getTempPath(self.layerName).replace("geojson", "sld")
        geoPath = self.getTempPath(self.layerName)
        print(sldPath)
        if(os.path.isfile(sldPath)): ## existuje sld?
            files = [('file', open(geoPath, 'rb')), ('sld', open(sldPath, 'rb'))]
            print("sld")
        else:
            files = {'file': (geoPath, open(geoPath, 'rb')),}  
            print("ne sld")
        url = self.URI+'/rest/'+self.laymanUsername+"/layers/" + layer_name
        print(url)
        r = requests.patch(url, files=files, data = data, headers = self.authHeader, verify=False)
        print(r.content)

    def getTempPath(self, name):

        print (name)
        if type(name) is tuple:
            return (name[0] +  name[1])
        else:
            tempFile = tempfile.gettempdir() + os.sep + name +'.geojson'

            return tempFile
    def sendLayer(self):       
        layer = self.getActiveLayer()      
        if (layer == None):
            QMessageBox.information(None, "Message", "Neexistuje žádná vrstva k uložení")
        else:
            self.json_export()
            self.postRequest()
    def getExistingLayers(self):
        url = self.URI+'/rest/'+self.laymanUsername+"/layers"
        r = requests.get(url = url) 
        data = r.json()
        for x in range(len(data)):
            print(data[x]['name'])
        return data
    def checkExistingLayer(self, layerName):
        layerName = self.removeUnacceptableChars(layerName)
        url = self.URI+'/rest/'+self.laymanUsername+"/layers"
        r = requests.get(url = url) 
        data = r.json()
        
        pom = set()
        for x in range(len(data)):
            pom.add((data[x]['name']))
        layerName = layerName.replace(" ", "_").lower()
        print(layerName)
        print(pom)
        if (layerName in pom):
            return True
        else:
            return False
   
    def removeUnacceptableChars(self, input):
        input = input.lower()
        input = input.replace("ř","r")
        input = input.replace("š","s")
        input = input.replace("ž","z")
        input = input.replace("ů","u")
        input = input.replace("ú","u")
        input = input.replace(" ","_")
        input = input.replace("é","e")
        input = input.replace("í","i")
        input = input.replace("ý","y")
        input = input.replace("á","a")
        input = input.replace("ó","o")
        input = input.replace("č","c")
        input = input.replace("ď","d")
        input = input.replace("ě","e")
        input = input.replace("ť","t")
        input = re.sub(r'[?|$|.|!]',r'',input)
        
       # iface.messageBar().pushWidget(iface.messageBar().createMessage("Layman:", "Diacritics in name of layer was replaced."), Qgis.Success, duration=3)
        return input
    def removeUnacceptableChars2(self, input):
        input = input.encode('utf-8')
        input = input.hex()
        
       # iface.messageBar().pushWidget(iface.messageBar().createMessage("Layman:", "Diacritics in name of layer was replaced."), Qgis.Success, duration=3)
        return input
    def test (self):
        item = self.dlgGetLayers.items.currentItem().text()
        print( item)
    
    def isLayerInComposite(self, x):      
        layers =[]
        layers.append(self.dlg.mMapLayerComboBox.currentLayer())
        print (self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name']+'/file')
        req = requests.get (self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name']+'/file')
        data = req.json()
       
        print (data['abstract'])
        print (len(self.compositeList[x]['layers']))
        existingLayers = []
        for i in range (0, len(data['layers'])):
            for j in range (0, len(layers)):
                if (data['layers'][i]['params']['LAYERS'] in layers[j].name() ):
                    existingLayers.append(data['layers'][i]['params']['LAYERS'])

        return existingLayers
    def getLayerInCompositePosition(self, x):      
        layers =[]
        layers.append(self.dlg.mMapLayerComboBox.currentLayer())
        print (self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name']+'/file')
        req = requests.get (self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name']+'/file')
        data = req.json()
       
        print (data['abstract'])
        print (len(self.compositeList[x]['layers']))
        existingLayers = []
        j = 0
        for i in range (0, len(data['layers'])):
            for j in range (0, len(layers)):
                if (data['layers'][i]['params']['LAYERS'] in layers[j].name() ):
                  #  existingLayers.append(data['layers'][i]['params']['LAYERS'])
                   j = i
                   print("founded")

        return j

    def isRasterLayerInComposite(self, x, name):
        req = requests.get (self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name']+'/file')
        data = req.json()
        existingLayers = []
        for i in range (0, len(data['layers'])):
            if (data['layers'][i]['params']['LAYERS'] ==  name ):
                existingLayers.append(data['layers'][i]['params']['LAYERS'])
        return existingLayers
    
    def addComposite(self, data, service, groupName = ''):      
        #self.compositeList.append (data)
        print(len(data['layers']))
        for x in range(0, len(data['layers'])):        
          #  repairUrl = self.convertUrlFromHex(data['layers'][x]['url'])  
            repairUrl = self.URI+"/geoserver/"+self.laymanUsername+"/ows"
            layerName = data['layers'][x]['params']['LAYERS']
            format = data['layers'][x]['params']['FORMAT']
           #  epsg = str(data['groups']['projection']).upper()
            epsg = 'EPSG:4326' 
            #abstract = data['data']['layers'][x]['params']['ABSTRACT']
            wmsName = data['layers'][x]['params']['LAYERS']
            
            print("groupName " +groupName)
            print("groupName " +layerName)
            
            print("groupName " +format)
            print("groupName " +epsg)
            layerNameTitle = self.getLayerTitle(layerName)
            print("groupName " +layerNameTitle)
            
            
            if service == 'WMS':         
                self.loadWms(repairUrl, layerName,layerNameTitle, format,epsg, groupName)

            if service == 'WFS':          
                self.loadWfs(repairUrl, layerName,layerNameTitle, groupName)
    def loadService(self, data, service, groupName = ''):     
        
        #print(len(data['layers']))
        for x in range(len(data['layers'])- 1, -1, -1):       ## descending order 
            #repairUrl = self.convertUrlFromHex(data['layers'][x]['url'])  
            repairUrl = self.URI+"/geoserver/"+self.laymanUsername+"/ows"
            layerName = data['layers'][x]['params']['LAYERS']
            format = data['layers'][x]['params']['FORMAT']
           #  epsg = str(data['groups']['projection']).upper()
            epsg = 'EPSG:4326' 
            #abstract = data['data']['layers'][x]['params']['ABSTRACT']
            wmsName = data['layers'][x]['params']['LAYERS']  
            if self.checkLayerOnLayman(layerName):
                if service == 'WMS':         
                    print("zzzzzzz" +layerName)
                    self.loadWms(repairUrl, layerName, format,epsg, groupName)

                if service == 'WFS':          
                    self.loadWfs(repairUrl, layerName, groupName)
            else:
                QMessageBox.information(None, "Layman", "Layer: "+layerName + " is corrupted and will not be loaded.")
    def getLayerTitle(self, layerName):
        layerName = self.removeUnacceptableChars(layerName)
        url = self.URI+'/rest/'+self.laymanUsername+'/layers/'+layerName
        r = requests.get(url = url)
        data = r.json()
        print(data)
        title = data['title']
        return title
        
    def loadWms(self, url, layerName,layerNameTitle, format, epsg, groupName = ''):          
        print(url)
        layerName = self.removeUnacceptableChars(layerName)
        epsg = "EPSG:4326"
        urlWithParams = 'contextualWMSLegend=0&crs='+epsg+'&IgnoreReportedLayerExtents=1&dpiMode=7&featureCount=10&format=image/png&layers='+layerName+'&styles=&url=' + url
        print(urlWithParams)
        print("test")
        print(layerNameTitle)
        rlayer = QgsRasterLayer(urlWithParams, layerNameTitle, 'wms')
        try:
            print("extents")
            print(rlayer.ignoreExtents())
        except:
            print("ignoreExtents works only with qgis 3.10 and higher")
            pass # pro qgis 3.10 a vys
            
           
        if (groupName != ''):
            self.addWmsToGroup(groupName,rlayer)
        else:
            QgsProject.instance().addMapLayer(rlayer)

    def loadWfs(self, url, layerName,layerNameTitle, groupName = ''):
        layerName = self.removeUnacceptableChars(layerName)
        epsg = 'EPSG:4326'        
        uri = self.URI+"/geoserver/"+self.laymanUsername+"/ows?srsname="+epsg+"&typename="+self.laymanUsername+":"+layerName+"&restrictToRequestBBOX=1&pagingEnabled=True&version=auto&request=GetFeature&service=WFS"
        
        print(uri)        
        vlayer = QgsVectorLayer(uri, layerNameTitle, "WFS")
        print(vlayer.isValid())  
        if (groupName != ''):
            self.addWmsToGroup(groupName,vlayer)
        else:
            QgsProject.instance().addMapLayer(vlayer)
    def addWmsToGroup(self, groupName, layer):
        root = QgsProject.instance().layerTreeRoot()
        group = root.findGroup(groupName)
        if not(group):
            group = root.addGroup(groupName)  
            group = self.reorderToTop(groupName)
        QgsProject.instance().addMapLayer(layer,False)
        group.insertChildNode(0,QgsLayerTreeLayer(layer))         
    def reorderToTop(self, name):
        root = QgsProject.instance().layerTreeRoot()
        for ch in root.children():
            if ch.name() == name:
                _ch = ch.clone()
                root.insertChildNode(0, _ch)
                root.removeChildNode(ch)
        return _ch
    def convertUrlFromHex(self, url):
        url = url.replace('%3A',':')
        url = url.replace('%2F','/')
        url = url.replace('%3F','?')
        url = url.replace('%3D','=')
        url = url.replace('%26','&') 
        return url

    def checkEpsg(self, name):
        ret = False
        layer = QgsProject.instance().mapLayersByName(name)
        layerCRS = layer[0].crs().authid()
        if ((layerCRS == 'EPSG:4326') or (layerCRS == 'EPSG:3857')):
            ret = True
        return ret

    def registerLayer(self, name):
        sldPath = self.getTempPath(name).replace("geojson", "sld").lower()
        geoPath = self.getTempPath(name).lower()

        url = "http://layman.lesprojekt.cz/rest/"+self.laymanUsername+"/layers"
                             
        files = {'sld': (sldPath, open(sldPath, 'rb')),} # nahrávám sld
        payload = {        
            'file': name.lower()+".geojson",
            'title': name
            }    
        response = requests.request("POST", url, files = files, data=payload, headers = self.authHeader)    
        print(response.text)

    def read_in_chunks(self, file_object): ## cca 1MB chunk převzato z laymana test klienta
        chunk_size=self.CHUNK_SIZE
        while True:
            data = file_object.read(chunk_size)
            if not data:
                break
            yield data
    
    def postInChunks(self, layer_name, reqType):
        print(reqType)
        if (reqType == "patch"):
            url = self.URI+'/rest/'+self.laymanUsername+'/layers/'+layer_name
            r = requests.delete(url,headers = self.authHeader)
           # print(r.content)
         
        self.registerLayer(layer_name)

        filePath = os.path.join(tempfile.gettempdir(), "atlas_chunks" ) ## chunky se ukládají do adresáře v tempu
        
        if not (os.path.exists(filePath)):
            os.mkdir(filePath)
        file = self.getTempPath(layer_name) 
        f = open(file, 'rb')
        arr = []
        for piece in self.read_in_chunks(f):
            arr.append(piece)
        layer_name = layer_name.lower()
        url = self.URI+'/rest/'+self.laymanUsername+'/layers/'+layer_name+'/chunk'     
        resumableFilename = layer_name+'.geojson'
        layman_original_parameter = "file"  
        resumableTotalChunks = len(arr)
        try:
            for i in range (1, len(arr)+1):  ##chunky jsou počítané od 1 proto +1  
                print("chunk" + str(i))
                file = arr[i-1] # rozsekaná část souboru
                resumableChunkNumber = i  # cislo casti
                payload = {
                'file' : "chunk"+str(i)+".geojson",
                'resumableFilename': resumableFilename,
                'layman_original_parameter': layman_original_parameter,
                'resumableChunkNumber': i,
                'resumableTotalChunks': resumableTotalChunks
                } 
         
                f = open(filePath + os.sep+"chunk"+str(i)+".geojson", "wb")
                f.write(bytearray(arr[i-1]))
                f.close()              
                files = {'file': (layer_name+".geojson", open(filePath +os.sep+ "chunk"+str(i)+".geojson", 'rb')),}              
                response = requests.post(url, files = files, data=payload, headers = self.authHeader)

                print(response.content)
            iface.messageBar().pushWidget(iface.messageBar().createMessage("Import:", " Layer  " + layer_name + " was imported successfully."), Qgis.Success, duration=3)
        except:
            iface.messageBar().pushWidget(iface.messageBar().createMessage("Import:", " Layer  " + layer_name + " was not imported successfully!"), Qgis.Warning, duration=3)

############################################# auth part############################

    def startThread(self): 
        self.thread1 = threading.Thread(target=self.refreshToken)
        self.thread1.start()

    def refreshToken(self):
        #self.expires_in = 60
        path = tempfile.gettempdir() + os.sep + "atlas" + os.sep + "tsts.txt" 
        i = 0
        tokenEndpoint = "https://www."+self.liferayServer+"/o/oauth2/token"
        while (i < self.expires_in):        
            f = open(path, "a")
            f.write(str(i))

            f.close()            
            time.sleep(1)         
            if i == self.expires_in - 4:
            
               
                data = {'grant_type':'refresh_token',
                        'refresh_token': self.refresh_token,
                        'client_id':'id-3462f94b-875c-9185-4ced-b69841f24b3', 
                        'redirect_uri':'http://localhost:3000/client/authn/oauth2-liferay/callback', 
                        'code_verifier':'test'
                        } 
                
                r = requests.post(url = tokenEndpoint, data = data, headers = self.authHeader) 
                res = self.fromByteToJson(r.content)
                self.access_token = res['access_token']
                self.refresh_token = res['refresh_token']
                self.expires_in = res['expires_in']
                print(self.access_token)
                self.setAuthHeader()
                i = 0
            else:
                i += 1
        
        
        
        



    
    def authOptained (self):        
        self.dlg.pushButton_Continue.setEnabled(True)

        self.menu_Connection.setEnabled(True)
        self.menu_saveLocalFile.setEnabled(True)
        self.menu_loadJson.setEnabled(True)
        self.menu_ImportLayerDialog.setEnabled(True)
        self.menu_AddLayerDialog.setEnabled(True) 
        self.menu_AddMapDialog.setEnabled(True)       
        self.menu_ImportLayerDialog.setEnabled(True)
        self.menu_ImportMapDialog.setEnabled(True)       
     #   self.menu_DeleteMapDialog.setEnabled(True)
    #    self.menu_CreateCompositeDialog.setEnabled(True)
        self.menu_UserInfoDialog.setEnabled(True)
        self.textbox.setText("Layman: Logged user")

    def getCodeVerifier(self):
        code_verifier = base64.urlsafe_b64encode(os.urandom(40)).decode('utf-8')
        code_verifier = re.sub('[^a-zA-Z0-9]+', '', code_verifier)
        self.code_verifier = code_verifier
        return (code_verifier)
      
    def getCodeChallenge(self, code_verifier):
        code_challenge = hashlib.sha256(code_verifier.encode('utf-8')).digest()
        code_challenge = base64.urlsafe_b64encode(code_challenge).decode('utf-8')
        code_challenge = code_challenge.replace('=', '')
        self.code_challenge = code_challenge
        return (code_challenge)        

    def printVariables(self):
        print (self.access_token)
        print(self.refresh_token)
        print(self.authHeader)
        print(self.laymanUsername)

    def getAuthCode(self):
        path = tempfile.gettempdir() + os.sep + "atlas" + os.sep + "auth.txt"        
        f = open(path, "r")
        ret =  f.read()
        f.close()
        return ret

    def getToken(self):
        self.saveIni()

        tokenEndpoint = "https://www."+self.liferayServer+"/o/oauth2/token"
        # data to be sent to api 
        data = {'grant_type':'authorization_code', 
                'client_id': self.client_id, 
                'redirect_uri':'http://localhost:3000/client/authn/oauth2-liferay/callback', 
                'code_verifier': self.code_verifier, 
                'code': self.getAuthCode()} 
  
        # sending post request and saving response as response object 
        r = requests.post(url = tokenEndpoint, data = data, headers = self.authHeader) 
        res = self.fromByteToJson(r.content)
        print (res)
        try:
            print(res['access_token'])
            print(res['expires_in'])
            print(res['refresh_token'])
        except:
            QMessageBox.information(None, "Message", "Autorization was not sucessfull! Please try it again.")
            return
        self.access_token = res['access_token']
        self.refresh_token = res['refresh_token']
        self.expires_in = res['expires_in']
        self.setAuthHeader()
        data ={
            'access_token': res['access_token'], 
            'refresh_token': res['refresh_token'],
            'expires_in':res['expires_in']
            }
        path = tempfile.gettempdir() + os.sep + "atlas" + os.sep + "tokens.json"        
        with open(path, 'w') as outfile:
            json.dump(data, outfile)
        self.startThread()
        self.registerUserIfNotExists()
        self.dlg.close()
        
    def setAuthHeader(self):
        self.authHeader ={
          "Authorization": "Bearer " + self.access_token, 
          "AuthorizationIssUrl" : 'https://www.'+self.liferayServer+'/o/oauth2/authorize'
        } 
        
    def registerUserIfNotExists(self):
        userEndpoint = "http://layman.lesprojekt.cz/rest/current-user"
        #self.laymanUsername = self.dlg.lineEdit_userName.text()
        id = self.client_id.replace('-', '')
        user = {'username':self.Agrimail}  
        #user =  self.Agrimail        
        print("authheader: "+ str(self.authHeader))
        r = requests.patch(url = userEndpoint, data = user, headers = self.authHeader)
        res = r.text
        res = self.fromByteToJson(r.content)
        print (res)
        print(user)
        print(res)
        try:
           # if res['message'] == 'User already reserved username.': # res['code'] == 34, code 35 je pokud již jiný uživatel má účet, který chceme registrovat
           if res['code'] == 34: # res['code'] == 34, code 35 je pokud již jiný uživatel má účet, který chceme registrovat (code 35 pravděpodobně nemůže nastat)

                print("user exists")
                self.laymanUsername = res['detail']['username']
            #self.laymanUsername = res['username']
            #else:
            #    self.laymanUsername =  user['username']
        except:

            print("creating new user: " + res['username'])
            self.laymanUsername =  res['username']
        #API_ENDPOINT = "http://layman.lesprojekt.cz/rest/current-user"
        #headers ={
        #  "Authorization": "Bearer "+ self.access_token, 
        #  "AuthorizationIssUrl" : 'https://www.'+self.liferayServer+'/o/oauth2/authorize'
        #} 


    def openAuthLiferayUrl(self):
        self.liferayServer = self.dlg.lineEdit_server.text()
        self.URI = self.dlg.lineEdit_serverLayman.text()
        self.getCodeChallenge(self.getCodeVerifier()) ##generování kódů
        self.client_id = self.dlg.lineEdit_AgriID.text()
        path = tempfile.gettempdir() + os.sep + "atlas" + os.sep + "auth.txt" 
        self.watcher = QFileSystemWatcher()
        self.watcher.addPath(path)
        self.watcher.fileChanged.connect(self.authOptained)
      
        
            #################       
     
        print ("##### flask server is starting #####")                     
        self.flaskThread = StartFlaskDaemon()
        self.flaskThread.daemon = True
        self.flaskThread.start()       
        url = 'https://www.'+self.liferayServer+'/o/oauth2/authorize?response_type=code&client_id='+self.client_id+'&redirect_uri=http%3A%2F%2Flocalhost:3000%2Fclient%2Fauthn%2Foauth2-liferay%2Fcallback&code_challenge='+self.code_challenge ##n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg'
        webbrowser.open(url, new=2)

    def saveIni(self):
        file =  os.getenv("HOME") + os.sep + ".layman" + os.sep + 'layman_user.INI'  
        dir = os.getenv("HOME") + os.sep + ".layman"
        if not (os.path.isdir(dir)):
            try:  
                os.mkdir(dir)
            except OSError:  
                print ("vytváření adresáře selhalo")
        config = configparser.ConfigParser()

        config['DEFAULT']['login'] = self.Agrimail
        config['DEFAULT']['id'] = self.client_id
        print("saveliferay" + self.liferayServer)
        config['DEFAULT']['server'] = self.liferayServer
        config['DEFAULT']['layman'] = self.URI
        

        with open(file, 'w') as configfile:
            config.write(configfile)        
    def loadIni(self):
        file =  os.getenv("HOME") + os.sep + ".layman" + os.sep +'layman_user.INI'        
        config = configparser.ConfigParser()
        config.read(file)
        return config   

    def layerChanged(self):  
        
        print(iface.activeLayer())
        if (iface.activeLayer() != None):
            self.menu_saveLocalFile.setEnabled(True)
        else:
            self.menu_saveLocalFile.setEnabled(False)


    def run(self):
        """Run method that loads and starts the plugin"""

        if not self.pluginIsActive:
            self.pluginIsActive = True

            #print "** STARTING Atlas"

            # dockwidget may not exist if:
            #    first run of plugin
            #    removed on close (see self.onClosePlugin method)
            if self.dockwidget == None:
                # Create the dockwidget (after translation) and keep reference
                self.dockwidget = AtlasDockWidget()

            
            # connect to provide cleanup on closing of dockwidget
            self.dockwidget.closingPlugin.connect(self.onClosePlugin)     
            
            self.dockwidget.pushButton.clicked.connect(self.sendLayer)   
            self.dockwidget.pushButton_2.clicked.connect(self.loadLocalFile) 
            self.dockwidget.pushButton_3.clicked.connect(self.saveLocalFile)
            self.dockwidget.pushButton_getLayers.clicked.connect(self.run_getLayer)            
            self.dlgGetLayers.pushButtonxx.clicked.connect(lambda: print(self.dlgGetLayers.items.currentItem().text()))          
            
            # show the dockwidget
            # TODO: fix to allow choice of dock location
            self.iface.addDockWidget(Qt.TopDockWidgetArea, self.dockwidget)
            self.dockwidget.show()
            
class StartFlaskDaemon(threading.Thread):
    def run(self):
        from subprocess import Popen, PIPE
        import platform
        import sys
        from pathlib import Path
        d= os.path.dirname(Path(__file__).absolute()) + os.sep+"flask_listener" + os.sep + "flask_listener.py" 
       
        if platform.system() == 'Windows':
            process = subprocess.Popen(["python", d],stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        else:
            process = subprocess.Popen(["python " + d],stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        stdout, stderr = process.communicate()
        print (stdout, stderr)  
        '''Start your thread here'''
        