com.wit.and.dialog.manage.DialogManager.java Source code

Java tutorial

Introduction

Here is the source code for com.wit.and.dialog.manage.DialogManager.java

Source

/*
 * =================================================================================
 * Copyright (C) 2013 Martin Albedinsky [Wolf-ITechnologies]
 * =================================================================================
 * Licensed under the Apache License, Version 2.0 or later (further "License" only);
 * ---------------------------------------------------------------------------------
 * You may use this file only in compliance with the License. More details and copy
 * of this License you may obtain at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 * You can redistribute, modify or publish any part of the code written in this
 * file but as it is described in the License, the software distributed under the 
 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES or CONDITIONS OF
 * ANY KIND.
 * 
 * See the License for the specific language governing permissions and limitations
 * under the License.
 * =================================================================================
 */
package com.wit.and.dialog.manage;

import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.util.Log;

import com.wit.and.dialog.EditDialog;
import com.wit.and.dialog.IDialog;
import com.wit.and.dialog.IEditDialog;
import com.wit.and.dialog.IListDialog;
import com.wit.and.dialog.ILoginDialog;
import com.wit.and.dialog.ListDialog;
import com.wit.and.dialog.LoginDialog;
import com.wit.and.dialog.internal.BaseDialog;

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

/**
 * <h4>Class Overview</h4>
 * <p>
 * Manager used to handle showing and hiding of dialog fragments in the fragment
 * activity or fragment. Cooperates with the {@link IDialogFactory } which
 * provides instances of dialogs to show.
 * </p>
 *
 * @author Martin Albedinsky
 * @see DialogFactory
 * @see com.wit.and.dialog.Dialog
 */
public class DialogManager {
    /**
     * Constants =============================
     */

    /**
     * <p>
     * Default tag for the showing on dialog fragments.
     * </p>
     */
    public static final String DIALOG_FRAGMENT_TAG = "com.wit.and.dialog.manage.DialogManager.DialogFragment.TAG";

    /**
     * Log TAG.
     */
    private static final String TAG = DialogManager.class.getSimpleName();

    /**
     * Indicates if debug private output trough log-cat is enabled.
     */
    private static final boolean DEBUG = true;

    /**
     * Indicates if logging for user output trough log-cat is enabled.
     */
    private static final boolean USER_LOG = true;

    /**
     * Enums =================================
     */

    /**
     * Static members ========================
     */

    /**
     * Members ===============================
     */

    /**
     * Fragment manager to handle showing dialog fragments.
     */
    private FragmentManager mFragmentManager = null;

    /**
     * Dialog factory to handle obtaining of dialog fragment instances to show.
     */
    private IDialogFactory mDialogFactory = null;

    /**
     * Tag of the parent fragment in case of dialog manager used in fragment.
     */
    private String mParentFragmentTag = null;

    /**
     * Listeners -----------------------------
     */

    /**
     * Listener to handle callback when the showed dialogs were recreated.
     */
    private OnDialogRestoreListener iRestoreListener = null;

    /**
     * Arrays --------------------------------
     */

    /**
     * Booleans ------------------------------
     */

    /**
     *
     */
    private boolean bDialogsRestoreCheckPerformed = false;

    /**
     * Constructors ==========================
     */

    /**
     * <p>
     * Same as
     * {@link #DialogManager(FragmentManager, IDialogFactory)}, but with not
     * initialized factory.
     * </p>
     *
     * @param fragmentManager Support fragment manager.
     */
    public DialogManager(FragmentManager fragmentManager) {
        this(fragmentManager, null);
    }

    /**
     * <p>
     * Constructs the manager to handle dialog fragments.
     * </p>
     * <p>
     * <b>Note: </b>always use {@link FragmentManager} provided by
     * {@link FragmentActivity}.
     * </p>
     * <p>
     * <b>DialogManager parent:</b>
     * <ul>
     * <li>FragmentActivity:
     * <code>yourActivity.getSupportFragmentManager()</code></li>
     * <li>Fragment: <code>yourFragment.getFragmentManager()</code></li>
     * </ul>
     * </p>
     *
     * @param fragmentManager Support fragment manager.
     * @param factory         Dialog factory to provide dialog fragment instances.
     */
    public DialogManager(FragmentManager fragmentManager, IDialogFactory factory) {
        this.mFragmentManager = fragmentManager;
        this.mDialogFactory = factory;
    }

