import earthpy.spatial as es
import os
import tqdm


class RasterStack:

    """Stacks all raster files detected by GIS object (gh) into a single raster stack (.tif) file. This procedure is
    only successful if all detected environmental layers have identical affine transformation and resolution.
    WARNING: the file 'empty_land_map.tif' in 'root/data/gis/layers' needs to have the same affine transformation and
    resolution as all other raster files provided, as presence maps are create using this file as a template.
    This currently makes it impossible to use other environmental layers without transforming them to have the same
    affine projection and coordinate system as 'empty_land_map.tif' (or vice versa).

    :param gh: a GIS object: holds path and file names required for computation of gis data.
    :param verbose: a boolean: prints a progress bar if True, silent if False

    :return: Object. Used to stack all provided environmental layers into one single object that is subsequently written
    to a raster (.tif) file. Performed by calling class method create_raster_stack on RasterStack object.
    """

    def __init__(self, gh, verbose):
        self.gh = gh
        self.verbose = verbose

    def create_raster_stack(self):

        """Stacks all provided raster files by the GIS object (gh) into a single raster stack, where each band
        corresponds to one environmental variable.

        :param self: a class instance of RasterStack

        :return: None. Does not return value or object, instead writes away the raster stack to a new (.tif) file.
        """

        for _ in tqdm.tqdm([0], desc='Creating raster stack' + (29 * ' ')) if self.verbose else [0]:
            if not os.path.isdir(self.gh.stack):
                os.makedirs(self.gh.stack, exist_ok=True)

            # WARNING: this can cause errors if raster layers with different affine transformations / spatial extent or
            # resolutions are detected and used by the model, THIS ALSO INCLUDES THE FILE 'empty_land_map.tif'. This
            # means that the input raster files should match the spatial extent (Longitude_max = 180, Longitude_
            # min = -180, Latitude_max = 90, Latitude_min = -60) of the already existing 'empty_land_map.tif' included
            # in the repository. Alternatively the included 'empty_land_map.tif' can be edited to match the affine
            # transformation of the users raster files.

            es.stack(self.gh.variables, self.gh.stack + '/stacked_env_variables.tif')
