# -*- coding: utf-8 -*-

"""
/***************************************************************************
 CreateLinkset
                                 A QGIS plugin
 Process that able you to create a Linkset for Graphab
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2020-07-02
        copyright            : (C) 2020 by ThéMA
        email                : robin.marlinl@gmail.com
        author               : Robin Marlin-Lefebvre
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/
"""

__author__ = 'robin.marlinl@gmail.com'
__date__ = '2020-07-02'
__copyright__ = '(C) 2020 by ThéMA'

# This will get replaced with a git SHA1 when you do a git archive

__revision__ = '$Format:%H$'

from qgis.core import (QgsProcessingParameterString,
                       QgsProcessingParameterEnum,
                       QgsProcessingParameterFile,
                       QgsProcessingParameterNumber)

from .GraphabAlgoProcessing import GraphabAlgoProcessing

import os


class CreateLinkset(GraphabAlgoProcessing):
    """
    Processing algorithm use to create a new Linkset. It inherit of GraphabAlgoProcessing
    that execute the command send by this class and it inherit of QgsProcessingAlgorithm
    """
    
    def __init__(self, plugin):
        super().__init__(plugin)

    # Constants used to refer to parameters and outputs. They will be
    # used when calling the algorithm from another algorithm, or when
    # calling from the QGIS console.

    INPUT =   'INPUT'
    NAME =    'NAME'
    TYPE =    'TYPE'
    MAXCOST = 'MAXCOST'
    CODE =    'CODE'
    EXTCOST = 'EXTCOST'
    
    TYPES = ['euclid', 'cost']

    def initAlgorithm(self, config):
        """
        Here we define the inputs and output of the algorithm, along
        with some other properties.
        """

        # Input for the XML file that represent the Graphab Project
        self.addParameter(
            QgsProcessingParameterFile(
                self.INPUT,
                self.translate('py', 'XML project file'),
                fileFilter='xml(*.xml)'
            )
        )

        # Input for the Linkset name
        self.addParameter(
            QgsProcessingParameterString(
                self.NAME,
                self.translate('py', 'Linkset name'),
                defaultValue='',
                optional=True
            )
        )

        # Input for the type of Linkset
        self.addParameter(
            QgsProcessingParameterEnum(self.TYPE,
                self.translate('py', 'Distance type'),
                self.TYPES,
                allowMultiple=False,
                defaultValue=0
            )
        )
        
        # Input for Linkset max cost
        self.addParameter(
            QgsProcessingParameterNumber(
                self.MAXCOST,
                type=QgsProcessingParameterNumber.Double,
                optional=True
            )
        )
        
        # Input for Linkset codes
        self.addParameter(
            QgsProcessingParameterString(
                self.CODE,
                self.translate('py', 'Costs definition from landscape codes (ex: 1,2=1 3,4,5=10 6,7=100)'),
                defaultValue='',
                optional=True
            )
        )
        
        # Input for the TIF file that represent external cost
        self.addParameter(
            QgsProcessingParameterFile(
                self.EXTCOST,
                self.translate('py', 'External cost raster'),
                fileFilter='tif(*.tif)',
                optional=True
            )
        )

    def processAlgorithm(self, parameters, context, feedback):
        """
        Create a command line depending of parameters set by the user and send it to its parent 
        to execute it
        """
        
        # Get all parameter set
        project = self.parameterAsFile(parameters, self.INPUT, context)
        self.linksetName = self.parameterAsString(parameters, self.NAME, context)
        typeLinkset = self.parameterAsString(parameters, self.TYPE, context)
        maxCost = self.parameterAsDouble(parameters,self.MAXCOST,context)
        codeLinkset = self.parameterAsString(parameters, self.CODE, context)
        externalCost = self.parameterAsFile(parameters, self.EXTCOST, context)
        
        if typeLinkset == str(0):
            typeLinkset = 'euclid'
        else:
            typeLinkset = 'cost'
            
        self.projectPath = os.path.normcase(r''+project)
            
        commandToExec = ['--project', self.projectPath, '--linkset', 'distance=' + typeLinkset]
        
        if self.linksetName:
            commandToExec.append('name=' + self.linksetName)
            
        if maxCost:
            commandToExec.append('maxcost=' + str(maxCost))
            
        if typeLinkset == 'cost' and codeLinkset:
            commandToExec += codeLinkset.strip().split(' ')
        elif typeLinkset == 'cost' and externalCost:
            externalCost = os.path.normcase(r''+externalCost)
            commandToExec.append('extcost=' + externalCost)
            
        super().processAlgorithm(commandToExec, context, feedback)
        
        return {}

    def postProcessAlgorithm(self, context, feedback):
        """After the execution of the processing, this function
        add and show the new Linkset in the map. """
        project = self.plugin.projects[self.projectPath]
        if not (self.executionError or project is None):
            # if the project is already loaded add the Linkset that has been created
            project.addLinksetProject(self.linksetName)

        return {}

    def name(self):
        """
        Returns the algorithm name, used for identifying the algorithm. This
        string should be fixed for the algorithm, and must not be localised.
        The name should be unique within each provider. Names should contain
        lowercase alphanumeric characters only and no spaces or other
        formatting characters.
        """
        return 'create_linkset'

    def displayName(self):
        """
        Returns the translated algorithm name, which should be used for any
        user-visible display of the algorithm name.
        """
        return self.translate('py', 'Create Linkset')


    def createInstance(self):
        return CreateLinkset(self.plugin)
