/*
 * 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.systemui.car.systembar;

import android.annotation.IntDef;
import android.annotation.Nullable;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

import com.android.systemui.R;
import com.android.systemui.car.hvac.HvacPanelOverlayViewController;
import com.android.systemui.car.statusicon.ui.QuickControlsEntryPointsController;
import com.android.systemui.car.statusicon.ui.ReadOnlyIconsController;
import com.android.systemui.car.systembar.CarSystemBarController.HvacPanelController;
import com.android.systemui.car.systembar.CarSystemBarController.NotificationsShadeController;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.statusbar.phone.StatusBarIconController;

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

/**
 * A custom system bar for the automotive use case.
 * <p>
 * The system bar in the automotive use case is more like a list of shortcuts, rendered
 * in a linear layout.
 */
public class CarSystemBarView extends LinearLayout {

    @IntDef(value = {BUTTON_TYPE_NAVIGATION, BUTTON_TYPE_KEYGUARD, BUTTON_TYPE_OCCLUSION})
    @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
    private @interface ButtonsType {
    }

    private static final String TAG = CarSystemBarView.class.getSimpleName();
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    public static final int BUTTON_TYPE_NAVIGATION = 0;
    public static final int BUTTON_TYPE_KEYGUARD = 1;
    public static final int BUTTON_TYPE_OCCLUSION = 2;

    private final boolean mConsumeTouchWhenPanelOpen;
    private final boolean mButtonsDraggable;

    private View mNavButtons;
    private CarSystemBarButton mNotificationsButton;
    private HvacButton mHvacButton;
    private NotificationsShadeController mNotificationsShadeController;
    private HvacPanelController mHvacPanelController;
    private View mLockScreenButtons;
    private View mOcclusionButtons;
    private ViewGroup mQcEntryPointsContainer;
    private ViewGroup mReadOnlyIconsContainer;
    // used to wire in open/close gestures for notifications
    private OnTouchListener mStatusBarWindowTouchListener;
    private HvacPanelOverlayViewController mHvacPanelOverlayViewController;

