/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.sis.metadata.iso.content;

import javax.measure.Unit;
import javax.measure.quantity.Length;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.opengis.metadata.content.Band;
import org.opengis.metadata.content.BandDefinition;
import org.opengis.metadata.content.PolarizationOrientation;
import org.opengis.metadata.content.TransferFunctionType;
import org.apache.sis.measure.ValueRange;
import org.apache.sis.internal.jaxb.gco.GO_Real;
import org.apache.sis.internal.jaxb.gco.UnitAdapter;

import static org.apache.sis.internal.metadata.MetadataUtilities.ensurePositive;

// Branch-specific imports
import org.opengis.annotation.UML;
import static org.opengis.annotation.Obligation.OPTIONAL;
import static org.opengis.annotation.Specification.ISO_19115;


/**
 * Range of wavelengths in the electromagnetic spectrum.
 * The following property is conditional (i.e. mandatory under some circumstances)
 * in a well-formed metadata according ISO 19115:
 *
 * <div class="preformat">{@code MD_Band}
 * {@code   └─units……} Units of data in each dimension included in the resource.</div>
 *
 * <p><b>Limitations:</b></p>
 * <ul>
 *   <li>Instances of this class are not synchronized for multi-threading.
 *       Synchronization, if needed, is caller's responsibility.</li>
 *   <li>Serialized objects of this class are not guaranteed to be compatible with future Apache SIS releases.
 *       Serialization support is appropriate for short term storage or RMI between applications running the
 *       same version of Apache SIS. For long term storage, use {@link org.apache.sis.xml.XML} instead.</li>
 * </ul>
 *
 * @author  Martin Desruisseaux (IRD, Geomatys)
 * @author  Touraïvane (IRD)
 * @author  Cédric Briançon (Geomatys)
 * @author  Rémi Maréchal (Geomatys)
 * @author  Cullen Rombach (Image Matters)
 * @version 1.0
 * @since   0.3
 * @module
 */
@XmlType(name = "MD_Band_Type", propOrder = {
    "boundMax",
    "boundMin",
    "boundUnits",
    "peakResponse",
    "toneGradation",
    "bandBoundaryDefinition",
    "nominalSpatialResolution",
    "transferFunctionType",
    "transmittedPolarization",
    "detectedPolarization"
})
@XmlRootElement(name = "MD_Band")
@XmlSeeAlso(org.apache.sis.internal.jaxb.gmi.MI_Band.class)
public class DefaultBand extends DefaultSampleDimension implements Band {
    /**
     * Serial number for inter-operability with different versions.
     */
    private static final long serialVersionUID = -2474871120376144737L;

    /**
     * Shortest wavelength that the sensor is capable of collecting within a designated band.
     */
    private Double boundMin;

    /**
     * Longest wavelength that the sensor is capable of collecting within a designated band.
     */
    private Double boundMax;

    /**
     * Units in which sensor wavelengths are expressed.
     */
    private Unit<Length> boundUnits;

    /**
     * Designation of criterion for defining maximum and minimum wavelengths for a spectral band.
     */
    private BandDefinition bandBoundaryDefinition;

    /**
     * Wavelength at which the response is the highest.
     */
    private Double peakResponse;

    /**
     * Number of discrete numerical values in the grid data.
     */
    private Integer toneGradation;

    /**
     * Polarization of the radiation transmitted.
     */
    private PolarizationOrientation transmittedPolarization;

    /**
     * Polarization of the radiation detected.
     */
    private PolarizationOrientation detectedPolarization;

    /**
     * Constructs an initially empty band.
     */
    public DefaultBand() {
    }