    /**
     * Methods ===============================
     */

    /**
     * Public --------------------------------
     */

    /**
     * <p>
     * Same as {@link #showDialog(int, com.wit.and.dialog.manage.DialogManager.ListenerOptions)}
     * with empty listeners.
     * </p>
     *
     * @param dialogID Dialog id.
     * @return <code>True</code> if dialog was currently showed,
     * <code>false</code> if there is currently showing dialog with the
     * same tag.
     * @throws IllegalStateException
     */
    public final boolean showDialog(int dialogID) {
        return showDialog(dialogID, new ListenerOptions());
    }

    /**
     * <p>
     * Same as {@link #showDialog(int, DialogOptions, com.wit.and.dialog.manage.DialogManager.ListenerOptions)}
     * with empty listeners.
     * </p>
     *
     * @param dialogID Dialog id.
     * @param options  Dialog options.
     * @return <code>True</code> if dialog was currently showed,
     * <code>false</code> if there is currently showing dialog with the
     * same tag.
     * @throws IllegalStateException
     */
    public final boolean showDialog(int dialogID, DialogOptions options) {
        return showDialog(dialogID, options, new ListenerOptions());
    }

    /**
     * <p>
     * Same as {@link #showDialog(int, DialogOptions, com.wit.and.dialog.manage.DialogManager.ListenerOptions)}
     * with no options.
     * </p>
     *
     * @param dialogID  Dialog id.
     * @param listeners Callback to be invoked when specific dialog action occurs.
     * @return <code>True</code> if dialog was currently showed,
     * <code>false</code> if there is currently showing dialog with the
     * same tag.
     * @throws IllegalStateException
     */
    public final boolean showDialog(int dialogID, ListenerOptions listeners) {
        return showDialog(dialogID, null, listeners);
    }

    /**
     * <p>
     * Shows dialog fragment mapped to the given <var>dialogID</var> in the current
     * dialog factory. Given options will be passed to that factory and instance of
     * requested dialog will be obtained with dialog tag from it. Also the given
     * listeners will be assigned to that dialog instance.
     * </p>
     *
     * @param dialogID  Id of dialog to show. Id should be provided by {@link IDialogFactory}
     * @param options   Dialog options.
     * @param listeners Callback to be invoked when specific dialog action occurs.
     * @return <code>True</code> if dialog was currently showed,
     * <code>false</code> if there is currently showing dialog with the
     * same tag.
     * @throws IllegalStateException
     */
    public final boolean showDialog(int dialogID, DialogOptions options, ListenerOptions listeners) {
        return this.performShowFactoryDialog(dialogID, options, listeners);
    }

    /**
     * <p>
     * Same as {@link #showDialog(android.support.v4.app.DialogFragment, com.wit.and.dialog.manage.DialogManager.ListenerOptions)}
     * with empty listeners.
     * </p>
     *
     * @param dialog Dialog to show.
     * @return <code>True</code> if dialog was currently showed,
     * <code>false</code> if there is currently showing dialog with the
     * same tag.
     */
    public final boolean showDialog(DialogFragment dialog) {
        return this.showDialog(dialog, new ListenerOptions());
    }

    /**
     * <p>
     * Same as {@link #showDialog(android.support.v4.app.DialogFragment, com.wit.and.dialog.manage.DialogManager.ListenerOptions, String)},
     * where {@link #DIALOG_FRAGMENT_TAG} will be used as dialog tag.
     * </p>
     *
     * @param dialog    Dialog to show.
     * @param listeners Set of listeners to assign to the given dialog.
     * @return <code>True</code> if dialog was currently showed,
     * <code>false</code> if there is currently showing dialog with the
     * same tag.
     */
    public final boolean showDialog(DialogFragment dialog, ListenerOptions listeners) {
        return this.showDialog(dialog, listeners, DIALOG_FRAGMENT_TAG);
    }

