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

import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.os.Parcel;
import android.os.Parcelable;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Represents attributes of video calls.
 */
public class VideoProfile implements Parcelable {

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef({QUALITY_UNKNOWN, QUALITY_HIGH, QUALITY_MEDIUM, QUALITY_LOW, QUALITY_DEFAULT})
    public @interface VideoQuality {}

    /**
     * "Unknown" video quality.
     * @hide
     */
    public static final int QUALITY_UNKNOWN = 0;
    /**
     * "High" video quality.
     */
    public static final int QUALITY_HIGH = 1;

    /**
     * "Medium" video quality.
     */
    public static final int QUALITY_MEDIUM = 2;

    /**
     * "Low" video quality.
     */
    public static final int QUALITY_LOW = 3;

    /**
     * Use default video quality.
     */
    public static final int QUALITY_DEFAULT = 4;

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(
            flag = true,
            prefix = { "STATE_" },
            value = {STATE_AUDIO_ONLY, STATE_TX_ENABLED, STATE_RX_ENABLED, STATE_BIDIRECTIONAL,
                    STATE_PAUSED})
    public @interface VideoState {}

    /**
     * Used when answering or dialing a call to indicate that the call does not have a video
     * component.
     * <p>
     * Should <b>not</b> be used in comparison checks to determine if a video state represents an
     * audio-only call.
     * <p>
     * The following, for example, is not the correct way to check if a call is audio-only:
     * <pre>
     * {@code
     * // This is the incorrect way to check for an audio-only call.
     * if (videoState == VideoProfile.STATE_AUDIO_ONLY) {
     *      // Handle audio-only call.
     * }
     * }
     * </pre>
     * <p>
     * Instead, use the {@link VideoProfile#isAudioOnly(int)} helper function to check if a
     * video state represents an audio-only call:
     * <pre>
     * {@code
     * // This is the correct way to check for an audio-only call.
     * if (VideoProfile.isAudioOnly(videoState)) {
     *      // Handle audio-only call.
     * }
     * }
     * </pre>
     */
    public static final int STATE_AUDIO_ONLY = 0x0;

    /**
     * Video transmission is enabled.
     */
    public static final int STATE_TX_ENABLED = 0x1;

    /**
     * Video reception is enabled.
     */
    public static final int STATE_RX_ENABLED = 0x2;

    /**
     * Video signal is bi-directional.
     */
    public static final int STATE_BIDIRECTIONAL = STATE_TX_ENABLED | STATE_RX_ENABLED;

    /**
     * Video is paused.
     */
    public static final int STATE_PAUSED = 0x4;

    private final int mVideoState;

    private final int mQuality;

    /**
     * Creates an instance of the VideoProfile
     *
     * @param videoState The video state.
     */
    public VideoProfile(@VideoState int videoState) {
        this(videoState, QUALITY_DEFAULT);
    }

    /**
     * Creates an instance of the VideoProfile
     *
     * @param videoState The video state.
     * @param quality The video quality.
     */
    public VideoProfile(@VideoState int videoState, @VideoQuality int quality) {
        mVideoState = videoState;
        mQuality = quality;
    }

    /**
     * The video state of the call.
     * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY},
     * {@link VideoProfile#STATE_BIDIRECTIONAL},
     * {@link VideoProfile#STATE_TX_ENABLED},
     * {@link VideoProfile#STATE_RX_ENABLED},
     * {@link VideoProfile#STATE_PAUSED}.
     */
    @VideoState
    public int getVideoState() {
        return mVideoState;
    }

    /**
     * The desired video quality for the call.
     * Valid values: {@link VideoProfile#QUALITY_HIGH}, {@link VideoProfile#QUALITY_MEDIUM},
     * {@link VideoProfile#QUALITY_LOW}, {@link VideoProfile#QUALITY_DEFAULT}.
     */
    @VideoQuality
    public int getQuality() {
        return mQuality;
    }

