/*
 * Copyright (C) 2012 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.content.Context;
import android.os.Handler;
import android.view.Display;

import java.io.PrintWriter;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * A display adapter makes zero or more display devices available to the system
 * and provides facilities for discovering when displays are connected or disconnected.
 * <p>
 * For now, all display adapters are registered in the system server but
 * in principle it could be done from other processes.
 * </p><p>
 * Display adapters are guarded by the {@link DisplayManagerService.SyncRoot} lock.
 * </p>
 */
abstract class DisplayAdapter {
    private final DisplayManagerService.SyncRoot mSyncRoot;
    private final Context mContext;
    private final Handler mHandler;
    private final Listener mListener;
    private final String mName;

    public static final int DISPLAY_DEVICE_EVENT_ADDED = 1;
    public static final int DISPLAY_DEVICE_EVENT_CHANGED = 2;
    public static final int DISPLAY_DEVICE_EVENT_REMOVED = 3;

    /**
     * Used to generate globally unique display mode ids.
     */
    private static final AtomicInteger NEXT_DISPLAY_MODE_ID = new AtomicInteger(1);  // 0 = no mode.

    /**
     * Used to generate globally unique color transform ids.
     *
     * Valid IDs start at 1 with 0 as the sentinel value for the default mode.
     */
    private static final AtomicInteger NEXT_COLOR_TRANSFORM_ID = new AtomicInteger(1);

    // Called with SyncRoot lock held.
    public DisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
            Context context, Handler handler, Listener listener, String name) {
        mSyncRoot = syncRoot;
        mContext = context;
        mHandler = handler;
        mListener = listener;
        mName = name;
    }

    /**
     * Gets the object that the display adapter should synchronize on when handling
     * calls that come in from outside of the display manager service.
     */
    public final DisplayManagerService.SyncRoot getSyncRoot() {
        return mSyncRoot;
    }

    /**
     * Gets the display adapter's context.
     */
    public final Context getContext() {
        return mContext;
    }

    /**
     * Gets a handler that the display adapter may use to post asynchronous messages.
     */
    public final Handler getHandler() {
        return mHandler;
    }

    /**
     * Gets the display adapter name for debugging purposes.
     */
    public final String getName() {
        return mName;
    }

    /**
     * Registers the display adapter with the display manager.
     *
     * The display adapter should register any built-in display devices as soon as possible.
     * The boot process will wait for the default display to be registered.
     * Other display devices can be registered dynamically later.
     */
    public void registerLocked() {
    }

    /**
     * Dumps the local state of the display adapter.
     */
    public void dumpLocked(PrintWriter pw) {
    }

    /**
     * Sends a display device event to the display adapter listener asynchronously.
     */
    protected final void sendDisplayDeviceEventLocked(
            final DisplayDevice device, final int event) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mListener.onDisplayDeviceEvent(device, event);
            }
        });
    }

    /**
     * Sends a request to perform traversals.
     */
    protected final void sendTraversalRequestLocked() {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mListener.onTraversalRequested();
            }
        });
    }

    public static Display.Mode createMode(int width, int height, float refreshRate) {
        return new Display.Mode(
                NEXT_DISPLAY_MODE_ID.getAndIncrement(), width, height, refreshRate);
    }

    public static Display.ColorTransform createColorTransform(int colorTransform) {
        return new Display.ColorTransform(
                NEXT_COLOR_TRANSFORM_ID.getAndIncrement(), colorTransform);
    }

    public interface Listener {
        public void onDisplayDeviceEvent(DisplayDevice device, int event);
        public void onTraversalRequested();
    }
}
