/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed 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 android.location;

import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;

import java.security.InvalidParameterException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;

/**
 * A class implementing a container for data associated with a measurement event.
 * Events are delivered to registered instances of {@link Listener}.
 *
 * @hide
 */
@SystemApi
public class GpsMeasurementsEvent implements Parcelable {

    /**
     * The system does not support tracking of GPS Measurements. This status will not change in the
     * future.
     */
    public static final int STATUS_NOT_SUPPORTED = 0;

    /**
     * GPS Measurements are successfully being tracked, it will receive updates once they are
     * available.
     */
    public static final int STATUS_READY = 1;

    /**
     * GPS provider or Location is disabled, updates will not be received until they are enabled.
     */
    public static final int STATUS_GPS_LOCATION_DISABLED = 2;

    private final GpsClock mClock;
    private final Collection<GpsMeasurement> mReadOnlyMeasurements;

    /**
     * Used for receiving GPS satellite measurements from the GPS engine.
     * Each measurement contains raw and computed data identifying a satellite.
     * You can implement this interface and call {@link LocationManager#addGpsMeasurementListener}.
     *
     * @hide
     */
    @SystemApi
    public interface Listener {

        /**
         * Returns the latest collected GPS Measurements.
         */
        void onGpsMeasurementsReceived(GpsMeasurementsEvent eventArgs);

        /**
         * Returns the latest status of the GPS Measurements sub-system.
         */
        void onStatusChanged(int status);
    }

    public GpsMeasurementsEvent(GpsClock clock, GpsMeasurement[] measurements) {
        if (clock == null) {
            throw new InvalidParameterException("Parameter 'clock' must not be null.");
        }
        if (measurements == null || measurements.length == 0) {
            throw new InvalidParameterException(
                    "Parameter 'measurements' must not be null or empty.");
        }

        mClock = clock;
        Collection<GpsMeasurement> measurementCollection = Arrays.asList(measurements);
        mReadOnlyMeasurements = Collections.unmodifiableCollection(measurementCollection);
    }

    @NonNull
    public GpsClock getClock() {
        return mClock;
    }

    /**
     * Gets a read-only collection of measurements associated with the current event.
     */
    @NonNull
    public Collection<GpsMeasurement> getMeasurements() {
        return mReadOnlyMeasurements;
    }

    public static final @android.annotation.NonNull Creator<GpsMeasurementsEvent> CREATOR =
            new Creator<GpsMeasurementsEvent>() {
        @Override
        public GpsMeasurementsEvent createFromParcel(Parcel in) {
            ClassLoader classLoader = getClass().getClassLoader();

            GpsClock clock = in.readParcelable(classLoader);

            int measurementsLength = in.readInt();
            GpsMeasurement[] measurementsArray = new GpsMeasurement[measurementsLength];
            in.readTypedArray(measurementsArray, GpsMeasurement.CREATOR);

            return new GpsMeasurementsEvent(clock, measurementsArray);
        }

        @Override
        public GpsMeasurementsEvent[] newArray(int size) {
            return new GpsMeasurementsEvent[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeParcelable(mClock, flags);

        int measurementsCount = mReadOnlyMeasurements.size();
        GpsMeasurement[] measurementsArray =
                mReadOnlyMeasurements.toArray(new GpsMeasurement[measurementsCount]);
        parcel.writeInt(measurementsArray.length);
        parcel.writeTypedArray(measurementsArray, flags);
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder("[ GpsMeasurementsEvent:\n\n");

        builder.append(mClock.toString());
        builder.append("\n");

        for (GpsMeasurement measurement : mReadOnlyMeasurements) {
            builder.append(measurement.toString());
            builder.append("\n");
        }

        builder.append("]");

        return builder.toString();
    }
}
