package com.phl.rxjavademo.activity;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.support.v4.graphics.drawable.RoundedBitmapDrawable;
import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;

import com.phl.rxjavademo.R;

import butterknife.BindView;
import butterknife.ButterKnife;
import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Function;

/**
 * description: do操作符
 * author: phl
 * date: 2017-12-18 上午 11:34
 * update:
 * version: 1.0
 */
public class DoActivity extends AppCompatActivity {

    private static final String TAG = "DoActivity";
    @BindView(R.id.iv_do)
    ImageView ivDo;
    @BindView(R.id.iv_do1)
    ImageView ivDo1;
    @BindView(R.id.tv_d)
    TextView tvD;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_do);
        ButterKnife.bind(this);
//        handDo();
//        processRetry();
//        processRetryWhen();
//        processRepeat();
        processRepeatWhen();

        GradientDrawable drawable = new GradientDrawable();
        drawable.setColor(Color.BLUE);
        drawable.setCornerRadius(5);
        tvD.setText("赢");
        tvD.setBackground(drawable);
        BitmapDrawable drawable1 = new BitmapDrawable(getResources(), BitmapFactory.decodeResource(getResources(), R.drawable.bg1));
        Bitmap bm = drawTBit(drawable1);
        ivDo.setImageBitmap(drawCircle(bm));
        RoundedBitmapDrawable roundedBitmapDrawable = RoundedBitmapDrawableFactory.create(getResources(), BitmapFactory.decodeResource(getResources(), R.drawable.bg1));
        roundedBitmapDrawable.setCornerRadius(20);
        ivDo1.setImageDrawable(roundedBitmapDrawable);
    }

    /**
     * do操作符的使用
     */
    public void handDo() {
        Observable.create((ObservableOnSubscribe<Integer>) e -> {
            e.onNext(1);
            e.onNext(2);
            e.onNext(3);
//            e.onComplete();
            e.onError(new Throwable("发送错误事件"));
        }).doOnEach(integerNotification -> {
            Log.d(TAG, "doOnEach: " + integerNotification.getValue());
        }).doOnNext(integer -> {
            Log.d(TAG, "执行OnNext()之前");
        }).doAfterNext(integer -> {
            Log.d(TAG, "执行OnNext()完毕后");
        }).doOnComplete(() -> {
            Log.d(TAG, "正常发送事件完毕后");
        }).doOnError(throwable -> {
            Log.e(TAG, "doOnError 被观察者发送错误事件时调用");
        }).doOnSubscribe(disposable -> {
            Log.e(TAG, "doOnSubscribe 观察者订阅时调用");
        }).doOnTerminate(() -> {
            Log.e(TAG, "doOnTerminate");
        }).doAfterTerminate(() -> {
            Log.e(TAG, "doAfterTerminate");
        }).doFinally(() -> {
            Log.e(TAG, "doFinally");
        })/*.onErrorReturn(throwable -> {
            Log.e(TAG, "onErrorReturn: 捕获异常 -> 返回一个0"+throwable.getMessage());
            return 0;
        })*/.onErrorResumeNext(throwable -> {
            Log.e(TAG, "onErrorResumeNext : 捕获异常throwable: " + throwable.getMessage());
            return Observable.just(10);
        })
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer integer) {
                        Log.d(TAG, "onNext 接收到 : " + integer);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "onError 对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "onComplete 对Complete事件作出响应");
                    }
                });

    }

    private void processRetry() {
        Observable.create((ObservableOnSubscribe<Integer>) e -> {
            e.onNext(1);
            e.onNext(2);
            e.onError(new Throwable("发送一个错误事件"));
            e.onNext(3);
        })
                .retry((integer, throwable) -> {
                    Log.e(TAG, "test: 重试次数 :" + integer);
                    Log.e(TAG, "test: 捕获异常" + throwable.getMessage());
                    return true;
                })
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer integer) {
                        Log.d(TAG, "onNext: 接收到的事件 = " + integer);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e(TAG, "onError: 对错误事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "onComplete: ");
                    }
                });


    }

    private void processRetryWhen() {
        Observable.create((ObservableOnSubscribe<Integer>) e -> {
            e.onNext(1);
            e.onNext(2);
            e.onError(new Throwable("发送一个错误事件"));
            e.onNext(3);
        })
                .retryWhen(throwableObservable ->
                        throwableObservable.flatMap(throwable -> Observable.just(4))
                )
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer integer) {
                        Log.d(TAG, "onNext: 接收到的事件 = " + integer);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e(TAG, "onError: 对错误事件作出响应" + e.getMessage());
                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "onComplete: ");
                    }
                });
    }

    private void processRepeat() {
        Observable.just(1, 2, 3)
                .repeat(3)
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "开始采用subscribe连接");
                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }

                });
    }

    private void processRepeatWhen() {
        Observable.just(1, 2, 4)
                .repeatWhen(new Function<Observable<Object>, ObservableSource<?>>() {
                    @Override
                    // 在Function函数中,必须对输入的 Observable<Object>进行处理,这里我们使用的是flatMap操作符接收上游的数据
                    public ObservableSource<?> apply(@NonNull Observable<Object> objectObservable) throws Exception {
                        // 将原始 Observable 停止发送事件的标识(Complete() /  Error())转换成1个 Object 类型数据传递给1个新被观察者(Observable)
                        // 以此决定是否重新订阅 & 发送原来的 Observable
                        // 此处有2种情况:
                        // 1. 若新被观察者(Observable)返回1个Complete() /  Error()事件,则不重新订阅 & 发送原来的 Observable
                        // 2. 若新被观察者(Observable)返回其余事件,则重新订阅 & 发送原来的 Observable
                        return objectObservable.flatMap(new Function<Object, ObservableSource<?>>() {
                            @Override
                            public ObservableSource<?> apply(@NonNull Object throwable) throws Exception {

                                // 情况1:若新被观察者(Observable)返回1个Complete() /  Error()事件,则不重新订阅 & 发送原来的 Observable
                                return Observable.empty();
                                // Observable.empty() = 发送Complete事件,但不会回调观察者的onComplete()

//                                 return Observable.error(new Throwable("不再重新订阅事件"));
                                // 返回Error事件 = 回调onError()事件,并接收传过去的错误信息。

                                // 情况2:若新被观察者(Observable)返回其余事件,则重新订阅 & 发送原来的 Observable
//                                 return Observable.just(1);
                                // 仅仅是作为1个触发重新订阅被观察者的通知,发送的是什么数据并不重要,只要不是Complete() /  Error()事件
                            }
                        });

                    }
                })
                .doOnSubscribe(disposable -> {
                    Log.e(TAG, "processRepeatWhen: 订阅之前");
                })
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "开始采用subscribe连接");
                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应:" + e.toString());
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }

                });
    }

    private Bitmap drawTBit(Drawable drawable) {
        Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(),
                drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);

        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
        drawable.draw(canvas);
        return bitmap;
    }

    private Bitmap drawCircle(Bitmap bm) {
        int width = bm.getWidth();
        int height = bm.getHeight();
        int left = 0;
        int top = 0;
        int right = width;
        int bottom = height;
        int roundX = height / 2;
        if (width > height) {
            left = (width - height) / 2;
            top = 0;
            right = left + height;
            bottom = height;
        } else {
            left = 0;
            top = (height - width) / 2;
            right = width;
            bottom = top + width;
            roundX = width / 2;
        }
        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);

        Rect rect = new Rect(left, top, right, bottom);
        RectF rectF = new RectF(rect);

        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setARGB(0, 0, 0, 0);
        paint.setColor(Color.GRAY);
        canvas.drawRoundRect(rectF, roundX, roundX, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bm,rect,rect,paint);
        bm.recycle();
        return bitmap;
    }
}