/*
 * Copyright (C) 2013 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.os.Parcel;
import android.os.Parcelable;

/**
 * A data class representing a set of options to configure batching sessions.
 * @hide
 */
public class FusedBatchOptions implements Parcelable {
    private volatile long mPeriodInNS = 0;
    private volatile int mSourcesToUse = 0;
    private volatile int mFlags = 0;

    // the default value is set to request fixes at no cost
    private volatile double mMaxPowerAllocationInMW = 0;
    // If non-zero can be used for power savings by throttling location when device hasn't moved.
    private volatile float mSmallestDisplacementMeters = 0;

    /*
     * Getters and setters for properties needed to hold the options.
     */
    public void setMaxPowerAllocationInMW(double value) {
        mMaxPowerAllocationInMW = value;
    }

    public double getMaxPowerAllocationInMW() {
        return mMaxPowerAllocationInMW;
    }

    public void setPeriodInNS(long value) {
        mPeriodInNS = value;
    }

    public long getPeriodInNS() {
        return mPeriodInNS;
    }

    public void setSmallestDisplacementMeters(float value) {
        mSmallestDisplacementMeters = value;
    }

    public float getSmallestDisplacementMeters() {
        return mSmallestDisplacementMeters;
    }

    public void setSourceToUse(int source) {
        mSourcesToUse |= source;
    }

    public void resetSourceToUse(int source) {
        mSourcesToUse &= ~source;
    }

    public boolean isSourceToUseSet(int source) {
        return (mSourcesToUse & source) != 0;
    }

    public int getSourcesToUse() {
        return mSourcesToUse;
    }

    public void setFlag(int flag) {
        mFlags |= flag;
    }

    public void resetFlag(int flag) {
        mFlags &= ~flag;
    }

    public boolean isFlagSet(int flag) {
        return (mFlags & flag) != 0;
    }

    public int getFlags() {
        return mFlags;
    }

    /**
     * Definition of enum flag sets needed by this class.
     * Such values need to be kept in sync with the ones in fused_location.h
     */
    public static final class SourceTechnologies {
        public static int GNSS = 1<<0;
        public static int WIFI = 1<<1;
        public static int SENSORS = 1<<2;
        public static int CELL = 1<<3;
        public static int BLUETOOTH = 1<<4;
    }

    public static final class BatchFlags {
        // follow the definitions to the letter in fused_location.h
        public static int WAKEUP_ON_FIFO_FULL = 0x0000001;
        public static int CALLBACK_ON_LOCATION_FIX =0x0000002;
    }

    /*
     * Method definitions to support Parcelable operations.
     */
    public static final @android.annotation.NonNull Parcelable.Creator<FusedBatchOptions> CREATOR =
            new Parcelable.Creator<FusedBatchOptions>() {
        @Override
        public FusedBatchOptions createFromParcel(Parcel parcel) {
            FusedBatchOptions options = new FusedBatchOptions();
            options.setMaxPowerAllocationInMW(parcel.readDouble());
            options.setPeriodInNS(parcel.readLong());
            options.setSourceToUse(parcel.readInt());
            options.setFlag(parcel.readInt());
            options.setSmallestDisplacementMeters(parcel.readFloat());
            return options;
        }

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

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

    @Override
    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeDouble(mMaxPowerAllocationInMW);
        parcel.writeLong(mPeriodInNS);
        parcel.writeInt(mSourcesToUse);
        parcel.writeInt(mFlags);
        parcel.writeFloat(mSmallestDisplacementMeters);
    }
}
