# -*- coding: utf-8 -*-
"""
/***************************************************************************
 Burying_Laterals
                                 A QGIS plugin
  This plugin adds lateral and prints a recommended elevation and Distance along the mainlines.
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2021-01-12
        git sha              : $Format:%H$
        copyright            : (C) 2021 by FALASY Anamelechi
        email                : fvw.services@gmail.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
"""
from qgis.PyQt.QtCore import *
from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication
from qgis.PyQt.QtCore import QVariant
from qgis.PyQt.QtGui import *
from qgis.PyQt.QtGui import QIcon
from qgis.PyQt.QtWidgets import *
from qgis.PyQt.QtWidgets import QAction, QFileDialog
from qgis.core import *
from qgis.core import QgsProject, QgsProcessingException, Qgis
from qgis.utils import *

from qgis.gui import QgsMapLayerComboBox, QgsFieldComboBox

from csv import writer
from csv import reader
from csv import DictReader
from csv import DictWriter

from qgis import processing
import os
import glob

import errno
import os.path
#import saga_api
import sys
import csv
import pandas as pd

from os.path import dirname

# Initialize Qt resources from file resources.py
from .resources import *
# Import the code for the dialog
from .Burying_Laterals_dialog import Burying_LateralsDialog


class Burying_Laterals:
    """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__)
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(
            self.plugin_dir,
            'i18n',
            'Burying_Laterals_{}.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)

        # Create the dialog (after translation) and keep reference
        self.dlg = Burying_LateralsDialog()
        
        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&Burying_Laterals')
        # TODO: We are going to let the user set this up in a future iteration
        self.toolbar = self.iface.addToolBar(u'Burying_Laterals')
        self.toolbar.setObjectName(u'Burying_Laterals')
                                
                        
        self.dlg.lineEdit.clear()
        self.initFolder();
        self.dlg.pushButton.clicked.connect(self.selectOutputFile);

        # Check if plugin was started the first time in current QGIS session
        # Must be set in initGui() to survive plugin reloads
        # self.first_start = None

    # 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('Burying_Laterals', 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):
        """Add a toolbar icon to the toolbar.

        :param icon_path: Path to the icon for this action. Can be a resource
            path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
        :type icon_path: str

        :param text: Text that should be shown in menu items for this action.
        :type text: str

        :param callback: Function to be called when the action is triggered.
        :type callback: function

        :param enabled_flag: A flag indicating if the action should be enabled
            by default. Defaults to True.
        :type enabled_flag: bool

        :param add_to_menu: Flag indicating whether the action should also
            be added to the menu. Defaults to True.
        :type add_to_menu: bool

        :param add_to_toolbar: Flag indicating whether the action should also
            be added to the toolbar. Defaults to True.
        :type add_to_toolbar: bool

        :param status_tip: Optional text to show in a popup when mouse pointer
            hovers over the action.
        :type status_tip: str

        :param parent: Parent widget for the new action. Defaults None.
        :type parent: QWidget

        :param whats_this: Optional text to show in the status bar when the
            mouse pointer hovers over the action.

        :returns: The action that was created. Note that the action is also
            added to self.actions list.
        :rtype: QAction
        """

        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:
            # Adds plugin icon to Plugins toolbar
            self.iface.addToolBarIcon(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/Burying_Laterals/icon.png'
        self.add_action(
            icon_path,
            text=self.tr(u'Burying Laterals'),
            callback=self.run,
            parent=self.iface.mainWindow())

        # will be set False in run()
        self.first_start = True


    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginMenu(
                self.tr(u'&Burying_Laterals'),
                action)
            self.iface.removeToolBarIcon(action)
    
    def initFolder(self):
        path_project = QgsProject.instance().fileName()
        path_project = path_project[:path_project.rfind("/"):]

        self.folderName = path_project

        self.dlg.lineEdit.setText(self.folderName);

    def selectOutputFile(self):
        folderTmp = QFileDialog.getExistingDirectory(self.dlg,
                                                     self.tr("Select output folder "), self.folderName)

        if folderTmp != "":
            self.folderName = folderTmp

        self.dlg.lineEdit.setText(self.folderName);

    def isFileOpened(self, file_path):
        if os.path.exists(file_path):
            try:
                os.rename(file_path, file_path + "_")
                os.rename(file_path + "_", file_path)
                return False
            except OSError as e:
                return True
                        
                    
    def combo_layers1(self):                                                       #loads layers in comboBox 1
        self.dlg.mMapLayerComboBox.clear()
        self.layer = self.dlg.mMapLayerComboBox.currentLayer()
        
    def select_layer_fields(self, mains):                                          #loads fields in comboBox 1 layer
        self.dlg.mFieldComboBox.clear()
        self.dlg.mFieldComboBox.setLayer(mains)
        field = self.dlg.mFieldComboBox.setLayer(mains)
    
    def combo_layers2(self):                                                       #loads layers in comboBox 2
        self.dlg.mMapLayerComboBox_2.clear()
        self.layer = self.dlg.mMapLayerComboBox_2.currentLayer()    
    
    def select_layer_fields2(self, laterals):                                      #loads fields in comboBox 1 layer
        self.dlg.mFieldComboBox_2.clear()
        self.dlg.mFieldComboBox_2.setLayer(laterals)
        field = self.dlg.mFieldComboBox_2.setLayer(laterals)
        
    def combo_layers3(self):                                                       #loads layers in comboBox 3
        self.dlg.mMapLayerComboBox_3.clear()
        self.layer = self.dlg.mMapLayerComboBox_3.currentLayer()
    
    def combo_layers4(self):                                                       #loads layers in comboBox 4
        self.dlg.mMapLayerComboBox_4.clear()
        self.layer = self.dlg.mMapLayerComboBox_4.currentLayer() 
    
    
    def run(self):
        """Run method that performs all the real work"""
        # Get all loaded layers in the Maplayer Canvas
        layers = QgsProject.instance().mapLayers().values()
                       
        # Fetch all currently loaded layer from comboBox 1
        mains = self.dlg.mMapLayerComboBox.currentLayer()                             #new line
        self.dlg.mFieldComboBox.setLayer(mains)                                       #new line
        self.dlg.mMapLayerComboBox.layerChanged.connect(self.select_layer_fields)  
                
        # Fetch all currently loaded layer from comboBox 2
        laterals = self.dlg.mMapLayerComboBox_2.currentLayer()                        #new line
        self.dlg.mFieldComboBox_2.setLayer(laterals)                                  #new line
        self.dlg.mMapLayerComboBox_2.layerChanged.connect(self.select_layer_fields2)
        
        # Fetch all currently loaded layer from comboBox 4
        boundary = self.dlg.mMapLayerComboBox_4.currentLayer()                        #new line
                
        # Fetch all currently loaded layer from comboBox 3
        ovalay = self.dlg.mMapLayerComboBox_3.currentLayer()
        
        # Fetch all currently loaded fields in layer from comboBox 1
        mains_idi = self.dlg.mFieldComboBox.currentField()
        
        # Fetch all currently loaded fields in layer from comboBox 2
        lateral_idi = self.dlg.mFieldComboBox_2.currentField()
                                                      
                            
        # show the dialog
        self.dlg.show()
                        
        # Run the dialog event loop
        result = self.dlg.exec_()
        
        # See if OK was pressed
        if result:
                                   
            dirName = self.dlg.lineEdit.text().strip()
            if len(dirName) == 0:
                self.iface.messageBar().pushMessage(self.tr("Warning"),
                                                    self.tr("Please select target folder"), level=Qgis.Warning)
                return
            if not (
            self.dlg.checkBox_3.isChecked(), self.dlg.radioButton_2.isChecked(), self.dlg.checkBox_2.isChecked() or self.dlg.checkBox.isChecked()):
                # self.dlg.checkBox_2.isChecked()):
                self.iface.messageBar().pushMessage(self.tr("Warning"),
                                                    self.tr(
                                                   "No checkBox is checked. At least check open output file after running algorithm"),
                                                    level=Qgis.Warning)
                return
                                                          
                        
            # # # Reference Layer in ComboBox 1
            index = self.dlg.mMapLayerComboBox.currentIndex()         # Identify selected layer by its index
            selection = self.dlg.mMapLayerComboBox.itemData(index)    # Mains Line layer
            
            # # # Reference Layer in ComboBox 2
            index = self.dlg.mMapLayerComboBox_2.currentIndex()
            selection2 = self.dlg.mMapLayerComboBox_2.itemData(index) # Laterals Line layer
                       
            # # # Reference Layer in ComboBox 3
            index = self.dlg.mMapLayerComboBox_3.currentIndex()
            selection3 = self.dlg.mMapLayerComboBox_3.itemData(index) # DEM layer
            
            # # # Reference Layer in ComboBox 4
            index = self.dlg.mMapLayerComboBox_4.currentIndex()
            selection4 = self.dlg.mMapLayerComboBox_4.itemData(index) # Boundary Line layer
                                                                     
            checkedLayers = QgsProject.instance().layerTreeRoot().checkedLayers()
            # iface.layerTreeView().selectedLayers()
                                                                                              
            # search existence of output folder, if not create it
            if not os.path.isdir(self.folderName):
                raise FileNotFoundError(
                    errno.ENOENT, os.strerror(errno.ENOENT), self.folderName)
            
            directory = self.folderName + "/Plugin_Results"
            if not os.path.exists(directory) and self.dlg.checkBox_3.isChecked():
                os.makedirs(directory)
                       
                     
            # Progress bar
            progressMessageBar = self.iface.messageBar().createMessage(self.tr("Burying Main & Laterals..."))
            progress = QProgressBar()
            progress.setMaximum(len(checkedLayers) - 1)
            progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter)
            progressMessageBar.layout().addWidget(progress)
            self.iface.messageBar().pushWidget(progressMessageBar, Qgis.Info)
            progression = 0
                         
            # Analyses part
           
            for layer in checkedLayers:
                if layer.type() == QgsMapLayer.RasterLayer and layer != selection2 and self.dlg.checkBox_3.isChecked():
                                                                                                                                                                                                                                                                                                                                                                                                                   
                                                        
                    mains = self.dlg.mMapLayerComboBox.currentLayer()
                    
                    # get extension about the raster
                    filename, file_extension = os.path.splitext(layer.source())
                    output1 = self.folderName + "/Plugin_Results/m-length_" + layer.name() + ".shp"
                                        
                    # check file isn't opened and is writable
                    version = 0
                    while self.isFileOpened(output1):
                            output1 = self.folderName + "/Plugin_Results/m-length_" + layer.name() + "("+ str(version) + ").shp"
                            version +=1
                    
                                               
                                    # #001### Getting Length measurement for the entire mains line
                    processing.run("qgis:exportaddgeometrycolumns", {"INPUT": mains, "CALC_METHOD": 0, "OUTPUT": output1})
                                                        
                    
                if layer.type() == QgsMapLayer.RasterLayer and layer != selection and self.dlg.checkBox_2.isChecked():
                                                                                                                                                                                                                                                                                                                                                                                                                       
                                      
                    ovalay = self.dlg.mMapLayerComboBox_3.currentLayer()
                    mains = self.dlg.mMapLayerComboBox.currentLayer()
                    mains_idi = self.dlg.mFieldComboBox.currentField()
                    boundary = self.dlg.mMapLayerComboBox_4.currentLayer()
                        
                    # get extension about the raster
                    filename, file_extension = os.path.splitext(layer.source())
                    output2 = self.folderName + "/Plugin_Results/M-Profile_" + layer.name() + ".shp"
                    output3 = self.folderName + "/Plugin_Results/Renamz_" + layer.name() + ".shp"
                    output4 = self.folderName + "/Plugin_Results/M-Layer_" + layer.name() + ".shp"
                    
                                       
                    # check file isn't opened and is writable
                    version = 0
                    while self.isFileOpened(output2):
                            output2 = self.folderName + "/Plugin_Results/M-Profile_" + layer.name() + "("+ str(version) + ").shp"
                            version +=1
                    
                    # check file isn't opened and is writable
                    version = 0
                    while self.isFileOpened(output3):
                            output3 = self.folderName + "/Plugin_Results/Renamz_" + layer.name() + "("+ str(version) + ").shp"
                            version +=1
                    
                    # check file isn't opened and is writable
                    version = 0
                    while self.isFileOpened(output4):
                            output4 = self.folderName + "/Plugin_Results/M-Layer_" + layer.name() + "("+ str(version) + ").shp"
                            version +=1                                               
                                                                                     
                                    # #002### Getting Main Terrain Profiles
                    processing.run("saga:profilesfromlines", {"DEM": ovalay, "LINES": mains, "NAME": mains_idi, "PROFILE": output2})
                    #processing.run("saga:profilesfromlines", {"DEM": output15, "LINES": mains, "NAME": mains_idi, "PROFILE": output2})
                    
                                    # #003### Renaming field name in the mains
                    processing.run('qgis:renametablefield', {"INPUT": output2, "FIELD": 'Z', "NEW_NAME": 'Surf_Elev', "OUTPUT": output3})
                    
                                    # #004### Delecting the Unwanted column
                    processing.run('qgis:deletecolumn', {"INPUT": output3, "COLUMN": ['LINE_ID', 'DIST_SURF', 'X', 'Y'], "OUTPUT": output4})
                                                                            
                    # load layer
                    if self.dlg.checkBox_2.isChecked():
                        out = iface.addVectorLayer(output4, "", "ogr")
                        if not out:
                            iface.messageBar().pushMessage(self.tr("Error"), self.tr("Could not load ") +  output4, level=Qgis.Warning)
                    
            # Update progression
                time.sleep(1)
                progress.setValue(progression + 1)
                progression += 1

            self.iface.messageBar().clearWidgets()
                     
                                                                                       
            # # Get layer object for Mains
            fn = 'output4'
            #m_layer = iface.addVectorLayer(fn, '', 'ogr')
            #m_layer = QgsVectorLayer(fn)
            m_layer = QgsVectorLayer(fn, '', 'ogr')
                                                                                          
            # Determine max and min values from mains
            m_layer= self.iface.activeLayer()
            emex=m_layer.fields().indexFromName('Surf_Elev')
            idex=m_layer.fields().indexFromName('DIST')
                    
            # Determine max Distance values from mains
            max_distance = m_layer.maximumValue(idex)            # highest value in the distances from the mains layer
                               
            #cend = (max_distance + 1)
                               
            cend = max_distance
                                                                          
            # Determine max and min Elevation values from mains
            min_elevation = m_layer.minimumValue(emex)           # lowest value in the elevation from the mains layer
            max_elevation = m_layer.maximumValue(emex)           # highest value in the elevation from the mains layer
                    
            nmasidiya = min_elevation
            
            # Determine other Input Parameters for burying the mains and laterals
            const_slope = self.dlg.doubleSpinBox.value()
            constant_slope = (const_slope * 0.01)
                    
            upper = self.dlg.doubleSpinBox_2.value()
            lower = self.dlg.doubleSpinBox_3.value()
                    
            abs_upper = self.dlg.doubleSpinBox_5.value()
            abs_lower = self.dlg.doubleSpinBox_6.value()
                    
            slope_mx = self.dlg.doubleSpinBox_8.value()
            slope_mn = self.dlg.doubleSpinBox_9.value()
                    
            max_slope = (slope_mx * 0.01) 
            min_slope = (slope_mn * 0.01)
            
            # Burying Tile Drianage System (MAINS)
            pv = m_layer.dataProvider()
            pv.addAttributes([QgsField("main_bury",QVariant.Double)])
            
            m_layer.updateFields()
                        
            context = QgsExpressionContext()
            context.appendScopes(QgsExpressionContextUtils.globalProjectLayerScopes(m_layer))
                        
            with edit(m_layer):
                for f in m_layer.getFeatures():
                                     
                    # Plotting with Slope Calculations
                    offset = self.dlg.doubleSpinBox_7.value()
                    # lateral_no = self.dlg.doubleSpinBox_4.value()                                       
                    middle_depth = (upper + lower) / 2
                    start_depth = nmasidiya - middle_depth
                    average_plot = (middle_depth - start_depth) / 19.995
                    
                    # Use Constant Slope
                    if self.dlg.checkBox.isChecked()and 0 < 19.995 < cend:
                        tiledepth = start_depth + 19.995 * constant_slope / 100
                                                                                
                    if '19.995' == '0':   
                        tiledepth = start_depth
                                            
                    elif average_plot < min_slope:
                        tiledepth = start_depth + 19.995 * min_slope
                                    
                    elif tiledepth < f['Surf_Elev'] - abs_lower:
                        tiledepth = f['Surf_Elev'] - abs_lower
                    
                    elif average_plot > max_slope:
                        tiledepth = start_depth + 19.995 * max_slope
                                            
                    elif tiledepth > f['Surf_Elev'] - abs_upper:
                        tiledepth = f['Surf_Elev'] - abs_upper
                    else:
                        tiledepth = middle_depth
                    
                    # # Use Constant Slope
                    # if self.dlg.checkBox.isChecked() and dk > cstart and dk < cend:
                        # tiledepth = start_depth + (dist_diff) * constant_slope / 100
                    
                    f['main_bury'] = tiledepth + offset
                    m_layer.updateFeature(f)
                    # f['Lat_Num'] = lateral_no 
                    # m_layer.updateFeature(f)                    
                                                                                                                                                                                                                                                                                                                                           
                      
            for layer in checkedLayers:
            
                            # # Export Final Bury Mains File (if displayed and checked)
                if layer.type() == QgsMapLayer.RasterLayer and layer != selection and self.dlg.checkBox_3.isChecked():
                
                    # get extension about the vector
                    filename, file_extension = os.path.splitext(layer.source())
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
                    # output14 = self.folderName + "/Plugin_Results/Bury_Mains_" + layer.name() + ".shp"
                    output5 = self.folderName + "/Plugin_Results/Bury_Mains_" + layer.name() + ".csv"
                    output16 = self.folderName + "/Plugin_Results/Buried_Main_" + layer.name() + ".shp"
                                                                               
                    # # check file isn't opened and is writable
                    version = 0
                    while self.isFileOpened(output5):
                        output5 = self.folderName + "/Plugin_Results/Bury_Mains_" + layer.name() + "(" + str(
                            version) + ").csv"
                        version += 1                                                
                    
                    # # check file isn't opened and is writable
                    version = 0
                    while self.isFileOpened(output16):
                        output16 = self.folderName + "/Plugin_Results/Buried_Main_" + layer.name() + "(" + str(
                            version) + ").shp"
                        version += 1 
                    
                            # # #005### Generate and export x and y coordinates for Points to CSV File (if displayed and checked)
                    processing.run('native:addxyfields', {"INPUT": m_layer, "CRS": 'EPSG4326', "OUTPUT": output5})

                    # # #005### Generate and export Line Depth for Main)
                    processing.run('native:pointstopath', {"INPUT": m_layer, "ORDER_EXPRESSION": 'main_bury', "OUTPUT": output16})           
                    
                    # Execution Status Report
                    self.iface.messageBar().pushMessage("Success", "Output file written and loaded at " + output16, level=Qgis.Success, duration=3)
                                                          
                    # load layer
                    if self.dlg.checkBox_2.isChecked():
                        out = self.iface.addVectorLayer(output16, "", "ogr")
                        if not out:
                            self.iface.messageBar().pushMessage(self.tr("Error"), self.tr("Could not load ") + output16, level=Qgis.Warning)
                                                                                       
                # Update progression
                time.sleep(1)
                progress.setValue(progression + 1)
                progression += 1

            self.iface.messageBar().clearWidgets()
            
            for layer in checkedLayers:
                if layer.type() == QgsMapLayer.RasterLayer and layer != selection2 and self.dlg.checkBox_2.isChecked():
                                                                                                                                                                                                                                                                                                                                                                                                                       
                                                                               
                    ovalay = self.dlg.mMapLayerComboBox_3.currentLayer()
                    laterals = self.dlg.mMapLayerComboBox_2.currentLayer() 
                    lateral_idi = self.dlg.mFieldComboBox_2.currentField()
                                                               
                        # get extension about the raster
                    filename, file_extension = os.path.splitext(layer.source())
                    output6 = self.folderName + "/Plugin_Results/L-Profile_" + layer.name() + ".shp"
                    output7 = self.folderName + "/Plugin_Results/RnameLats_" + layer.name() + ".shp"
                    output8 = self.folderName + "/Plugin_Results/Z-values_" + layer.name() + ".shp"
                                                             
                    # check file isn't opened and is writable
                    version = 0
                    while self.isFileOpened(output6):
                            output6 = self.folderName + "/Plugin_Results/L-Profile_" + layer.name() + "("+ str(version) + ").shp"
                            version +=1
                    
                    # check file isn't opened and is writable
                    version = 0
                    while self.isFileOpened(output7):
                            output7 = self.folderName + "/Plugin_Results/RnameLats_" + layer.name() + "("+ str(version) + ").shp"
                            version +=1
                    
                    # check file isn't opened and is writable
                    version = 0
                    while self.isFileOpened(output8):
                            output8 = self.folderName + "/Plugin_Results/Z-values_" + layer.name() + "("+ str(version) + ").shp"
                            version +=1
                                                                                                          
                                    # #006### Getting Lateral Terrain Profiles
                    processing.run("saga:profilesfromlines", {"DEM": ovalay, "LINES": laterals, "NAME": lateral_idi, "PROFILE": output6})
                                        
                                    # #007### Renaming field name in the mains
                    processing.run('qgis:renametablefield', {"INPUT": output6, "FIELD": 'Z', "NEW_NAME": 'Lat_Height', "OUTPUT": output7})
                                    
                                    # #008### Delecting the Unwanted column
                    processing.run('qgis:deletecolumn', {"INPUT": output7, "COLUMN": ['DIST_SURF'], "OUTPUT": output8})
                    
                    # load layer
                    if self.dlg.checkBox_2.isChecked():
                        out = self.iface.addVectorLayer(output8, "", "ogr")
                        if not out:
                            self.iface.messageBar().pushMessage(self.tr("Error"), self.tr("Could not load ") + output8, level=Qgis.Warning)
                    
            # Update progression
                time.sleep(1)
                progress.setValue(progression + 1)
                progression += 1

            self.iface.messageBar().clearWidgets()
            
            for layer in checkedLayers:
                if layer.type() == QgsMapLayer.RasterLayer and layer != selection and self.dlg.checkBox_2.isChecked():
                                                                                                                                                                                                                                                                                                                                                                                                                       
                                                                              
                    mains = self.dlg.mMapLayerComboBox.currentLayer()
                    laterals = self.dlg.mMapLayerComboBox_2.currentLayer()
                                                                                    
                        # get extension about the raster
                    filename, file_extension = os.path.splitext(layer.source())
                    
                    output9 = self.folderName + "/Plugin_Results/Points_" + layer.name() + ".shp"
                    output10 = self.folderName + "/Plugin_Results/Lines_" + layer.name() + ".shp"
                    output11 = self.folderName + "/Plugin_Results/s-length_" + layer.name() + ".shp"
                    
                    # check file isn't opened and is writable
                    version = 0
                    while self.isFileOpened(output9):
                            output9 = self.folderName + "/Plugin_Results/Points_" + layer.name() + "("+ str(version) + ").shp"
                            version +=1
                            
                    # check file isn't opened and is writable
                    version = 0
                    while self.isFileOpened(output10):
                            output10 = self.folderName + "/Plugin_Results/Lines_" + layer.name() + "("+ str(version) + ").shp"
                            version +=1
                    
                    # check file isn't opened and is writable
                    version = 0
                    while self.isFileOpened(output11):
                            output11 = self.folderName + "/Plugin_Results/s-length_" + layer.name() + "("+ str(version) + ").shp"
                            version +=1
                    
                                    # #009### Getting Point intersects of mains and laterals lines
                    processing.run("qgis:lineintersections", {"INPUT": mains, "INTERSECT": laterals, "OUTPUT": output9})
                    
                                    # #010### Getting Line Splits between mains and laterals lines
                    processing.run("qgis:splitwithlines", {"INPUT": mains, "LINES": laterals, "OUTPUT": output10})
                    
                                    # #011### Getting Length measurement for each line splits in the mains
                    processing.run("qgis:exportaddgeometrycolumns", {"INPUT": output10, "CALC_METHOD": 0, "OUTPUT": output11})
          
            # Update progression
                time.sleep(1)
                progress.setValue(progression + 1)
                progression += 1

            self.iface.messageBar().clearWidgets()
                                                                                                            
            # # Get layer object for Laterals
            fn = 'output8'
            #l_layer = iface.addVectorLayer(fn, '', 'ogr')
            #l_layer = QgsVectorLayer(fn)
            l_layer = QgsVectorLayer(fn, '', 'ogr')
                                                                                          
            # Determine max and min values from mains
            l_layer= self.iface.activeLayer()
            emel=l_layer.fields().indexFromName('Lat_Height')
            idej=l_layer.fields().indexFromName('DIST')
            
            # Determine max Distance values from mains
            max_distanze = l_layer.maximumValue(idej)            # highest value in the distances from the mains layer
                               
            #cend = (max_distance + 1)
                               
            cendd = max_distanze
            
            # Determine other Input Parameters for burying the mains and laterals
            const_slope = self.dlg.doubleSpinBox.value()
            constant_slope = (const_slope * 0.01)
                        
            # Burying Tile Drianage System (LATERALS)
            pv = l_layer.dataProvider()
            pv.addAttributes([QgsField("bury_lines", QVariant.Double)])
                        
            l_layer.updateFields()
                        
            context = QgsExpressionContext()
            context.appendScopes(QgsExpressionContextUtils.globalProjectLayerScopes(l_layer))
                        
            with edit(l_layer):
                for f in l_layer.getFeatures():
                                     
                    # Plotting with Slope Calculations
                    offset = self.dlg.doubleSpinBox_7.value()
                    
                    # Use Constant Slope
                    if self.dlg.checkBox.isChecked()and 0 < 19.995 < cendd:
                        tiledepth = f['Lat_Height'] + 19.995 * constant_slope / 100
                        
                    if '19.995' == '0':   
                        tiledepth = f['Lat_Height']
                    else:
                        tiledepth = f['Lat_Height']
                                                                                                                                  
                    f['bury_lines'] = tiledepth + offset - 7.4
                    #f['bury_lines'] = emel + offset - 7.4
                    l_layer.updateFeature(f)
                                                                                   
            for layer in checkedLayers:
            
                            # # Export Final Bury Laterals File (if displayed and checked)
                if layer.type() == QgsMapLayer.RasterLayer and layer != selection and self.dlg.checkBox_3.isChecked():
                
                    # get extension about the vector
                    filename, file_extension = os.path.splitext(layer.source())                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
                    
                    output12 = self.folderName + "/Laterals_" + layer.name() + ".shp"
                    #output17 = self.folderName + "/Laterals_" + layer.name() + ".shp"
                                                                              
                                                                                    
                    # check file isn't opened and is writable
                    version = 0
                    while self.isFileOpened(output12):
                            #output12 = self.folderName + "/Plugin_Results/Laterals_" + layer.name() + "("+ str(version) + ").shp"
                            output12 = self.folderName + "/Laterals_" + layer.name() + "("+ str(version) + ").shp"
                            version +=1
                                                                          
                    # # # check file isn't opened and is writable
                    # version = 0
                    # while self.isFileOpened(output17):
                        # output17 = self.folderName + "/Laterals_" + layer.name() + "(" + str(
                            # version) + ").shp"
                        # version += 1                                                                
                                                                                                                     
                                # #012### Getting Individual Lateral Terrain Profiles Layers Seperately
                    processing.run("qgis:splitvectorlayer", {"INPUT": l_layer, "FIELD": 'LINE_ID', "FILE_TYPE": 1, "OUTPUT": output12})
                                        
                    # # #005### Generate and export Line Depth for individual laterals)
                    # processing.run('native:pointstopath', {"INPUT": output12, "ORDER_EXPRESSION": 'bury_lines', "OUTPUT": output17})
                    
                    # Execution Status Report
                    self.iface.messageBar().pushMessage("Success", "Output file written and loaded at " + output12, level=Qgis.Success, duration=3)
                                                            
                    # load layer
                    if self.dlg.checkBox_2.isChecked():
                        out = self.iface.addVectorLayer(output12, "", "ogr")
                        if not out:
                            self.iface.messageBar().pushMessage(self.tr("Error"), self.tr("Could not load ") + output12, level=Qgis.Warning)
                    
                # Update progression
                time.sleep(1)
                progress.setValue(progression + 1)
                progression += 1

            self.iface.messageBar().clearWidgets()
  