    public CarSystemBarView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mConsumeTouchWhenPanelOpen = getResources().getBoolean(
                R.bool.config_consumeSystemBarTouchWhenNotificationPanelOpen);
        mButtonsDraggable = getResources().getBoolean(R.bool.config_systemBarButtonsDraggable);
    }

    @Override
    public void onFinishInflate() {
        mNavButtons = findViewById(R.id.nav_buttons);
        mLockScreenButtons = findViewById(R.id.lock_screen_nav_buttons);
        mOcclusionButtons = findViewById(R.id.occlusion_buttons);
        mNotificationsButton = findViewById(R.id.notifications);
        mHvacButton = findViewById(R.id.hvac);
        mQcEntryPointsContainer = findViewById(R.id.qc_entry_points_container);
        mReadOnlyIconsContainer = findViewById(R.id.read_only_icons_container);
        if (mNotificationsButton != null) {
            mNotificationsButton.setOnClickListener(this::onNotificationsClick);
        }
        // Needs to be clickable so that it will receive ACTION_MOVE events.
        setClickable(true);
        // Needs to not be focusable so rotary won't highlight the entire nav bar.
        setFocusable(false);
    }

    void setupHvacButton() {
        if (mHvacButton != null) {
            mHvacButton.setOnClickListener(this::onHvacClick);
        }
    }

    void setupQuickControlsEntryPoints(
            QuickControlsEntryPointsController quickControlsEntryPointsController,
            boolean isSetUp) {
        if (mQcEntryPointsContainer != null) {
            quickControlsEntryPointsController.addIconViews(mQcEntryPointsContainer, isSetUp);
        }
    }

    void setupReadOnlyIcons(ReadOnlyIconsController readOnlyIconsController) {
        if (mReadOnlyIconsContainer != null) {
            readOnlyIconsController.addIconViews(mReadOnlyIconsContainer);
        }
    }

    void setupIconController(FeatureFlags featureFlags, StatusBarIconController iconController) {
        View mStatusIcons = findViewById(R.id.statusIcons);
        if (mStatusIcons != null) {
            // Attach the controllers for Status icons such as wifi and bluetooth if the standard
            // container is in the view.
            StatusBarIconController.DarkIconManager mDarkIconManager =
                    new StatusBarIconController.DarkIconManager(
                            mStatusIcons.findViewById(R.id.statusIcons), featureFlags);
            mDarkIconManager.setShouldLog(true);
            iconController.addIconGroup(mDarkIconManager);
        }
    }

    // Used to forward touch events even if the touch was initiated from a child component
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (mStatusBarWindowTouchListener != null) {
            if (!mButtonsDraggable) {
                return false;
            }
            boolean shouldConsumeEvent = mNotificationsShadeController == null ? false
                    : mNotificationsShadeController.isNotificationPanelOpen();

            // Forward touch events to the status bar window so it can drag
            // windows if required (Notification shade)
            mStatusBarWindowTouchListener.onTouch(this, ev);

            if (mConsumeTouchWhenPanelOpen && shouldConsumeEvent) {
                return true;
            }
        }
        return super.onInterceptTouchEvent(ev);
    }

    /** Sets the notifications panel controller. */
    public void setNotificationsPanelController(NotificationsShadeController controller) {
        mNotificationsShadeController = controller;
    }

    /** Sets the HVAC panel controller. */
    public void setHvacPanelController(HvacPanelController controller) {
        mHvacPanelController = controller;
    }

    /** Gets the notifications panel controller. */
    public NotificationsShadeController getNotificationsPanelController() {
        return mNotificationsShadeController;
    }

    /** Gets the HVAC panel controller. */
    public HvacPanelController getHvacPanelController() {
        return mHvacPanelController;
    }

    /**
     * Sets a touch listener that will be called from onInterceptTouchEvent and onTouchEvent
     *
     * @param statusBarWindowTouchListener The listener to call from touch and intercept touch
     */
    public void setStatusBarWindowTouchListener(OnTouchListener statusBarWindowTouchListener) {
        mStatusBarWindowTouchListener = statusBarWindowTouchListener;
    }

    /** Gets the touch listener that will be called from onInterceptTouchEvent and onTouchEvent. */
    public OnTouchListener getStatusBarWindowTouchListener() {
        return mStatusBarWindowTouchListener;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mStatusBarWindowTouchListener != null) {
            mStatusBarWindowTouchListener.onTouch(this, event);
        }
        return super.onTouchEvent(event);
    }

    protected void onNotificationsClick(View v) {
        if (mNotificationsButton != null
                && mNotificationsButton.getDisabled()) {
            mNotificationsButton.runOnClickWhileDisabled();
            return;
        }
        if (mNotificationsShadeController != null) {
            mNotificationsShadeController.togglePanel();
        }
    }

    protected void onHvacClick(View v) {
        if (mHvacPanelController != null) {
            mHvacPanelController.togglePanel();
        }
    }

    /**
     * Shows buttons of the specified {@link ButtonsType}.
     *
     * NOTE: Only one type of buttons can be shown at a time, so showing buttons of one type will
     * hide all buttons of other types.
     *
     * @param buttonsType
     */
    public void showButtonsOfType(@ButtonsType int buttonsType) {
        switch(buttonsType) {
            case BUTTON_TYPE_NAVIGATION:
                setNavigationButtonsVisibility(View.VISIBLE);
                setKeyguardButtonsVisibility(View.GONE);
                setOcclusionButtonsVisibility(View.GONE);
                break;
            case BUTTON_TYPE_KEYGUARD:
                setNavigationButtonsVisibility(View.GONE);
                setKeyguardButtonsVisibility(View.VISIBLE);
                setOcclusionButtonsVisibility(View.GONE);
                break;
            case BUTTON_TYPE_OCCLUSION:
                setNavigationButtonsVisibility(View.GONE);
                setKeyguardButtonsVisibility(View.GONE);
                setOcclusionButtonsVisibility(View.VISIBLE);
                break;
        }
    }

    /**
     * Sets the system bar view's disabled state and runnable when disabled.
     */
    public void setDisabledSystemBarButton(int viewId, boolean disabled, Runnable runnable,
                @Nullable String buttonName) {
        CarSystemBarButton button = findViewById(viewId);
        if (button != null) {
            if (DEBUG) {
                Log.d(TAG, "setDisabledSystemBarButton for: " + buttonName + " to: " + disabled);
            }
            button.setDisabled(disabled, runnable);
        }
    }

    /**
     * Sets the system bar specific View container's visibility. ViewName is used just for
     * debugging.
     */
    public void setVisibilityByViewId(int viewId, @Nullable String viewName,
                @View.Visibility int visibility) {
        View v = findViewById(viewId);
        if (v != null) {
            if (DEBUG) Log.d(TAG, "setVisibilityByViewId for: " + viewName + " to: " + visibility);
            v.setVisibility(visibility);
        }
    }

    /**
     * Sets the HvacPanelOverlayViewController and adds HVAC button listeners
     */
    public void registerHvacPanelOverlayViewController(HvacPanelOverlayViewController controller) {
        mHvacPanelOverlayViewController = controller;
        if (mHvacPanelOverlayViewController != null && mHvacButton != null) {
            mHvacPanelOverlayViewController.registerViewStateListener(mHvacButton);
        }
    }

    private void setNavigationButtonsVisibility(@View.Visibility int visibility) {
        if (mNavButtons != null) {
            mNavButtons.setVisibility(visibility);
        }
    }

    private void setKeyguardButtonsVisibility(@View.Visibility int visibility) {
        if (mLockScreenButtons != null) {
            mLockScreenButtons.setVisibility(visibility);
        }
    }

    private void setOcclusionButtonsVisibility(@View.Visibility int visibility) {
        if (mOcclusionButtons != null) {
            mOcclusionButtons.setVisibility(visibility);
        }
    }

    /**
     * Toggles the notification unseen indicator on/off.
     *
     * @param hasUnseen true if the unseen notification count is great than 0.
     */
    public void toggleNotificationUnseenIndicator(Boolean hasUnseen) {
        if (mNotificationsButton == null) return;

        mNotificationsButton.setUnseen(hasUnseen);
    }
}
