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

import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;

import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.style.TextAppearanceSpan;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Switch;
import android.widget.TextView;

import androidx.annotation.ColorInt;
import androidx.annotation.StringRes;
import androidx.annotation.VisibleForTesting;

import com.android.settings.R;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;

import java.util.ArrayList;
import java.util.List;

public class SwitchBar extends LinearLayout implements CompoundButton.OnCheckedChangeListener {

    public interface OnSwitchChangeListener {
        /**
         * Called when the checked state of the Switch has changed.
         *
         * @param switchView The Switch view whose state has changed.
         * @param isChecked  The new checked state of switchView.
         */
        void onSwitchChanged(Switch switchView, boolean isChecked);
    }

    private static final int[] XML_ATTRIBUTES = {
            R.attr.switchBarMarginStart,
            R.attr.switchBarMarginEnd,
            R.attr.switchBarBackgroundColor,
            R.attr.switchBarBackgroundActivatedColor,
            R.attr.switchBarRestrictionIcon};

    private final List<OnSwitchChangeListener> mSwitchChangeListeners = new ArrayList<>();
    private final MetricsFeatureProvider mMetricsFeatureProvider;
    private final TextAppearanceSpan mSummarySpan;

    private ToggleSwitch mSwitch;
    private ImageView mRestrictedIcon;
    private TextView mTextView;
    private String mLabel;
    private String mSummary;
    @ColorInt
    private int mBackgroundColor;
    @ColorInt
    private int mBackgroundActivatedColor;
    @StringRes
    private int mOnTextId;
    @StringRes
    private int mOffTextId;

    private boolean mLoggingIntialized;
    private boolean mDisabledByAdmin;
    private EnforcedAdmin mEnforcedAdmin = null;
    private String mMetricsTag;


    public SwitchBar(Context context) {
        this(context, null);
    }

    public SwitchBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SwitchBar(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public SwitchBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);

        LayoutInflater.from(context).inflate(R.layout.switch_bar, this);
        // Set the whole SwitchBar focusable and clickable.
        setFocusable(true);
        setClickable(true);

        final TypedArray a = context.obtainStyledAttributes(attrs, XML_ATTRIBUTES);
        final int switchBarMarginStart = (int) a.getDimension(0, 0);
        final int switchBarMarginEnd = (int) a.getDimension(1, 0);
        mBackgroundColor = a.getColor(2, 0);
        mBackgroundActivatedColor = a.getColor(3, 0);
        final Drawable restrictedIconDrawable = a.getDrawable(4);
        a.recycle();

        mTextView = findViewById(R.id.switch_text);
        mSummarySpan = new TextAppearanceSpan(mContext, R.style.TextAppearance_Small_SwitchBar);
        ViewGroup.MarginLayoutParams lp = (MarginLayoutParams) mTextView.getLayoutParams();
        lp.setMarginStart(switchBarMarginStart);

        mSwitch = findViewById(R.id.switch_widget);
        // Prevent onSaveInstanceState() to be called as we are managing the state of the Switch
        // on our own
        mSwitch.setSaveEnabled(false);
        // Set the ToggleSwitch non-focusable and non-clickable to avoid multiple focus.
        mSwitch.setFocusable(false);
        mSwitch.setClickable(false);

        lp = (MarginLayoutParams) mSwitch.getLayoutParams();
        lp.setMarginEnd(switchBarMarginEnd);
        setBackgroundColor(mBackgroundColor);

        setSwitchBarText(R.string.switch_on_text, R.string.switch_off_text);

        addOnSwitchChangeListener(
                (switchView, isChecked) -> setTextViewLabelAndBackground(isChecked));

