public class PolaApplication extends Application {

    private PolaComponent component;
    public static Retrofit retrofit;

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

        component = PolaComponent.Initializer.init(this);
        if(BuildConfig.USE_FIREBASE) {
            FirebaseAnalytics.getInstance(this);
        }

        if (BuildConfig.DEBUG) {
            Timber.plant(new Timber.DebugTree());
        } else {
            Timber.plant(new CrashReportingTree());
        }

        final HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(Utils.TIMEOUT_SECONDS, TimeUnit.SECONDS)
                .readTimeout(Utils.TIMEOUT_SECONDS, TimeUnit.SECONDS)
                .addInterceptor(interceptor)
                .build();

        retrofit = new Retrofit.Builder()
                .baseUrl(this.getResources().getString(R.string.pola_api_url))
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .client(client)
                .build();
    }

    public static PolaComponent component(Context context) {
        return ((PolaApplication) context.getApplicationContext()).component;
    }

    private static class CrashReportingTree extends Timber.Tree {
        @Override protected void log(int priority, String tag, @NotNull String message, Throwable t) {
            if (priority == Log.VERBOSE || priority == Log.DEBUG) {
                return;
            }
            if(BuildConfig.USE_FIREBASE) {
                FirebaseCrashlytics.getInstance().log("E/" + tag + ":" + message);
                if(t != null) {
                    FirebaseCrashlytics.getInstance().recordException(t);
                }
            }

            if (t != null) {
                if (priority == Log.ERROR) {
                    Log.e(tag, t.getMessage());
                } else if (priority == Log.WARN) {
                    Log.w(tag, t.getMessage());
                }
            }
        }
    }
} public class EventLogger {

    private Context c;

    public EventLogger(Context context) {
        c = context;
    }

    public void logSearch(String result, String deviceId, String source) {
        if (!BuildConfig.USE_FIREBASE) {
            return;
        }

        Bundle bundle = new Bundle();
        bundle.putString("code", result);
        bundle.putString("device_id", deviceId);
        bundle.putString("source", source);
        FirebaseAnalytics.getInstance(c).logEvent("scan_code", bundle);
    }

    public void logCustom(String eventName, Bundle bundle) {
        if (!BuildConfig.USE_FIREBASE) {
            return;
        }

        FirebaseAnalytics.getInstance(c).logEvent(eventName, bundle);
    }

    public void logContentView(String contentName, String contentType, String contentId, String code, String deviceId) {
        if (!BuildConfig.USE_FIREBASE) {
            return;
        }

        Bundle bundle = new Bundle();
        bundle.putString("company", contentName);
        bundle.putString("device_id", deviceId);
        bundle.putString("product_id", contentId);
        bundle.putString("code", code);
        FirebaseAnalytics.getInstance(c).logEvent(contentType, bundle);
    }

    public void logException(Throwable throwable) {
        if (!BuildConfig.USE_FIREBASE) {
            return;
        }

        try {
            FirebaseCrashlytics.getInstance().recordException(throwable);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void logLevelStart(String levelName, String productId, String deviceId) {
        if(!BuildConfig.USE_FIREBASE) {
            return;
        }

        Bundle bundle = new Bundle();
        bundle.putString("device_id", deviceId);
        bundle.putString("code", productId);
        FirebaseAnalytics.getInstance(c).logEvent(levelName+"_started", bundle);
    }

    public void logLevelEnd(String levelName, String productId, String deviceId) {
        if(!BuildConfig.USE_FIREBASE) {
            return;
        }

        Bundle bundle = new Bundle();
        bundle.putString("device_id", deviceId);
        bundle.putString("code", productId);
        FirebaseAnalytics.getInstance(c).logEvent(levelName+"_finished", bundle);
    }

    public void logMenuItemOpened(String itemName, String deviceId) {
        if(!BuildConfig.USE_FIREBASE) {
            return;
        }

        Bundle bundle = new Bundle();
        bundle.putString("item", itemName);
        bundle.putString("device_id", deviceId);
        FirebaseAnalytics.getInstance(c).logEvent("menu_item_opened", bundle);
    }

    public void logSupportPolaButtonClick(String deviceId) {
        if(!BuildConfig.USE_FIREBASE) {
            return;
        }

        Bundle bundle = new Bundle();
        bundle.putString("device_id", deviceId);
        FirebaseAnalytics.getInstance(c).logEvent("donate_opened", bundle);
    }
} public class ProductsListLinearLayoutManager extends LinearLayoutManager {

    private static final double HEIGHT_LIMIT = 0.45; //45% of the screen

    public ProductsListLinearLayoutManager(Context context) {
        super(context);
        setAutoMeasureEnabled(true);
    }

    @Override
    public void setMeasuredDimension(Rect childrenBounds, int wSpec, int hSpec) {
        int heightSize = View.MeasureSpec.getSize(hSpec);
        heightSize = Math.min(heightSize, (int) (heightSize * HEIGHT_LIMIT));
        hSpec = View.MeasureSpec.makeMeasureSpec(heightSize, View.MeasureSpec.AT_MOST);
        super.setMeasuredDimension(childrenBounds, wSpec, hSpec);
    }
} public class SessionId {
    private static final String PREF_SESSION_GUID = "session_guid";
    private static final Object lock = new Object();
    private final String sessionId;

    public static SessionId create(Context context) {
        return new SessionId(context);
    }

    private SessionId(Context context) {
        sessionId = init(context);
    }

    public String get() {
        return sessionId;
    }

    private static SharedPreferences getDefaultSharedPreferences(Context context) {
        return PreferenceManager.getDefaultSharedPreferences(context);
    }

    private static String init(Context context) {
        synchronized (lock) {
            SharedPreferences pref = getDefaultSharedPreferences(context);
            String sessionGuid = pref.getString(PREF_SESSION_GUID, null);

            if (sessionGuid == null) {
                sessionGuid = UUID.randomUUID().toString();
                final SharedPreferences.Editor editor = pref.edit();
                editor.putString(PREF_SESSION_GUID, sessionGuid);
                editor.apply();
            }
            return sessionGuid;
        }
    }
} @Parcel
public class SearchResult {
    public Integer product_id;
    public String code;
    public String name;
    public String card_type;
    public String altText;
    public ArrayList<Company> companies;

    public ReportV4 report; 

    public String friend_text;

    public Donate donate;

    public boolean askForSupport() {
        return donate != null;
    }


} public class ProductList {
    @NonNull private final List<SearchResult> searchResults;
    @Nullable private OnProductListChanged onProductListChanged;

    public static ProductList create(@Nullable Bundle bundle) {
        final List<SearchResult> searchResults;
        if (bundle != null) {
            searchResults = Parcels.unwrap(bundle.getParcelable(SearchResult.class.getName()));
        } else {
            searchResults = new ArrayList<>();
        }

        return new ProductList(searchResults);
    }

    private ProductList(@NonNull final List<SearchResult> searchResults) {
        this.searchResults = searchResults;
    }

    public void setOnProductListChanged(@Nullable OnProductListChanged onProductListChanged) {
        this.onProductListChanged = onProductListChanged;
    }


    public void writeToBundle(@NonNull final Bundle bundle) {
        bundle.putParcelable(SearchResult.class.getName(), Parcels.wrap(searchResults));
    }

    public void addProduct(SearchResult searchResult) {
        if (searchResults.size() > 0 && searchResults.get(0) == null) {
            searchResults.set(0, searchResult);
        } else {
            searchResults.add(0, searchResult);
        }
        notifyOnChanged();
    }

    public void createProductPlaceholder() {
        searchResults.add(0, null);
        notifyOnChanged();
    }

    public void removeProductPlaceholder() {
        if (searchResults.size() > 0 && searchResults.get(0) == null) {
            searchResults.remove(0);
            notifyOnChanged();
        }
    }

    public boolean itemExists(String code) {
        for (SearchResult p : searchResults) {
            if (p != null) {
                if (p.code.equals(code)) {
                    searchResults.remove(p);
                    searchResults.add(0, p);
                    notifyOnChanged();
                    return true;
                }
            }
        }

        return false;
    }

    public int size() {
        return searchResults.size();
    }

    public SearchResult get(int position) {
        return searchResults.get(position);
    }

    private void notifyOnChanged() {
        if (onProductListChanged != null) {
            onProductListChanged.onChanged();
        }
    }

} public class ProductsAdapter extends RecyclerView.Adapter<ProductsAdapter.ViewHolder> {

    public interface ProductClickListener {
        void itemClicked(SearchResult searchResult);
    }

    @NonNull
    private final Context context;
    @NonNull
    private final ProductList searchResults;
    @Nullable
    private ProductClickListener productClickListener;

    public ProductsAdapter(@NonNull final Context context,
            @NonNull final ProductList searchResults) {
        this.searchResults = searchResults;
        this.context = context;
    }

    public void setOnProductClickListener(ProductClickListener productClickListener) {
        this.productClickListener = productClickListener;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
        ViewProductItemBinding binding = ViewProductItemBinding.inflate(inflater, viewGroup, false);
        return new ViewHolder(binding);
    }

    @Override
    public void onBindViewHolder(final ViewHolder viewHolder, final int i) {
        final SearchResult p = searchResults.get(i);
        viewHolder.bind(p);
    }

    @Override
    public int getItemCount() {
        return searchResults.size();
    }

    private void onItemClicked(int position) {
        if (productClickListener == null) {
            return;
        }

        if (position > searchResults.size()) { //TODO: is it even possible to reach this state?
            Timber.w(new IndexOutOfBoundsException(), "Position: %d, list size: %d", position, searchResults.size());
            return;
        }

        SearchResult searchResult = searchResults.get(position);
        if (searchResult != null) {
            productClickListener.itemClicked(searchResult);
        }
    }

    class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        ViewProductItemBinding binding;

        ViewHolder(ViewProductItemBinding binding) {
            super(binding.getRoot());
            this.binding = binding;
        }

        void bind(SearchResult searchResult) {
            itemView.setOnClickListener(this);
            if (searchResult == null) {
                binding.progressBar.setVisibility(View.VISIBLE);
                binding.companyName.setText("");
                binding.scoreBar.setProgress(0);
                binding.progressBar.setVisibility(View.VISIBLE);
                binding.companyName.setText("");
                binding.scoreBar.setProgress(0);
                return;
            }

            binding.progressBar.setVisibility(View.GONE);

            binding.companyName.setText(searchResult.name != null ? searchResult.name : searchResult.companies.get(0).name);
            binding.companyName.setText(searchResult.name != null ? searchResult.name : searchResult.companies.get(0).name);

            if (searchResult.companies != null && searchResult.companies.get(0).plScore != null) {
                binding.scoreBar.setProgress(searchResult.companies.get(0).plScore);
            } else {
                binding.scoreBar.setProgress(0);
            }

            if (searchResult.companies != null && searchResult.companies.get(0).is_friend != null && searchResult.companies.get(
                    0).is_friend) {
                binding.heartImage.setVisibility(View.VISIBLE);
            } else {
                binding.heartImage.setVisibility(View.GONE);
            }
        }


        @Override
        public void onClick(View view) {
            int position = getAdapterPosition();
            if (position != RecyclerView.NO_POSITION) {
                onItemClicked(position);
            }
        }
    }
} public interface DetailsFragmentDelegate {

    void onsSeePolaFriendsAction();
} public interface FlashActionListener {
    void onFlashAction();

    boolean isTorchOn();
} public interface BarcodeListener {
    void onBarcode(String barcode, boolean fromCamera);
} public class KeyboardFragment extends Fragment implements KeyboardListener {

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        final NumericKeyboard numericKeyboard = new NumericKeyboard(inflater.getContext());
        final ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        numericKeyboard.setLayoutParams(layoutParams);
        numericKeyboard.setKeyboardListener(this);

        return numericKeyboard;
    }

    @Override
    public void onInputConfirmed(@NonNull String text) {
        final Activity activity = getActivity();
        ((MainActivity) activity).onBarcode(text, false);
        activity.getFragmentManager().popBackStack();
    }
} public class LidlDetailsFragment extends DetailsFragment {

    FragmentProductDetailsLidlBinding binding;

    public static LidlDetailsFragment newInstance(SearchResult searchResult) {
        LidlDetailsFragment fragment = new LidlDetailsFragment();
        Bundle args = new Bundle();
        args.putParcelable(SearchResult.class.getName(), Parcels.wrap(searchResult));
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        binding = FragmentProductDetailsLidlBinding.inflate(inflater, container, false);
        PolaApplication.component(getActivity()).inject(this);
        return binding.getRoot();
    }

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

        binding.companyName.setText(searchResult.companies.get(1).name + " / " + searchResult.companies.get(0).name);
        binding.firstCompanyName.setText(searchResult.companies.get(1).name);
        binding.secondCompanyName.setText(searchResult.companies.get(0).name);

        binding.plScoreBar.setProgress(0);
        binding.plScoreText.setText("?");

        if (searchResult.companies.get(1).plScore != null) {
            binding.firstCompanyProgressbar.setProgress(searchResult.companies.get(1).plScore);
            binding.firstCompanyScoreText.setText(searchResult.companies.get(1).plScore + getString(R.string.pt));
        } else {
            binding.firstCompanyProgressbar.setProgress(0);
            binding.firstCompanyScoreText.setText("?");
        }

        if (searchResult.companies.get(0).plScore != null) {
            binding.secondCompanyProgressbar.setProgress(searchResult.companies.get(0).plScore);
            binding.secondCompanyScoreText.setText(searchResult.companies.get(0).plScore + getString(R.string.pt));
        } else {
            binding.secondCompanyProgressbar.setProgress(0);
            binding.secondCompanyScoreText.setText("?");
        }

        if (searchResult.altText != null) {
            binding.plDataLayout.setVisibility(View.GONE);
            binding.altText.setVisibility(View.VISIBLE);
            binding.altText.setText(searchResult.altText);
        } else {
            binding.altText.setVisibility(View.GONE);
            binding.plDataLayout.setVisibility(View.VISIBLE);

            if (searchResult.companies.get(0).description != null) {
                binding.description.setVisibility(View.VISIBLE);
                binding.description.setText(searchResult.companies.get(0).description);
            } else {
                binding.description.setVisibility(View.GONE);
            }
        }

        if (searchResult.askForSupport()) {
            binding.seePolaFriends.setVisibility(View.VISIBLE);
            binding.seePolaFriends.setOnClickListener((view) -> {
                if (delegate != null) {
                    delegate.onsSeePolaFriendsAction();
                }
            });
        } else {
            binding.seePolaFriends.setVisibility(View.GONE);
        }

        if (searchResult.companies.get(0).is_friend != null && searchResult.companies.get(0).is_friend && searchResult.friend_text != null) {
            binding.isFriendLayout.setVisibility(View.VISIBLE);
            binding.isFriendText.setText(searchResult.friend_text);
        }

        binding.productInfoCard.setOnClickListener(v -> eventBus.post(new ProductDetailsFragmentDismissedEvent()));
    }
} public class ProductDetailsFragment extends DetailsFragment {

    private FragmentProductDetailsBinding binding;

    public static ProductDetailsFragment newInstance(SearchResult searchResult) {
        ProductDetailsFragment fragment = new ProductDetailsFragment();
        Bundle args = new Bundle();
        args.putParcelable(SearchResult.class.getName(), Parcels.wrap(searchResult));
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        binding = FragmentProductDetailsBinding.inflate(inflater, container, false);
        PolaApplication.component(getActivity()).inject(this);
        return binding.getRoot();
    }

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

        binding.companyName.setText(searchResult.name != null ? searchResult.name : searchResult.companies.get(0).name);

        if (searchResult.companies != null && searchResult.companies.get(0).plScore != null) {
            binding.plScoreBar.setProgress(searchResult.companies.get(0).plScore);
            binding.plScoreText.setText(searchResult.companies.get(0).plScore + getString(R.string.pt));
        } else {
            binding.plScoreBar.setProgress(0);
            binding.plScoreText.setText("?");
        }

        if (searchResult.companies != null && searchResult.companies.get(0).plCapital != null) {
            binding.plCapitalBar.setProgress(searchResult.companies.get(0).plCapital);
            binding.plCapitalScoreText.setText(searchResult.companies.get(0).plCapital + "%");
        } else {
            binding.plCapitalBar.setProgress(0);
            binding.plCapitalScoreText.setText("?");
        }

        if (searchResult.altText != null) {
            binding.plDataLayout.setVisibility(View.GONE);
            binding.altText.setVisibility(View.VISIBLE);
            binding.altText.setText(searchResult.altText);
        } else {
            binding.altText.setVisibility(View.GONE);
            binding.plDataLayout.setVisibility(View.VISIBLE);

            if (searchResult.companies.get(0).plWorkers != null && searchResult.companies.get(0).plWorkers != 0) {
                binding.buttonWorkers.setSelected(true);
            } else if (searchResult.companies.get(0).plWorkers == null) {
                binding.buttonWorkers.setEnabled(false);
            }

            if (searchResult.companies.get(0).plRnD != null && searchResult.companies.get(0).plRnD != 0) {
                binding.buttonRnd.setSelected(true);
            } else if (searchResult.companies.get(0).plRnD == null) {
                binding.buttonRnd.setEnabled(false);
            }

            if (searchResult.companies.get(0).plRegistered != null && searchResult.companies.get(0).plRegistered != 0) {
                binding.buttonRegistered.setSelected(true);
            } else if (searchResult.companies.get(0).plRegistered == null) {
                binding.buttonRegistered.setEnabled(false);
            }

            if (searchResult.companies.get(0).plNotGlobEnt != null && searchResult.companies.get(0).plNotGlobEnt != 0) {
                binding.buttonGlobent.setSelected(true);
            } else if (searchResult.companies.get(0).plNotGlobEnt == null) {
                binding.buttonGlobent.setEnabled(false);
            }

            if (searchResult.companies.get(0).description != null) {
                binding.description.setVisibility(View.VISIBLE);
                binding.description.setText(searchResult.companies.get(0).description);
            } else {
                binding.description.setVisibility(View.GONE);
            }
        }

        if (searchResult.askForSupport()) {
            binding.seePolaFriends.setVisibility(View.VISIBLE);
            binding.seePolaFriends.setOnClickListener((view) -> {
                if (delegate != null) {
                    delegate.onsSeePolaFriendsAction();
                }
            });
        } else {
            binding.seePolaFriends.setVisibility(View.GONE);
        }

        if (searchResult.companies != null &&
                searchResult.companies.get(0).is_friend != null &&
                searchResult.companies.get(0).is_friend &&
                searchResult.friend_text != null) {
            binding.isFriendLayout.setVisibility(View.VISIBLE);
            binding.isFriendText.setText(searchResult.friend_text);
        }

        binding.productInfoCard.setOnClickListener(v -> eventBus.post(new ProductDetailsFragmentDismissedEvent()));
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        delegate = null;
    }
} public class ScannerFragment extends Fragment implements CompoundBarcodeView.TorchListener, FlashActionListener {

    @Inject
    Bus eventBus;

    private boolean isTorchOn = false;
    private FragmentScannerBinding binding;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        PolaApplication.component(getActivity()).inject(this);
        super.onCreate(savedInstanceState);
    }

    //ZXING barcode result
    private BarcodeCallback callback = new BarcodeCallback() {
        @Override
        public void barcodeResult(final BarcodeResult result) {
            if (result.getText() != null) {
                binding.barcodeScanner.getBarcodeView().stopDecoding();
                binding.barcodeScanner.setStatusText("");
                ((Vibrator) getActivity().getSystemService(Context.VIBRATOR_SERVICE)).vibrate(100);
                getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        onBarcode(result.getText());
                    }
                });

                Timber.d(result.getText());
                Timber.d(result.getBarcodeFormat().toString());
            }
        }

        @Override
        public void possibleResultPoints(List<ResultPoint> resultPoints) {
        }
    };

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        binding = FragmentScannerBinding.inflate(inflater, container, false);

        DisplayMetrics metrics = new DisplayMetrics();
        getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
        int width = metrics.widthPixels;
        int height = metrics.heightPixels;
        binding.barcodeScanner.getBarcodeView().setFramingRectSize(new Size((int) (width * 0.9f), (int) (height * 0.25f)));
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);

        layoutParams.setMargins(0, (int) (-1 * (height * 0.2)), 0, 0);
        binding.barcodeScanner.setLayoutParams(layoutParams);

        CameraSettings cameraSettings = binding.barcodeScanner.getBarcodeView().getCameraSettings();
        cameraSettings.setContinuousFocusEnabled(true);
        cameraSettings.setAutoFocusEnabled(true);
        binding.barcodeScanner.getBarcodeView().setCameraSettings(cameraSettings);
        binding.barcodeScanner.setStatusText(getActivity().getString(R.string.scanner_status_text));
        FrameLayout.LayoutParams statusTextLayoutParams = new FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
        statusTextLayoutParams.setMargins(0, (int) (height * 0.34), 0, 0);
        binding.barcodeScanner.getStatusView().setLayoutParams(statusTextLayoutParams);

        binding.barcodeScanner.setTorchListener(this);
        binding.barcodeScanner.setTorchOff();
        Nammu.askForPermission(getActivity(), android.Manifest.permission.CAMERA, permissionCameraCallback);

        binding.appIcon.setOnClickListener(view -> {
            Intent intent = new Intent(getActivity(), ActivityWebView.class);
            intent.putExtra("url", Utils.URL_POLA_ABOUT);
            startActivity(intent);
        });

        return binding.getRoot();
    }

    @Override
    public void onResume() {
        super.onResume();
        eventBus.register(this);
        binding.barcodeScanner.resume();
    }

    @Override
    public void onPause() {
        super.onPause();
        eventBus.unregister(this);
        binding.barcodeScanner.setTorchOff();
        binding.barcodeScanner.pause();
    }

    final PermissionCallback permissionCameraCallback = new PermissionCallback() {
        @Override
        public void permissionGranted() {
            resumeScanning();
        }

        @Override
        public void permissionRefused() {
            Toast.makeText(getActivity(), getString(R.string.toast_no_camera_access), Toast.LENGTH_SHORT).show();
        }
    };

    public void resumeScanning() {
        if(binding != null && callback != null){
            binding.barcodeScanner.decodeContinuous(callback);
        }
    }

    private void onBarcode(String barcode) {
        final Activity activity = getActivity();
        if (activity != null && !activity.isFinishing() && activity instanceof BarcodeListener) {
            ((BarcodeListener) activity).onBarcode(barcode, true);
        }
    }

    @Override
    public boolean isTorchOn() {
        return isTorchOn;
    }

    @Override
    public void onFlashAction() {
        if (isTorchOn) {
            binding.barcodeScanner.setTorchOff();
        } else {
            binding.barcodeScanner.setTorchOn();
        }
    }

    @Override
    public void onTorchOn() {
        isTorchOn = true;
    }

    @Override
    public void onTorchOff() {
        isTorchOn = false;
    }

    public void setTorchOff() {
        if (isTorchOn) {
            binding.barcodeScanner.setTorchOff();
        }
    }
}
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.facebook.device.yearclass.YearClass;
import com.google.android.play.core.review.ReviewManager;
import com.google.android.play.core.review.ReviewManagerFactory;
import com.squareup.otto.Bus;
import javax.inject.Inject;
import pl.pola_app.PolaApplication;
import pl.pola_app.R;
import pl.pola_app.databinding.ActivityMainBinding;
import pl.pola_app.helpers.EventLogger;
import pl.pola_app.helpers.ProductsListLinearLayoutManager;
import pl.pola_app.helpers.SessionId;
import pl.pola_app.helpers.SettingsPreference;
import pl.pola_app.model.SearchResult;
import pl.pola_app.ui.adapter.ProductList;
import pl.pola_app.ui.adapter.ProductsAdapter;
import pl.pola_app.ui.delegate.DetailsFragmentDelegate;
import pl.pola_app.ui.event.FlashActionListener;
import pl.pola_app.ui.fragment.BarcodeListener;
import pl.pola_app.ui.fragment.KeyboardFragment;
import pl.pola_app.ui.fragment.LidlDetailsFragment;
import pl.pola_app.ui.fragment.ProductDetailsFragment;
import pl.pola_app.ui.fragment.ScannerFragment;
import pl.tajchert.nammu.Nammu;
import timber.log.Timber;
package pl.pola_app.ui.activity;







