/*
 * Copyright (C) 2015 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.settings.accessibility;

import android.content.res.Resources;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v7.preference.Preference;
import android.view.View;
import android.view.accessibility.AccessibilityManager;
import android.widget.Switch;

import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.SeekBarPreference;
import com.android.settings.widget.SwitchBar;


/**
 * Fragment for preference screen for settings related to Automatically click after mouse stops
 * feature.
 */
public class ToggleAutoclickPreferenceFragment extends ToggleFeaturePreferenceFragment
        implements SwitchBar.OnSwitchChangeListener, Preference.OnPreferenceChangeListener {

    /** Min allowed autoclick delay value. */
    private static final int MIN_AUTOCLICK_DELAY = 200;
    /** Max allowed autoclick delay value. */
    private static final int MAX_AUTOCLICK_DELAY = 1000;
    /**
     * Allowed autoclick delay values are discrete. This is the difference between two allowed
     * values.
     */
    private static final int AUTOCLICK_DELAY_STEP = 100;

    /**
     * Resource ids from which autoclick preference summaries should be derived. The strings have
     * placeholder for integer delay value.
     */
    private static final int[] mAutoclickPreferenceSummaries = {
            R.plurals.accessibilty_autoclick_preference_subtitle_extremely_short_delay,
            R.plurals.accessibilty_autoclick_preference_subtitle_very_short_delay,
            R.plurals.accessibilty_autoclick_preference_subtitle_short_delay,
            R.plurals.accessibilty_autoclick_preference_subtitle_long_delay,
            R.plurals.accessibilty_autoclick_preference_subtitle_very_long_delay
    };

    /**
     * Seek bar preference for autoclick delay value. The seek bar has values between 0 and
     * number of possible discrete autoclick delay values. These will have to be converted to actual
     * delay values before saving them in settings.
     */
    private SeekBarPreference mDelay;

    /**
     * Gets string that should be used as a autoclick preference summary for provided autoclick
     * delay.
     * @param resources Resources from which string should be retrieved.
     * @param delay Delay for whose value summary should be retrieved.
     */
    static CharSequence getAutoclickPreferenceSummary(Resources resources, int delay) {
        int summaryIndex = getAutoclickPreferenceSummaryIndex(delay);
        return resources.getQuantityString(
                mAutoclickPreferenceSummaries[summaryIndex], delay, delay);
    }

    /**
     * Finds index of the summary that should be used for the provided autoclick delay.
     */
    private static int getAutoclickPreferenceSummaryIndex(int delay) {
        if (delay <= MIN_AUTOCLICK_DELAY) {
            return 0;
        }
        if (delay >= MAX_AUTOCLICK_DELAY) {
            return mAutoclickPreferenceSummaries.length - 1;
        }
        int rangeSize = (MAX_AUTOCLICK_DELAY - MIN_AUTOCLICK_DELAY) /
                (mAutoclickPreferenceSummaries.length - 1);
        return (delay - MIN_AUTOCLICK_DELAY) / rangeSize;
    }

    @Override
    protected void onPreferenceToggled(String preferenceKey, boolean enabled) {
        Settings.Secure.putInt(getContentResolver(), preferenceKey, enabled ? 1 : 0);
        mDelay.setEnabled(enabled);
    }

    @Override
    protected int getMetricsCategory() {
        return MetricsEvent.ACCESSIBILITY_TOGGLE_AUTOCLICK;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        addPreferencesFromResource(R.xml.accessibility_autoclick_settings);

        int delay = Settings.Secure.getInt(
                getContentResolver(), Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY,
                AccessibilityManager.AUTOCLICK_DELAY_DEFAULT);

        // Initialize seek bar preference. Sets seek bar size to the number of possible delay
        // values.
        mDelay = (SeekBarPreference) findPreference("autoclick_delay");
        mDelay.setMax(delayToSeekBarProgress(MAX_AUTOCLICK_DELAY));
        mDelay.setProgress(delayToSeekBarProgress(delay));
        mDelay.setOnPreferenceChangeListener(this);
    }

    @Override
    protected void onInstallSwitchBarToggleSwitch() {
        super.onInstallSwitchBarToggleSwitch();

        int value = Settings.Secure.getInt(getContentResolver(),
                Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED, 0);
        mSwitchBar.setCheckedInternal(value == 1);
        mSwitchBar.addOnSwitchChangeListener(this);
        mDelay.setEnabled(value == 1);
    }

    @Override
    protected void onRemoveSwitchBarToggleSwitch() {
        super.onRemoveSwitchBarToggleSwitch();
        mSwitchBar.removeOnSwitchChangeListener(this);
    }

    @Override
    public void onSwitchChanged(Switch switchView, boolean isChecked) {
        onPreferenceToggled(Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED, isChecked);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        setTitle(getString(R.string.accessibility_autoclick_preference_title));
    }

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        if (preference == mDelay && newValue instanceof Integer) {
            Settings.Secure.putInt(getContentResolver(),
                   Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY,
                   seekBarProgressToDelay((int)newValue));
            return true;
         }
         return false;
    }

    /**
     * Converts seek bar preference progress value to autoclick delay associated with it.
     */
    private int seekBarProgressToDelay(int progress) {
        return progress * AUTOCLICK_DELAY_STEP + MIN_AUTOCLICK_DELAY;
    }

    /**
     * Converts autoclick delay value to seek bar preference progress values that represents said
     * delay.
     */
    private int delayToSeekBarProgress(int delay) {
        return (delay - MIN_AUTOCLICK_DELAY) / AUTOCLICK_DELAY_STEP;
    }
}
