/*
 * 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.os.UserHandle;
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";
    private static final String USER_ID_KEY = "userId";

    // 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, UserHandle userHandle) {
        Bundle args = new Bundle();
        args.putCharSequence(TITLE_KEY, title);
        args.putParcelable(NAME_KEY, name);
        args.putBoolean(PINNED_KEY, pinned);
        args.putParcelable(USER_ID_KEY, userHandle);
        setArguments(args);
    }

    public ResolverTargetActionsDialogFragment(CharSequence title, ComponentName name,
            List<DisplayResolveInfo> targets, List<CharSequence> labels, UserHandle userHandle) {
        Bundle args = new Bundle();
        args.putCharSequence(TITLE_KEY, title);
        args.putParcelable(NAME_KEY, name);
        args.putParcelable(USER_ID_KEY, userHandle);
        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);
            UserHandle userHandle = args.getParcelable(USER_ID_KEY);
            getActivity().startActivityAsUser(in, userHandle);
        }
        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();
    }

}
