/*
 * 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.car.ui.paintbooth;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.os.IBinder;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;

import androidx.core.app.NotificationCompat;

/**
 * To start the service:
 * adb shell am start-foreground-service com.android.car.ui.paintbooth/.DisplayService
 *
 * To stop the service:
 * adb shell am stopservice com.android.car.ui.paintbooth/.DisplayService
 *
 * When the service is started it will draw a overlay view on top of the screen displayed. This
 * overlay comes from a SVG file that can be modified to take different shapes. This service will be
 * used to display different screen styles from OEMs.
 */
public class VisibleBoundsSimulator extends Service {
    private static final int FOREGROUND_SERVICE_ID = 222;
    private View mContainer;

    private WindowManager mWindowManager;

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented.");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (MainActivity.STOP_SERVICE.equals(intent.getAction())) {
            stopSelf();
        }

        return START_STICKY;
    }

    @Override
    public void onCreate() {

        Intent notificationIntent = new Intent(this, VisibleBoundsSimulator.class);

        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
                notificationIntent, 0);

        NotificationChannel channel = new NotificationChannel("DisplayService",
                "Show overlay screen",
                NotificationManager.IMPORTANCE_DEFAULT);
        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.createNotificationChannel(channel);

        Notification notification =
                new NotificationCompat.Builder(this, "DisplayService")
                        .setSmallIcon(R.drawable.ic_launcher)
                        .setContentTitle("DisplayService")
                        .setContentText("Show overlay screen")
                        .setContentIntent(pendingIntent).build();

        startForeground(FOREGROUND_SERVICE_ID, notification);
        applyDisplayOverlay();
    }

    /**
     * Creates a view overlay on top of a new window. The overlay gravity is set to left and
     * bottom. If the width and height is not provided then the default is to take up the entire
     * screen. Overlay will show bounds around the view and we can still click through the window.
     */
    private void applyDisplayOverlay() {
        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

        DisplayMetrics displayMetrics = new DisplayMetrics();

        mWindowManager.getDefaultDisplay().getRealMetrics(displayMetrics);
        int screenHeight = displayMetrics.heightPixels;
        int screenWidth = displayMetrics.widthPixels;
        LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                // WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY is a hidden api, so
                // use its value here so we can still compile on gradle / google3
                WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW + 26,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                        | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
                PixelFormat.TRANSLUCENT);

        params.packageName = this.getPackageName();
        params.gravity = Gravity.BOTTOM | Gravity.LEFT;

        Display display = mWindowManager.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        int height = size.y;

        params.x = 0;
        // If the sysUI is showing and nav bar is taking up some space at the bottom we want to
        // offset the height of the navBar so that the overlay starts from the bottom left.
        params.y = -(screenHeight - height);

        float overlayWidth = getApplicationContext().getResources().getDimension(
                R.dimen.screen_shape_container_width);
        float overlayHeight = getApplicationContext().getResources().getDimension(
                R.dimen.screen_shape_container_height);


        params.width = (int) (overlayWidth == 0 ? screenWidth : overlayHeight);
        params.height = (int) (overlayHeight == 0 ? screenHeight : overlayHeight);
        params.setTitle("Simulated display bound");

        mContainer = inflater.inflate(R.layout.simulated_screen_shape_container, null);
        mContainer.setLayoutParams(params);

        mWindowManager.addView(mContainer, params);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mWindowManager.removeView(mContainer);
        stopSelf();
    }
}