    /**
     * <p>
     * Same as {@link #showDialog(android.support.v4.app.DialogFragment, com.wit.and.dialog.manage.DialogManager.ListenerOptions, String)}
     * with empty listeners.
     * </p>
     *
     * @param dialog    Dialog to show.
     * @param dialogTag Tag under which should be the given dialog showed.
     * @return <code>True</code> if dialog was currently showed,
     * <code>false</code> if there is currently showing dialog with the
     * same tag.
     */
    public final boolean showDialog(DialogFragment dialog, String dialogTag) {
        return this.showDialog(dialog, new ListenerOptions(), dialogTag);
    }

    /**
     * <p>
     * Shows the given dialog fragment under the given dialog tag. Also the given
     * listeners will be assigned to that dialog instance.
     * </p>
     *
     * @param dialog    Dialog to show.
     * @param listeners Set of listeners to assign to the given dialog.
     * @param dialogTag Tag under which should be the given dialog showed.
     * @return <code>True</code> if dialog was currently showed,
     * <code>false</code> if there is currently showing dialog with the
     * same tag.
     */
    public final boolean showDialog(DialogFragment dialog, ListenerOptions listeners, String dialogTag) {
        return this.performShowDialog(dialog, listeners, dialogTag);
    }

    /**
     * <p>
     * Dismiss dialog fragment by the given id.
     * Same as {@link #dismissDialog(String)}, where dialog tag is obtained
     * from current dialog factory.
     * </p>
     *
     * @param dialogID Id from the {@link DialogFactory} responsible for dialog.
     * @return <code>True</code> if there is some dialog fragment active in the fragment
     * manager under the given <var>dialogID</var> and was successfully dismissed,
     * <code>false</code> otherwise.
     * @throws java.lang.IllegalStateException
     * @see #dismissDialog(android.support.v4.app.DialogFragment)
     * @see #dismissDialog(String)
     */
    public final boolean dismissDialog(int dialogID) {
        if (mDialogFactory == null)
            throw new IllegalStateException(
                    "No factory to provide dialog tag for dialog with id(" + dialogID + ")");

        return dismissDialog(mDialogFactory.getDialogTag(dialogID));
    }

    /**
     * <p>
     * Dismiss dialog fragment by the given tag.
     * Same as {@link #dismissDialog(android.support.v4.app.DialogFragment)}.
     * </p>
     *
     * @param dialogTag Tag under which was dialog displayed.
     * @return <code>True</code> if there is some dialog fragment visible in the fragment
     * manager under the given <var>dialogTag</var> and was successfully dismissed,
     * <code>false</code> otherwise.
     * @see #dismissDialog(android.support.v4.app.DialogFragment)
     * @see #dismissDialog(int)
     */
    public final boolean dismissDialog(String dialogTag) {
        Fragment dialog = mFragmentManager.findFragmentByTag(dialogTag == null ? DIALOG_FRAGMENT_TAG : dialogTag);
        return dialog != null && dialog instanceof DialogFragment && dismissDialog((DialogFragment) dialog);
    }

