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

import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.Editable;
import android.text.InputType;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;

import com.android.car.ui.AlertDialogBuilder;
import com.android.car.ui.baselayout.Insets;
import com.android.car.ui.baselayout.InsetsChangedListener;
import com.android.car.ui.core.CarUi;
import com.android.car.ui.paintbooth.R;
import com.android.car.ui.recyclerview.CarUiRecyclerView;
import com.android.car.ui.toolbar.MenuItem;
import com.android.car.ui.toolbar.TabLayout;
import com.android.car.ui.toolbar.Toolbar;
import com.android.car.ui.toolbar.ToolbarController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ToolbarActivity extends AppCompatActivity implements InsetsChangedListener {

    private List<MenuItem> mMenuItems = new ArrayList<>();
    private List<Pair<CharSequence, View.OnClickListener>> mButtons = new ArrayList<>();

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

        ToolbarController toolbarNonFinal = CarUi.getToolbar(this);
        if (toolbarNonFinal == null) {
            toolbarNonFinal = requireViewById(R.id.toolbar);
        }
        ToolbarController toolbar = toolbarNonFinal;
        toolbar.setTitle(getTitle());
        toolbar.setState(Toolbar.State.SUBPAGE);
        toolbar.setLogo(R.drawable.ic_launcher);
        toolbar.registerOnBackListener(
                () -> {
                    if (toolbar.getState() == Toolbar.State.SEARCH
                            || toolbar.getState() == Toolbar.State.EDIT) {
                        toolbar.setState(Toolbar.State.SUBPAGE);
                        return true;
                    }
                    return false;
                });

        mMenuItems.add(MenuItem.builder(this)
                .setToSearch()
                .setOnClickListener(i -> toolbar.setState(Toolbar.State.SEARCH))
                .build());

        toolbar.setMenuItems(mMenuItems);

        mButtons.add(Pair.create("Toggle progress bar", v -> {
            toolbar.getProgressBar().setVisible(!toolbar.getProgressBar().isVisible());
        }));

        mButtons.add(Pair.create("Change title", v ->
                toolbar.setTitle(toolbar.getTitle() + " X")));

        mButtons.add(Pair.create("Add/Change subtitle", v -> {
            CharSequence subtitle = toolbar.getSubtitle();
            if (TextUtils.isEmpty(subtitle)) {
                toolbar.setSubtitle("Subtitle");
            } else {
                toolbar.setSubtitle(subtitle + " X");
            }
        }));

        mButtons.add(Pair.create(getString(R.string.toolbar_set_xml_resource), v -> {
            mMenuItems.clear();
            toolbar.setMenuItems(R.xml.menuitems);
        }));

        mButtons.add(Pair.create(getString(R.string.toolbar_add_icon), v -> {
            mMenuItems.add(MenuItem.builder(this)
                    .setToSettings()
                    .setOnClickListener(i -> Toast.makeText(this, "Clicked",
                            Toast.LENGTH_SHORT).show())
                    .build());
            toolbar.setMenuItems(mMenuItems);
        }));

        mButtons.add(Pair.create(getString(R.string.toolbar_add_untined_icon), v -> {
            mMenuItems.add(MenuItem.builder(this)
                    .setIcon(R.drawable.ic_tracklist)
                    .setTinted(false)
                    .setOnClickListener(
                            i -> Toast.makeText(this, "Clicked",
                                    Toast.LENGTH_SHORT).show())
                    .build());
            toolbar.setMenuItems(mMenuItems);
        }));

        mButtons.add(Pair.create(getString(R.string.toolbar_add_switch), v -> {
            mMenuItems.add(MenuItem.builder(this)
                    .setCheckable()
                    .setOnClickListener(
                            i ->
                                    Toast.makeText(this,
                                            "Checked? " + i.isChecked(),
                                            Toast.LENGTH_SHORT)
                                            .show())
                    .build());
            toolbar.setMenuItems(mMenuItems);
        }));

        mButtons.add(Pair.create(getString(R.string.toolbar_add_text), v -> {
            mMenuItems.add(MenuItem.builder(this)
                    .setTitle("Baz")
                    .setOnClickListener(
                            i -> Toast.makeText(this, "Clicked",
                                    Toast.LENGTH_SHORT).show())
                    .build());
            toolbar.setMenuItems(mMenuItems);
        }));

        mButtons.add(Pair.create(getString(R.string.toolbar_add_icon_text), v -> {
            mMenuItems.add(MenuItem.builder(this)
                    .setIcon(R.drawable.ic_tracklist)
                    .setTitle("Bar")
                    .setShowIconAndTitle(true)
                    .setOnClickListener(
                            i -> Toast.makeText(this, "Clicked",
                                    Toast.LENGTH_SHORT).show())
                    .build());
            toolbar.setMenuItems(mMenuItems);
        }));

        mButtons.add(Pair.create(getString(R.string.toolbar_add_untinted_icon_and_text), v -> {
            mMenuItems.add(MenuItem.builder(this)
                    .setIcon(R.drawable.ic_tracklist)
                    .setTitle("Bar")
                    .setShowIconAndTitle(true)
                    .setTinted(false)
                    .setOnClickListener(
                            i -> Toast.makeText(this, "Clicked",
                                    Toast.LENGTH_SHORT).show())
                    .build());
            toolbar.setMenuItems(mMenuItems);
        }));

        mButtons.add(Pair.create(getString(R.string.toolbar_add_activatable), v -> {
            mMenuItems.add(MenuItem.builder(this)
                    .setIcon(R.drawable.ic_tracklist)
                    .setActivatable()
                    .setOnClickListener(
                            i -> Toast.makeText(this, "Clicked",
                                    Toast.LENGTH_SHORT).show())
                    .build());
            toolbar.setMenuItems(mMenuItems);
        }));

        mButtons.add(Pair.create(getString(R.string.toolbar_add_morphing), v -> {
            mMenuItems.add(MenuItem.builder(this)
                    .setTitle("Become icon")
                    .setOnClickListener(i ->
                            i.setIcon(i.getIcon() == null ? R.drawable.ic_tracklist : 0))
                    .build());
            toolbar.setMenuItems(mMenuItems);
        }));

        Mutable<Integer> overflowCounter = new Mutable<>(1);
        mButtons.add(Pair.create(getString(R.string.toolbar_add_overflow), v -> {
            mMenuItems.add(MenuItem.builder(this)
                    .setTitle("Foo " + overflowCounter.value)
                    .setOnClickListener(
                            i -> Toast.makeText(this, "Clicked",
                                    Toast.LENGTH_SHORT).show())
                    .setDisplayBehavior(MenuItem.DisplayBehavior.NEVER)
                    .build());
            toolbar.setMenuItems(mMenuItems);
            overflowCounter.value++;
        }));

        mButtons.add(Pair.create(getString(R.string.toolbar_add_overflow_switch), v -> {
            mMenuItems.add(MenuItem.builder(this)
                    .setTitle("Foo " + overflowCounter.value)
                    .setOnClickListener(
                            i -> Toast.makeText(this,
                                    i.isChecked() ? "Checked" : "Unchecked",
                                    Toast.LENGTH_SHORT)
                                    .show())
                    .setDisplayBehavior(MenuItem.DisplayBehavior.NEVER)
                    .setCheckable()
                    .build());
            toolbar.setMenuItems(mMenuItems);
            overflowCounter.value++;
        }));

        mButtons.add(Pair.create(getString(R.string.toolbar_add_icon_text_overflow), v -> {
            mMenuItems.add(MenuItem.builder(this)
                    .setIcon(R.drawable.ic_tracklist)
                    .setTitle("Bar")
                    .setShowIconAndTitle(true)
                    .setOnClickListener(
                            i -> Toast.makeText(this, "Clicked",
                                    Toast.LENGTH_SHORT).show())
                    .setDisplayBehavior(MenuItem.DisplayBehavior.NEVER)
                    .build());
            toolbar.setMenuItems(mMenuItems);
        }));

        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_visibility),
                v -> getMenuItem(item -> item.setVisible(!item.isVisible()))));

        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_enable),
                v -> getMenuItem(item -> item.setEnabled(!item.isEnabled()))));

        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_perform_click),
                v -> getMenuItem(MenuItem::performClick)));

        final Drawable altIcon = getDrawable(R.drawable.ic_cut);
        Map<MenuItem, Drawable> iconBackups = new HashMap<>();
        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_icon), v ->
                getMenuItem(item -> {
                    Drawable currentIcon = item.getIcon();
                    Drawable newIcon = altIcon;
                    if (iconBackups.containsKey(item)) {
                        newIcon = iconBackups.get(item);
                    }
                    item.setIcon(newIcon);
                    iconBackups.put(item, currentIcon);
                })));

        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_show_while_search), v ->
                toolbar.setShowMenuItemsWhileSearching(
                        !toolbar.getShowMenuItemsWhileSearching())));

        mButtons.add(Pair.create(getString(R.string.toolbar_cycle_nav_button), v -> {
            Toolbar.NavButtonMode mode = toolbar.getNavButtonMode();
            if (mode == Toolbar.NavButtonMode.BACK) {
                toolbar.setNavButtonMode(Toolbar.NavButtonMode.CLOSE);
            } else if (mode == Toolbar.NavButtonMode.CLOSE) {
                toolbar.setNavButtonMode(Toolbar.NavButtonMode.DOWN);
            } else {
                toolbar.setNavButtonMode(Toolbar.NavButtonMode.BACK);
            }
        }));

        Mutable<Boolean> hasLogo = new Mutable<>(true);
        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_logo), v -> {
            toolbar.setLogo(hasLogo.value ? 0 : R.drawable.ic_launcher);
            hasLogo.value = !hasLogo.value;
        }));

        mButtons.add(Pair.create(getString(R.string.toolbar_cycle_state), v -> {
            if (toolbar.getState() == Toolbar.State.SUBPAGE) {
                toolbar.setState(Toolbar.State.HOME);
            } else if (toolbar.getState() == Toolbar.State.HOME) {
                toolbar.setState(Toolbar.State.EDIT);
            } else {
                toolbar.setState(Toolbar.State.SUBPAGE);
            }
        }));

        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_search_hint), v -> {
            if (toolbar.getSearchHint().toString().contentEquals("Foo")) {
                toolbar.setSearchHint("Bar");
            } else {
                toolbar.setSearchHint("Foo");
            }
        }));

        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_background),
                v -> toolbar.setBackgroundShown(!toolbar.getBackgroundShown())));

        mButtons.add(Pair.create(getString(R.string.toolbar_add_tab), v -> toolbar.addTab(
                new TabLayout.Tab(getDrawable(R.drawable.ic_launcher), "Foo"))));

        mButtons.add(Pair.create(getString(R.string.toolbar_add_tab_with_custom_text), v -> {
            SimpleTextWatcher textWatcher = new SimpleTextWatcher();
            new AlertDialogBuilder(this)
                    .setEditBox(null, textWatcher, null)
                    .setTitle("Enter the text for the title")
                    .setPositiveButton("Ok", (dialog, which) ->
                            toolbar.addTab(
                                    new TabLayout.Tab(
                                            getDrawable(
                                                    R.drawable.ic_launcher),
                                            textWatcher.getText())))
                    .show();
        }));

        mButtons.add(Pair.create(getString(R.string.toolbar_show_tabs_in_subpage), v ->
                toolbar.setShowTabsInSubpage(!toolbar.getShowTabsInSubpage())));

        Mutable<Boolean> showingLauncherIcon = new Mutable<>(false);
        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_search_icon), v -> {
            if (showingLauncherIcon.value) {
                toolbar.setSearchIcon(null);
            } else {
                toolbar.setSearchIcon(R.drawable.ic_launcher);
            }
            showingLauncherIcon.value = !showingLauncherIcon.value;
        }));

        CarUiRecyclerView prv = requireViewById(R.id.list);
        prv.setAdapter(mAdapter);
    }

    /** Override in subclasses to change the layout */
    protected int getLayout() {
        return R.layout.car_ui_recycler_view_activity;
    }

    @Override
    public void onCarUiInsetsChanged(@NonNull Insets insets) {
        requireViewById(R.id.list)
                .setPadding(0, insets.getTop(), 0, insets.getBottom());
        requireViewById(android.R.id.content)
                .setPadding(insets.getLeft(), 0, insets.getRight(), 0);
    }

    public void xmlMenuItemClicked(MenuItem item) {
        Toast.makeText(this, "Xml item clicked! " + item.getTitle() + ", id: " + item.getId(),
                Toast.LENGTH_SHORT).show();
    }

    private void getMenuItem(MenuItem.OnClickListener listener) {
        if (mMenuItems.size() == 1) {
            listener.onClick(mMenuItems.get(0));
            return;
        }

        SimpleTextWatcher textWatcher = new SimpleTextWatcher();
        new AlertDialogBuilder(this)
                .setEditBox("", textWatcher, null, InputType.TYPE_CLASS_NUMBER)
                .setTitle("Enter the index of the MenuItem")
                .setPositiveButton("Ok", (dialog, which) -> {
                    try {
                        MenuItem item = mMenuItems.get(
                                Integer.parseInt(textWatcher.getText()));
                        listener.onClick(item);
                    } catch (NumberFormatException | IndexOutOfBoundsException e) {
                        Toast.makeText(this, "Invalid index \"" + textWatcher.getText()
                                        + "\", valid range is 0 to " + (mMenuItems.size() - 1),
                                Toast.LENGTH_LONG).show();
                    }
                }).show();
    }

    private static class ViewHolder extends RecyclerView.ViewHolder {

        private final Button mButton;

        ViewHolder(View itemView) {
            super(itemView);
            mButton = itemView.requireViewById(R.id.button);
        }

        public void bind(CharSequence title, View.OnClickListener listener) {
            mButton.setText(title);
            mButton.setOnClickListener(listener);
        }
    }

    private final RecyclerView.Adapter<ViewHolder> mAdapter =
            new RecyclerView.Adapter<ViewHolder>() {
                @Override
                public int getItemCount() {
                    return mButtons.size();
                }

                @Override
                public ViewHolder onCreateViewHolder(ViewGroup parent, int position) {
                    View item =
                            LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,
                                    parent, false);
                    return new ViewHolder(item);
                }

                @Override
                public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
                    Pair<CharSequence, View.OnClickListener> pair = mButtons.get(position);
                    holder.bind(pair.first, pair.second);
                }
            };

    /**
     * For changing values from lambdas
     */
    private static final class Mutable<E> {

        public E value;

        Mutable() {
            value = null;
        }

        Mutable(E value) {
            this.value = value;
        }
    }

    /**
     * Used for getting text from a dialog.
     */
    private static final class SimpleTextWatcher implements TextWatcher {

        private String mValue;

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
        }

        @Override
        public void afterTextChanged(Editable s) {
            mValue = s.toString();
        }

        public String getText() {
            return mValue;
        }
    }
}
