package de.greenrobot.event.util;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Application;
import android.os.Build;
import android.os.Bundle;
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 de.greenrobot.event.EventBus;

/**
 * Central class for app that want to use event based error dialogs.<br/>
 * <br/>
 * How to use:
 * <ol>
 * <li>Set the {@link #factory} to configure dialogs for your app, typically in {@link Application#onCreate()}</li>
 * <li>Use one of {@link #attachTo(Activity)}, {@link #attachTo(Activity, boolean)} or
 * {@link #attachTo(Activity, boolean, Bundle)} in your Activity, typically in onCreate.</li>
 * </ol>
 * 
 * For more complex mappings, you can supply your own {@link ErrorDialogFragmentFactory}.
 * 
 * @author Markus
 */
public class ErrorDialogManager {

    public static class SupportManagerFragment extends Fragment {
        protected boolean finishAfterDialog;
        protected Bundle argumentsForErrorDialog;
        private EventBus eventBus;

        @Override
        public void onResume() {
            super.onResume();
            eventBus = ErrorDialogManager.factory.config.getEventBus();
            eventBus.register(this);
        }

        @Override
        public void onPause() {
            eventBus.unregister(this);
            super.onPause();
        }

        public void onEventMainThread(ThrowableFailureEvent event) {
            if (factory.config.logExceptions) {
                String tag = factory.config.tagForLoggingExceptions;
                if (tag == null) {
                    tag = EventBus.TAG;
                }
                Log.i(tag, "Opening error dialog for exception", event.throwable);
            }
            // Execute pending commits before finding to avoid multiple error fragments being shown
            FragmentManager fm = getFragmentManager();
            fm.executePendingTransactions();

            DialogFragment existingFragment = (DialogFragment) fm.findFragmentByTag(TAG_ERROR_DIALOG);
            if (existingFragment != null) {
                // Just show the latest error
                existingFragment.dismiss();
            }

            android.support.v4.app.DialogFragment errorFragment = (android.support.v4.app.DialogFragment) factory
                    .prepareErrorFragment(event, finishAfterDialog, argumentsForErrorDialog);
            errorFragment.show(fm, TAG_ERROR_DIALOG);
        }

        public static void attachTo(Activity activity, boolean finishAfterDialog, Bundle argumentsForErrorDialog) {
            FragmentManager fm = ((FragmentActivity) activity).getSupportFragmentManager();
            SupportManagerFragment fragment = (SupportManagerFragment) fm.findFragmentByTag(TAG_ERROR_DIALOG_MANAGER);
            if (fragment == null) {
                fragment = new SupportManagerFragment();
                fm.beginTransaction().add(fragment, TAG_ERROR_DIALOG_MANAGER).commit();
            }
            fragment.finishAfterDialog = finishAfterDialog;
            fragment.argumentsForErrorDialog = argumentsForErrorDialog;
        }
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public static class HoneycombManagerFragment extends android.app.Fragment {
        protected boolean finishAfterDialog;
        protected Bundle argumentsForErrorDialog;
        private EventBus eventBus;

        @Override
        public void onResume() {
            super.onResume();
            eventBus = ErrorDialogManager.factory.config.getEventBus();
            eventBus.register(this);
        }

        @Override
        public void onPause() {
            eventBus.unregister(this);
            super.onPause();
        }

        public void onEventMainThread(ThrowableFailureEvent event) {
            // Execute pending commits before finding to avoid multiple error fragments being shown
            android.app.FragmentManager fm = getFragmentManager();
            fm.executePendingTransactions();

            android.app.DialogFragment existingFragment = (android.app.DialogFragment) fm
                    .findFragmentByTag(TAG_ERROR_DIALOG);
            if (existingFragment != null) {
                // Just show the latest error
                existingFragment.dismiss();
            }

            android.app.DialogFragment errorFragment = (android.app.DialogFragment) factory.prepareErrorFragment(event,
                    finishAfterDialog, argumentsForErrorDialog);
            errorFragment.show(fm, TAG_ERROR_DIALOG);
        }

        public static void attachTo(Activity activity, boolean finishAfterDialog, Bundle argumentsForErrorDialog) {
            android.app.FragmentManager fm = activity.getFragmentManager();
            HoneycombManagerFragment fragment = (HoneycombManagerFragment) fm
                    .findFragmentByTag(TAG_ERROR_DIALOG_MANAGER);
            if (fragment == null) {
                fragment = new HoneycombManagerFragment();
                fm.beginTransaction().add(fragment, TAG_ERROR_DIALOG_MANAGER).commit();
            }
            fragment.finishAfterDialog = finishAfterDialog;
            fragment.argumentsForErrorDialog = argumentsForErrorDialog;
        }
    }

