/*
 * Copyright (C) 2019 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.toolbar;

import android.car.drivingstate.CarUxRestrictions;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import com.android.car.ui.R;
import com.android.car.ui.utils.CarUxRestrictionsUtil;
import com.android.car.ui.uxr.DrawableStateView;

class MenuItemRenderer implements MenuItem.Listener {

    private static final int[] RESTRICTED_STATE = new int[] {R.attr.state_ux_restricted};

    private Toolbar.State mToolbarState;
    private CarUxRestrictions mUxRestrictions;

    private MenuItem mMenuItem;
    private ViewGroup mParentView;
    private View mView;
    private boolean mPreviouslySetOnClickListener = false;

    MenuItemRenderer(MenuItem item, ViewGroup parentView) {
        mMenuItem = item;
        mParentView = parentView;
        mUxRestrictions = CarUxRestrictionsUtil.getInstance(parentView.getContext())
                .getCurrentRestrictions();
        mMenuItem.setListener(this);
    }

    void setToolbarState(Toolbar.State state) {
        mToolbarState = state;

        if (mMenuItem.isSearch()) {
            updateView();
        }
    }

    void setUxRestrictions(CarUxRestrictions restrictions) {
        mUxRestrictions = restrictions;

        if (mMenuItem.getUxRestrictions() != CarUxRestrictions.UX_RESTRICTIONS_BASELINE) {
            updateView();
        }
    }

    @Override
    public void performClick() {
        if (!isRestricted() && mView != null) {
            mView.performClick();
        }
    }

    @Override
    public void onMenuItemChanged() {
        updateView();
    }

    @Override
    public View getView() {
        if (mMenuItem.mCustomLayoutId != 0) {
            return mView;
        }
        return null;
    }

    View createView() {
        LayoutInflater inflater = (LayoutInflater) mParentView.getContext().getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);

        if (mMenuItem.mCustomLayoutId != 0) {
            mView = inflater.inflate(mMenuItem.mCustomLayoutId, mParentView, false);
        } else if (mMenuItem.isCheckable()) {
            mView = inflater.inflate(
                    R.layout.car_ui_toolbar_menu_item_switch, mParentView, false);
        } else if (mMenuItem.getIcon() != null) {
            mView = inflater.inflate(
                    R.layout.car_ui_toolbar_menu_item_icon, mParentView, false);
        } else {
            mView = inflater.inflate(
                    R.layout.car_ui_toolbar_menu_item_text, mParentView, false);
        }

        updateView();
        return mView;
    }

    private void updateView() {
        if (mView == null) {
            return;
        }

        if (!mMenuItem.isVisible()
                || (mMenuItem.isSearch() && mToolbarState == Toolbar.State.SEARCH)) {
            mView.setVisibility(View.GONE);
            return;
        }

        mView.setVisibility(View.VISIBLE);

        ImageView imageView = mView.findViewById(R.id.car_ui_toolbar_menu_item_icon);
        if (imageView != null) {
            imageView.setImageDrawable(mMenuItem.getIcon());
        }

        TextView textView = mView.findViewById(R.id.car_ui_toolbar_menu_item_text);
        if (textView != null) {
            textView.setText(mMenuItem.getTitle());
        }

        Switch s = mView.findViewById(R.id.car_ui_toolbar_menu_item_switch);
        if (s != null) {
            s.setChecked(mMenuItem.isChecked());
        }

        recursiveSetEnabledAndDrawableState(mView);
        mView.setActivated(mMenuItem.isActivated());

        MenuItem.OnClickListener onClickListener = mMenuItem.getOnClickListener();
        if (onClickListener != null || mMenuItem.isCheckable()) {
            if (isRestricted()) {
                mView.setOnClickListener(v -> Toast.makeText(mView.getContext(),
                        R.string.car_ui_restricted_while_driving, Toast.LENGTH_LONG).show());
            } else {
                mView.setOnClickListener(v -> {
                    if (mMenuItem.isActivatable()) {
                        mMenuItem.setActivated(!mMenuItem.isActivated());
                    }

                    if (mMenuItem.isCheckable()) {
                        mMenuItem.setChecked(!mMenuItem.isChecked());
                    }

                    if (onClickListener != null) {
                        onClickListener.onClick(mMenuItem);
                    }
                });
            }

            mPreviouslySetOnClickListener = true;
        } else if (mPreviouslySetOnClickListener) {
            // We should only set this stuff to null if we had previously set our own listener
            // to avoid overwriting a custom view's onClickListener
            mView.setOnClickListener(null);
            mView.setClickable(false);
            mPreviouslySetOnClickListener = false;
        }
    }

    private void recursiveSetEnabledAndDrawableState(View view) {
        view.setEnabled(mMenuItem.isEnabled());

        if (view instanceof ImageView) {
            ((ImageView) view).setImageState(isRestricted() ? RESTRICTED_STATE : null, true);
        } else if (view instanceof DrawableStateView) {
            ((DrawableStateView) view).setDrawableState(isRestricted() ? RESTRICTED_STATE : null);
        }

        if (view instanceof ViewGroup) {
            ViewGroup viewGroup = ((ViewGroup) view);
            for (int i = 0; i < viewGroup.getChildCount(); i++) {
                recursiveSetEnabledAndDrawableState(viewGroup.getChildAt(i));
            }
        }
    }

    private boolean isRestricted() {
        return CarUxRestrictionsUtil.isRestricted(mMenuItem.getUxRestrictions(), mUxRestrictions);
    }
}
