// Path: kraken_lib/src/main/java/com/github/marcosalis/kraken/utils/android/LogUtils.java
// @Beta
// public class LogUtils {
// 
//     @SuppressWarnings("unused")
//     private static final String TAG = LogUtils.class.getSimpleName();
// 
//     private LogUtils() {
//         // hidden constructor, no instantiation needed
//     }
// 
//     /**
//      * Logs a message in LogCat, only if library debugging is active.
//      *
//      * @param logLevel   The log level to use: must be one of the level constants provided by the
//      *                   {@link Log} class.
//      * @param logTag
//      * @param logMessage
//      */
//     public static void log(int logLevel, String logTag, String logMessage) {
//         if (DroidConfig.DEBUG) {
//             switch (logLevel) {
//                 case Log.ASSERT:
//                 case Log.VERBOSE:
//                     Log.v(logTag, logMessage);
//                     break;
//                 case Log.DEBUG:
//                     Log.d(logTag, logMessage);
//                     break;
//                 case Log.INFO:
//                     Log.i(logTag, logMessage);
//                     break;
//                 case Log.WARN:
//                     Log.w(logTag, logMessage);
//                     break;
//                 case Log.ERROR:
//                     Log.e(logTag, logMessage);
//                     break;
//             }
//         }
//     }
// 
//     /**
//      * Prints on LogCat a stack track of an exception, only if library debugging is active.
//      *
//      * @param t The {@link Throwable} to get the stack trace from
//      */
//     public static void logException(Throwable t) {
//         if (DroidConfig.DEBUG) {
//             if (t != null) {
//                 t.printStackTrace();
//             }
//         }
//     }
// 
//     /**
//      * Prints on LogCat a log warning message with the exception stack, only if library debugging is
//      * active.
//      *
//      * @param logTag
//      * @param logMessage
//      * @param t          The {@link Throwable} to get the stack trace from
//      */
//     public static void logException(String logTag, String logMessage, Throwable t) {
//         if (DroidConfig.DEBUG) {
//             if (t != null) {
//                 Log.w(logTag, logMessage, t);
//             }
//         }
//     }
// 
//     /**
//      * Prints on LogCat a log warning message with the exception's message string, only if library
//      * debugging is active.
//      *
//      * @param t The {@link Throwable} to get the message from
//      */
//     public static void logExceptionMessage(String logTag, String logMessage, Throwable t) {
//         if (DroidConfig.DEBUG) {
//             if (t != null) {
//                 Log.w(logTag,
//                         logMessage + "\n" + t.getClass().getSimpleName() + " message: "
//                                 + t.getMessage());
//             }
//         }
//     }
// 
// }


import android.app.Application;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.support.annotation.NonNull;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import com.github.marcosalis.kraken.utils.android.LogUtils;
import com.google.common.annotations.Beta;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.concurrent.ThreadSafe;
/*
 * Copyright 2013 Luluvise Ltd
 * Copyright 2013 Marco Salis - fast3r(at)gmail.com
 *
 * 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.github.marcosalis.kraken.utils.network;





/**
 * Application global network connection monitor.<br> Useful to easily retrieve the device's current
 * connection status without querying the {@link ConnectivityManager}.
 *
 * Must be initialized by calling {@link #register(Application)} within the {@link
 * Application#onCreate()} method.
 *
 * @author Marco Salis
 * @since 1.0
 */
@Beta
@ThreadSafe
public enum ConnectionDefaultMonitor implements ConnectionMonitor {
    INSTANCE;

    /**
     * Shortcut method to return the {@link ConnectionDefaultMonitor} singleton instance.
     */
    public static ConnectionDefaultMonitor get() {
        return INSTANCE;
    }

    private final static String TAG = ConnectionDefaultMonitor.class.getSimpleName();

    private final AtomicBoolean mConnectionActive;
    private final AtomicBoolean mIsRegistered;
    private final NetworkReceiver mNetReceiver = new NetworkReceiver() {
        @Override
        public void onConnectionActive(int type) {
            mConnectionActive.compareAndSet(false, true);
        }

        @Override
        public void onConnectionGone() {
            mConnectionActive.compareAndSet(true, false);
        }
    };

    private ConnectionDefaultMonitor() {
        // defaults to true to avoid issue at initialization
        mConnectionActive = new AtomicBoolean(true);
        mIsRegistered = new AtomicBoolean(false);
    }