    /**
     * Constructs a new instance initialized with the values from the specified metadata object.
     * This is a <cite>shallow</cite> copy constructor, since the other metadata contained in the
     * given object are not recursively copied.
     *
     * <div class="note"><b>Note on properties validation:</b>
     * This constructor does not verify the property values of the given metadata (e.g. whether it contains
     * unexpected negative values). This is because invalid metadata exist in practice, and verifying their
     * validity in this copy constructor is often too late. Note that this is not the only hole, as invalid
     * metadata instances can also be obtained by unmarshalling an invalid XML document.
     * </div>
     *
     * @param  object  the metadata to copy values from, or {@code null} if none.
     *
     * @see #castOrCopy(Band)
     */
    public DefaultBand(final Band object) {
        super(object);
        if (object != null) {
            if (object instanceof DefaultBand) {
                final DefaultBand c = (DefaultBand) object;
                boundMin   = c.getBoundMin();
                boundMax   = c.getBoundMax();
                boundUnits = c.getBoundUnits();
            }
            peakResponse             = object.getPeakResponse();
            toneGradation            = object.getToneGradation();
            bandBoundaryDefinition   = object.getBandBoundaryDefinition();
            transmittedPolarization  = object.getTransmittedPolarization();
            detectedPolarization     = object.getDetectedPolarization();
        }
    }

    /**
     * Returns a SIS metadata implementation with the values of the given arbitrary implementation.
     * This method performs the first applicable action in the following choices:
     *
     * <ul>
     *   <li>If the given object is {@code null}, then this method returns {@code null}.</li>
     *   <li>Otherwise if the given object is already an instance of
     *       {@code DefaultBand}, then it is returned unchanged.</li>
     *   <li>Otherwise a new {@code DefaultBand} instance is created using the
     *       {@linkplain #DefaultBand(Band) copy constructor}
     *       and returned. Note that this is a <cite>shallow</cite> copy operation, since the other
     *       metadata contained in the given object are not recursively copied.</li>
     * </ul>
     *
     * @param  object  the object to get as a SIS implementation, or {@code null} if none.
     * @return a SIS implementation containing the values of the given object (may be the
     *         given object itself), or {@code null} if the argument was null.
     */
    public static DefaultBand castOrCopy(final Band object) {
        if (object == null || object instanceof DefaultBand) {
            return (DefaultBand) object;
        }
        return new DefaultBand(object);
    }

    /**
     * Returns the shortest wavelength that the sensor is capable of collecting within a designated band.
     * The units of measurement is given by {@link #getBoundUnits()}.
     *
     * @return Shortest wavelength that the sensor is capable of collecting within a designated band,
     *         or {@code null} if unspecified.
     *
     * @since 0.5
     */
    @ValueRange(minimum = 0)
    @XmlElement(name = "boundMin")
    @XmlJavaTypeAdapter(GO_Real.Since2014.class)
    @UML(identifier="boundMin", obligation=OPTIONAL, specification=ISO_19115)
    public Double getBoundMin() {
        return boundMin;
    }

    /**
     * Sets the shortest wavelength that the sensor is capable of collecting within a designated band.
     *
     * @param  newValue  the new shortest wavelength, or {@code null}.
     * @throws IllegalArgumentException if the given value is negative.
     *
     * @since 0.5
     */
    public void setBoundMin(final Double newValue) {
        checkWritePermission(boundMin);
        if (ensurePositive(DefaultBand.class, "boundMin", false, newValue)) {
            boundMin = newValue;
        }
    }

    /**
     * Returns the longest wavelength that the sensor is capable of collecting within a designated band.
     * The units of measurement is given by {@link #getUnits()}.
     *
     * @return longest wavelength that the sensor is capable of collecting within a designated band,
     *         or {@code null} if unspecified.
     *
     * @since 0.5
     */
    @ValueRange(minimum = 0)
    @XmlElement(name = "boundMax")
    @XmlJavaTypeAdapter(GO_Real.Since2014.class)
    @UML(identifier="boundMax", obligation=OPTIONAL, specification=ISO_19115)
    public Double getBoundMax() {
        return boundMax;
    }