public class MainActivity extends AppCompatActivity implements MainViewBinder, BarcodeListener, DetailsFragmentDelegate {

    private static final int DONATE_POLA = 1000;
    @Inject
    Bus eventBus;
    @Inject
    SettingsPreference settingsPreference;

    private ScannerFragment scannerFragment;
    private MainPresenter mainPresenter;
    private EventLogger logger;
    private SessionId sessionId;
    private ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        PolaApplication.component(this).inject(this);
        Nammu.init(this);

        ProductList productList = ProductList.create(savedInstanceState);
        final ProductsAdapter productsAdapter = new ProductsAdapter(this, productList);
        sessionId = SessionId.create(this);
        mainPresenter = MainPresenter.create(getApplicationContext(), this, productList, productsAdapter, sessionId, eventBus, settingsPreference);

        logger = new EventLogger(this);

        binding.openKeyboardButton.setOnClickListener(v -> openKeyboard());
        scannerFragment = (ScannerFragment) getFragmentManager().findFragmentById(R.id.scanner_fragment);

        binding.productsList.setLayoutManager(new ProductsListLinearLayoutManager(this));

        getFragmentManager().addOnBackStackChangedListener(() -> {
            final boolean isNotBackStackEmpty = getFragmentManager().getBackStackEntryCount() > 0;
            mainPresenter.onBackStackChange(isNotBackStackEmpty);
            if (isNotBackStackEmpty) {
                binding.openKeyboardButton.hide();
            } else {
                binding.openKeyboardButton.show();
            }
        });

