/*
 * Copyright (C) 2016 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.internal.app;

import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;

import com.android.internal.R;
import com.android.internal.app.chooser.DisplayResolveInfo;

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

/**
 * Shows a dialog with actions to take on a chooser target.
 */
public class ResolverTargetActionsDialogFragment extends DialogFragment
        implements DialogInterface.OnClickListener {
    private static final String NAME_KEY = "componentName";
    private static final String TITLE_KEY = "title";
    private static final String PINNED_KEY = "pinned";

    // Sync with R.array.resolver_target_actions_* resources
    private static final int TOGGLE_PIN_INDEX = 0;
    private static final int APP_INFO_INDEX = 1;

    private List<DisplayResolveInfo> mTargetInfos = new ArrayList<>();
    private List<CharSequence> mLabels = new ArrayList<>();
    private boolean[] mPinned;

    public ResolverTargetActionsDialogFragment() {
    }

    public ResolverTargetActionsDialogFragment(CharSequence title, ComponentName name,
            boolean pinned) {
        Bundle args = new Bundle();
        args.putCharSequence(TITLE_KEY, title);
        args.putParcelable(NAME_KEY, name);
        args.putBoolean(PINNED_KEY, pinned);
        setArguments(args);
    }

    public ResolverTargetActionsDialogFragment(CharSequence title, ComponentName name,
            List<DisplayResolveInfo> targets, List<CharSequence> labels) {
        Bundle args = new Bundle();
        args.putCharSequence(TITLE_KEY, title);
        args.putParcelable(NAME_KEY, name);
        mTargetInfos = targets;
        mLabels = labels;
        setArguments(args);
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        final Bundle args = getArguments();
        final int itemRes = args.getBoolean(PINNED_KEY, false)
                ? R.array.resolver_target_actions_unpin
                : R.array.resolver_target_actions_pin;
        String[] defaultActions = getResources().getStringArray(itemRes);
        CharSequence[] items;

        if (mTargetInfos == null || mTargetInfos.size() < 2) {
            items = defaultActions;
        } else {
            // Pin item for each sub-item
            items = new CharSequence[mTargetInfos.size() + 1];
            for (int i = 0; i < mTargetInfos.size(); i++) {
                items[i] = mTargetInfos.get(i).isPinned()
                         ? getResources().getString(R.string.unpin_specific_target, mLabels.get(i))
                         : getResources().getString(R.string.pin_specific_target, mLabels.get(i));
            }
            // "App info"
            items[mTargetInfos.size()] = defaultActions[1];
        }


        return new Builder(getContext())
                .setCancelable(true)
                .setItems(items, this)
                .setTitle(args.getCharSequence(TITLE_KEY))
                .create();
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        final Bundle args = getArguments();
        ComponentName name = args.getParcelable(NAME_KEY);
        if (which == 0 || (mTargetInfos.size() > 0 && which < mTargetInfos.size())) {
            if (mTargetInfos == null || mTargetInfos.size() == 0) {
                pinComponent(name);
            } else {
                pinComponent(mTargetInfos.get(which).getResolvedComponentName());
            }
            // Force the chooser to requery and resort things
            ((ChooserActivity) getActivity()).handlePackagesChanged();
        } else {
            // Last item in dialog is App Info
            Intent in = new Intent().setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                    .setData(Uri.fromParts("package", name.getPackageName(), null))
                    .addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
            startActivity(in);
        }
        dismiss();
    }

    private void pinComponent(ComponentName name) {
        SharedPreferences sp = ChooserActivity.getPinnedSharedPrefs(getContext());
        final String key = name.flattenToString();
        boolean currentVal = sp.getBoolean(name.flattenToString(), false);
        if (currentVal) {
            sp.edit().remove(key).apply();
        } else {
            sp.edit().putBoolean(key, true).apply();
        }
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        // Dismiss on config changed (eg: rotation)
        // TODO: Maintain state on config change
        super.onConfigurationChanged(newConfig);
        dismiss();
    }

}
