<commit_before>package com.samourai.wallet.whirlpool.newPool.fragments;

import android.content.res.ColorStateList;
import android.graphics.PorterDuff;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.util.DiffUtil;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.samourai.wallet.R;
import com.samourai.wallet.api.APIFactory;
import com.samourai.wallet.send.MyTransactionOutPoint;
import com.samourai.wallet.send.UTXO;
import com.samourai.wallet.utxos.models.UTXOCoin;
import com.samourai.wallet.utxos.models.UTXOCoinSegment;
import com.samourai.wallet.whirlpool.WhirlpoolMeta;
import com.samourai.wallet.widgets.ItemDividerDecorator;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

import static com.samourai.wallet.util.LogUtil.debug;


public class ChooseUTXOsFragment extends Fragment {

    private static final String TAG = "ChooseUTXOsFragment";

    private OnUTXOSelectionListener onUTXOSelectionListener;
    private ArrayList<UTXOCoin> utxos = new ArrayList<UTXOCoin>();
    private WhirlpoolUTXOAdapter utxoAdapter;
    final DecimalFormat df = new DecimalFormat("#");
    private CompositeDisposable compositeDisposable = new CompositeDisposable();

    private RecyclerView utxoRecyclerView;

    public ChooseUTXOsFragment() {
        df.setMinimumIntegerDigits(1);
        df.setMinimumFractionDigits(8);
    }


    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        utxoRecyclerView = view.findViewById(R.id.whirlpool_utxo_recyclerview);
        utxoRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        utxoAdapter = new WhirlpoolUTXOAdapter();
        loadCoins();
        utxoRecyclerView.setAdapter(utxoAdapter);
        utxoRecyclerView.addItemDecoration(new ItemDividerDecorator(getActivity().getDrawable(R.color.disabled_white)));
        utxoRecyclerView.setItemAnimator(new DefaultItemAnimator());
    }

    private void loadCoins() {
        Disposable disposable = getUTXOs()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(this::applyFilters, err -> {
                    Toast.makeText(getContext(), "Error Loading UTXO: ".concat(err.getMessage()), Toast.LENGTH_SHORT).show();
                    err.printStackTrace();
                });
        compositeDisposable.add(disposable);

    }

    private void applyFilters(List<UTXOCoin> utxoCoins) {
        ArrayList<UTXOCoin> unCycled = new ArrayList<>();


        for (UTXOCoin model : utxoCoins) {
            if (model.account == 0 && model.path.startsWith("M/0/")) {
                if (!unCycled.contains(model)) {
                    unCycled.add(model);
                }
            } else if (model.account == 0 && model.path.equals("")) {
                if (!unCycled.contains(model)) {
                    unCycled.add(model);
                }
            }
        }
        Collections.sort(unCycled, (model, t1) -> Long.compare(t1.amount, model.amount));

        UTXOCoinSegment section = new UTXOCoinSegment(null, null);
        section.unCycled = true;
        unCycled.add(0, section);

        UTXOCoinSegment cycled = new UTXOCoinSegment(null, null);
        cycled.unCycled = false;
        ArrayList<UTXOCoin> changes = new ArrayList<>();

        for (UTXOCoin model : utxoCoins) {
            if (model.account == WhirlpoolMeta.getInstance(getActivity()).getWhirlpoolPostmix()
                    && model.path.startsWith("M/1/")) {
                if (!changes.contains(model)) {
                    changes.add(model);
                }
            }
            if (model.account == 0
                    && model.path.startsWith("M/1/")) {
                if (!changes.contains(model)) {
                    changes.add(model);
                }
            }
        }

        Collections.sort(changes, (model, t1) -> Long.compare(t1.amount, model.amount));
        changes.add(0, cycled);

        unCycled.addAll(changes);

        utxoAdapter.updateList(unCycled);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_choose_utxos, container, false);
    }


    public void setOnUTXOSelectionListener(OnUTXOSelectionListener onUTXOSelectionListener) {
        this.onUTXOSelectionListener = onUTXOSelectionListener;
    }

    @Override
    public void onDetach() {
        super.onDetach();
        this.onUTXOSelectionListener = null;
        compositeDisposable.dispose();
    }

    public interface OnUTXOSelectionListener {
        void onSelect(List<UTXOCoin> coins);
    }


    private void selectOrDeselect(int position) {
        utxos.get(position).isSelected = !utxos.get(position).isSelected;
        utxoRecyclerView.post(() -> utxoAdapter.notifyItemChanged(position));

        List<UTXOCoin> selectedList = new ArrayList<>();

        for (UTXOCoin model : utxos) {
            if (model.isSelected) {
                selectedList.add(model);
            }
        }

        if (onUTXOSelectionListener != null)
            onUTXOSelectionListener.onSelect(selectedList);
    }

    private Observable<List<UTXOCoin>> getUTXOs() {
        return Observable.fromCallable(() -> {
            Map<String, Object> dataSet = new HashMap<>();
            List<UTXO> utxos = new ArrayList<>();
            List<UTXO> account0 = APIFactory.getInstance(getActivity()).getUtxos(false);
//            List<UTXO> accountWhirlpool = APIFactory.getInstance(getActivity()).getUtxosPostMix(false);

            utxos.addAll(account0);
//            utxos.addAll(accountWhirlpool);


            long amount = 0L;
            for (UTXO utxo : utxos) {
                for (MyTransactionOutPoint out : utxo.getOutpoints()) {<commit_msg>ChooseUTXOsFragment: do not select blocked utxos for tx0 composition<commit_after>package com.samourai.wallet.whirlpool.newPool.fragments;

import android.content.res.ColorStateList;
import android.graphics.PorterDuff;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.util.DiffUtil;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.samourai.wallet.R;
import com.samourai.wallet.api.APIFactory;
import com.samourai.wallet.send.MyTransactionOutPoint;
import com.samourai.wallet.send.UTXO;
import com.samourai.wallet.utxos.models.UTXOCoin;
import com.samourai.wallet.utxos.models.UTXOCoinSegment;
import com.samourai.wallet.whirlpool.WhirlpoolMeta;
import com.samourai.wallet.widgets.ItemDividerDecorator;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

import static com.samourai.wallet.util.LogUtil.debug;


public class ChooseUTXOsFragment extends Fragment {

    private static final String TAG = "ChooseUTXOsFragment";

    private OnUTXOSelectionListener onUTXOSelectionListener;
    private ArrayList<UTXOCoin> utxos = new ArrayList<UTXOCoin>();
    private WhirlpoolUTXOAdapter utxoAdapter;
    final DecimalFormat df = new DecimalFormat("#");
    private CompositeDisposable compositeDisposable = new CompositeDisposable();

    private RecyclerView utxoRecyclerView;

    public ChooseUTXOsFragment() {
        df.setMinimumIntegerDigits(1);
        df.setMinimumFractionDigits(8);
    }


    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        utxoRecyclerView = view.findViewById(R.id.whirlpool_utxo_recyclerview);
        utxoRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        utxoAdapter = new WhirlpoolUTXOAdapter();
        loadCoins();
        utxoRecyclerView.setAdapter(utxoAdapter);
        utxoRecyclerView.addItemDecoration(new ItemDividerDecorator(getActivity().getDrawable(R.color.disabled_white)));
        utxoRecyclerView.setItemAnimator(new DefaultItemAnimator());
    }

    private void loadCoins() {
        Disposable disposable = getUTXOs()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(this::applyFilters, err -> {
                    Toast.makeText(getContext(), "Error Loading UTXO: ".concat(err.getMessage()), Toast.LENGTH_SHORT).show();
                    err.printStackTrace();
                });
        compositeDisposable.add(disposable);

    }

    private void applyFilters(List<UTXOCoin> utxoCoins) {
        ArrayList<UTXOCoin> unCycled = new ArrayList<>();


        for (UTXOCoin model : utxoCoins) {
            if (model.account == 0 && model.path.startsWith("M/0/")) {
                if (!unCycled.contains(model)) {
                    unCycled.add(model);
                }
            } else if (model.account == 0 && model.path.equals("")) {
                if (!unCycled.contains(model)) {
                    unCycled.add(model);
                }
            }
        }
        Collections.sort(unCycled, (model, t1) -> Long.compare(t1.amount, model.amount));

        UTXOCoinSegment section = new UTXOCoinSegment(null, null);
        section.unCycled = true;
        unCycled.add(0, section);

        UTXOCoinSegment cycled = new UTXOCoinSegment(null, null);
        cycled.unCycled = false;
        ArrayList<UTXOCoin> changes = new ArrayList<>();

        for (UTXOCoin model : utxoCoins) {
            if (model.account == WhirlpoolMeta.getInstance(getActivity()).getWhirlpoolPostmix()
                    && model.path.startsWith("M/1/")) {
                if (!changes.contains(model)) {
                    changes.add(model);
                }
            }
            if (model.account == 0
                    && model.path.startsWith("M/1/")) {
                if (!changes.contains(model)) {
                    changes.add(model);
                }
            }
        }

        Collections.sort(changes, (model, t1) -> Long.compare(t1.amount, model.amount));
        changes.add(0, cycled);

        unCycled.addAll(changes);

        utxoAdapter.updateList(unCycled);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_choose_utxos, container, false);
    }


    public void setOnUTXOSelectionListener(OnUTXOSelectionListener onUTXOSelectionListener) {
        this.onUTXOSelectionListener = onUTXOSelectionListener;
    }

    @Override
    public void onDetach() {
        super.onDetach();
        this.onUTXOSelectionListener = null;
        compositeDisposable.dispose();
    }

    public interface OnUTXOSelectionListener {
        void onSelect(List<UTXOCoin> coins);
    }


    private void selectOrDeselect(int position) {
        utxos.get(position).isSelected = !utxos.get(position).isSelected;
        utxoRecyclerView.post(() -> utxoAdapter.notifyItemChanged(position));

        List<UTXOCoin> selectedList = new ArrayList<>();

        for (UTXOCoin model : utxos) {
            if (model.isSelected) {
                selectedList.add(model);
            }
        }

        if (onUTXOSelectionListener != null)
            onUTXOSelectionListener.onSelect(selectedList);
    }

    private Observable<List<UTXOCoin>> getUTXOs() {
        return Observable.fromCallable(() -> {
            Map<String, Object> dataSet = new HashMap<>();
            List<UTXO> utxos = new ArrayList<>();
            List<UTXO> account0 = APIFactory.getInstance(getActivity()).getUtxos(true);
//            List<UTXO> accountWhirlpool = APIFactory.getInstance(getActivity()).getUtxosPostMix(false);

            utxos.addAll(account0);
//            utxos.addAll(accountWhirlpool);


            long amount = 0L;
            for (UTXO utxo : utxos) {
                for (MyTransactionOutPoint out : utxo.getOutpoints()) {
{'fraction_non_alphanumeric': 0.10548922539312755, 'fraction_numerical': 0.0034216656959813628, 'mean_word_length': 2.9036658141517475, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5632973', 'n_tokens_mistral': 4200, 'n_tokens_neox': 4034, 'n_words': 670}