/*
 * 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 com.android.keyguard;

import android.app.Presentation;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.graphics.Point;
import android.media.MediaRouter;
import android.media.MediaRouter.RouteInfo;
import android.os.Bundle;
import android.util.Slog;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;

public class KeyguardDisplayManager {
    protected static final String TAG = "KeyguardDisplayManager";
    private static boolean DEBUG = KeyguardConstants.DEBUG;
    Presentation mPresentation;
    private MediaRouter mMediaRouter;
    private Context mContext;
    private boolean mShowing;

    public KeyguardDisplayManager(Context context) {
        mContext = context;
        mMediaRouter = (MediaRouter) mContext.getSystemService(Context.MEDIA_ROUTER_SERVICE);
    }

    public void show() {
        if (!mShowing) {
            if (DEBUG) Slog.v(TAG, "show");
            mMediaRouter.addCallback(MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY,
                    mMediaRouterCallback, MediaRouter.CALLBACK_FLAG_PASSIVE_DISCOVERY);
            updateDisplays(true);
        }
        mShowing = true;
    }

    public void hide() {
        if (mShowing) {
            if (DEBUG) Slog.v(TAG, "hide");
            mMediaRouter.removeCallback(mMediaRouterCallback);
            updateDisplays(false);
        }
        mShowing = false;
    }

    private final MediaRouter.SimpleCallback mMediaRouterCallback =
            new MediaRouter.SimpleCallback() {
        @Override
        public void onRouteSelected(MediaRouter router, int type, RouteInfo info) {
            if (DEBUG) Slog.d(TAG, "onRouteSelected: type=" + type + ", info=" + info);
            updateDisplays(mShowing);
        }

        @Override
        public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) {
            if (DEBUG) Slog.d(TAG, "onRouteUnselected: type=" + type + ", info=" + info);
            updateDisplays(mShowing);
        }

        @Override
        public void onRoutePresentationDisplayChanged(MediaRouter router, RouteInfo info) {
            if (DEBUG) Slog.d(TAG, "onRoutePresentationDisplayChanged: info=" + info);
            updateDisplays(mShowing);
        }
    };

    private OnDismissListener mOnDismissListener = new OnDismissListener() {

        @Override
        public void onDismiss(DialogInterface dialog) {
            mPresentation = null;
        }
    };

    protected void updateDisplays(boolean showing) {
        if (showing) {
            MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(
                    MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY);
            boolean useDisplay = route != null
                    && route.getPlaybackType() == MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE;
            Display presentationDisplay = useDisplay ? route.getPresentationDisplay() : null;

            if (mPresentation != null && mPresentation.getDisplay() != presentationDisplay) {
                if (DEBUG) Slog.v(TAG, "Display gone: " + mPresentation.getDisplay());
                mPresentation.dismiss();
                mPresentation = null;
            }

            if (mPresentation == null && presentationDisplay != null) {
                if (DEBUG) Slog.i(TAG, "Keyguard enabled on display: " + presentationDisplay);
                mPresentation = new KeyguardPresentation(mContext, presentationDisplay,
                        R.style.keyguard_presentation_theme);
                mPresentation.setOnDismissListener(mOnDismissListener);
                try {
                    mPresentation.show();
                } catch (WindowManager.InvalidDisplayException ex) {
                    Slog.w(TAG, "Invalid display:", ex);
                    mPresentation = null;
                }
            }
        } else {
            if (mPresentation != null) {
                mPresentation.dismiss();
                mPresentation = null;
            }
        }
    }

    private final static class KeyguardPresentation extends Presentation {
        private static final int VIDEO_SAFE_REGION = 80; // Percentage of display width & height
        private static final int MOVE_CLOCK_TIMEOUT = 10000; // 10s
        private View mClock;
        private int mUsableWidth;
        private int mUsableHeight;
        private int mMarginTop;
        private int mMarginLeft;
        Runnable mMoveTextRunnable = new Runnable() {
            @Override
            public void run() {
                int x = mMarginLeft + (int) (Math.random() * (mUsableWidth - mClock.getWidth()));
                int y = mMarginTop + (int) (Math.random() * (mUsableHeight - mClock.getHeight()));
                mClock.setTranslationX(x);
                mClock.setTranslationY(y);
                mClock.postDelayed(mMoveTextRunnable, MOVE_CLOCK_TIMEOUT);
            }
        };

        public KeyguardPresentation(Context context, Display display, int theme) {
            super(context, display, theme);
            getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
        }

        @Override
        public void onDetachedFromWindow() {
            mClock.removeCallbacks(mMoveTextRunnable);
        }

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            Point p = new Point();
            getDisplay().getSize(p);
            mUsableWidth = VIDEO_SAFE_REGION * p.x/100;
            mUsableHeight = VIDEO_SAFE_REGION * p.y/100;
            mMarginLeft = (100 - VIDEO_SAFE_REGION) * p.x / 200;
            mMarginTop = (100 - VIDEO_SAFE_REGION) * p.y / 200;

            setContentView(R.layout.keyguard_presentation);
            mClock = findViewById(R.id.clock);

            // Avoid screen burn in
            mClock.post(mMoveTextRunnable);
        }
    }
}
