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

import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;

import java.util.ArrayList;

/**
 * Information available from IRemoteDisplayProvider about available remote displays.
 *
 * Clients must not modify the contents of this object.
 * @hide
 */
public final class RemoteDisplayState implements Parcelable {
    // Note: These constants are used by the remote display provider API.
    // Do not change them!
    public static final String SERVICE_INTERFACE =
            "com.android.media.remotedisplay.RemoteDisplayProvider";
    public static final int DISCOVERY_MODE_NONE = 0;
    public static final int DISCOVERY_MODE_PASSIVE = 1;
    public static final int DISCOVERY_MODE_ACTIVE = 2;

    /**
     * A list of all remote displays.
     */
    @UnsupportedAppUsage
    public final ArrayList<RemoteDisplayInfo> displays;

    @UnsupportedAppUsage
    public RemoteDisplayState() {
        displays = new ArrayList<RemoteDisplayInfo>();
    }

    RemoteDisplayState(Parcel src) {
        displays = src.createTypedArrayList(RemoteDisplayInfo.CREATOR);
    }

    public boolean isValid() {
        if (displays == null) {
            return false;
        }
        final int count = displays.size();
        for (int i = 0; i < count; i++) {
            if (!displays.get(i).isValid()) {
                return false;
            }
        }
        return true;
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeTypedList(displays);
    }

    public static final @android.annotation.NonNull Parcelable.Creator<RemoteDisplayState> CREATOR =
            new Parcelable.Creator<RemoteDisplayState>() {
        @Override
        public RemoteDisplayState createFromParcel(Parcel in) {
            return new RemoteDisplayState(in);
        }

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

    public static final class RemoteDisplayInfo implements Parcelable {
        // Note: These constants are used by the remote display provider API.
        // Do not change them!
        public static final int STATUS_NOT_AVAILABLE = 0;
        public static final int STATUS_IN_USE = 1;
        public static final int STATUS_AVAILABLE = 2;
        public static final int STATUS_CONNECTING = 3;
        public static final int STATUS_CONNECTED = 4;

        public static final int PLAYBACK_VOLUME_VARIABLE =
                MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE;
        public static final int PLAYBACK_VOLUME_FIXED =
                MediaRouter.RouteInfo.PLAYBACK_VOLUME_FIXED;

        public String id;
        public String name;
        public String description;
        public int status;
        public int volume;
        public int volumeMax;
        public int volumeHandling;
        public int presentationDisplayId;

        public RemoteDisplayInfo(String id) {
            this.id = id;
            status = STATUS_NOT_AVAILABLE;
            volumeHandling = MediaRouter.RouteInfo.PLAYBACK_VOLUME_FIXED;
            presentationDisplayId = -1;
        }

        public RemoteDisplayInfo(RemoteDisplayInfo other) {
            id = other.id;
            name = other.name;
            description = other.description;
            status = other.status;
            volume = other.volume;
            volumeMax = other.volumeMax;
            volumeHandling = other.volumeHandling;
            presentationDisplayId = other.presentationDisplayId;
        }

        RemoteDisplayInfo(Parcel in) {
            id = in.readString();
            name = in.readString();
            description = in.readString();
            status = in.readInt();
            volume = in.readInt();
            volumeMax = in.readInt();
            volumeHandling = in.readInt();
            presentationDisplayId = in.readInt();
        }

        public boolean isValid() {
            return !TextUtils.isEmpty(id) && !TextUtils.isEmpty(name);
        }

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

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(id);
            dest.writeString(name);
            dest.writeString(description);
            dest.writeInt(status);
            dest.writeInt(volume);
            dest.writeInt(volumeMax);
            dest.writeInt(volumeHandling);
            dest.writeInt(presentationDisplayId);
        }

        @Override
        public String toString() {
            return "RemoteDisplayInfo{ id=" + id
                    + ", name=" + name
                    + ", description=" + description
                    + ", status=" + status
                    + ", volume=" + volume
                    + ", volumeMax=" + volumeMax
                    + ", volumeHandling=" + volumeHandling
                    + ", presentationDisplayId=" + presentationDisplayId
                    + " }";
        }

        @SuppressWarnings("hiding")
        public static final @android.annotation.NonNull Parcelable.Creator<RemoteDisplayInfo> CREATOR =
                new Parcelable.Creator<RemoteDisplayInfo>() {
            @Override
            public RemoteDisplayInfo createFromParcel(Parcel in) {
                return new RemoteDisplayInfo(in);
            }

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