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

import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.KEY;
import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.KEY_CODE_END;
import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.KEY_CODE_START;
import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.KEY_IMAGE_DELIM;
import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.MENU_IME_ROTATE;
import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.NAVSPACE;
import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.NAV_BAR_LEFT;
import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.NAV_BAR_RIGHT;
import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.NAV_BAR_VIEWS;
import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.extractButton;
import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.extractImage;
import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.extractKeycode;

import android.annotation.Nullable;
import android.app.AlertDialog;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.Preference.OnPreferenceChangeListener;
import android.text.SpannableStringBuilder;
import android.text.style.ImageSpan;
import android.util.Log;
import android.util.TypedValue;
import android.view.KeyEvent;
import android.widget.EditText;

import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.tuner.TunerService.Tunable;

import java.util.ArrayList;

public class NavBarTuner extends TunerPreferenceFragment {

    private static final String LAYOUT = "layout";
    private static final String LEFT = "left";
    private static final String RIGHT = "right";

    private static final String TYPE = "type";
    private static final String KEYCODE = "keycode";
    private static final String ICON = "icon";

    private static final int[][] ICONS = new int[][]{
            {R.drawable.ic_qs_circle, R.string.tuner_circle},
            {R.drawable.ic_add, R.string.tuner_plus},
            {R.drawable.ic_remove, R.string.tuner_minus},
            {R.drawable.ic_left, R.string.tuner_left},
            {R.drawable.ic_right, R.string.tuner_right},
            {R.drawable.ic_menu, R.string.tuner_menu},
    };

    private final ArrayList<Tunable> mTunables = new ArrayList<>();
    private Handler mHandler;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        mHandler = new Handler();
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);
    }

    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        addPreferencesFromResource(R.xml.nav_bar_tuner);
        bindLayout((ListPreference) findPreference(LAYOUT));
        bindButton(NAV_BAR_LEFT, NAVSPACE, LEFT);
        bindButton(NAV_BAR_RIGHT, MENU_IME_ROTATE, RIGHT);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mTunables.forEach(t -> Dependency.get(TunerService.class).removeTunable(t));
    }

    private void addTunable(Tunable tunable, String... keys) {
        mTunables.add(tunable);
        Dependency.get(TunerService.class).addTunable(tunable, keys);
    }

    private void bindLayout(ListPreference preference) {
        addTunable((key, newValue) -> mHandler.post(() -> {
            String val = newValue;
            if (val == null) {
                val = "default";
            }
            preference.setValue(val);
        }), NAV_BAR_VIEWS);
        preference.setOnPreferenceChangeListener((preference1, newValue) -> {
            String val = (String) newValue;
            if ("default".equals(val)) val = null;
            Dependency.get(TunerService.class).setValue(NAV_BAR_VIEWS, val);
            return true;
        });
    }

    private void bindButton(String setting, String def, String k) {
        ListPreference type = (ListPreference) findPreference(TYPE + "_" + k);
        Preference keycode = findPreference(KEYCODE + "_" + k);
        ListPreference icon = (ListPreference) findPreference(ICON + "_" + k);
        setupIcons(icon);
        addTunable((key, newValue) -> mHandler.post(() -> {
            String val = newValue;
            if (val == null) {
                val = def;
            }
            String button = extractButton(val);
            if (button.startsWith(KEY)) {
                type.setValue(KEY);
                String uri = extractImage(button);
                int code = extractKeycode(button);
                icon.setValue(uri);
                updateSummary(icon);
                keycode.setSummary(code + "");
                keycode.setVisible(true);
                icon.setVisible(true);
            } else {
                type.setValue(button);
                keycode.setVisible(false);
                icon.setVisible(false);
            }
        }), setting);
        OnPreferenceChangeListener listener = (preference, newValue) -> {
            mHandler.post(() -> {
                setValue(setting, type, keycode, icon);
                updateSummary(icon);
            });
            return true;
        };
        type.setOnPreferenceChangeListener(listener);
        icon.setOnPreferenceChangeListener(listener);
        keycode.setOnPreferenceClickListener(preference -> {
            EditText editText = new EditText(getContext());
            new AlertDialog.Builder(getContext())
                    .setTitle(preference.getTitle())
                    .setView(editText)
                    .setNegativeButton(android.R.string.cancel, null)
                    .setPositiveButton(android.R.string.ok, (dialog, which) -> {
                        int code = KeyEvent.KEYCODE_ENTER;
                        try {
                            code = Integer.parseInt(editText.getText().toString());
                        } catch (Exception e) {
                        }
                        keycode.setSummary(code + "");
                        setValue(setting, type, keycode, icon);
                    }).show();
            return true;
        });
    }

    private void updateSummary(ListPreference icon) {
        try {
            int size = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 14,
                    getContext().getResources().getDisplayMetrics());
            String pkg = icon.getValue().split("/")[0];
            int id = Integer.parseInt(icon.getValue().split("/")[1]);
            SpannableStringBuilder builder = new SpannableStringBuilder();
            Drawable d = Icon.createWithResource(pkg, id)
                    .loadDrawable(getContext());
            d.setTint(Color.BLACK);
            d.setBounds(0, 0, size, size);
            ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
            builder.append("  ", span, 0);
            builder.append(" ");
            for (int i = 0; i < ICONS.length; i++) {
                if (ICONS[i][0] == id) {
                    builder.append(getString(ICONS[i][1]));
                }
            }
            icon.setSummary(builder);
        } catch (Exception e) {
            Log.d("NavButton", "Problem with summary", e);
            icon.setSummary(null);
        }
    }

    private void setValue(String setting, ListPreference type, Preference keycode,
            ListPreference icon) {
        String button = type.getValue();
        if (KEY.equals(button)) {
            String uri = icon.getValue();
            int code = KeyEvent.KEYCODE_ENTER;
            try {
                code = Integer.parseInt(keycode.getSummary().toString());
            } catch (Exception e) {
            }
            button = button + KEY_CODE_START + code + KEY_IMAGE_DELIM + uri + KEY_CODE_END;
        }
        Dependency.get(TunerService.class).setValue(setting, button);
    }

    private void setupIcons(ListPreference icon) {
        CharSequence[] labels = new CharSequence[ICONS.length];
        CharSequence[] values = new CharSequence[ICONS.length];
        int size = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 14,
                getContext().getResources().getDisplayMetrics());
        for (int i = 0; i < ICONS.length; i++) {
            SpannableStringBuilder builder = new SpannableStringBuilder();
            Drawable d = Icon.createWithResource(getContext().getPackageName(), ICONS[i][0])
                    .loadDrawable(getContext());
            d.setTint(Color.BLACK);
            d.setBounds(0, 0, size, size);
            ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
            builder.append("  ", span, 0);
            builder.append(" ");
            builder.append(getString(ICONS[i][1]));
            labels[i] = builder;
            values[i] = getContext().getPackageName() + "/" + ICONS[i][0];
        }
        icon.setEntries(labels);
        icon.setEntryValues(values);
    }
}
