/*
 * 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.tv.settings.dialog.old;

import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentManager.OnBackStackChangedListener;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;

import androidx.annotation.NonNull;

import com.android.tv.settings.R;
import com.android.tv.settings.core.instrumentation.InstrumentedActivity;

import java.util.ArrayList;

/**
 * A DialogActivity has 2 fragments, a content fragment and a list fragment.
 * <p>
 * Subclasses should override to supply the content fragment and list items.
 * <p>
 * The DialogActivity will handle animating in and out.
 * <p>
 * This class will use a default layout, but a custom layout can be provided by
 * calling {@link #setLayoutProperties}
 */
public abstract class DialogActivity extends InstrumentedActivity
        implements ActionAdapter.Listener, OnBackStackChangedListener {

    /**
     * Dialog Content Fragment title.
     */
    public static final String EXTRA_DIALOG_TITLE = "dialog_title";

    /**
     * Dialog Content Fragment breadcrumb.
     */
    public static final String EXTRA_DIALOG_BREADCRUMB = "dialog_breadcrumb";

    /**
     * Dialog Content Fragment description.
     */
    public static final String EXTRA_DIALOG_DESCRIPTION = "dialog_description";

    /**
     * Dialog Content Fragment image uri.
     */
    public static final String EXTRA_DIALOG_IMAGE_URI = "dialog_image_uri";

    /**
     * Dialog Content Fragment image background color
     */
    public static final String EXTRA_DIALOG_IMAGE_BACKGROUND_COLOR
            = "dialog_image_background_color";

    /**
     * Dialog Action Fragment actions starting index.
     */
    public static final String EXTRA_DIALOG_ACTIONS_START_INDEX = "dialog_actions_start_index";

    /**
     * Dialog Action Fragment actions.
     */
    public static final String EXTRA_PARCELABLE_ACTIONS = "parcelable_actions";

    /**
     * Whether DialogActivity should create Content Fragment and Action Fragment from extras.
     */
    public static final String EXTRA_CREATE_FRAGMENT_FROM_EXTRA = "create_fragment_from_extra";

    public static final String TAG_DIALOG = "tag_dialog";
    public static final String BACKSTACK_NAME_DIALOG = "backstack_name_dialog";
    public static final String KEY_BACKSTACK_COUNT = "backstack_count";

    protected static final int ANIMATE_IN_DURATION = 250;

    private DialogFragment mDialogFragment;
    private int mLayoutResId = R.layout.lb_dialog_fragment;
    private View mContent;
    private int mLastBackStackCount = 0;

    public DialogActivity() {
        mDialogFragment = new DialogFragment();
        mDialogFragment.setActivity(this);
    }

    public static Intent createIntent(Context context, String title,
            String breadcrumb, String description, String imageUri,
            ArrayList<Action> actions) {
        return createIntent(context, title, breadcrumb, description, imageUri,
                Color.TRANSPARENT, actions);
    }

    public static Intent createIntent(Context context, String title,
            String breadcrumb, String description, String imageUri,
            int imageBackground, ArrayList<Action> actions) {
        Intent intent = new Intent(context, DialogActivity.class);
        intent.putExtra(EXTRA_DIALOG_TITLE, title);
        intent.putExtra(EXTRA_DIALOG_BREADCRUMB, breadcrumb);
        intent.putExtra(EXTRA_DIALOG_DESCRIPTION, description);
        intent.putExtra(EXTRA_DIALOG_IMAGE_URI, imageUri);
        intent.putExtra(EXTRA_DIALOG_IMAGE_BACKGROUND_COLOR, imageBackground);
        intent.putParcelableArrayListExtra(EXTRA_PARCELABLE_ACTIONS, actions);

        return intent;
    }

    public static Intent createIntent(Context context, String title,
            String breadcrumb, String description, String imageUri,
            ArrayList<Action> actions, Class<? extends DialogActivity> activityClass) {
        return createIntent(context, title, breadcrumb, description, imageUri, Color.TRANSPARENT,
                actions, activityClass);
    }

    public static Intent createIntent(Context context, String title,
            String breadcrumb, String description, String imageUri, int imageBackground,
            ArrayList<Action> actions, Class<? extends DialogActivity> activityClass) {
        Intent intent = new Intent(context, activityClass);
        intent.putExtra(EXTRA_DIALOG_TITLE, title);
        intent.putExtra(EXTRA_DIALOG_BREADCRUMB, breadcrumb);
        intent.putExtra(EXTRA_DIALOG_DESCRIPTION, description);
        intent.putExtra(EXTRA_DIALOG_IMAGE_URI, imageUri);
        intent.putExtra(EXTRA_DIALOG_IMAGE_BACKGROUND_COLOR, imageBackground);
        intent.putParcelableArrayListExtra(EXTRA_PARCELABLE_ACTIONS, actions);

        return intent;
    }

    public static Intent createIntent(Context context, String title,
            String breadcrumb, String description, String imageUri, int imageBackground,
            ArrayList<Action> actions, Class<? extends DialogActivity> activityClass,
            int startIndex) {
        Intent intent = new Intent(context, activityClass);
        intent.putExtra(EXTRA_DIALOG_TITLE, title);
        intent.putExtra(EXTRA_DIALOG_BREADCRUMB, breadcrumb);
        intent.putExtra(EXTRA_DIALOG_DESCRIPTION, description);
        intent.putExtra(EXTRA_DIALOG_IMAGE_URI, imageUri);
        intent.putExtra(EXTRA_DIALOG_IMAGE_BACKGROUND_COLOR, imageBackground);
        intent.putParcelableArrayListExtra(EXTRA_PARCELABLE_ACTIONS, actions);
        intent.putExtra(EXTRA_DIALOG_ACTIONS_START_INDEX, startIndex);

        return intent;
    }

    public View getContentView() {
        return mContent;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO: replace these hardcoded values with the commented constants whenever Hangouts
        // updates their manifest to build against JB MR2.
        if (Build.VERSION.SDK_INT >= 18 /* Build.VERSION_CODES.JELLY_BEAN_MR2 */) {
            getWindow().addFlags(0x02000000
                    /* WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN */);
        }
        if(savedInstanceState != null) {
            mLastBackStackCount = savedInstanceState.getInt(KEY_BACKSTACK_COUNT);
        }

        super.onCreate(savedInstanceState);
        getFragmentManager().addOnBackStackChangedListener(this);

        LayoutInflater helium = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mContent = helium.inflate(mLayoutResId, null);
        setContentView(mContent);
        if (mLayoutResId == R.layout.lb_dialog_fragment) {
            helium.inflate(R.layout.dialog_container, (ViewGroup) mContent);
            setDialogFragment(mDialogFragment);
        }

        Bundle bundle = getIntent().getExtras();
        if (bundle != null) {
            boolean createFragmentFromExtra = bundle.getBoolean(EXTRA_CREATE_FRAGMENT_FROM_EXTRA);
            if (createFragmentFromExtra) {
                // If intent bundle is not null, and flag indicates that should create fragments,
                // set ContentFragment and ActionFragment using bundle extras.
                String title = bundle.getString(EXTRA_DIALOG_TITLE);
                String breadcrumb = bundle.getString(EXTRA_DIALOG_BREADCRUMB);
                String description = bundle.getString(EXTRA_DIALOG_DESCRIPTION);
                String imageUriStr = bundle.getString(EXTRA_DIALOG_IMAGE_URI);
                Uri imageUri = Uri.parse(imageUriStr);
                int backgroundColor = bundle.getInt(EXTRA_DIALOG_IMAGE_BACKGROUND_COLOR);

                ArrayList<Action> actions =
                        bundle.getParcelableArrayList(EXTRA_PARCELABLE_ACTIONS);

                setContentFragment(ContentFragment.newInstance(title, breadcrumb,
                        description, imageUri, backgroundColor));

                setActionFragment(ActionFragment.newInstance(actions));
            }
        }
    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        savedInstanceState.putInt(KEY_BACKSTACK_COUNT, mLastBackStackCount);
    }

    @Override
    protected void onStart() {
        super.onStart();
        if (mLayoutResId == R.layout.lb_dialog_fragment) {
            getDialogFragment().performEntryTransition();
        }
    }

    @Override
    public void onBackStackChanged() {
        int count = getFragmentManager().getBackStackEntryCount();
        if (count > 0 && count < mLastBackStackCount && DialogActivity.BACKSTACK_NAME_DIALOG.equals(
                getFragmentManager().getBackStackEntryAt(count - 1).getName())) {
            getFragmentManager().popBackStack();
        }
        mLastBackStackCount = count;
    }

    @Override
    public void onActionClicked(Action action) {
        Intent intent = action.getIntent();
        if (intent != null) {
            startActivity(intent);
            finish();
        }
    }

    /**
     * Disables the entry animation that normally happens onStart().
     */
    protected void disableEntryAnimation() {
        getDialogFragment().disableEntryAnimation();
    }

    /**
     * This method sets the layout property of this class. <br/>
     * Activities extending {@link DialogActivity} should call this method
     * before calling {@link #onCreate(Bundle)} if they want to have a
     * custom view.
     *
     * @param layoutResId resource if of the activity layout
     * @param contentAreaId id of the content area
     * @param actionAreaId id of the action area
     */
    protected void setLayoutProperties(int layoutResId, int contentAreaId, int actionAreaId) {
        mLayoutResId = layoutResId;
        getDialogFragment().setLayoutProperties(contentAreaId, actionAreaId);
    }

    /**
     * Animates a view.
     *
     * @param v              view to animate
     * @param initAlpha      initial alpha
     * @param initTransX     initial translation in the X
     * @param delay          delay in ms
     * @param duration       duration in ms
     * @param interpolator   interpolator to be used, can be null
     * @param isIcon         if {@code true}, this is the main icon being moved
     */
    protected void prepareAndAnimateView(final View v, float initAlpha, float initTransX, int delay,
            int duration, Interpolator interpolator, final boolean isIcon) {
        getDialogFragment().prepareAndAnimateView(
                v, initAlpha, initTransX, delay, duration, interpolator, isIcon);
    }

    /**
     * Called when intro animation is finished.
     * <p>
     * If a subclass is going to alter the view, should wait until this is called.
     */
    protected void onIntroAnimationFinished() {
        getDialogFragment().onIntroAnimationFinished();
    }

    protected boolean isIntroAnimationInProgress() {
        return getDialogFragment().isIntroAnimationInProgress();
    }

    protected ColorDrawable getBackgroundDrawable() {
        return getDialogFragment().getBackgroundDrawable();
    }

    protected void setBackgroundDrawable(ColorDrawable drawable) {
        getDialogFragment().setBackgroundDrawable(drawable);
    }

    /**
     * Sets the content fragment into the view.
     */
    protected void setContentFragment(Fragment fragment) {
        getDialogFragment().setContentFragment(fragment);
    }

    /**
     * Sets the action fragment into the view.
     * <p>
     * If an action fragment currently exists, this will be added to the back stack.
     */
    protected void setActionFragment(Fragment fragment) {
        getDialogFragment().setActionFragment(fragment);
    }

    /**
     * Sets the action fragment into the view.
     * <p>
     * If addToBackStack is true, and action fragment currently exists,
     * this will be added to the back stack.
     */
    protected void setActionFragment(Fragment fragment, boolean addToBackStack) {
        getDialogFragment().setActionFragment(fragment, addToBackStack);
    }

    protected Fragment getActionFragment() {
        return getDialogFragment().getActionFragment();
    }

    protected Fragment getContentFragment() {
        return getDialogFragment().getContentFragment();
    }

    /**
     * Set the content and action fragments in the same transaction.
     * <p>
     * If an action fragment currently exists, this will be added to the back stack.
     */
    protected void setContentAndActionFragments(Fragment contentFragment, Fragment actionFragment) {
        getDialogFragment().setContentAndActionFragments(contentFragment, actionFragment);
    }

    /**
     * Set the content and action fragments in the same transaction.
     * <p>
     * If addToBackStack and an action fragment currently exists,
     * this will be added to the back stack.
     */
    protected void setContentAndActionFragments(Fragment contentFragment, Fragment actionFragment,
            boolean addToBackStack) {
        getDialogFragment().setContentAndActionFragments(
                contentFragment, actionFragment, addToBackStack);
    }

    protected void setDialogFragment(DialogFragment fragment) {
        setDialogFragment(fragment, true);
    }

    protected void setDialogFragment(DialogFragment fragment, boolean addToBackStack) {
        mDialogFragment = fragment;
        fragment.setActivity(this);
        FragmentManager fm = getFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        boolean hasDialog = fm.findFragmentByTag(DialogActivity.TAG_DIALOG) != null;
        if (hasDialog) {
            if (addToBackStack) {
                ft.addToBackStack(DialogActivity.BACKSTACK_NAME_DIALOG);
            }
        }
        ft.replace(R.id.dialog_fragment, fragment, DialogActivity.TAG_DIALOG);
        ft.commit();
    }

    protected DialogFragment getDialogFragment() {
        final DialogFragment fragment =
                (DialogFragment) getFragmentManager().findFragmentByTag(TAG_DIALOG);
        if (fragment != null) {
            mDialogFragment = fragment;
        }

        return mDialogFragment;
    }
}