        binding.menu.setOnClickListener(view -> {
            startActivity(new Intent(this, MenuActivity.class));
        });

        binding.flashIcon.setOnClickListener(this::onFlashIconClicked);
        binding.supportPolaApp.setOnClickListener(this::onSupportPolaButtonClick);
    }

    public void onFlashIconClicked(View view) {
        Fragment fragment = getFragmentManager().findFragmentById(R.id.scanner_fragment);
        if (fragment != null && fragment instanceof FlashActionListener) {
            final FlashActionListener flashActionListener = (FlashActionListener) fragment;
            flashActionListener.onFlashAction();
            if (view != null && view instanceof ImageView) {
                ((ImageView) view).setImageDrawable(ContextCompat.getDrawable(this,
                        flashActionListener.isTorchOn() ? R.drawable.ic_flash_off_white_48dp : R.drawable.ic_flash_on_white_48dp));
            }
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        mainPresenter.register();
    }

    @Override
    protected void onStop() {
        mainPresenter.unregister();
        super.onStop();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mainPresenter.onSaveState(outState);
    }

    @Override
    public void openProductDetails(@NonNull final SearchResult searchResult) {
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.setCustomAnimations(R.animator.slide_in, 0, 0, R.animator.slide_out);

        if (searchResult.companies != null && searchResult.companies.size() > 1) {
            // lidl
            LidlDetailsFragment newFragment = LidlDetailsFragment.newInstance(searchResult);
            ft.add(R.id.container, newFragment, LidlDetailsFragment.class.getName());
            ft.addToBackStack(LidlDetailsFragment.class.getName());
        } else {
            // not lidl
            ProductDetailsFragment newFragment = ProductDetailsFragment.newInstance(searchResult);