<commit_before>package co.smartreceipts.android.workers;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
import android.widget.Toast;

import com.itextpdf.text.BadElementException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.BadPdfFormatException;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;

import co.smartreceipts.android.BuildConfig;
import co.smartreceipts.android.R;
import co.smartreceipts.android.SmartReceiptsApplication;
import co.smartreceipts.android.model.CSVColumns;
import co.smartreceipts.android.model.Distance;
import co.smartreceipts.android.model.PDFColumns;
import co.smartreceipts.android.model.Receipt;
import co.smartreceipts.android.model.Trip;
import co.smartreceipts.android.model.comparators.ReceiptDateComparator;
import co.smartreceipts.android.model.converters.DistanceToReceiptsConverter;
import co.smartreceipts.android.persistence.DatabaseHelper;
import co.smartreceipts.android.persistence.PersistenceManager;
import co.smartreceipts.android.persistence.Preferences;
import co.smartreceipts.android.workers.reports.DistanceTableGenerator;
import wb.android.dialog.BetterDialogBuilder;
import wb.android.flex.Flex;
import wb.android.storage.StorageManager;

//TODO: Redo this class... Really sloppy
public class EmailAssistant {

    public enum EmailOptions {
        PDF_FULL(0),
        PDF_IMAGES_ONLY(1),
        CSV(2),
        ZIP_IMAGES_STAMPED(3);

        private final int index;

        EmailOptions(int index) {
            this.index = index;
        }

        public int getIndex() {
            return this.index;
        }
    }

    private static final String TAG = "EmailAssistant";

    private static final Rectangle DEFAULT_PAGE_SIZE = PageSize.A4;

    private final Context mContext;
    private final Flex mFlex;
    private final PersistenceManager mPersistenceManager;
    private final Trip mTrip;

    public static final void email(SmartReceiptsApplication app, Context context, Trip trip) {
        EmailAssistant assistant = new EmailAssistant(context, app.getFlex(), app.getPersistenceManager(), trip);
        assistant.emailTrip();
    }

    public static final Intent getEmailDeveloperIntent() {
        Intent intent = new Intent(Intent.ACTION_SENDTO);
        intent.setType("text/plain");
        intent.setData(Uri.parse("mailto:" + "will.r.b" + "aumann" + "@" + "gm" + "ail" + "." + "com"));
        return intent;
    }

    public static final Intent getEmailDeveloperIntent(String subject) {
        Intent intent = getEmailDeveloperIntent();
        intent.putExtra(Intent.EXTRA_SUBJECT, subject);
        return intent;
    }

    public static final Intent getEmailDeveloperIntent(String subject, String body) {
        Intent intent = getEmailDeveloperIntent(subject);
        intent.putExtra(Intent.EXTRA_TEXT, body);
        return intent;
    }

    public EmailAssistant(Context context, Flex flex, PersistenceManager persistenceManager, Trip trip) {
        mContext = context;
        mFlex = flex;
        mPersistenceManager = persistenceManager;
        mTrip = trip;
    }