        mRestrictedIcon = findViewById(R.id.restricted_icon);
        mRestrictedIcon.setImageDrawable(restrictedIconDrawable);
        mRestrictedIcon.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mDisabledByAdmin) {
                    mMetricsFeatureProvider.action(
                            SettingsEnums.PAGE_UNKNOWN,
                            SettingsEnums.ACTION_SETTINGS_PREFERENCE_CHANGE,
                            SettingsEnums.PAGE_UNKNOWN,
                            mMetricsTag + "/switch_bar|restricted",
                            1);

                    RestrictedLockUtils.sendShowAdminSupportDetailsIntent(context,
                            mEnforcedAdmin);
                }
            }
        });

        // Default is hide
        setVisibility(View.GONE);

        mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
    }

    // Override the performClick method to eliminate redundant click.
    @Override
    public boolean performClick() {
        return getDelegatingView().performClick();
    }

    public void setMetricsTag(String tag) {
        mMetricsTag = tag;
    }

    public void setTextViewLabelAndBackground(boolean isChecked) {
        mLabel = getResources().getString(isChecked ? mOnTextId : mOffTextId);
        setBackgroundColor(isChecked ? mBackgroundActivatedColor : mBackgroundColor);
        updateText();
    }

    public void setSwitchBarText(int onText, int offText) {
        mOnTextId = onText;
        mOffTextId = offText;
        setTextViewLabelAndBackground(isChecked());
    }

    public void setSummary(String summary) {
        mSummary = summary;
        updateText();
    }

    private void updateText() {
        if (TextUtils.isEmpty(mSummary)) {
            mTextView.setText(mLabel);
            return;
        }
        final SpannableStringBuilder ssb = new SpannableStringBuilder(mLabel).append('\n');
        final int start = ssb.length();
        ssb.append(mSummary);
        ssb.setSpan(mSummarySpan, start, ssb.length(), 0);
        mTextView.setText(ssb);
    }

    public void setChecked(boolean checked) {
        setTextViewLabelAndBackground(checked);
        mSwitch.setChecked(checked);
    }

    public void setCheckedInternal(boolean checked) {
        setTextViewLabelAndBackground(checked);
        mSwitch.setCheckedInternal(checked);
    }

    public boolean isChecked() {
        return mSwitch.isChecked();
    }

    public void setEnabled(boolean enabled) {
        if (enabled && mDisabledByAdmin) {
            setDisabledByAdmin(null);
            return;
        }
        super.setEnabled(enabled);
        mTextView.setEnabled(enabled);
        mSwitch.setEnabled(enabled);
    }

    @VisibleForTesting
    View getDelegatingView() {
        return mDisabledByAdmin ? mRestrictedIcon : mSwitch;
    }

    /**
     * If admin is not null, disables the text and switch but keeps the view clickable.
     * Otherwise, calls setEnabled which will enables the entire view including
     * the text and switch.
     */
    public void setDisabledByAdmin(EnforcedAdmin admin) {
        mEnforcedAdmin = admin;
        if (admin != null) {
            super.setEnabled(true);
            mDisabledByAdmin = true;
            mTextView.setEnabled(false);
            mSwitch.setEnabled(false);
            mSwitch.setVisibility(View.GONE);
            mRestrictedIcon.setVisibility(View.VISIBLE);
            mRestrictedIcon.setFocusable(false);
            mRestrictedIcon.setClickable(false);
        } else {
            mDisabledByAdmin = false;
            mSwitch.setVisibility(View.VISIBLE);
            mRestrictedIcon.setVisibility(View.GONE);
            setEnabled(true);
        }
    }

    public final ToggleSwitch getSwitch() {
        return mSwitch;
    }

    public void show() {
        if (!isShowing()) {
            setVisibility(View.VISIBLE);
            mSwitch.setOnCheckedChangeListener(this);
        }
    }

    public void hide() {
        if (isShowing()) {
            setVisibility(View.GONE);
            mSwitch.setOnCheckedChangeListener(null);
        }
    }

    public boolean isShowing() {
        return (getVisibility() == View.VISIBLE);
    }

    public void propagateChecked(boolean isChecked) {
        final int count = mSwitchChangeListeners.size();
        for (int n = 0; n < count; n++) {
            mSwitchChangeListeners.get(n).onSwitchChanged(mSwitch, isChecked);
        }
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (mLoggingIntialized) {
            mMetricsFeatureProvider.action(
                    SettingsEnums.PAGE_UNKNOWN,
                    SettingsEnums.ACTION_SETTINGS_PREFERENCE_CHANGE,
                    SettingsEnums.PAGE_UNKNOWN,
                    mMetricsTag + "/switch_bar",
                    isChecked ? 1 : 0);
        }
        mLoggingIntialized = true;
        propagateChecked(isChecked);
    }

    public void addOnSwitchChangeListener(OnSwitchChangeListener listener) {
        if (mSwitchChangeListeners.contains(listener)) {
            throw new IllegalStateException("Cannot add twice the same OnSwitchChangeListener");
        }
        mSwitchChangeListeners.add(listener);
    }

    public void removeOnSwitchChangeListener(OnSwitchChangeListener listener) {
        if (!mSwitchChangeListeners.contains(listener)) {
            throw new IllegalStateException("Cannot remove OnSwitchChangeListener");
        }
        mSwitchChangeListeners.remove(listener);
    }

    static class SavedState extends BaseSavedState {
        boolean checked;
        boolean visible;

        SavedState(Parcelable superState) {
            super(superState);
        }

        /**
         * Constructor called from {@link #CREATOR}
         */
        private SavedState(Parcel in) {
            super(in);
            checked = (Boolean) in.readValue(null);
            visible = (Boolean) in.readValue(null);
        }

        @Override
        public void writeToParcel(Parcel out, int flags) {
            super.writeToParcel(out, flags);
            out.writeValue(checked);
            out.writeValue(visible);
        }

        @Override
        public String toString() {
            return "SwitchBar.SavedState{"
                    + Integer.toHexString(System.identityHashCode(this))
                    + " checked=" + checked
                    + " visible=" + visible + "}";
        }

        public static final Parcelable.Creator<SavedState> CREATOR
                = new Parcelable.Creator<SavedState>() {
            public SavedState createFromParcel(Parcel in) {
                return new SavedState(in);
            }

            public SavedState[] newArray(int size) {
                return new SavedState[size];
            }
        };
    }

    @Override
    public Parcelable onSaveInstanceState() {
        Parcelable superState = super.onSaveInstanceState();

        SavedState ss = new SavedState(superState);
        ss.checked = mSwitch.isChecked();
        ss.visible = isShowing();
        return ss;
    }

    @Override
    public void onRestoreInstanceState(Parcelable state) {
        SavedState ss = (SavedState) state;

        super.onRestoreInstanceState(ss.getSuperState());

        mSwitch.setCheckedInternal(ss.checked);
        setTextViewLabelAndBackground(ss.checked);
        setVisibility(ss.visible ? View.VISIBLE : View.GONE);
        mSwitch.setOnCheckedChangeListener(ss.visible ? this : null);

        requestLayout();
    }
}
