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

"""
Reamb_ResizePhotos.py
***************************************************************************
*                                                                         *
*   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__ = 'Leandro França'
__date__ = '2022-03-07'
__copyright__ = '(C) 2022, Leandro França'


from qgis.core import (QgsApplication,
                       QgsProcessingParameterFile,
                       QgsProcessingParameterBoolean,
                       QgsProcessingParameterNumber,
                       QgsProcessingException,
                       QgsProcessingAlgorithm)

from lftools.geocapt.imgs import Imgs
from lftools.translations.translate import translate
import os
from qgis.PyQt.QtGui import QIcon


class ResizePhotos(QgsProcessingAlgorithm):

    LOC = QgsApplication.locale()[:2]

    def tr(self, *string):
        return translate(string, self.LOC)

    def createInstance(self):
        return ResizePhotos()

    def name(self):
        return 'resizephotos'

    def displayName(self):
        return self.tr('Resize photos', 'Redimensionar fotos')

    def group(self):
        return self.tr('Reambulation', 'Reambulação')

    def groupId(self):
        return 'reambulation'

    def tags(self):
        return 'GeoOne,resized,photo,reambulation,redimensionar,geophoto,reambulação,fotografia,photography,diminuir,reduzir,compactar,foto'.split(',')

    def icon(self):
        return QIcon(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'images/reamb_camera.png'))

    txt_en = '''The largest width or height value of the original image is resized to the user-defined value. The short side is scaled proportionately.
    Note: The metadata is preserved.'''
    txt_pt = '''O maior valor de largura ou altura da imagem original é redimensionado para o valor definido pelo usuário. O lado menor é redimensionado proporcionalmente.
    Obs.: Os metadados são preservados.'''
    figure = 'images/tutorial/reamb_resize_photo.jpg'

    def shortHelpString(self):
        social_BW = Imgs().social_BW
        footer = '''<div align="center">
                      <img src="'''+ os.path.join(os.path.dirname(os.path.dirname(__file__)), self.figure) +'''">
                      </div>
                      <div align="right">
                      <p align="right">
                      <b>'''+self.tr('Author: Leandro Franca', 'Autor: Leandro França')+'''</b>
                      </p>'''+ social_BW + '''</div>
                    </div>'''
        return self.tr(self.txt_en, self.txt_pt) + footer

    INPUT_FOLDER = 'INPUT_FOLDER'
    OUTPUT_FOLDER = 'OUTPUT_FOLDER'
    SUBFOLDER = 'SUBFOLDER'
    SIZE = 'SIZE'

    def initAlgorithm(self, config=None):

        self.addParameter(
            QgsProcessingParameterFile(
                self.INPUT_FOLDER,
                self.tr('Folder with photos (.jpeg or .jpg)', 'Pasta com fotografias (.jpeg ou .jpg)'),
                behavior=QgsProcessingParameterFile.Folder,
                defaultValue=None
            )
        )

        self.addParameter(
            QgsProcessingParameterBoolean(
                self.SUBFOLDER,
                self.tr('Check subfolders', 'Verificar sub-pastas'),
                defaultValue = False
            )
        )

        self.addParameter(
            QgsProcessingParameterNumber(
                self.SIZE,
                self.tr('Size for the larger side', 'Tamanho para o lado maior'),
                type = QgsProcessingParameterNumber.Type.Integer,
                minValue = 10,
                defaultValue = 800
                )
            )

        self.addParameter(
            QgsProcessingParameterFile(
                self.OUTPUT_FOLDER,
                self.tr('Folder for the resized photos', 'Pasta para as fotos redimensionadas'),
                behavior=QgsProcessingParameterFile.Folder,
                defaultValue=None
            )
        )

    def processAlgorithm(self, parameters, context, feedback):

        from lftools.dependencies import ensure_pillow
        Image = ensure_pillow(feedback)
        if Image is None:
            raise QgsProcessingException(
                "The Pillow library (PIL) is required for this tool and could not be loaded automatically."
            )

        pasta_in = self.parameterAsFile(
            parameters,
            self.INPUT_FOLDER,
            context
        )
        if not pasta_in:
            raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT_FOLDER))

        subpasta = self.parameterAsBool(
            parameters,
            self.SUBFOLDER,
            context
        )

        lado = self.parameterAsInt(
            parameters,
            self.SIZE,
            context
        )

        pasta_out = self.parameterAsFile(
            parameters,
            self.OUTPUT_FOLDER,
            context
        )
        if not pasta_out:
            raise QgsProcessingException(self.invalidSourceError(parameters, self.OUTPUT_FOLDER))
        if pasta_in == pasta_out:
            raise QgsProcessingException(self.tr('Input and output folders cannot be the same!', 'As pastas de entrada e de saída não podem ser iguais!'))

        feedback.pushInfo(self.tr('Checking files in the folder...', 'Checando arquivos na pasta...'))
        lista = []
        if subpasta:
            for root, dirs, files in os.walk(pasta_in, topdown=True):
                for name in files:
                    if (name).lower().endswith(('.jpg', '.jpeg')):
                        lista += [os.path.join(root, name)]
        else:
            for item in os.listdir(pasta_in):
                if (item).lower().endswith(('.jpg', '.jpeg')):
                    lista += [os.path.join(pasta_in, item)]

        tam = len(lista)
        Percent = 100.0/tam if tam!=0 else 0

        # Redimensionando imagens
        feedback.pushInfo(self.tr('Resizing the images...', 'Redimensionando as imagens...'))
        for index, caminho in enumerate(lista):
            arquivo = os.path.split(caminho)[-1]
            img = Image.open(caminho)
            if 'exif' in img.info:
                exif = img.info['exif']
            altura = img.size[1]
            largura = img.size[0]
            if largura > altura:
                new_height = int(lado/float(largura)*altura)
                new_width = lado
            else:
                new_width = int(lado/float(altura)*largura)
                new_height = lado
            img = img.resize((new_width, new_height))
            if 'exif' in img.info:
                img.save(os.path.join(pasta_out, arquivo), exif=exif)
            else:
                img.save(os.path.join(pasta_out, arquivo))
            if feedback.isCanceled():
                break
            feedback.setProgress(int((index+1) * Percent))

        del img
        feedback.pushInfo(self.tr('Operation completed successfully!', 'Operação finalizada com sucesso!'))
        feedback.pushInfo(self.tr('Leandro Franca - Cartographic Engineer', 'Leandro França - Eng Cart'))

        return {}