    /**
     * Initializes the {@link ConnectionDefaultMonitor}. It registers a {@link NetworkReceiver} in
     * order to be notified about network state changes.
     *
     * @param application The {@link Application} object
     */
    public void register(@NonNull Application application) {
        if (mIsRegistered.compareAndSet(false, true)) {
            // permanently register the listener using the application context
            final IntentFilter filter = NetworkReceiver.getFilter();
            LocalBroadcastManager.getInstance(application).registerReceiver(mNetReceiver, filter);
        } else {
// Path: kraken_lib/src/main/java/com/github/marcosalis/kraken/utils/android/LogUtils.java
// @Beta
// public class LogUtils {
// 
//     @SuppressWarnings("unused")
//     private static final String TAG = LogUtils.class.getSimpleName();
// 
//     private LogUtils() {
//         // hidden constructor, no instantiation needed
//     }
// 
//     /**
//      * Logs a message in LogCat, only if library debugging is active.
//      *
//      * @param logLevel   The log level to use: must be one of the level constants provided by the
//      *                   {@link Log} class.
//      * @param logTag
//      * @param logMessage
//      */
//     public static void log(int logLevel, String logTag, String logMessage) {
//         if (DroidConfig.DEBUG) {
//             switch (logLevel) {
//                 case Log.ASSERT:
//                 case Log.VERBOSE:
//                     Log.v(logTag, logMessage);
//                     break;
//                 case Log.DEBUG:
//                     Log.d(logTag, logMessage);
//                     break;
//                 case Log.INFO:
//                     Log.i(logTag, logMessage);
//                     break;
//                 case Log.WARN:
//                     Log.w(logTag, logMessage);
//                     break;
//                 case Log.ERROR:
//                     Log.e(logTag, logMessage);
//                     break;
//             }
//         }
//     }
// 
//     /**
//      * Prints on LogCat a stack track of an exception, only if library debugging is active.
//      *
//      * @param t The {@link Throwable} to get the stack trace from
//      */
//     public static void logException(Throwable t) {
//         if (DroidConfig.DEBUG) {
//             if (t != null) {
//                 t.printStackTrace();
//             }
//         }
//     }
// 
//     /**
//      * Prints on LogCat a log warning message with the exception stack, only if library debugging is
//      * active.
//      *
//      * @param logTag
//      * @param logMessage
//      * @param t          The {@link Throwable} to get the stack trace from
//      */
//     public static void logException(String logTag, String logMessage, Throwable t) {
//         if (DroidConfig.DEBUG) {
//             if (t != null) {
//                 Log.w(logTag, logMessage, t);
//             }
//         }
//     }
// 
//     /**
//      * Prints on LogCat a log warning message with the exception's message string, only if library
//      * debugging is active.
//      *
//      * @param t The {@link Throwable} to get the message from
//      */
//     public static void logExceptionMessage(String logTag, String logMessage, Throwable t) {
//         if (DroidConfig.DEBUG) {
//             if (t != null) {
//                 Log.w(logTag,
//                         logMessage + "\n" + t.getClass().getSimpleName() + " message: "
//                                 + t.getMessage());
//             }
//         }
//     }
// 
// }


// Path: kraken_lib/src/main/java/com/github/marcosalis/kraken/utils/network/ConnectionDefaultMonitor.java
import android.app.Application;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.support.annotation.NonNull;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import com.github.marcosalis.kraken.utils.android.LogUtils;
import com.google.common.annotations.Beta;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.concurrent.ThreadSafe;

/*
 * Copyright 2013 Luluvise Ltd
 * Copyright 2013 Marco Salis - fast3r(at)gmail.com
 *
 * 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.github.marcosalis.kraken.utils.network;





/**
 * Application global network connection monitor.<br> Useful to easily retrieve the device's current
 * connection status without querying the {@link ConnectivityManager}.
 *
 * Must be initialized by calling {@link #register(Application)} within the {@link
 * Application#onCreate()} method.
 *
 * @author Marco Salis
 * @since 1.0
 */
@Beta
@ThreadSafe
public enum ConnectionDefaultMonitor implements ConnectionMonitor {
    INSTANCE;

    /**
     * Shortcut method to return the {@link ConnectionDefaultMonitor} singleton instance.
     */
    public static ConnectionDefaultMonitor get() {
        return INSTANCE;
    }

    private final static String TAG = ConnectionDefaultMonitor.class.getSimpleName();

    private final AtomicBoolean mConnectionActive;
    private final AtomicBoolean mIsRegistered;
    private final NetworkReceiver mNetReceiver = new NetworkReceiver() {
        @Override
        public void onConnectionActive(int type) {
            mConnectionActive.compareAndSet(false, true);
        }

        @Override
        public void onConnectionGone() {
            mConnectionActive.compareAndSet(true, false);
        }
    };

    private ConnectionDefaultMonitor() {
        // defaults to true to avoid issue at initialization
        mConnectionActive = new AtomicBoolean(true);
        mIsRegistered = new AtomicBoolean(false);
    }

    /**
     * Initializes the {@link ConnectionDefaultMonitor}. It registers a {@link NetworkReceiver} in
     * order to be notified about network state changes.
     *
     * @param application The {@link Application} object
     */
    public void register(@NonNull Application application) {
        if (mIsRegistered.compareAndSet(false, true)) {
            // permanently register the listener using the application context
            final IntentFilter filter = NetworkReceiver.getFilter();
            LocalBroadcastManager.getInstance(application).registerReceiver(mNetReceiver, filter);
        } else {
            LogUtils.log(Log.WARN, TAG, "ConnectionMonitor multiple initialization attempt");