package com.morihacky.android.rxjava.fragments;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import butterknife.Bind;
import butterknife.ButterKnife;
import com.morihacky.android.rxjava.R;
import java.util.ArrayList;
import java.util.List;
import rx.android.schedulers.AndroidSchedulers;
import rx.subjects.PublishSubject;

public class NetworkDetectorFragment
      extends BaseFragment {

    @Bind(R.id.list_threading_log) ListView logsList;

    private LogAdapter adapter;
    private BroadcastReceiver broadcastReceiver;
    private List<String> logs;
    private PublishSubject<Boolean> publishSubject;

    @Override
    public void onDestroy() {
        super.onDestroy();
        ButterKnife.unbind(this);
    }

    @Override
    public View onCreateView(LayoutInflater inflater,
                             @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        View layout = inflater.inflate(R.layout.fragment_network_detector, container, false);
        ButterKnife.bind(this, layout);
        return layout;
    }

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

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

        publishSubject = PublishSubject.create();

        publishSubject
              .startWith(getConnectivityStatus(getActivity()))
              .distinctUntilChanged()
              .observeOn(AndroidSchedulers.mainThread())
              .subscribe(online -> {
                  if (online) {
                      log("You are online");
                  }
                  else {
                      log("You are offline");
                  }
              });

        listenToNetworkConnectivity();
    }

    @Override
    public void onStop() {
        super.onStop();
        getActivity().unregisterReceiver(broadcastReceiver);
    }

    private void listenToNetworkConnectivity() {

        broadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                publishSubject.onNext(getConnectivityStatus(context));
            }
        };

        final IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
        getActivity().registerReceiver(broadcastReceiver, intentFilter);
    }

    private boolean getConnectivityStatus(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = cm.getActiveNetworkInfo();
        return networkInfo != null && networkInfo.isConnected();
    }

    // -----------------------------------------------------------------------------------
    // Method that help wiring up the example (irrelevant to RxJava)

    private void log(String logMsg) {

        if (isCurrentlyOnMainThread()) {
            logs.add(0, logMsg + " (main thread) ");
            adapter.clear();
            adapter.addAll(logs);
        }
        else {
            logs.add(0, logMsg + " (NOT main thread) ");

            // You can only do below stuff on main thread.
            new Handler(Looper.getMainLooper()).post(() -> {
                adapter.clear();
                adapter.addAll(logs);
            });
        }
    }

    private void setupLogger() {
        logs = new ArrayList<>();
        adapter = new LogAdapter(getActivity(), new ArrayList<>());
        logsList.setAdapter(adapter);
    }

    private boolean isCurrentlyOnMainThread() {
        return Looper.myLooper() == Looper.getMainLooper();
    }

    private class LogAdapter
          extends ArrayAdapter<String> {

        public LogAdapter(Context context, List<String> logs) {
            super(context, R.layout.item_log, R.id.item_log, logs);
        }
    }
}
@@ -647,132 +647,200 @@
 ort 
-java.util.ArrayList;%0Aimport java.util.List;%0Aimport rx.android.schedulers.AndroidSchedulers;%0Aimport rx.subjects.PublishSubjec
+io.reactivex.android.schedulers.AndroidSchedulers;%0Aimport io.reactivex.disposables.Disposable;%0Aimport io.reactivex.processors.PublishProcessor;%0Aimport java.util.ArrayList;%0Aimport java.util.Lis
 t;%0A%0A
@@ -1085,30 +1085,67 @@
 private 
-PublishSubject
+Disposable disposable;%0A    private PublishProcessor
 %3CBoolean
@@ -1153,23 +1153,25 @@
  publish
-Subject
+Processor
 ;%0A%0A    @
@@ -1890,23 +1890,25 @@
  publish
-Subject
+Processor
  = Publi
@@ -1909,23 +1909,25 @@
  Publish
-Subject
+Processor
 .create(
@@ -1938,30 +1938,45 @@
         
-publishSubject
+disposable = publishProcessor
 %0A       
@@ -2480,16 +2480,47 @@
 nStop();
+%0A%0A        disposable.dispose();
 %0A       
@@ -2801,15 +2801,17 @@
 lish
-Subject
+Processor
 .onN

change network detector to Rx 2