    /**
     * Responsible for creating VideoProfile objects from deserialized Parcels.
     **/
    public static final @android.annotation.NonNull Parcelable.Creator<VideoProfile> CREATOR =
            new Parcelable.Creator<VideoProfile> () {
                /**
                 * Creates a MediaProfile instances from a parcel.
                 *
                 * @param source The parcel.
                 * @return The MediaProfile.
                 */
                @Override
                public VideoProfile createFromParcel(Parcel source) {
                    int state = source.readInt();
                    int quality = source.readInt();

                    ClassLoader classLoader = VideoProfile.class.getClassLoader();
                    return new VideoProfile(state, quality);
                }

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

    /**
     * Describe the kinds of special objects contained in this Parcelable's
     * marshalled representation.
     *
     * @return a bitmask indicating the set of special object types marshalled
     * by the Parcelable.
     */
    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * Flatten this object in to a Parcel.
     *
     * @param dest  The Parcel in which the object should be written.
     * @param flags Additional flags about how the object should be written.
     *              May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mVideoState);
        dest.writeInt(mQuality);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[VideoProfile videoState = ");
        sb.append(videoStateToString(mVideoState));
        sb.append(" videoQuality = ");
        sb.append(mQuality);
        sb.append("]");
        return sb.toString();
    }

    /**
     * Generates a string representation of a video state.
     *
     * @param videoState The video state.
     * @return String representation of the video state.
     */
    public static String videoStateToString(@VideoState int videoState) {
        StringBuilder sb = new StringBuilder();
        sb.append("Audio");

        if (videoState == STATE_AUDIO_ONLY) {
            sb.append(" Only");
        } else {
            if (isTransmissionEnabled(videoState)) {
                sb.append(" Tx");
            }

            if (isReceptionEnabled(videoState)) {
                sb.append(" Rx");
            }

            if (isPaused(videoState)) {
                sb.append(" Pause");
            }
        }

        return sb.toString();
    }

    /**
     * Indicates whether the video state is audio only.
     * <p>
     * Note: Considers only whether either both the {@link #STATE_RX_ENABLED} or
     * {@link #STATE_TX_ENABLED} bits are off, but not {@link #STATE_PAUSED}.
     *
     * @param videoState The video state.
     * @return {@code True} if the video state is audio only, {@code false} otherwise.
     */
    public static boolean isAudioOnly(@VideoState int videoState) {
        return !hasState(videoState, VideoProfile.STATE_TX_ENABLED)
                && !hasState(videoState, VideoProfile.STATE_RX_ENABLED);
    }

    /**
     * Indicates whether video transmission or reception is enabled for a video state.
     *
     * @param videoState The video state.
     * @return {@code True} if video transmission or reception is enabled, {@code false} otherwise.
     */
    public static boolean isVideo(@VideoState int videoState) {
        return hasState(videoState, VideoProfile.STATE_TX_ENABLED)
                || hasState(videoState, VideoProfile.STATE_RX_ENABLED)
                || hasState(videoState, VideoProfile.STATE_BIDIRECTIONAL);
    }

    /**
     * Indicates whether the video state has video transmission enabled.
     *
     * @param videoState The video state.
     * @return {@code True} if video transmission is enabled, {@code false} otherwise.
     */
    public static boolean isTransmissionEnabled(@VideoState int videoState) {
        return hasState(videoState, VideoProfile.STATE_TX_ENABLED);
    }

    /**
     * Indicates whether the video state has video reception enabled.
     *
     * @param videoState The video state.
     * @return {@code True} if video reception is enabled, {@code false} otherwise.
     */
    public static boolean isReceptionEnabled(@VideoState int videoState) {
        return hasState(videoState, VideoProfile.STATE_RX_ENABLED);
    }

    /**
     * Indicates whether the video state is bi-directional.
     *
     * @param videoState The video state.
     * @return {@code True} if the video is bi-directional, {@code false} otherwise.
     */
    public static boolean isBidirectional(@VideoState int videoState) {
        return hasState(videoState, VideoProfile.STATE_BIDIRECTIONAL);
    }

