/*
 * 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.PolarisationOrientation;
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;


/**
 * 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>
 *
 * <h2>Limitations</h2>
 * <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",
    "transmittedPolarisation",
    "detectedPolarisation"
})
@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 = 2492553738885938445L;

    /**
     * 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 PolarisationOrientation transmittedPolarisation;

    /**
     * Polarization of the radiation detected.
     */
    private PolarisationOrientation detectedPolarisation;

    /**
     * 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) {
            boundMin                 = object.getBoundMin();
            boundMax                 = object.getBoundMax();
            boundUnits               = object.getBoundUnits();
            peakResponse             = object.getPeakResponse();
            toneGradation            = object.getToneGradation();
            bandBoundaryDefinition   = object.getBandBoundaryDefinition();
            transmittedPolarisation  = object.getTransmittedPolarisation();
            detectedPolarisation     = object.getDetectedPolarisation();
        }
    }

    /**
     * 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
     */
    @Override
    @ValueRange(minimum = 0)
    @XmlElement(name = "boundMin")
    @XmlJavaTypeAdapter(GO_Real.Since2014.class)
    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
     */
    @Override
    @ValueRange(minimum = 0)
    @XmlElement(name = "boundMax")
    @XmlJavaTypeAdapter(GO_Real.Since2014.class)
    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
     */
    @Override
    @XmlElement(name = "boundUnits")
    @XmlJavaTypeAdapter(UnitAdapter.Since2014.class)
    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 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.
     *
     * @return polarization of the radiation transmitted, or {@code null}.
     */
    @Override
    @XmlElement(name = "transmittedPolarisation")
    public PolarisationOrientation getTransmittedPolarisation() {
        return transmittedPolarisation;
    }

    /**
     * Sets the polarization of the radiation transmitted.
     *
     * @param  newValue  the new transmitted polarization.
     */
    public void setTransmittedPolarisation(final PolarisationOrientation newValue) {
        checkWritePermission(transmittedPolarisation);
        transmittedPolarisation = newValue;
    }

    /**
     * Returns polarization of the radiation detected.
     *
     * @return polarization of the radiation detected, or {@code null}.
     */
    @Override
    @XmlElement(name = "detectedPolarisation")
    public PolarisationOrientation getDetectedPolarisation() {
        return detectedPolarisation;
    }

    /**
     * Sets the polarization of the radiation detected.
     *
     * @param  newValue  the new detected polarization.
     */
    public void setDetectedPolarisation(final PolarisationOrientation newValue) {
        checkWritePermission(detectedPolarisation);
        detectedPolarisation = newValue;
    }
}