    /**
     * <p>
     * Dismiss the given dialog fragment.
     * </p>
     *
     * @param dialog Dialog fragment to dismiss.
     * @return <code>True</code> if dismissing succeed, <code>false</code> otherwise.
     * @see #dismissDialog(int)
     * @see #dismissDialog(String)
     */
    public final boolean dismissDialog(DialogFragment dialog) {
        // Check dialog.
        if (dialog != null && dialog.isVisible()) {
            // Try to dismiss dialog.
            try {
                dialog.dismissAllowingStateLoss();
                return true;
            } catch (IllegalStateException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     * <p>
     * </p>
     */
    public final boolean dispatchParentRestored() {
        // Check for restored dialog fragments.
        boolean restored = !bDialogsRestoreCheckPerformed && checkRestoredDialogs();

        // Dispatch.
        onParentRestored();
        return restored;
    }

    /**
     * Getters + Setters ---------------------
     */

    /**
     * <p>
     * Sets the fragment manager to handle showing dialog fragments.
     * </p>
     * <b>Note: </b>always use {@link FragmentManager} provided by fragment
     * activity.</p>
     * <p>
     * <b>DialogManager parent:</b>
     * <ul>
     * <li>FragmentActivity:
     * <code>yourActivity.getSupportFragmentManager()</code></li>
     * <li>Fragment: <code>yourFragment.getFragmentManager()</code></li>
     * </ul>
     * </p>
     *
     * @param fragmentManager Support fragment manager.
     */
    public final void setFragmentManager(FragmentManager fragmentManager) {
        this.mFragmentManager = fragmentManager;
    }

    /**
     * <p>
     * Sets dialogs factory which will provides the dialog fragment instances
     * for this manager.
     * </p>
     *
     * @param factory Factory used when this manager shows the dialog depends on the
     *                <var>id</var>.
     */
    public final void setDialogFactory(IDialogFactory factory) {
        this.mDialogFactory = factory;
    }

    /**
     * <p>
     * Register listener to handle callback to be invoked when a dialog
     * fragment is recreated.
     * </p>
     *
     * @param listener Listener callback.
     */
    public final void setOnDialogRestoreListener(OnDialogRestoreListener listener) {
        this.iRestoreListener = listener;
    }

    /**
     * <p>
     * Returns dialog factory of this manager.
     * </p>
     *
     * @return Dialog factory or <code>null</code> if there wasn't set dialog
     * factory yet.
     */
    public final IDialogFactory getDialogFactory() {
        return mDialogFactory;
    }

    /**
     * <p>
     * Sets the tag of the parent fragment.
     * </p>
     *
     * @param tag Tag of the fragment which use this dialog manager.
     */
    public final void setParentFragmentTag(String tag) {
        this.mParentFragmentTag = tag;
    }

    /**
     * <p>
     * Same as {@link #getDialog(String)}. Dialog tag is obtained from the dialog factory.
     * </p>
     *
     * @param dialogID Dialog id from the correspond {@link DialogFactory} which was used to show requested dialog.
     * @return Dialog fragment if there is some in the fragment manager with resolved tag or <code>null</code> if not.
     */
    public DialogFragment getDialog(int dialogID) {
        if (mDialogFactory == null)
            throw new IllegalStateException(
                    "No factory to provide dialog tag for dialog with id(" + dialogID + ")");

        return getDialog(mDialogFactory.getDialogTag(dialogID));
    }

    /**
     * <p>
     * Returns dialog fragment with the given tag.
     * </p>
     *
     * @param dialogTAG Dialog tag under which was dialog showed.
     * @return Dialog fragment if there is some in the fragment manager with given tag or <code>null</code> if not.
     */
    public DialogFragment getDialog(String dialogTAG) {
        return (DialogFragment) mFragmentManager.findFragmentByTag(dialogTAG);
    }

    /**
     * <p>
     * Returns tag of top (last showed) visible dialog fragment.
     * </p>
     *
     * @return Tag of top dialog fragment.
     * @see #getTopVisibleDialog()
     * @see #getVisibleDialogs()
     */
    public String getTopVisibleDialogTag() {
        List<DialogFragment> visible = getVisibleDialogs();
        return (visible.size() > 0) ? visible.get(visible.size() - 1).getTag() : null;
    }

    /**
     * <p>
     * Returns top visible dialog fragment.
     * </p>
     *
     * @return Dialog fragment which is currently at the top of visible dialogs
     * or <code>null</code> if there are no currently visible any dialogs
     * @see #getTopVisibleDialogTag()
     */
    public DialogFragment getTopVisibleDialog() {
        List<DialogFragment> visible = getVisibleDialogs();
        return (visible.size() > 0) ? visible.get(visible.size() - 1) : null;
    }

    /**
     * <p>
     * </p>
     *
     * @return
     */
    public List<DialogFragment> getVisibleDialogs() {
        List<DialogFragment> dialogs = getDialogs();
        List<DialogFragment> visible = new ArrayList<DialogFragment>();

        if (dialogs.size() > 0) {
            for (DialogFragment dialog : dialogs) {
                if (dialog.isVisible()) {
                    visible.add(dialog);
                }
            }
        }
        return visible;
    }

    /**
     * <p>
     * </p>
     *
     * @return
     */
    public List<DialogFragment> getDialogs() {
        List<DialogFragment> dialogs = new ArrayList<DialogFragment>();
        if (mFragmentManager != null) {
            List<Fragment> fragments = mFragmentManager.getFragments();
            if (fragments != null) {
                // Find the dialog fragments between current fragments.
                for (Fragment fragment : fragments) {
                    if (fragment != null && fragment instanceof DialogFragment) {
                        dialogs.add((DialogFragment) fragment);
                    }
                }
            }
        }
        return dialogs;
    }

    /**
     * Protected -----------------------------
     */

    /**
     * <p>
     * </p>
     */
    protected void onParentRestored() {
    }

    /**
     * <p>
     * Invoked to resolve given listeners for the given dialog.
     * </p>
     *
     * @param dialog    Dialog to which should be given listeners assigned.
     * @param listeners Set of listeners to assign to the given dialog.
     */
    protected void onResolveListeners(DialogFragment dialog, ListenerOptions listeners) {
    }

    /**
     * <p>
     * Returns current fragment manager.
     * </p>
     *
     * @return Fragment manager.
     * @see #setFragmentManager(android.support.v4.app.FragmentManager)
     * @see #DialogManager(android.support.v4.app.FragmentManager)
     * @see #DialogManager(android.support.v4.app.FragmentManager, com.wit.and.dialog.manage.DialogManager.IDialogFactory)
     */
    protected final FragmentManager getFragmentManager() {
        return mFragmentManager;
    }

    /**
     * <p>
     * Invoked to show the given dialog fragment under the given tag.
     * </p>
     *
     * @param dialog    Dialog fragment to show.
     * @param dialogTag Tag under which should be the given dialog showed.
     * @return <code>True</code> if dialog was currently showed,
     * <code>false</code> if there is currently showing dialog with the
     * same tag.
     */
    protected boolean onShowDialog(DialogFragment dialog, String dialogTag) {
        // Check valid dialog.
        if (dialog == null)
            return false;

        // Set parent fragment tag to be possible resolve implicit listener as
        // fragment.
        if (dialog instanceof BaseDialog) {
            ((BaseDialog) dialog).setParentFragmentTag(mParentFragmentTag);
        }

        // Correct dialog tag.
        dialogTag = (dialogTag == null) ? DIALOG_FRAGMENT_TAG : dialogTag;

        if (DEBUG)
            Log.d(TAG, "showDialog(tag('" + dialogTag + "'))");

        // Check for existing dialog fragment.
        DialogFragment currentDialog = (DialogFragment) mFragmentManager.findFragmentByTag(dialogTag);
        if (currentDialog != null) {
            if (USER_LOG)
                Log.i(TAG, String.format("Request to show dialog with tag '" + dialogTag
                        + "' failed. Dialog with this tag is already being showing. Set another tag or dismiss the previous dialog with same tag."));
            return false;
        }

        // Show dialog.
        dialog.show(mFragmentManager.beginTransaction(), dialogTag);
        return true;
    }

    /**
     * Resolves the setting of the given listeners to the given dialog. Given
     * dialog must be instanceof {@link BaseDialog} to be listeners successfully
     * resolved and set.
     *
     * @param dialog    Dialog fragment.
     * @param listeners Set of listeners to assign to the given dialog.
     * @return Given dialog instance with listeners set.
     */
    static <D extends DialogFragment> D resolveListeners(D dialog, ListenerOptions listeners) {
        if (!listeners.isEmpty()) {
            if (dialog instanceof BaseDialog) {
                if (listeners.dialogListener != null) {
                    ((BaseDialog) dialog).setOnDialogListener(listeners.dialogListener);
                }
                if (listeners.cancelListener != null) {
                    ((BaseDialog) dialog).setOnCancelListener(listeners.cancelListener);
                }

                // Others specific dialog listeners.
                if (listeners.listener != null) {
                    if (dialog instanceof ListDialog && listeners.listener instanceof IListDialog.OnListListener) {
                        ((ListDialog) dialog)
                                .setOnListDialogListener(listeners.<IListDialog.OnListListener>getListener());
                    } else if (dialog instanceof LoginDialog
                            && listeners.listener instanceof ILoginDialog.OnAuthenticationListener) {
                        ((LoginDialog) dialog).setOnAuthenticationListener(
                                listeners.<ILoginDialog.OnAuthenticationListener>getListener());
                    } else if (dialog instanceof EditDialog
                            && listeners.listener instanceof IEditDialog.OnEditListener) {
                        ((EditDialog) dialog)
                                .setOnEditListener(listeners.<IEditDialog.OnEditListener>getListener());
                    }
                }
            }
        }
        return dialog;
    }

    /**
     * Private -------------------------------
     */

    /**
     * Resolved dialog listeners.
     *
     * @param dialog    Dialog fragment.
     * @param listeners Set of listeners to assign to the given dialog.
     * @param <D>       Type of dialog.
     * @return Same dialog with resolved listeners.
     */
    @SuppressWarnings("unchecked")
    private <D extends DialogFragment> D resolveListenersInternal(DialogFragment dialog,
            ListenerOptions listeners) {
        dialog = resolveListeners(dialog, listeners);
        onResolveListeners(dialog, listeners);
        return (D) dialog;
    }

    /**
     * Performs showing of the dialog obtained from the dialog factory with the
     * given parameters.
     *
     * @param dialogID  Id of dialog.
     * @param options   Dialog options.
     * @param listeners Set of listeners to assign to the given dialog.
     * @return <code>True</code> if dialog was successfully showed, <code>false</code> otherwise.
     * @throws IllegalStateException
     */
    private boolean performShowFactoryDialog(int dialogID, DialogOptions options, ListenerOptions listeners) {
        // Check if we have dialog factory.
        if (mDialogFactory == null) {
            throw new IllegalStateException(
                    "No dialog factory found. Please set factory before you use any showDialog(int, ...) methods.");
        }

        // First obtain dialog instance then dialog tag.
        DialogFragment dialog = mDialogFactory.createDialogInstance(dialogID, options);
        if (dialog == null) {
            // Invalid dialog instance.
            Log.e(TAG, "No such dialog fragment instance for the requested dialog id(" + dialogID
                    + "). Please check your dialog factory.");
            return false;
        }
        String dialogTag = mDialogFactory.getDialogTag(dialogID);

        return showDialog(dialog, listeners, dialogTag);
    }

    /**
     * Performs showing of the given dialog fragment with the given parameters.
     *
     * @param dialog    Dialog to show.
     * @param listeners Set of listeners to assign to the given dialog.
     * @param dialogTag Tag under which should be the given dialog showed.
     * @return <code>True</code> if dialog was successfully showed, <code>false</code> otherwise.
     */
    private boolean performShowDialog(DialogFragment dialog, ListenerOptions listeners, String dialogTag) {
        // Check valid dialog.
        if (dialog == null) {
            if (USER_LOG)
                Log.i(TAG, "Invalid dialog instance(null) to show.");
            return false;
        }

        // Set listeners to the dialog.
        dialog = this.resolveListenersInternal(dialog, listeners);

        // Show dialog and return it's options.
        return onShowDialog(dialog, dialogTag);
    }

    /**
     * Performs check for restored dialogs.
     *
     * @return <code>True</code> if some dialog was restored, <code>false</code> otherwise.
     */
    private boolean checkRestoredDialogs() {
        if (bDialogsRestoreCheckPerformed)
            return false;

        boolean restored = false;
        List<DialogFragment> restoredDialogs = getDialogs();
        if (restoredDialogs.size() > 0) {
            for (DialogFragment dialog : restoredDialogs) {
                if (USER_LOG)
                    Log.i(TAG, "Restored dialog(" + dialog.getTag() + ").");

                // Fire on restored dialog callback.
                if (iRestoreListener != null) {
                    if (dialog instanceof IDialog) {
                        iRestoreListener.onDialogRestored(dialog, ((IDialog) dialog).getDialogID());
                    } else {
                        iRestoreListener.onDialogRestored(dialog, dialog.getId());
                    }
                }
                restored = true;
            }
        }
        // Save check state.
        this.bDialogsRestoreCheckPerformed = true;
        return restored;
    }

    /**
     * Abstract methods ----------------------
     */

    /**
     * Inner classes =========================
     */

    /**
     * <h4>Class Overview</h4>
     * <p>
     * Fast listener options to set the listener for the {@link com.wit.and.dialog.Dialog}.
     * </p>
     *
     * @author Martin Albedinsky
     * @see DialogManager
     */
    public static final class ListenerOptions {

        /**
         * Members ===============================
         */

        /**
         * <p>
         * Dialog listener.
         * </p>
         */
        protected IDialog.OnDialogListener dialogListener = null;

        /**
         * <p>
         * Cancel dialog listener.
         * </p>
         */
        protected IDialog.OnDialogCancelListener cancelListener = null;

        /**
         * <p>
         * Custom on dialog listener.
         * </p>
         */
        protected IDialog.OnBaseDialogListener listener = null;

        /**
         * Constructors ==========================
         */

        /**
         * <p>
         * Constructs empty fast dialog listener options.
         * </p>
         */
        public ListenerOptions() {
        }

        /**
         * Methods ===============================
         */

        /**
         * Public --------------------------------
         */

        /**
         * <p>
         * Return flag indicating if some of the listeners is set.
         * </p>
         *
         * @return <code>True</code> if some of the listeners is set,
         * <code>false</code> otherwise.
         */
        public boolean isEmpty() {
            return dialogListener == null && cancelListener == null && listener == null;
        }

        /**
         * Getters + Setters ---------------------
         */

        /**
         * <p>
         * Sets the given callback as dialog listener for the {@link com.wit.and.dialog.Dialog}.
         * </p>
         *
         * @param listener Listener callback.
         * @return This options.
         */
        public ListenerOptions dialogListener(IDialog.OnDialogListener listener) {
            this.dialogListener = listener;
            return this;
        }

        /**
         * <p>
         * Sets the given callback as cancel listener for the {@link com.wit.and.dialog.Dialog}.
         * </p>
         *
         * @param listener Listener callback.
         * @return This options.
         */
        public ListenerOptions cancelListener(IDialog.OnDialogCancelListener listener) {
            this.cancelListener = listener;
            return this;
        }

        /**
         * <p>
         * Sets the given callback as specific listener for the {@link com.wit.and.dialog.Dialog} derived class.
         * </p>
         *
         * @return This options.
         */
        public ListenerOptions listener(IDialog.OnBaseDialogListener listener) {
            this.listener = listener;
            return this;
        }

        /**
         * Protected -----------------------------
         */

        /**
         * <p>
         * Returns specific listener for one of the derived classes of
         * {@link com.wit.and.dialog.Dialog}.
         * </p>
         *
         * @param <L> Type of the requested listener.
         * @return Listener callback.
         */
        @SuppressWarnings("unchecked")
        <L extends IDialog.OnBaseDialogListener> L getListener() {
            return (L) listener;
        }
    }

    /**
     * Interface =============================
     */

    /**
     * <h4>Interface Overview</h4>
     * <p>
     * </p>
     *
     * @author Martin Albedinsky
     * @see DialogManager
     */
    public static interface IDialogFactory {

        /**
         * Methods ===============================
         */

        /**
         * <p>
         * Returns instance of the dialog fragment. Instance of the dialog
         * depends on the given <var>dialogID</var>.
         * </p>
         *
         * @param dialogID Id of dialog.
         * @param options  Dialog options with data or <code>null</code> if options should
         *                 be populated in the factory.
         * @see DialogManager
         */
        public DialogFragment createDialogInstance(int dialogID, DialogOptions options);

        /**
         * <p>
         * Returns tag for dialog fragment associated with the given
         * <var>dialogID</var>.
         * </p>
         *
         * @param dialogID Id of dialog for which is tag requested.
         */
        public String getDialogTag(int dialogID);
    }

    /**
     * <h4>Interface Overview</h4>
     * <p>
     * </p>
     *
     * @author Martin Albedinsky
     * @see DialogManager
     */
    public static interface OnDialogRestoreListener {

        /**
         * Methods ===============================
         */

        /**
         * <p>
         * Invoked when some dialog was restored after orientation change.
         * </p>
         * <p>
         * <b>Contract:</b><br/>
         * If you want to handle restored dialogs, you must all that dialogs show by
         * {@link com.wit.and.dialog.manage.DialogManager}. Only dialog which was showed by
         * dialog manager can be ... as restored.
         * </p>
         *
         * @param dialog   Dialog fragment which was restored after orientation change and is still visible.
         * @param dialogID Id of restored dialog.
         */
        public void onDialogRestored(DialogFragment dialog, int dialogID);
    }
}