    public final void emailTrip() {
        if (!mPersistenceManager.getStorageManager().isExternal()) {
            Toast.makeText(mContext, mFlex.getString(mContext, R.string.SD_ERROR), Toast.LENGTH_LONG).show();
            return;
        }
        View scrollView = mFlex.getView(mContext, R.layout.dialog_email);
        final CheckBox pdfFull = (CheckBox) mFlex.getSubView(mContext, scrollView, R.id.DIALOG_EMAIL_CHECKBOX_PDF_FULL);
        final CheckBox pdfImages = (CheckBox) mFlex.getSubView(mContext, scrollView, R.id.DIALOG_EMAIL_CHECKBOX_PDF_IMAGES);
        final CheckBox csv = (CheckBox) mFlex.getSubView(mContext, scrollView, R.id.DIALOG_EMAIL_CHECKBOX_CSV);
        final CheckBox zipStampedImages = (CheckBox) mFlex.getSubView(mContext, scrollView, R.id.DIALOG_EMAIL_CHECKBOX_ZIP_IMAGES_STAMPED);
        final BetterDialogBuilder builder = new BetterDialogBuilder(mContext);
        String msg = mFlex.getString(mContext, R.string.DIALOG_EMAIL_MESSAGE);
        if (msg.length() > 0) {
            builder.setMessage(msg);
        }
        builder.setTitle(mFlex.getString(mContext, R.string.DIALOG_EMAIL_TITLE))
                .setCancelable(true)
                .setView(scrollView)
                .setPositiveButton(mFlex.getString(mContext, R.string.DIALOG_EMAIL_POSITIVE_BUTTON), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        if (!pdfFull.isChecked() && !pdfImages.isChecked() && !csv.isChecked() && !zipStampedImages.isChecked()) {
                            Toast.makeText(mContext, mFlex.getString(mContext, R.string.DIALOG_EMAIL_TOAST_NO_SELECTION), Toast.LENGTH_SHORT).show();
                            dialog.cancel();
                            return;
                        }
                        if (mPersistenceManager.getDatabase().getReceiptsSerial(mTrip).size() == 0) {
                            Toast.makeText(mContext, mFlex.getString(mContext, R.string.DIALOG_EMAIL_TOAST_NO_RECEIPTS), Toast.LENGTH_SHORT).show();
                            dialog.cancel();
                            return;
                        }
                        ProgressDialog progress = ProgressDialog.show(mContext, "", "Building Reports...", true, false);
                        EnumSet<EmailOptions> options = EnumSet.noneOf(EmailOptions.class);
                        if (pdfFull.isChecked()) {
                            options.add(EmailOptions.PDF_FULL);
                        }
                        if (pdfImages.isChecked()) {
                            options.add(EmailOptions.PDF_IMAGES_ONLY);
                        }
                        if (csv.isChecked()) {
                            options.add(EmailOptions.CSV);
                        }
                        if (zipStampedImages.isChecked()) {
                            options.add(EmailOptions.ZIP_IMAGES_STAMPED);
                        }
                        EmailAttachmentWriter attachmentWriter = new EmailAttachmentWriter(mPersistenceManager, progress, options);
                        attachmentWriter.execute(mTrip);
                    }<commit_msg>Fixed an edgecase there is distance but no receipts<commit_after>package co.smartreceipts.android.workers;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
import android.widget.Toast;

import com.itextpdf.text.BadElementException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.BadPdfFormatException;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;

import co.smartreceipts.android.BuildConfig;
import co.smartreceipts.android.R;
import co.smartreceipts.android.SmartReceiptsApplication;
import co.smartreceipts.android.model.CSVColumns;
import co.smartreceipts.android.model.Distance;
import co.smartreceipts.android.model.PDFColumns;
import co.smartreceipts.android.model.Receipt;
import co.smartreceipts.android.model.Trip;
import co.smartreceipts.android.model.comparators.ReceiptDateComparator;
import co.smartreceipts.android.model.converters.DistanceToReceiptsConverter;
import co.smartreceipts.android.persistence.DatabaseHelper;
import co.smartreceipts.android.persistence.PersistenceManager;
import co.smartreceipts.android.persistence.Preferences;
import co.smartreceipts.android.workers.reports.DistanceTableGenerator;
import wb.android.dialog.BetterDialogBuilder;
import wb.android.flex.Flex;
import wb.android.storage.StorageManager;

//TODO: Redo this class... Really sloppy
public class EmailAssistant {

    public enum EmailOptions {
        PDF_FULL(0),
        PDF_IMAGES_ONLY(1),
        CSV(2),
        ZIP_IMAGES_STAMPED(3);

        private final int index;

        EmailOptions(int index) {
            this.index = index;
        }

        public int getIndex() {
            return this.index;
        }
    }

    private static final String TAG = "EmailAssistant";

    private static final Rectangle DEFAULT_PAGE_SIZE = PageSize.A4;

    private final Context mContext;
    private final Flex mFlex;
    private final PersistenceManager mPersistenceManager;
    private final Trip mTrip;

    public static final void email(SmartReceiptsApplication app, Context context, Trip trip) {
        EmailAssistant assistant = new EmailAssistant(context, app.getFlex(), app.getPersistenceManager(), trip);
        assistant.emailTrip();
    }

    public static final Intent getEmailDeveloperIntent() {
        Intent intent = new Intent(Intent.ACTION_SENDTO);
        intent.setType("text/plain");
        intent.setData(Uri.parse("mailto:" + "will.r.b" + "aumann" + "@" + "gm" + "ail" + "." + "com"));
        return intent;
    }

    public static final Intent getEmailDeveloperIntent(String subject) {
        Intent intent = getEmailDeveloperIntent();
        intent.putExtra(Intent.EXTRA_SUBJECT, subject);
        return intent;
    }

    public static final Intent getEmailDeveloperIntent(String subject, String body) {
        Intent intent = getEmailDeveloperIntent(subject);
        intent.putExtra(Intent.EXTRA_TEXT, body);
        return intent;
    }

    public EmailAssistant(Context context, Flex flex, PersistenceManager persistenceManager, Trip trip) {
        mContext = context;
        mFlex = flex;
        mPersistenceManager = persistenceManager;
        mTrip = trip;
    }

    public final void emailTrip() {
        if (!mPersistenceManager.getStorageManager().isExternal()) {
            Toast.makeText(mContext, mFlex.getString(mContext, R.string.SD_ERROR), Toast.LENGTH_LONG).show();
            return;
        }
        View scrollView = mFlex.getView(mContext, R.layout.dialog_email);
        final CheckBox pdfFull = (CheckBox) mFlex.getSubView(mContext, scrollView, R.id.DIALOG_EMAIL_CHECKBOX_PDF_FULL);
        final CheckBox pdfImages = (CheckBox) mFlex.getSubView(mContext, scrollView, R.id.DIALOG_EMAIL_CHECKBOX_PDF_IMAGES);
        final CheckBox csv = (CheckBox) mFlex.getSubView(mContext, scrollView, R.id.DIALOG_EMAIL_CHECKBOX_CSV);
        final CheckBox zipStampedImages = (CheckBox) mFlex.getSubView(mContext, scrollView, R.id.DIALOG_EMAIL_CHECKBOX_ZIP_IMAGES_STAMPED);
        final BetterDialogBuilder builder = new BetterDialogBuilder(mContext);
        String msg = mFlex.getString(mContext, R.string.DIALOG_EMAIL_MESSAGE);
        if (msg.length() > 0) {
            builder.setMessage(msg);
        }
        builder.setTitle(mFlex.getString(mContext, R.string.DIALOG_EMAIL_TITLE))
                .setCancelable(true)
                .setView(scrollView)
                .setPositiveButton(mFlex.getString(mContext, R.string.DIALOG_EMAIL_POSITIVE_BUTTON), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        if (!pdfFull.isChecked() && !pdfImages.isChecked() && !csv.isChecked() && !zipStampedImages.isChecked()) {
                            Toast.makeText(mContext, mFlex.getString(mContext, R.string.DIALOG_EMAIL_TOAST_NO_SELECTION), Toast.LENGTH_SHORT).show();
                            dialog.cancel();
                            return;
                        }
                        if (mPersistenceManager.getDatabase().getReceiptsSerial(mTrip).isEmpty()) {
                            if (mPersistenceManager.getDatabase().getDistanceSerial(mTrip).isEmpty() || !pdfFull.isChecked()) {
                                // Only allow report processing to continue with no reciepts if we're doing a full pdf report with distances
                                Toast.makeText(mContext, mFlex.getString(mContext, R.string.DIALOG_EMAIL_TOAST_NO_RECEIPTS), Toast.LENGTH_SHORT).show();
                                dialog.cancel();
                                return;
                            }
                            else {
                                // Uncheck "Illegal" Items
                                pdfImages.setChecked(false);
                                csv.setChecked(false);
                                zipStampedImages.setChecked(false);
                            }
                        }
                        ProgressDialog progress = ProgressDialog.show(mContext, "", "Building Reports...", true, false);
                        EnumSet<EmailOptions> options = EnumSet.noneOf(EmailOptions.class);
                        if (pdfFull.isChecked()) {
                            options.add(EmailOptions.PDF_FULL);
                        }
                        if (pdfImages.isChecked()) {
                            options.add(EmailOptions.PDF_IMAGES_ONLY);
                        }
                        if (csv.isChecked()) {
                            options.add(EmailOptions.CSV);
                        }
                        if (zipStampedImages.isChecked()) {
                            options.add(EmailOptions.ZIP_IMAGES_STAMPED);
                        }
                        EmailAttachmentWriter attachmentWriter = new EmailAttachmentWriter(mPersistenceManager, progress, options);
                        attachmentWriter.execute(mTrip);
                    }
{'fraction_non_alphanumeric': 0.09376744186046512, 'fraction_numerical': 0.0008062015503875969, 'mean_word_length': 2.7493606138107416, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5760545', 'n_tokens_mistral': 4678, 'n_tokens_neox': 4454, 'n_words': 819}