    /**
     * Indicates whether the video state is paused.
     *
     * @param videoState The video state.
     * @return {@code True} if the video is paused, {@code false} otherwise.
     */
    public static boolean isPaused(@VideoState int videoState) {
        return hasState(videoState, VideoProfile.STATE_PAUSED);
    }

    /**
     * Indicates if a specified state is set in a videoState bit-mask.
     *
     * @param videoState The video state bit-mask.
     * @param state The state to check.
     * @return {@code True} if the state is set.
     */
    private static boolean hasState(@VideoState int videoState, @VideoState int state) {
        return (videoState & state) == state;
    }

    /**
     * Represents the camera capabilities important to a Video Telephony provider.
     */
    public static final class CameraCapabilities implements Parcelable {

        /**
         * The width of the camera video in pixels.
         */
        private final int mWidth;

        /**
         * The height of the camera video in pixels.
         */
        private final int mHeight;

        /**
         * Whether the camera supports zoom.
         */
        private final boolean mZoomSupported;

        /**
         * The maximum zoom supported by the camera.
         */
        private final float mMaxZoom;

        /**
         * Create a call camera capabilities instance.
         *
         * @param width The width of the camera video (in pixels).
         * @param height The height of the camera video (in pixels).
         */
        public CameraCapabilities(@IntRange(from = 0) int width, @IntRange(from = 0) int height) {
            this(width, height, false, 1.0f);
        }

        /**
         * Create a call camera capabilities instance that optionally supports zoom.
         *
         * @param width The width of the camera video (in pixels).
         * @param height The height of the camera video (in pixels).
         * @param zoomSupported True when camera supports zoom.
         * @param maxZoom Maximum zoom supported by camera.
         */
        public CameraCapabilities(@IntRange(from = 0) int width,  @IntRange(from = 0) int height,
                                   boolean zoomSupported,  @FloatRange(from = 1.0f) float maxZoom) {
            mWidth = width;
            mHeight = height;
            mZoomSupported = zoomSupported;
            mMaxZoom = maxZoom;
        }

        /**
         * Responsible for creating CallCameraCapabilities objects from deserialized Parcels.
         **/
        public static final @android.annotation.NonNull Parcelable.Creator<CameraCapabilities> CREATOR =
                new Parcelable.Creator<CameraCapabilities> () {
                    /**
                     * Creates a CallCameraCapabilities instances from a parcel.
                     *
                     * @param source The parcel.
                     * @return The CallCameraCapabilities.
                     */
                    @Override
                    public CameraCapabilities createFromParcel(Parcel source) {
                        int width = source.readInt();
                        int height = source.readInt();
                        boolean supportsZoom = source.readByte() != 0;
                        float maxZoom = source.readFloat();

                        return new CameraCapabilities(width, height, supportsZoom, maxZoom);
                    }

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

        /**
         * Describe the kinds of special objects contained in this Parcelable's
         * marshalled representation.
         *
         * @return a bitmask indicating the set of special object types marshalled
         * by the Parcelable.
         */
        @Override
        public int describeContents() {
            return 0;
        }

        /**
         * Flatten this object in to a Parcel.
         *
         * @param dest  The Parcel in which the object should be written.
         * @param flags Additional flags about how the object should be written.
         *              May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
         */
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeInt(getWidth());
            dest.writeInt(getHeight());
            dest.writeByte((byte) (isZoomSupported() ? 1 : 0));
            dest.writeFloat(getMaxZoom());
        }

        /**
         * The width of the camera video in pixels.
         */
        public int getWidth() {
            return mWidth;
        }

        /**
         * The height of the camera video in pixels.
         */
        public int getHeight() {
            return mHeight;
        }

        /**
         * Returns {@code true} is zoom is supported, {@code false} otherwise.
         */
        public boolean isZoomSupported() {
            return mZoomSupported;
        }

        /**
         * Returns the maximum zoom supported by the camera.
         */
        public float getMaxZoom() {
            return mMaxZoom;
        }
    }

}