    /**
     * Sets the longest wavelength that the sensor is capable of collecting within a designated band.
     *
     * @param  newValue  the new longest wavelength, or {@code null}.
     * @throws IllegalArgumentException if the given value is negative.
     *
     * @since 0.5
     */
    public void setBoundMax(final Double newValue) {
        checkWritePermission(boundMax);
        if (ensurePositive(DefaultBand.class, "boundMax", false, newValue)) {
            boundMax = newValue;
        }
    }

    /**
     * Returns units in which sensor wavelengths are expressed.
     *
     * @return units in which sensor wavelengths are expressed.
     *
     * @since 0.5
     *
     * @see org.apache.sis.measure.Units#NANOMETRE
     */
    @XmlElement(name = "boundUnits")
    @XmlJavaTypeAdapter(UnitAdapter.Since2014.class)
    @UML(identifier="boundUnits", obligation=OPTIONAL, specification=ISO_19115)
    public Unit<Length> getBoundUnits() {
        return boundUnits;
    }

    /**
     * Sets a new units in which sensor wavelengths are expressed.
     *
     * @param newValue the new unit.
     *
     * @since 0.5
     */
    public void setBoundUnits(final Unit<Length> newValue) {
        checkWritePermission(boundUnits);
        boundUnits = newValue;
    }

    /**
     * Returns the designation of criterion for defining maximum and minimum wavelengths for a spectral band.
     *
     * @return criterion for defining maximum and minimum wavelengths, or {@code null}.
     */
    @Override
    @XmlElement(name = "bandBoundaryDefinition")
    public BandDefinition getBandBoundaryDefinition() {
        return bandBoundaryDefinition;
    }

    /**
     * Sets designation of criterion for defining maximum and minimum wavelengths for a spectral band.
     *
     * @param  newValue  the new band definition.
     */
    public void setBandBoundaryDefinition(final BandDefinition newValue) {
        checkWritePermission(bandBoundaryDefinition);
        bandBoundaryDefinition = newValue;
    }

    /**
     * Returns the units of data as a unit of length.
     *
     * <div class="warning"><b>Upcoming API change — generalization</b><br>
     * As of ISO 19115:2014, the units of wavelength is rather {@code boundUnits}.
     * The restriction for units of length in this {@code units} property may be relaxed in GeoAPI 4.0.
     * </div>
     *
     * @return The units of data.
     */
    @Override
    public Unit<Length> getUnits() {
        final Unit<?> units = super.getUnits();
        return (units != null) ? units.asType(Length.class) : null;
    }

    /**
     * Sets the units of data as a unit of length.
     *
     * <div class="warning"><b>Upcoming precondition change — relaxation</b><br>
     * The current implementation requires the unit to be an instance of {@code Unit<Length>},
     * otherwise a {@link ClassCastException} is thrown. This is because the value returned by
     * {@link #getUnits()} was restricted by ISO 19115:2003 to units of length.
     * However this restriction may be relaxed in GeoAPI 4.0.
     * </div>
     *
     * @param newValue The new units of data as an instance of {@code Unit<Length>}.
     */
    @Override
    public void setUnits(final Unit<?> newValue) {
        super.setUnits(newValue.asType(Length.class));
    }

    /**
     * Returns the wavelength at which the response is the highest.
     * The units of measurement is given by {@link #getBoundUnits()}.
     *
     * @return wavelength at which the response is the highest, or {@code null} if unspecified.
     */
    @Override
    @ValueRange(minimum = 0)
    @XmlElement(name = "peakResponse")
    public Double getPeakResponse() {
        return peakResponse;
    }

    /**
     * Sets the wavelength at which the response is the highest.
     *
     * @param  newValue  the new peak response, or {@code null}.
     * @throws IllegalArgumentException if the given value is negative.
     */
    public void setPeakResponse(final Double newValue) {
        checkWritePermission(peakResponse);
        if (ensurePositive(DefaultBand.class, "peakResponse", false, newValue)) {
            peakResponse = newValue;
        }
    }

