/*
 * 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.deskclock;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.DialogFragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.app.LoaderManager;
import android.content.AsyncTaskLoader;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Loader;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.media.AudioManager;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.support.v13.app.FragmentCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

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

import static android.Manifest.permission.READ_EXTERNAL_STORAGE;

/**
 * This ringtone picker offers some flexibility over the system ringtone picker. It can be themed
 * and it allows control of the ringtones that are displayed and their labels.
 */
public final class RingtonePickerDialogFragment extends DialogFragment implements
        DialogInterface.OnClickListener,
        FragmentCompat.OnRequestPermissionsResultCallback,
        LoaderManager.LoaderCallbacks<RingtoneManager> {

    private static final String ARGS_KEY_TITLE = "title";
    private static final String ARGS_KEY_DEFAULT_RINGTONE_TITLE = "default_ringtone_title";
    private static final String ARGS_KEY_DEFAULT_RINGTONE_URI = "default_ringtone_uri";
    private static final String ARGS_KEY_EXISTING_RINGTONE_URI = "existing_ringtone_uri";

    private static final String STATE_KEY_REQUESTING_PERMISSION = "requesting_permission";
    private static final String STATE_KEY_SELECTED_RINGTONE_URI = "selected_ringtone_uri";

    private boolean mRequestingPermission;
    private Uri mSelectedRingtoneUri;

    private RingtoneAdapter mRingtoneAdapter;
    private AlertDialog mDialog;

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

        // Restore saved instance state.
        if (savedInstanceState != null) {
            mRequestingPermission = savedInstanceState.getBoolean(STATE_KEY_REQUESTING_PERMISSION);
            mSelectedRingtoneUri =
                    savedInstanceState.getParcelable(STATE_KEY_SELECTED_RINGTONE_URI);
        } else {
            // Initialize selection to the existing ringtone.
            mSelectedRingtoneUri = getArguments().getParcelable(ARGS_KEY_EXISTING_RINGTONE_URI);
        }
    }

    @Override
    public AlertDialog onCreateDialog(Bundle savedInstanceState) {
        final AlertDialog.Builder builder =
                new AlertDialog.Builder(getActivity(), R.style.DialogTheme);
        final Bundle args = getArguments();

        mRingtoneAdapter = new RingtoneAdapter(builder.getContext())
                .addStaticRingtone(R.string.silent_ringtone_title, Utils.RINGTONE_SILENT)
                .addStaticRingtone(args.getInt(ARGS_KEY_DEFAULT_RINGTONE_TITLE),
                        (Uri) args.getParcelable(ARGS_KEY_DEFAULT_RINGTONE_URI));
        mDialog = builder.setTitle(args.getInt(ARGS_KEY_TITLE))
                .setSingleChoiceItems(mRingtoneAdapter, -1, this /* listener */)
                .setPositiveButton(android.R.string.ok, this /* listener */)
                .setNegativeButton(android.R.string.cancel, null /* listener */)
                .create();

        return mDialog;
    }

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

        if (savedInstanceState == null
                && ContextCompat.checkSelfPermission(getActivity(), READ_EXTERNAL_STORAGE)
                    != PackageManager.PERMISSION_GRANTED) {
            mRequestingPermission = true;
            FragmentCompat.requestPermissions(this, new String[] { READ_EXTERNAL_STORAGE },
                    0 /* requestCode */);
        } else if (!mRequestingPermission) {
            getLoaderManager().initLoader(0 /* id */, null /* args */, this /* callback */);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
            @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        for (final String permission : permissions) {
            if (READ_EXTERNAL_STORAGE.equals(permission)) {
                mRequestingPermission = false;

                // Show the dialog now that we've prompted the user for permissions.
                mDialog.show();

                getLoaderManager().initLoader(0 /* id */, null /* args */, this /* callback */);
                break;
            }
        }
    }

    @Override
    public void onStart() {
        super.onStart();

        // Disable the positive button until we have a valid selection (Note: this is the first
        // point in the fragment's lifecycle that the dialog *should* have all its views).
        final View positiveButton = mDialog.getButton(DialogInterface.BUTTON_POSITIVE);
        if (positiveButton != null) {
            positiveButton.setEnabled(!mRingtoneAdapter.isEmpty() && mSelectedRingtoneUri != null);
        }

        // Hide the dialog if we are currently requesting permissions.
        if (mRequestingPermission) {
            mDialog.hide();
        }
    }

    @Override
    public void onResume() {
        super.onResume();

        // Allow the volume rocker to control the alarm stream volume while the picker is showing.
        mDialog.setVolumeControlStream(AudioManager.STREAM_ALARM);
    }

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putBoolean(STATE_KEY_REQUESTING_PERMISSION, mRequestingPermission);
        outState.putParcelable(STATE_KEY_SELECTED_RINGTONE_URI, mSelectedRingtoneUri);
    }

    @Override
    public void onStop() {
        super.onStop();

        // Stop playing the preview unless we are currently undergoing a configuration change
        // (e.g. orientation).
        final Activity activity = getActivity();
        if (activity != null && !activity.isChangingConfigurations()) {
            RingtonePreviewKlaxon.stop(activity);
        }
    }

    @Override
    public Loader<RingtoneManager> onCreateLoader(int id, Bundle args) {
        return new RingtoneManagerLoader(getActivity());
    }

    @Override
    public void onLoadFinished(Loader<RingtoneManager> loader, RingtoneManager ringtoneManager) {
        // Swap in the new ringtone manager.
        mRingtoneAdapter.setRingtoneManager(ringtoneManager);

        // Preserve the selected ringtone.
        final ListView listView = mDialog.getListView();
        final int checkedPosition = mRingtoneAdapter.getRingtonePosition(mSelectedRingtoneUri);
        if (checkedPosition != ListView.INVALID_POSITION) {
            listView.setItemChecked(checkedPosition, true);

            // Also scroll the list to the selected ringtone (this method is poorly named).
            listView.setSelection(checkedPosition);
        } else {
            // Can't find the selected ringtone, clear the current selection.
            mSelectedRingtoneUri = null;
            listView.clearChoices();
        }

        // Enable the positive button if we have a valid selection (Note: the positive button may
        // be null if this callback returns before onStart).
        final View positiveButton = mDialog.getButton(DialogInterface.BUTTON_POSITIVE);
        if (positiveButton != null) {
            positiveButton.setEnabled(mSelectedRingtoneUri != null);
        }

        // On M devices the checked view's drawable state isn't updated properly when it is first
        // bound, so we must use a blunt approach to force it to refresh correctly.
        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) {
            listView.post(new Runnable() {
                @Override
                public void run() {
                    for (int i = listView.getChildCount() - 1; i >= 0; --i) {
                        listView.getChildAt(i).refreshDrawableState();
                    }
                }
            });
        }
    }

    @Override
    public void onLoaderReset(Loader<RingtoneManager> loader) {
        mRingtoneAdapter.setRingtoneManager(null);
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        if (which == DialogInterface.BUTTON_POSITIVE) {
            if (mSelectedRingtoneUri != null) {
                OnRingtoneSelectedListener listener = null;
                if (getParentFragment() instanceof OnRingtoneSelectedListener) {
                    listener = (OnRingtoneSelectedListener) getParentFragment();
                } else if (getActivity() instanceof OnRingtoneSelectedListener) {
                    listener = (OnRingtoneSelectedListener) getActivity();
                }

                if (listener != null) {
                    listener.onRingtoneSelected(getTag(), mSelectedRingtoneUri);
                }
            }
        } else if (which >= 0) {
            // Update the selected ringtone, enabling the positive button if valid.
            mSelectedRingtoneUri = mRingtoneAdapter.getItem(which);

            // Enable the positive button if we have a valid selection.
            final View positiveButton = mDialog.getButton(DialogInterface.BUTTON_POSITIVE);
            positiveButton.setEnabled(mSelectedRingtoneUri != null);

            // Play the preview for the clicked ringtone.
            if (mSelectedRingtoneUri == null
                    || mSelectedRingtoneUri.equals(Utils.RINGTONE_SILENT)) {
                RingtonePreviewKlaxon.stop(getActivity());
            } else {
                RingtonePreviewKlaxon.start(getActivity(), mSelectedRingtoneUri);
            }
        }
    }

    /**
     * Callback interface for when a ringtone is selected via a picker. Typically implemented by
     * the activity or fragment which launches the ringtone picker.
     */
    public interface OnRingtoneSelectedListener {
        /**
         * Called when the ringtone picker dialog is confirmed and dismissed.
         *
         * @param tag         the tag of the ringtone picker dialog fragment
         * @param ringtoneUri the uri of the ringtone that was picked
         */
        void onRingtoneSelected(String tag, Uri ringtoneUri);
    }

    public static final class Builder {

        private final Bundle mArgs = new Bundle();

        public Builder setTitle(@StringRes int titleId) {
            mArgs.putInt(ARGS_KEY_TITLE, titleId);
            return this;
        }

        public Builder setDefaultRingtoneTitle(@StringRes int titleId) {
            mArgs.putInt(ARGS_KEY_DEFAULT_RINGTONE_TITLE, titleId);
            return this;
        }

        public Builder setDefaultRingtoneUri(Uri ringtoneUri) {
            mArgs.putParcelable(ARGS_KEY_DEFAULT_RINGTONE_URI, ringtoneUri);
            return this;
        }

        public Builder setExistingRingtoneUri(Uri ringtoneUri) {
            mArgs.putParcelable(ARGS_KEY_EXISTING_RINGTONE_URI, ringtoneUri);
            return this;
        }

        public void show(FragmentManager fragmentManager, String tag) {
            final DialogFragment fragment = new RingtonePickerDialogFragment();
            fragment.setArguments(mArgs);
            fragment.show(fragmentManager, tag);
        }

        public void show(FragmentTransaction fragmentTransaction, String tag) {
            final DialogFragment fragment = new RingtonePickerDialogFragment();
            fragment.setArguments(mArgs);
            fragment.show(fragmentTransaction, tag);
        }
    }

    private static class RingtoneManagerLoader extends AsyncTaskLoader<RingtoneManager> {

        private RingtoneManager mRingtoneManager;
        private Cursor mRingtoneCursor;

        public RingtoneManagerLoader(Context context) {
            super(context);
        }

        @Override
        public RingtoneManager loadInBackground() {
            final RingtoneManager ringtoneManager = new RingtoneManager(getContext());
            ringtoneManager.setType(AudioManager.STREAM_ALARM);

            // Force the ringtone manager to load its ringtones. The cursor will be cached
            // internally by the ringtone manager.
            try {
                ringtoneManager.getCursor();
            } catch (Exception e) {
                LogUtils.e("Error getting Ringtone Manager cursor", e);
            }

            return ringtoneManager;
        }

        @Override
        public void deliverResult(RingtoneManager ringtoneManager) {
            if (mRingtoneManager != ringtoneManager) {
                if (mRingtoneCursor != null && !mRingtoneCursor.isClosed()) {
                    mRingtoneCursor.close();
                }
                mRingtoneManager = ringtoneManager;
                try {
                    mRingtoneCursor = mRingtoneManager.getCursor();
                } catch (Exception e) {
                    LogUtils.e("Error getting Ringtone Manager cursor", e);
                }
            }
            super.deliverResult(ringtoneManager);
        }

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

            if (mRingtoneCursor != null && !mRingtoneCursor.isClosed()) {
                mRingtoneCursor.close();
                mRingtoneCursor = null;
            }
            mRingtoneManager = null;
        }

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

            if (mRingtoneManager != null) {
                deliverResult(mRingtoneManager);
            } else {
                forceLoad();
            }
        }
    }

    private static class RingtoneAdapter extends BaseAdapter {

        private final List<Pair<Integer, Uri>> mStaticRingtones;
        private final LayoutInflater mLayoutInflater;

        private RingtoneManager mRingtoneManager;
        private Cursor mRingtoneCursor;

        public RingtoneAdapter(Context context) {
            mStaticRingtones = new ArrayList<>(2 /* magic */);
            mLayoutInflater = LayoutInflater.from(context);
        }

        /**
         * Add a static ringtone item to display before the system ones.
         *
         * @param title the title to display for the ringtone
         * @param ringtoneUri the {@link Uri} for the ringtone
         * @return this object so method calls may be chained
         */
        public RingtoneAdapter addStaticRingtone(@StringRes int title, Uri ringtoneUri) {
            if (title != 0 && ringtoneUri != null) {
                mStaticRingtones.add(Pair.create(title, ringtoneUri));
                notifyDataSetChanged();
            }

            return this;
        }

        /**
         * Set the {@link RingtoneManager} to query for system ringtones.
         *
         * @param ringtoneManager the {@link RingtoneManager} to query for system ringtones
         * @return this object so method calls may be chained
         */
        public RingtoneAdapter setRingtoneManager(RingtoneManager ringtoneManager) {
            mRingtoneManager = ringtoneManager;
            try {
                mRingtoneCursor = ringtoneManager == null ? null : ringtoneManager.getCursor();
            } catch (Exception e) {
                LogUtils.e("Error getting Ringtone Manager cursor", e);
            }
            notifyDataSetChanged();

            return this;
        }

        /**
         * Returns the position of the given ringtone uri.
         *
         * @param ringtoneUri the {@link Uri} to retrieve the position of
         * @return the ringtones position in the adapter
         */
        public int getRingtonePosition(Uri ringtoneUri) {
            if (ringtoneUri == null) {
                return ListView.INVALID_POSITION;
            }

            final int staticRingtoneCount = mStaticRingtones.size();
            for (int position = 0; position < staticRingtoneCount; ++position) {
                if (ringtoneUri.equals(mStaticRingtones.get(position).second)) {
                    return position;
                }
            }

            final int position = mRingtoneManager.getRingtonePosition(ringtoneUri);
            if (position != -1) {
                return position + staticRingtoneCount;
            }
            return ListView.INVALID_POSITION;
        }

        @Override
        public int getCount() {
            if (mRingtoneCursor == null) {
                return 0;
            }
            return mStaticRingtones.size() + mRingtoneCursor.getCount();
        }

        @Override
        public Uri getItem(int position) {
            final int staticRingtoneCount = mStaticRingtones.size();
            if (position < staticRingtoneCount) {
                return mStaticRingtones.get(position).second;
            }
            return mRingtoneManager.getRingtoneUri(position - staticRingtoneCount);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        @SuppressLint("PrivateResource")
        public View getView(int position, View view, ViewGroup parent) {
            if (view == null) {
                // Use AlertDialog's singleChoiceItemLayout directly here, if this breaks in the
                // future just copy the layout to DeskClock's res/.
                view = mLayoutInflater.inflate(R.layout.select_dialog_singlechoice_material,
                        parent, false /* attachToRoot */);
            }

            final TextView textView = (TextView) view.findViewById(android.R.id.text1);
            final int staticRingtoneCount = mStaticRingtones.size();
            if (position < staticRingtoneCount) {
                textView.setText(mStaticRingtones.get(position).first);
            } else {
                mRingtoneCursor.moveToPosition(position - staticRingtoneCount);
                textView.setText(mRingtoneCursor.getString(RingtoneManager.TITLE_COLUMN_INDEX));
            }

            return view;
        }
    }
}
