/*
 * Copyright (C) 2020 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 com.android.server.display;

import android.util.IndentingPrintWriter;

import java.util.ArrayList;
import java.util.List;

/**
 * Represents a collection of {@link LogicalDisplay}s which act in unison for certain behaviors and
 * operations; particularly display-state.
 *
 * @hide
 */
public class DisplayGroup {
    // Indicates that the display group is adjacent to the default group. Some of the
    // properties that happen for such groups in conjuncture with the default groups are
    // 1. The device will lock only when all the groups with this flag and the default group are
    // made non interactive
    // 2. The power button will sleep only these groups and the default group
    public static long FLAG_DEFAULT_GROUP_ADJACENT = 1L << 1;
    private final List<LogicalDisplay> mDisplays = new ArrayList<>();
    private final int mGroupId;

    private String mGroupName;

    private long mFlags;

    private int mChangeCount;

    DisplayGroup(int groupId) {
        mGroupId = groupId;
    }

    /** Returns the identifier for the Group. */
    int getGroupId() {
        return mGroupId;
    }

    public String getGroupName() {
        return mGroupName;
    }

    public void setGroupName(String groupName) {
        mGroupName = groupName;
    }

    /**
     * Sets the supplied flag for this display group
     */
    public void setFlags(long flags) {
        mFlags |= flags;
    }

    /**
     * Gets the flags set for this display group
     */
    public long getFlags() {
        return mFlags;
    }

    /**
     * Adds the provided {@code display} to the Group
     *
     * @param display the {@link LogicalDisplay} to add to the Group
     */
    void addDisplayLocked(LogicalDisplay display) {
        if (!containsLocked(display)) {
            mChangeCount++;
            mDisplays.add(display);
        }
    }

    boolean containsLocked(LogicalDisplay display) {
        return mDisplays.contains(display);
    }

    /**
     * Removes the provided {@code display} from the Group.
     *
     * @param display The {@link LogicalDisplay} to remove from the Group.
     * @return {@code true} if the {@code display} was removed; otherwise {@code false}
     */
    boolean removeDisplayLocked(LogicalDisplay display) {
        mChangeCount++;
        return mDisplays.remove(display);
    }

    /** Returns {@code true} if there are no {@link LogicalDisplay LogicalDisplays} in the Group. */
    boolean isEmptyLocked() {
        return mDisplays.isEmpty();
    }

    /** Returns a count of the changes made to this display group. */
    int getChangeCountLocked() {
        return mChangeCount;
    }

    /** Returns the number of {@link LogicalDisplay LogicalDisplays} in the Group. */
    int getSizeLocked() {
        return mDisplays.size();
    }

    /** Returns the ID of the {@link LogicalDisplay} at the provided {@code index}. */
    int getIdLocked(int index) {
        return mDisplays.get(index).getDisplayIdLocked();
    }

    /** Returns the IDs of the {@link LogicalDisplay}s belonging to the DisplayGroup. */
    int[] getIdsLocked() {
        final int numDisplays = mDisplays.size();
        final int[] displayIds = new int[numDisplays];
        for (int i = 0; i < numDisplays; i++) {
            displayIds[i] = mDisplays.get(i).getDisplayIdLocked();
        }
        return displayIds;
    }

    /** Dumps information about the DisplayGroup. */
    void dumpLocked(IndentingPrintWriter ipw) {
        final int numDisplays = mDisplays.size();
        for (int i = 0; i < numDisplays; i++) {
            LogicalDisplay logicalDisplay = mDisplays.get(i);
            ipw.println("Display " + logicalDisplay.getDisplayIdLocked() + " "
                    + logicalDisplay.getPrimaryDisplayDeviceLocked());
        }
        ipw.println("Group Name: " + getGroupName());
        ipw.println("Flags: " + getFlags());
    }
}