    /**
     * Returns the number of discrete numerical values in the grid data.
     *
     * @return number of discrete numerical values in the grid data, or {@code null} if none.
     */
    @Override
    @ValueRange(minimum = 0)
    @XmlElement(name = "toneGradation")
    public Integer getToneGradation() {
        return toneGradation;
    }

    /**
     * Sets the number of discrete numerical values in the grid data.
     *
     * @param  newValue  the new tone gradation.
     */
    public void setToneGradation(final Integer newValue) {
        checkWritePermission(toneGradation);
        if (ensurePositive(DefaultBand.class, "toneGradation", false, newValue)) {
            toneGradation = newValue;
        }
    }

    /**
     * Returns the smallest distance between which separate points can be distinguished,
     * as specified in instrument design.
     *
     * @return {@inheritDoc}
     */
    @Override
    @ValueRange(minimum = 0, isMinIncluded = false)
    @XmlElement(name = "nominalSpatialResolution")
    public Double getNominalSpatialResolution() {
        return super.getNominalSpatialResolution();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setNominalSpatialResolution(final Double newValue) {
        super.setNominalSpatialResolution(newValue);
    }

    /**
     * Returns type of transfer function to be used when scaling a physical value for a given element.
     *
     * @return {@inheritDoc}
     */
    @Override
    @XmlElement(name = "transferFunctionType")
    public TransferFunctionType getTransferFunctionType() {
        return super.getTransferFunctionType();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setTransferFunctionType(final TransferFunctionType newValue) {
        super.setTransferFunctionType(newValue);
    }

    /**
     * Returns the polarization of the radiation transmitted.
     *
     * <div class="warning"><b>Upcoming API change</b><br>
     * This method may be renamed {@code getTransmittedPolarization} and its return type replaced by
     * {@code PolarisationOrientation} ("z" letter replaced by "s" letter) in GeoAPI 4.0
     * for compliance with ISO 19115-2:2019.</div>
     *
     * @return polarization of the radiation transmitted, or {@code null}.
     */
    @Override
    @XmlElement(name = "transmittedPolarisation")
    public PolarizationOrientation getTransmittedPolarization() {
        return transmittedPolarization;
    }

    /**
     * Sets the polarization of the radiation transmitted.
     *
     * <div class="warning"><b>Upcoming API change</b><br>
     * This method may be renamed {@code setTransmittedPolarization} and its argument type replaced by
     * {@code PolarisationOrientation} ("z" letter replaced by "s" letter) in GeoAPI 4.0
     * for compliance with ISO 19115-2:2019.</div>
     *
     * @param  newValue  the new transmitted polarization.
     */
    public void setTransmittedPolarization(final PolarizationOrientation newValue) {
        checkWritePermission(transmittedPolarization);
        transmittedPolarization = newValue;
    }

    /**
     * Returns polarization of the radiation detected.
     *
     * <div class="warning"><b>Upcoming API change</b><br>
     * This method may be renamed {@code getDetectedPolarization} and its return type replaced by
     * {@code PolarisationOrientation} ("z" letter replaced by "s" letter) in GeoAPI 4.0
     * for compliance with ISO 19115-2:2019.</div>
     *
     * @return polarization of the radiation detected, or {@code null}.
     */
    @Override
    @XmlElement(name = "detectedPolarisation")
    public PolarizationOrientation getDetectedPolarization() {
        return detectedPolarization;
    }

    /**
     * Sets the polarization of the radiation detected.
     *
     * <div class="warning"><b>Upcoming API change</b><br>
     * This method may be renamed {@code setDetectedPolarization} and its argument type replaced by
     * {@code PolarisationOrientation} ("z" letter replaced by "s" letter) in GeoAPI 4.0
     * for compliance with ISO 19115-2:2019.</div>
     *
     * @param  newValue  the new detected polarization.
     */
    public void setDetectedPolarization(final PolarizationOrientation newValue) {
        checkWritePermission(detectedPolarization);
        detectedPolarization = newValue;
    }
}
