# coding=UTF-8

from natcap.invest.ui import model, inputs
from natcap.invest import coastal_vulnerability

from osgeo import gdal


class CoastalVulnerability(model.InVESTModel):
    def __init__(self):
        model.InVESTModel.__init__(
            self,
            label=u'Coastal Vulnerability',
            target=coastal_vulnerability.execute,
            validator=coastal_vulnerability.validate,
            localdoc=u'coastal_vulnerability.html')

        self.aoi_vector_path = inputs.File(
            args_key=u'aoi_vector_path',
            helptext=(
                u"path to a polygon vector that is projected in "
                u"a coordinate system with units of meters. "
                u"The polygon should intersect the landmass and "
                u"the shelf contour line"),
            label=u'Area of Interest (Vector)',
            validator=self.validator)
        self.add_input(self.aoi_vector_path)

        self.model_resolution = inputs.Text(
            args_key=u'model_resolution',
            helptext=(
                u"distance in meters at which the coastline "
                u"will be resolved. Coastline features smaller than this "
                u"distance will not be represented by the shoreline points. "
                u"Points will be spaced at intervals of half the model "
                u"resolution."),
            label=u'Model resolution (meters)',
            validator=self.validator)
        self.add_input(self.model_resolution)

        self.landmass_vector_path = inputs.File(
            args_key=u'landmass_vector_path',
            helptext=(
                u"path to a polygon vector representing landmasses "
                u"in the region of interest."),
            label=u'Landmass (Vector)',
            validator=self.validator)
        self.add_input(self.landmass_vector_path)

        self.wwiii_vector_path = inputs.File(
            args_key=u'wwiii_vector_path',
            helptext=(
                u"path to a point vector containing wind and wave "
                u"data. This global dataset is provided with the InVEST "
                u"sample data."),
            label=u'WaveWatchIII (Vector)',
            validator=self.validator)
        self.add_input(self.wwiii_vector_path)

        self.max_fetch_distance = inputs.Text(
            args_key=u'max_fetch_distance',
            helptext=(
                u"maximum distance in meters to extend rays from shore points. "
                u"Points with rays equal to this distance accumulate "
                u"ocean-driven wave exposure along those rays and "
                u"local-wind-driven wave exposure along the shorter rays."),
            label=u'Maximum Fetch Distance (meters)',
            validator=self.validator)
        self.add_input(self.max_fetch_distance)

        self.shelf_contour_vector_path = inputs.File(
            args_key=u'shelf_contour_vector_path',
            helptext=(
                u"path to a polygon or polyline vector delineating the edge "
                u"of the continental shelf or another bathymetry contour. "),
            label=u'Continental Shelf Contour (Vector)',
            validator=self.validator)
        self.add_input(self.shelf_contour_vector_path)

        self.dem_path = inputs.File(
            args_key=u'dem_path',
            helptext=(
                u"path to a raster representing elevation on land. "),
            label=u'Digital Elevation Model (Raster)',
            validator=self.validator)
        self.add_input(self.dem_path)

        self.dem_averaging_radius = inputs.Text(
            args_key=u'dem_averaging_radius',
            helptext=(
                u"a radius around each shore point within which to "
                u"average the elevation values of the DEM raster. "),
            label=u'Elevation averaging radius (meters)',
            validator=self.validator)
        self.add_input(self.dem_averaging_radius)

        self.habitat_table_path = inputs.File(
            args_key=u'habitat_table_path',
            helptext=(
                u"path to a CSV file that specifies habitat layer input data "
                u"and parameters."),
            label=u'Habitats Table (CSV)',
            validator=self.validator)
        self.add_input(self.habitat_table_path)

        self.geomorphology_vector_path = inputs.File(
            args_key=u'geomorphology_vector_path',
            helptext=(
                u"path to a polyline vector that has a field called "
                u"'RANK' with values from 1 to 5. "),
            label=u'Geomorphology (Vector) (optional)',
            validator=self.validator)
        self.add_input(self.geomorphology_vector_path)

        self.geomorphology_fill_value = inputs.Dropdown(
            args_key=u'geomorphology_fill_value',
            helptext=(
                u"a value from 1 to 5 that will be used as a geomorphology "
                u"rank for any points not proximate (given the model "
                u"resolution) to the geomorphology_vector_path."),
            label=u'Geomorphology fill value',
            interactive=False,
            options=('1', '2', '3', '4', '5'))
            # validator=self.validator)
        self.add_input(self.geomorphology_fill_value)

        self.population_raster_path = inputs.File(
            args_key=u'population_raster_path',
            helptext=(
                u"path to a raster with values representing totals per pixel."),
            label=u'Human Population (Raster) (optional)',
            validator=self.validator)
        self.add_input(self.population_raster_path)

        self.population_radius = inputs.Text(
            args_key=u'population_radius',
            helptext=(
                u"a radius around each shore point within which to "
                u"compute the average population density."),
            label=u'Population search radius (meters)',
            interactive=False,
            validator=self.validator)
        self.add_input(self.population_radius)

        self.slr_vector_path = inputs.File(
            args_key=u'slr_vector_path',
            helptext=(
                u"path to a point vector with a field of sea-level-rise rates"
                u"or amounts."),
            label=u'Sea Level Rise (Vector) (optional)',
            validator=self.validator)
        self.add_input(self.slr_vector_path)

        self.slr_field = inputs.Dropdown(
            args_key=u'slr_field',
            helptext=(
                u"the name of a field in the SLR vector table"
                u"from which to load values"),
            label=u'Sea Level Rise fieldname',
            interactive=False,
            options=('UNKNOWN',))  # No options until valid OGR vector provided
            # validator=self.validator)
        self.add_input(self.slr_field)

        # Set interactivity requirement as input sufficiency changes
        self.slr_vector_path.sufficiency_changed.connect(
            self.slr_field.set_interactive)
        self.slr_vector_path.sufficiency_changed.connect(
            self._load_colnames)
        self.geomorphology_vector_path.sufficiency_changed.connect(
            self.geomorphology_fill_value.set_interactive)
        self.population_raster_path.sufficiency_changed.connect(
            self.population_radius.set_interactive)

    def _load_colnames(self, new_interactivity):
        if new_interactivity:
            new_vector_path = self.slr_vector_path.value()
            new_vector = gdal.OpenEx(new_vector_path, gdal.OF_VECTOR)
            new_layer = new_vector.GetLayer()
            colnames = [defn.GetName() for defn in new_layer.schema]
            self.slr_field.set_options(colnames)
            self.slr_field.set_interactive(True)
        elif not self.slr_vector_path.sufficient:
            self.slr_field.set_options([])

    def assemble_args(self):
        args = {
            self.workspace.args_key: self.workspace.value(),
            self.suffix.args_key: self.suffix.value(),
            self.aoi_vector_path.args_key: self.aoi_vector_path.value(),
            self.model_resolution.args_key:
                self.model_resolution.value(),
            self.landmass_vector_path.args_key:
                self.landmass_vector_path.value(),
            self.wwiii_vector_path.args_key:
                self.wwiii_vector_path.value(),
            self.max_fetch_distance.args_key: self.max_fetch_distance.value(),
            self.shelf_contour_vector_path.args_key:
                self.shelf_contour_vector_path.value(),
            self.dem_path.args_key: self.dem_path.value(),
            self.dem_averaging_radius.args_key:
                self.dem_averaging_radius.value(),
            self.habitat_table_path.args_key:
                self.habitat_table_path.value(),
            self.geomorphology_vector_path.args_key:
                self.geomorphology_vector_path.value(),
            self.geomorphology_fill_value.args_key:
                self.geomorphology_fill_value.value(),
            self.population_raster_path.args_key:
                self.population_raster_path.value(),
            self.population_radius.args_key:
                self.population_radius.value(),
            self.slr_vector_path.args_key:
                self.slr_vector_path.value(),
            self.slr_field.args_key:
                self.slr_field.value(),
        }

        return args