    /** Must be set by the application. */
    public static ErrorDialogFragmentFactory<?> factory;

    protected static final String TAG_ERROR_DIALOG = "de.greenrobot.eventbus.error_dialog";
    protected static final String TAG_ERROR_DIALOG_MANAGER = "de.greenrobot.eventbus.error_dialog_manager";

    public static final String KEY_TITLE = "de.greenrobot.eventbus.errordialog.title";
    public static final String KEY_MESSAGE = "de.greenrobot.eventbus.errordialog.message";
    public static final String KEY_FINISH_AFTER_DIALOG = "de.greenrobot.eventbus.errordialog.finish_after_dialog";
    public static final String KEY_ICON_ID = "de.greenrobot.eventbus.errordialog.icon_id";
    public static final String KEY_EVENT_TYPE_ON_CLOSE = "de.greenrobot.eventbus.errordialog.event_type_on_close";

    public static void attachTo(Activity activity) {
        attachTo(activity, false, null);
    }

    public static void attachTo(Activity activity, boolean finishAfterDialog) {
        attachTo(activity, finishAfterDialog, null);
    }

    public static void attachTo(Activity activity, boolean finishAfterDialog, Bundle argumentsForErrorDialog) {
        if (factory == null) {
            throw new RuntimeException("You must set the static factory field to configure error dialogs for your app.");
        }
        if (isSupportActivity(activity)) {
            SupportManagerFragment.attachTo(activity, finishAfterDialog, argumentsForErrorDialog);
        } else {
            HoneycombManagerFragment.attachTo(activity, finishAfterDialog, argumentsForErrorDialog);
        }
    }

    private static boolean isSupportActivity(Activity activity) {
        boolean isSupport = false;
        for (Class<?> c = activity.getClass().getSuperclass();; c = c.getSuperclass()) {
            if (c == null) {
                throw new RuntimeException("Illegal activity type: " + activity.getClass());
            }
            String name = c.getName();
            if (name.equals("android.support.v4.app.FragmentActivity")) {
                isSupport = true;
                break;
            }
            if (name.equals("android.app.Activity")) {
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
                    throw new RuntimeException(
                            "Illegal activity. Either use Android 3.0+ or android.support.v4.app.FragmentActivity");
                }
                break;
            }
        }
        return isSupport;
    }
}

@@ -7667,29 +7667,385 @@
        %7D
-%0D%0A           
+ else if (name.startsWith(%22com.actionbarsherlock.app%22)%0D%0A                    && (name.endsWith(%22.SherlockActivity%22) %7C%7C name.endsWith(%22.SherlockListActivity%22) %7C%7C name%0D%0A                            .endsWith(%22.SherlockPreferenceActivity%22))) %7B%0D%0A                throw new RuntimeException(%22Please use SherlockFragmentActivity. Illegal activity: %22 + name);%0D%0A            %7D else
  if (nam
@@ -8253,16 +8253,41 @@
 activity
+ without fragment support
 . Either
@@ -8346,16 +8346,17 @@
 Activity
+.
 %22);%0D%0A   

Check if SherlockFragmentActivity is used