com.ideationdesignservices.txtbook.pdf.TxtBookPdf.java Source code

Java tutorial

Introduction

Here is the source code for com.ideationdesignservices.txtbook.pdf.TxtBookPdf.java

Source

package com.ideationdesignservices.txtbook.pdf;

import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Environment;
import com.flurry.android.FlurryAgent;
import com.flurry.org.codehaus.jackson.util.MinimalPrettyPrinter;
import com.ideationdesignservices.txtbook.Txtbook;
import com.ideationdesignservices.txtbook.util.ImageUtilities;
import com.ideationdesignservices.txtbook.util.MMSUtilities;
import com.itextpdf.license.LicenseKey;
import com.itextpdf.text.Anchor;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Chunk;
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.html.HtmlTags;
import com.itextpdf.text.pdf.BaseField;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfAction;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfObject;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
import java.util.TimeZone;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class TxtBookPdf {
    private static final float BUBBLE_B_HEIGHT = 9.6f;
    private static final float BUBBLE_L_WIDTH = 9.6f;
    private static final float BUBBLE_R_WIDTH = 3.1f;
    private static final float BUBBLE_TEXT_INDENT_ALTERNATE = 5.0f;
    private static final float BUBBLE_TEXT_INDENT_MAIN = -1.0f;
    private static final float BUBBLE_T_HEIGHT = 1.44f;
    private static final float[][] COLUMNS_ALT = new float[][] {
            new float[] { Txtbook.RIGHT_MARGIN_ODD, Txtbook.TOP_MARGIN, 284.0f, 729.0f },
            new float[] { 344.0f, Txtbook.TOP_MARGIN, 562.0f, 729.0f } };
    private static final float[][] COLUMNS_REG = new float[][] {
            new float[] { Txtbook.RIGHT_MARGIN_EVEN, Txtbook.TOP_MARGIN, 268.0f, 729.0f },
            new float[] { 328.0f, Txtbook.TOP_MARGIN, 546.0f, 729.0f } };
    private static final float COLUMN_WIDTH = 218.0f;
    private static final float GAP_WIDTH = 60.0f;
    private static final float MAX_COLUMN_CONTENT_WIDTH = 206.0f;
    private final String[] closings = new String[] { " said [speaker].", " replied [speaker].",
            " answered [speaker].", " responded [speaker].", " texted [speaker]." };
    private int currentColumn;
    private float currentY;
    public String filename;
    private Random generator = new Random();
    private int lastPhraseIdx = -1;
    private Context mContext;
    private final String[] openings = new String[] { "[speaker] continued, ", "[speaker] said, ",
            "Then [speaker] replied, ", "[speaker] went on, ", "[speaker] texted, ", "Then [speaker] said, ",
            "[speaker] then replied with, ", "To which [speaker] responded, " };
    private Font sansFont11Gray;
    private Font sansFont6Gray;
    private Font sansFont9;
    private Font sansFont9Gray;
    private Font serifFont11;
    private Font serifFont14;
    private Font serifFont24;
    private Font serifFont8Gray;
    public TxtBookPdfSettings settings;
    private Boolean wasLastPhraseOpening = Boolean.valueOf(false);
    private PdfWriter writer;

    public void createPDF(Context context) throws DocumentException, IOException {
        LicenseKey.loadLicenseFile(context.getAssets().open("itextkey.xml"));
        this.mContext = context;
        Map<String, String> pdfParams = new HashMap();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy_MM_dd_Hmmss", Locale.US);
        dateFormat.setTimeZone(TimeZone.getDefault());
        this.filename = "txtbook_" + dateFormat.format(new Date()) + ".pdf";
        float leftMargin = Txtbook.RIGHT_MARGIN_EVEN;
        float rightMargin = Txtbook.RIGHT_MARGIN_ODD;
        if (this.settings.addFrontCover.booleanValue()) {
            leftMargin = Txtbook.RIGHT_MARGIN_ODD;
            rightMargin = Txtbook.RIGHT_MARGIN_EVEN;
        }
        Document document = new Document(PageSize.LETTER, leftMargin, rightMargin, Txtbook.TOP_MARGIN,
                Txtbook.TOP_MARGIN);
        File file = new File(Environment.getExternalStorageDirectory(), this.filename);
        if (!(file.exists() && file.canRead())) {
            file.createNewFile();
        }
        this.writer = PdfWriter.getInstance(document, new FileOutputStream(file));
        this.writer.setCompressionLevel(this.settings.compressionLevel);
        this.writer.setStrictImageSequence(true);
        FontFactory.register("assets/fonts/DroidSans.ttf");
        this.sansFont6Gray = FontFactory.getFont("DroidSans", BaseFont.WINANSI, true, 6.0f, 0,
                new BaseColor(152, 152, 152));
        this.sansFont9 = FontFactory.getFont("DroidSans", BaseFont.WINANSI, true, 9.0f);
        this.sansFont9Gray = FontFactory.getFont("DroidSans", BaseFont.WINANSI, true, 9.0f, 0,
                new BaseColor(103, 103, 103));
        this.sansFont11Gray = FontFactory.getFont("DroidSans", BaseFont.WINANSI, true, 11.0f, 0,
                new BaseColor(152, 152, 152));
        FontFactory.register("assets/fonts/CourierNew.ttf");
        this.serifFont8Gray = FontFactory.getFont("Courier New", BaseFont.WINANSI, true, 8.0f, 0,
                new BaseColor(103, 103, 103));
        this.serifFont11 = FontFactory.getFont("Courier New", BaseFont.WINANSI, true, 11.0f);
        this.serifFont14 = FontFactory.getFont("Courier New", BaseFont.WINANSI, true, 14.0f);
        this.serifFont24 = FontFactory.getFont("Courier New", BaseFont.WINANSI, true, 24.0f);
        document.open();
        document.setMarginMirroring(true);
        document.addCreationDate();
        document.addCreator("Created with txt-book for Android www.txt-book.com");
        document.addTitle("txt-book for Android");
        if (this.settings.bookStyle == 1) {
            ConversationHeaderFooter hf = new ConversationHeaderFooter();
            hf.footerFont = this.sansFont9;
            hf.hasFrontCover = this.settings.addFrontCover;
            this.writer.setPageEvent(hf);
        } else {
            StorybookHeaderFooter hf2 = new StorybookHeaderFooter();
            hf2.title = this.settings.bookCoverTitle;
            hf2.headerFont = this.serifFont8Gray;
            hf2.hasFrontCover = this.settings.addFrontCover;
            this.writer.setPageEvent(hf2);
        }
        if (this.settings.addFrontCover.booleanValue()) {
            createFrontCoverPage(document, this.settings.bookCoverTitle,
                    this.settings.addFrontCoverImage.booleanValue() ? this.settings.coverPhoto : null);
            pdfParams.put("PDF Front Cover", "YES");
        } else {
            pdfParams.put("PDF Front Cover", "NO");
        }
        if (this.settings.addFrontCoverImage.booleanValue()) {
            pdfParams.put("PDF Front Cover Image", "YES");
        } else {
            pdfParams.put("PDF Front Cover Image", "NO");
        }
        if (this.settings.bookStyle == 1) {
            createContentPagesConversation(document);
        } else {
            createContentPagesStorybook(document, this.settings.bookCoverTitle);
        }
        int pages = this.writer.getPageNumber();
        if (this.settings.bookStyle == 2) {
            ((StorybookHeaderFooter) this.writer.getPageEvent()).reachedEndOfContent = Boolean.valueOf(true);
        } else {
            ((ConversationHeaderFooter) this.writer.getPageEvent()).reachedEndOfContent = Boolean.valueOf(true);
        }
        if (this.settings.addBackCover.booleanValue()) {
            pages++;
            pdfParams.put("PDF Back Cover", "YES");
            if (pages % 2 == 1) {
                createBlankSpacerPage(document);
            }
            createBackCoverPage(document, this.settings.backCoverNote);
        } else {
            pdfParams.put("PDF Back Cover", "NO");
            if (pages % 2 == 1) {
                createBlankSpacerPage(document);
            }
        }
        if (this.settings.bookStyle == 2) {
            pdfParams.put("PDF Style", "Storybook");
        } else {
            pdfParams.put("PDF Style", "Conversation");
        }
        pdfParams.put("PDF Num Pages", Integer.valueOf(this.writer.getPageNumber()).toString());
        document.close();
        FlurryAgent.logEvent("PDF_CREATED", (Map) pdfParams);
    }

    public Boolean createFrontCoverPage(Document document, String coverTitle, Bitmap photo)
            throws DocumentException, MalformedURLException, IOException {
        if (photo != null) {
            int imageMaxWidth;
            int imageMaxHeight;
            int imagePosX;
            int imagePosY;
            if (photo.getWidth() < photo.getHeight()) {
                imageMaxWidth = 900;
                imageMaxHeight = 1200;
                imagePosX = 198;
                imagePosY = 379;
            } else {
                imageMaxWidth = 1200;
                imageMaxHeight = 900;
                imagePosX = 162;
                imagePosY = 379;
            }
            OutputStream stream = new ByteArrayOutputStream();
            ImageUtilities.scaleCenterCrop(photo, imageMaxWidth, imageMaxHeight).compress(CompressFormat.JPEG, 50,
                    stream);
            Image coverImage = Image.getInstance(stream.toByteArray());
            coverImage.setAbsolutePosition(0.0f, 0.0f);
            PdfTemplate t = this.writer.getDirectContent().createTemplate((float) imageMaxWidth,
                    (float) imageMaxHeight);
            t.newPath();
            t.moveTo(0.0f, (float) imageMaxHeight);
            t.lineTo(0.0f, 71.0f);
            t.lineTo(17.0f, 71.0f);
            t.lineTo(17.0f, 0.0f);
            t.lineTo(72.0f, 71.0f);
            t.lineTo((float) imageMaxWidth, 71.0f);
            t.lineTo((float) imageMaxWidth, (float) imageMaxHeight);
            t.lineTo(0.0f, (float) imageMaxHeight);
            t.closePath();
            t.clip();
            t.newPath();
            t.addImage(coverImage);
            t.setColorStroke(new BaseColor(0, 0, 0));
            t.setLineWidth(BUBBLE_TEXT_INDENT_ALTERNATE);
            t.newPath();
            t.moveTo(0.0f, (float) imageMaxHeight);
            t.lineTo(0.0f, 71.0f);
            t.lineTo(17.0f, 71.0f);
            t.lineTo(17.0f, 0.0f);
            t.lineTo(72.0f, 71.0f);
            t.lineTo((float) imageMaxWidth, 71.0f);
            t.lineTo((float) imageMaxWidth, (float) imageMaxHeight);
            t.lineTo(0.0f, (float) imageMaxHeight);
            t.closePathStroke();
            Image clipped = Image.getInstance(t);
            clipped.scalePercent(24.0f);
            clipped.setAbsolutePosition((float) imagePosX, (float) imagePosY);
            clipped.setCompressionLevel(this.settings.compressionLevel);
            clipped.setAlignment(5);
            document.add(clipped);
        }
        if (coverTitle != null && coverTitle.length() > 0) {
            PdfContentByte canvas = this.writer.getDirectContent();
            Paragraph coverTitleEl = new Paragraph(coverTitle, this.serifFont24);
            coverTitleEl.setAlignment(1);
            PdfPTable table = new PdfPTable(1);
            table.setTotalWidth(311.0f);
            PdfPCell cell = new PdfPCell();
            cell.setBorder(0);
            cell.addElement(coverTitleEl);
            cell.setPadding(0.0f);
            cell.setIndent(0.0f);
            table.addCell(cell);
            table.completeRow();
            table.writeSelectedRows(0, -1, 147.0f, 390.0f, canvas);
        }
        return Boolean.valueOf(true);
    }

    public Boolean createBackCoverPage(Document document, String backCoverNote)
            throws DocumentException, MalformedURLException, IOException {
        document.newPage();
        Image backCoverImageFrame = Image
                .getInstance(ImageUtilities.getImageDataForFile(this.mContext, "pdf/txtbook_backpage_300.png"));
        backCoverImageFrame.scalePercent(24.0f);
        backCoverImageFrame.setAbsolutePosition(87.0f, 78.0f);
        backCoverImageFrame.setCompressionLevel(this.settings.compressionLevel);
        document.add(backCoverImageFrame);
        PdfContentByte canvas = this.writer.getDirectContent();
        PdfPTable table = new PdfPTable(1);
        table.setTotalWidth(215.0f);
        if (backCoverNote != null && backCoverNote.length() > 0) {
            Paragraph backCoverEl = new Paragraph(backCoverNote, this.serifFont14);
            PdfPCell cell = new PdfPCell();
            cell.setBorder(0);
            cell.addElement(backCoverEl);
            cell.setPadding(13.0f);
            cell.setIndent(0.0f);
            cell.setFixedHeight(310.0f);
            table.addCell(cell);
            table.completeRow();
        }
        Element backUrl = new Anchor("txt-book.com", this.sansFont11Gray);
        backUrl.setName("txt-book.com");
        backUrl.setReference("http://www.txt-book.com");
        Paragraph paragraph = new Paragraph();
        paragraph.setAlignment(2);
        paragraph.add(backUrl);
        PdfPCell cell2 = new PdfPCell();
        cell2.setBorder(0);
        cell2.setHorizontalAlignment(2);
        cell2.addElement(paragraph);
        cell2.setPadding(0.0f);
        cell2.setPaddingTop(0.0f);
        cell2.setIndent(0.0f);
        table.addCell(cell2);
        table.completeRow();
        table.writeSelectedRows(0, -1, 306.0f, 400.0f, canvas);
        return Boolean.valueOf(true);
    }

    public Boolean createBlankSpacerPage(Document document) {
        document.newPage();
        this.writer.setPageEmpty(false);
        return Boolean.valueOf(true);
    }

    public int createContentPagesConversation(Document document) throws DocumentException {
        float[][] COLUMNS;
        document.newPage();
        ColumnText ct = new ColumnText(this.writer.getDirectContent());
        this.currentColumn = 0;
        if (COLUMNS_REG[0][0] == Txtbook.leftMargin(this.writer, document, this.settings.addFrontCover)) {
            COLUMNS = COLUMNS_REG;
        } else {
            COLUMNS = COLUMNS_ALT;
        }
        ct.setSimpleColumn(COLUMNS[this.currentColumn][0], COLUMNS[this.currentColumn][1],
                COLUMNS[this.currentColumn][2], COLUMNS[this.currentColumn][3]);
        Cursor cursor = this.mContext.getContentResolver().query(
                Uri.parse("content://mms-sms/conversations/" + this.settings.threadId),
                new String[] { "_id", "ct_t", "normalized_date" }, "normalized_date >= "
                        + this.settings.startDateMillis + " AND normalized_date <= " + this.settings.endDateMillis,
                null, "normalized_date");
        Iterator<Integer> itr = this.settings.getSelectedRows().iterator();
        while (itr.hasNext()) {
            if (cursor.moveToPosition(((Integer) itr.next()).intValue())) {
                String senderString;
                Boolean isMe;
                Long messageId = Long.valueOf(cursor.getLong(cursor.getColumnIndex("_id")));
                String mimetype = cursor.getString(cursor.getColumnIndex("ct_t"));
                if (MMSUtilities.getMessageSenderType(this.mContext, messageId, mimetype) == 1) {
                    senderString = this.settings.theirName;
                    isMe = Boolean.valueOf(false);
                } else {
                    senderString = this.settings.myName;
                    isMe = Boolean.valueOf(true);
                }
                String contentString = PdfObject.NOTHING;
                Boolean isVideo = Boolean.valueOf(false);
                if ("application/vnd.wap.multipart.related".equals(mimetype)) {
                    Cursor mmsCursor = this.mContext.getContentResolver().query(Uri.parse("content://mms/part"),
                            null, "mid=" + messageId, null, null);
                    Boolean hasNext = Boolean.valueOf(mmsCursor.moveToFirst());
                    while (hasNext.booleanValue()) {
                        contentString = PdfObject.NOTHING;
                        Bitmap contentImage = null;
                        isVideo = Boolean.valueOf(false);
                        String partId = mmsCursor.getString(mmsCursor.getColumnIndex("_id"));
                        String mimetype2 = mmsCursor.getString(mmsCursor.getColumnIndex("ct"));
                        if ("application/smil".equals(mimetype2)) {
                            hasNext = Boolean.valueOf(mmsCursor.moveToNext());
                        } else {
                            if (mimetype2.startsWith("image/")) {
                                contentImage = MMSUtilities.getMmsImage(this.mContext, partId);
                            } else {
                                if (mimetype2.startsWith("text/")) {
                                    contentString = mmsCursor.getString(mmsCursor.getColumnIndex("_data")) != null
                                            ? MMSUtilities.getMmsText(this.mContext, partId)
                                            : mmsCursor.getString(mmsCursor.getColumnIndex("text"));
                                } else {
                                    if (mimetype2.startsWith("video/")) {
                                        isVideo = Boolean.valueOf(true);
                                        contentImage = wrapVideoThumbnailWithFilm(this.mContext,
                                                MMSUtilities.getMmsVideoThumbnail(this.mContext, partId));
                                    } else {
                                        contentString = mimetype2.startsWith("audio/") ? "[audio message]"
                                                : "[unknown message type]";
                                    }
                                }
                            }
                            doAddNextConversation(document, cursor, ct, senderString, contentString, contentImage,
                                    isVideo, isMe);
                            hasNext = Boolean.valueOf(mmsCursor.moveToNext());
                        }
                    }
                    mmsCursor.close();
                } else {
                    Cursor smsCursor = this.mContext.getContentResolver().query(Uri.parse("content://sms"),
                            new String[] { HtmlTags.BODY, LicenseKey.LICENSE_DATE }, "_id = " + messageId, null,
                            null);
                    if (smsCursor.moveToFirst()) {
                        contentString = smsCursor.getString(smsCursor.getColumnIndex(HtmlTags.BODY));
                    }
                    smsCursor.close();
                    doAddNextConversation(document, cursor, ct, senderString, contentString, null,
                            Boolean.valueOf(false), isMe);
                }
            }
        }
        return 0;
    }

    public void doAddNextConversation(Document document, Cursor cursor, ColumnText ct, String senderString,
            String contentString, Bitmap contentImage, Boolean isVideo, Boolean isMe) {
        float[][] COLUMNS;
        if (COLUMNS_REG[0][0] == Txtbook.leftMargin(this.writer, document, this.settings.addFrontCover)) {
            COLUMNS = COLUMNS_REG;
        } else {
            COLUMNS = COLUMNS_ALT;
        }
        String dateString = PdfObject.NOTHING;
        if (this.settings.useTimestamps.booleanValue()) {
            Long date = Long.valueOf(cursor.getLong(cursor.getColumnIndex("normalized_date")));
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MMM dd, yyyy h:mm a", Locale.US);
            simpleDateFormat.setTimeZone(TimeZone.getDefault());
            dateString = simpleDateFormat.format(new Date(date.longValue()));
        }
        try {
            this.currentY = ct.getYLine();
            addConversationPart(ct, this.currentColumn, dateString, senderString, contentString, contentImage,
                    isVideo, isMe);
            if (ColumnText.hasMoreText(ct.go(true))) {
                this.currentColumn = (this.currentColumn + 1) % 2;
                if (this.currentColumn == 0) {
                    document.newPage();
                    if (COLUMNS_REG[0][0] == Txtbook.leftMargin(this.writer, document,
                            this.settings.addFrontCover)) {
                        COLUMNS = COLUMNS_REG;
                    } else {
                        COLUMNS = COLUMNS_ALT;
                    }
                }
                ct.setSimpleColumn(COLUMNS[this.currentColumn][0], COLUMNS[this.currentColumn][1],
                        COLUMNS[this.currentColumn][2], COLUMNS[this.currentColumn][3]);
                this.currentY = COLUMNS[this.currentColumn][3];
            }
            ct.setYLine(this.currentY);
            ct.setText(null);
            float width = addConversationPart(ct, this.currentColumn, dateString, senderString, contentString,
                    contentImage, isVideo, isMe);
            int status = ct.go(false);
            Document document2 = document;
            ColumnText columnText = ct;
            addConversationBackground(document2, columnText, this.currentColumn, this.currentY, width,
                    this.currentY - ct.getYLine(), isMe);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public float addConversationPart(ColumnText ct, int column, String dateString, String senderString,
            String contentString, Bitmap contentBitmap, Boolean isVideo, Boolean isMe)
            throws DocumentException, MalformedURLException, IOException {
        float messageWidth = 196.0f;
        Chunk dateChunk = new Chunk(new StringBuilder(String.valueOf(dateString))
                .append(MinimalPrettyPrinter.DEFAULT_ROOT_VALUE_SEPARATOR).toString(), this.sansFont6Gray);
        float dateWidth = dateChunk.getWidthPoint();
        Paragraph contentParagraph = new Paragraph();
        if (contentString.length() > 0) {
            Element contentChunk = new Chunk(contentString, this.sansFont9);
            messageWidth = contentChunk.getWidthPoint();
            contentParagraph.add(contentChunk);
        }
        if (messageWidth < dateWidth) {
            messageWidth = dateWidth;
        }
        if (messageWidth > MAX_COLUMN_CONTENT_WIDTH) {
            messageWidth = MAX_COLUMN_CONTENT_WIDTH;
            dateWidth += 7.0f;
        }
        Paragraph dateParagraph = new Paragraph(dateChunk);
        if (isMe.booleanValue()) {
            dateParagraph.setAlignment(0);
            dateParagraph
                    .setIndentationLeft((((BUBBLE_L_WIDTH + messageWidth) + BUBBLE_R_WIDTH) + 7.0f) - dateWidth);
        } else {
            dateParagraph.setAlignment(2);
            dateParagraph
                    .setIndentationRight((((BUBBLE_L_WIDTH + messageWidth) + BUBBLE_R_WIDTH) + 7.0f) - dateWidth);
        }
        ct.addElement(dateParagraph);
        contentParagraph.setExtraParagraphSpace(10.0f);
        if (contentString.length() > 0) {
            contentParagraph.setAlignment(0);
            if (isMe.booleanValue()) {
                contentParagraph.setIndentationLeft(8.6f);
                contentParagraph.setIndentationRight(BUBBLE_TEXT_INDENT_ALTERNATE);
            } else {
                contentParagraph.setIndentationRight(8.6f);
                float indentLeft = COLUMN_WIDTH - (BUBBLE_L_WIDTH + messageWidth);
                if (messageWidth == MAX_COLUMN_CONTENT_WIDTH) {
                    indentLeft += BUBBLE_TEXT_INDENT_ALTERNATE;
                }
                contentParagraph.setIndentationLeft(indentLeft);
            }
            ct.addElement(contentParagraph);
        } else if (contentBitmap != null) {
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            if (isVideo.booleanValue()) {
                contentBitmap.compress(CompressFormat.PNG, 50, stream);
            } else {
                contentBitmap.compress(CompressFormat.JPEG, 50, stream);
            }
            Image contentImage = Image.getInstance(stream.toByteArray());
            contentImage.scaleToFit(198.0f, 198.0f);
            if (isVideo.booleanValue()) {
                contentImage.setCompressionLevel(this.settings.compressionLevel);
            }
            contentImage.setSpacingBefore(10.0f);
            contentImage.setSpacingAfter(10.0f);
            if (isMe.booleanValue()) {
                contentImage.setAlignment(1);
            } else {
                contentImage.setAlignment(1);
            }
            ct.addElement(contentImage);
        }
        Paragraph senderParagraph = new Paragraph(new Chunk(senderString, this.sansFont9Gray));
        if (!isMe.booleanValue()) {
            senderParagraph.setAlignment(2);
        }
        senderParagraph.setSpacingAfter(BUBBLE_TEXT_INDENT_ALTERNATE);
        ct.addElement(senderParagraph);
        return messageWidth;
    }

    public void addConversationBackground(Document document, ColumnText ct, int column, float top,
            float messageWidth, float messageHeight, Boolean isMe)
            throws DocumentException, MalformedURLException, IOException {
        float[][] COLUMNS;
        if (messageWidth < MAX_COLUMN_CONTENT_WIDTH) {
            messageWidth += 8.0f;
        }
        messageHeight -= 35.0f;
        top -= BaseField.BORDER_WIDTH_THICK;
        if (COLUMNS_REG[0][0] == Txtbook.leftMargin(this.writer, document, this.settings.addFrontCover)) {
            COLUMNS = COLUMNS_REG;
        } else {
            COLUMNS = COLUMNS_ALT;
        }
        float left = COLUMNS[column][0];
        PdfContentByte under = this.writer.getDirectContentUnder();
        PdfTemplate bg = this.writer.getDirectContentUnder().createTemplate(
                (BUBBLE_L_WIDTH + messageWidth) + BUBBLE_R_WIDTH,
                (BUBBLE_T_HEIGHT + messageHeight) + BUBBLE_L_WIDTH);
        String num = isMe.booleanValue() ? "1" : "2";
        Image bgTL = Image
                .getInstance(ImageUtilities.getImageDataForFile(this.mContext, "pdf/bubble_" + num + "_tl.png"));
        bgTL.scaleAbsoluteWidth(BUBBLE_L_WIDTH);
        bgTL.scaleAbsoluteHeight(BUBBLE_T_HEIGHT);
        bgTL.setAbsolutePosition(0.0f, BUBBLE_L_WIDTH + messageHeight);
        bg.addImage(bgTL);
        Image bgT = Image
                .getInstance(ImageUtilities.getImageDataForFile(this.mContext, "pdf/bubble_" + num + "_t.png"));
        bgT.scaleAbsoluteWidth(messageWidth);
        bgT.scaleAbsoluteHeight(BUBBLE_T_HEIGHT);
        bgT.setAbsolutePosition(BUBBLE_L_WIDTH, BUBBLE_L_WIDTH + messageHeight);
        bg.addImage(bgT);
        Image bgTR = Image
                .getInstance(ImageUtilities.getImageDataForFile(this.mContext, "pdf/bubble_" + num + "_tr.png"));
        bgTR.scaleAbsoluteWidth(BUBBLE_R_WIDTH);
        bgTR.scaleAbsoluteHeight(BUBBLE_T_HEIGHT);
        bgTR.setAbsolutePosition(BUBBLE_L_WIDTH + messageWidth, BUBBLE_L_WIDTH + messageHeight);
        bg.addImage(bgTR);
        Image bgL = Image
                .getInstance(ImageUtilities.getImageDataForFile(this.mContext, "pdf/bubble_" + num + "_l.png"));
        bgL.scaleAbsoluteWidth(BUBBLE_L_WIDTH);
        bgL.scaleAbsoluteHeight(messageHeight);
        bgL.setAbsolutePosition(0.0f, BUBBLE_L_WIDTH);
        bg.addImage(bgL);
        bg.saveState();
        if (isMe.booleanValue()) {
            bg.setRGBColorFill(241, 241, 241);
        } else {
            bg.setRGBColorFill(208, 231, 196);
        }
        bg.rectangle(BUBBLE_L_WIDTH, BUBBLE_L_WIDTH, messageWidth, messageHeight);
        bg.fill();
        bg.restoreState();
        Image bgR = Image
                .getInstance(ImageUtilities.getImageDataForFile(this.mContext, "pdf/bubble_" + num + "_r.png"));
        bgR.scaleAbsoluteWidth(BUBBLE_R_WIDTH);
        bgR.scaleAbsoluteHeight(messageHeight);
        bgR.setAbsolutePosition(BUBBLE_L_WIDTH + messageWidth, BUBBLE_L_WIDTH);
        bg.addImage(bgR);
        Image bgBL = Image
                .getInstance(ImageUtilities.getImageDataForFile(this.mContext, "pdf/bubble_" + num + "_bl.png"));
        bgBL.scaleAbsoluteWidth(BUBBLE_L_WIDTH);
        bgBL.scaleAbsoluteHeight(BUBBLE_L_WIDTH);
        bgBL.setAbsolutePosition(0.0f, 0.0f);
        bg.addImage(bgBL);
        Image bgB = Image
                .getInstance(ImageUtilities.getImageDataForFile(this.mContext, "pdf/bubble_" + num + "_b.png"));
        bgB.scaleAbsoluteWidth(messageWidth);
        bgB.scaleAbsoluteHeight(BUBBLE_L_WIDTH);
        bgB.setAbsolutePosition(BUBBLE_L_WIDTH, 0.0f);
        bg.addImage(bgB);
        Image bgBR = Image
                .getInstance(ImageUtilities.getImageDataForFile(this.mContext, "pdf/bubble_" + num + "_br.png"));
        bgBR.scaleAbsoluteWidth(BUBBLE_R_WIDTH);
        bgBR.scaleAbsoluteHeight(BUBBLE_L_WIDTH);
        bgBR.setAbsolutePosition(BUBBLE_L_WIDTH + messageWidth, 0.0f);
        bg.addImage(bgBR);
        if (!isMe.booleanValue()) {
            bg.setMatrix(BUBBLE_TEXT_INDENT_MAIN, 0.0f, 0.0f, BaseField.BORDER_WIDTH_THIN, 0.0f, 0.0f);
            left += COLUMN_WIDTH;
        }
        under.addTemplate(bg, left, (top - messageHeight) - 20.0f);
    }

    public int createContentPagesStorybook(Document document, String title) throws DocumentException {
        document.newPage();
        ((StorybookHeaderFooter) this.writer.getPageEvent()).addHeader(this.writer, document);
        Cursor cursor = this.mContext.getContentResolver().query(
                Uri.parse("content://mms-sms/conversations/" + this.settings.threadId),
                new String[] { "_id", "ct_t", "normalized_date" }, "normalized_date >= "
                        + this.settings.startDateMillis + " AND normalized_date <= " + this.settings.endDateMillis,
                null, "normalized_date");
        int i = 0;
        Long previousDate = null;
        String previousSenderString = PdfObject.NOTHING;
        Iterator<Integer> itr = this.settings.getSelectedRows().iterator();
        while (itr.hasNext()) {
            if (cursor.moveToPosition(((Integer) itr.next()).intValue())) {
                Long messageId = Long.valueOf(cursor.getLong(cursor.getColumnIndex("_id")));
                String mimetype = cursor.getString(cursor.getColumnIndex("ct_t"));
                int type = MMSUtilities.getMessageSenderType(this.mContext, messageId, mimetype);
                String senderString = this.settings.myName;
                String receiverString = this.settings.theirName;
                if (type == 1) {
                    senderString = this.settings.theirName;
                    receiverString = this.settings.myName;
                }
                String contentString = PdfObject.NOTHING;
                Boolean isVideo = Boolean.valueOf(false);
                Long date;
                if ("application/vnd.wap.multipart.related".equals(mimetype)) {
                    Cursor mmsCursor = this.mContext.getContentResolver().query(Uri.parse("content://mms/part"),
                            null, "mid=" + messageId, null, null);
                    Boolean hasNext = Boolean.valueOf(mmsCursor.moveToFirst());
                    while (hasNext.booleanValue()) {
                        contentString = PdfObject.NOTHING;
                        Bitmap contentImage = null;
                        isVideo = Boolean.valueOf(false);
                        String partId = mmsCursor.getString(mmsCursor.getColumnIndex("_id"));
                        String mimetype2 = mmsCursor.getString(mmsCursor.getColumnIndex("ct"));
                        if ("application/smil".equals(mimetype2)) {
                            hasNext = Boolean.valueOf(mmsCursor.moveToNext());
                        } else {
                            if (mimetype2.startsWith("image/")) {
                                contentImage = MMSUtilities.getMmsImage(this.mContext, partId);
                            } else {
                                if (mimetype2.startsWith("text/")) {
                                    contentString = mmsCursor.getString(mmsCursor.getColumnIndex("_data")) != null
                                            ? MMSUtilities.getMmsText(this.mContext, partId)
                                            : mmsCursor.getString(mmsCursor.getColumnIndex("text"));
                                } else {
                                    if (mimetype2.startsWith("video/")) {
                                        isVideo = Boolean.valueOf(true);
                                        contentImage = wrapVideoThumbnailWithFilm(this.mContext,
                                                MMSUtilities.getMmsVideoThumbnail(this.mContext, partId));
                                    } else {
                                        contentString = mimetype2.startsWith("audio/") ? "[audio message]"
                                                : "[unknown message type]";
                                    }
                                }
                            }
                            date = null;
                            if (this.settings.useTimestamps.booleanValue()) {
                                date = Long.valueOf(cursor.getLong(cursor.getColumnIndex("normalized_date")));
                            }
                            try {
                                addStorybookPart(document, i, date, previousDate, senderString,
                                        previousSenderString, receiverString, contentString, contentImage, isVideo);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            previousDate = date;
                            previousSenderString = senderString;
                            hasNext = Boolean.valueOf(mmsCursor.moveToNext());
                        }
                    }
                    mmsCursor.close();
                } else {
                    Cursor smsCursor = this.mContext.getContentResolver().query(Uri.parse("content://sms"),
                            new String[] { HtmlTags.BODY, LicenseKey.LICENSE_DATE }, "_id = " + messageId, null,
                            null);
                    if (smsCursor.moveToFirst()) {
                        contentString = smsCursor.getString(smsCursor.getColumnIndex(HtmlTags.BODY));
                    }
                    smsCursor.close();
                    date = null;
                    if (this.settings.useTimestamps.booleanValue()) {
                        date = Long.valueOf(cursor.getLong(cursor.getColumnIndex("normalized_date")));
                    }
                    try {
                        addStorybookPart(document, i, date, previousDate, senderString, previousSenderString,
                                receiverString, contentString, null, Boolean.valueOf(false));
                    } catch (Exception e2) {
                        e2.printStackTrace();
                    }
                    previousDate = date;
                    previousSenderString = senderString;
                }
            }
            i++;
        }
        return 0;
    }

    public void addStorybookPart(Document document, int i, Long date, Long previousDate, String senderString,
            String previousSenderString, String receiverString, String contentString, Bitmap contentBitmap,
            Boolean isVideo) throws DocumentException, MalformedURLException, IOException {
        Paragraph paragraph = new Paragraph();
        if (i == 0) {
            paragraph.add(new Chunk("T", this.serifFont24));
            paragraph.add(new Chunk("his story begins", this.serifFont11));
            if (!this.settings.useTimestamps.booleanValue()) {
                paragraph.add(new Chunk(MinimalPrettyPrinter.DEFAULT_ROOT_VALUE_SEPARATOR, this.serifFont11));
            }
        } else if (!senderString.equals(previousSenderString)) {
            document.add(Chunk.NEWLINE);
        }
        Boolean dateChanged = Boolean.valueOf(false);
        if (this.settings.useTimestamps.booleanValue()) {
            SimpleDateFormat dateFormat;
            if (i == 0) {
                dateFormat = new SimpleDateFormat("MMMM dd, yyyy", Locale.US);
                dateFormat.setTimeZone(TimeZone.getDefault());
                paragraph.add(new Chunk(" on " + dateFormat.format(new Date(date.longValue()))
                        + MinimalPrettyPrinter.DEFAULT_ROOT_VALUE_SEPARATOR, this.serifFont11));
            } else {
                dateFormat = new SimpleDateFormat("MMMM dd, yyyy", Locale.US);
                dateFormat.setTimeZone(TimeZone.getDefault());
                String dateString = dateFormat.format(new Date(date.longValue()));
                String previousDateString = PdfObject.NOTHING;
                if (previousDate != null) {
                    previousDateString = dateFormat.format(new Date(previousDate.longValue()));
                }
                if (!previousDateString.equals(dateString)) {
                    dateChanged = Boolean.valueOf(true);
                    document.add(Chunk.NEWLINE);
                    paragraph.add(new Chunk("O", this.serifFont24));
                    paragraph.add(new Chunk("n " + dateString + MinimalPrettyPrinter.DEFAULT_ROOT_VALUE_SEPARATOR,
                            this.serifFont11));
                }
            }
        }
        if (i == 0) {
            paragraph.add(new Chunk("when " + senderString + " texted " + receiverString + ", ", this.serifFont11));
        }
        if (contentString.length() > 0) {
            Boolean addPhrase = Boolean.valueOf(false);
            String phrase = null;
            if (dateChanged.booleanValue()) {
                paragraph.add(new Chunk(new StringBuilder(String.valueOf(senderString)).append(" texted ")
                        .append(receiverString).append(", ").toString(), this.serifFont11));
            } else if (!(i == 0 || dateChanged.booleanValue() || senderString.equals(previousSenderString))) {
                Boolean isOpening = Boolean
                        .valueOf(this.wasLastPhraseOpening.booleanValue() ? this.generator.nextBoolean() : true);
                int phraseIdx = this.lastPhraseIdx;
                if (isOpening.booleanValue() && !this.wasLastPhraseOpening.booleanValue()) {
                    this.lastPhraseIdx = -1;
                }
                if (isOpening.booleanValue()) {
                    do {
                        phraseIdx = this.generator.nextInt(this.openings.length);
                    } while (phraseIdx == this.lastPhraseIdx);
                    phrase = this.openings[phraseIdx];
                } else {
                    do {
                        phraseIdx = this.generator.nextInt(this.closings.length);
                    } while (phraseIdx == this.lastPhraseIdx);
                    phrase = this.closings[phraseIdx];
                }
                this.lastPhraseIdx = phraseIdx;
                this.wasLastPhraseOpening = isOpening;
                phrase = phrase.replace("[speaker]", senderString);
                addPhrase = Boolean.valueOf(true);
            }
            if (addPhrase.booleanValue() && this.wasLastPhraseOpening.booleanValue()) {
                paragraph.add(new Chunk(phrase, this.serifFont11));
            }
            paragraph.add(new Chunk("\"" + contentString.trim() + "\"", this.serifFont11));
            if (addPhrase.booleanValue() && !this.wasLastPhraseOpening.booleanValue()) {
                paragraph.add(new Chunk(phrase, this.serifFont11));
            }
            document.add(paragraph);
        } else if (contentBitmap != null) {
            if (i != 0) {
                paragraph.add(new Chunk(new StringBuilder(String.valueOf(senderString)).append(" sent ")
                        .append(receiverString).append(":").toString(), this.serifFont11));
                document.add(paragraph);
                document.add(Chunk.NEWLINE);
            }
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            if (isVideo.booleanValue()) {
                contentBitmap.compress(CompressFormat.PNG, 50, stream);
            } else {
                contentBitmap.compress(CompressFormat.JPEG, 50, stream);
            }
            Image contentImage = Image.getInstance(stream.toByteArray());
            contentImage.scaleToFit(445.0f, 195.0f);
            contentImage.setAlignment(1);
            if (isVideo.booleanValue()) {
                contentImage.setCompressionLevel(this.settings.compressionLevel);
            }
            document.add(contentImage);
            document.add(Chunk.NEWLINE);
        }
    }

    public void zipPdf() {
        try {
            File srcFile = new File(Environment.getExternalStorageDirectory(), this.filename);
            if (srcFile.exists() && srcFile.canRead()) {
                String zipFilename = this.filename.replace(".pdf", ".zip");
                byte[] buffer = new byte[PdfAction.SUBMIT_EXCL_NON_USER_ANNOTS];
                ZipOutputStream zos = new ZipOutputStream(
                        new FileOutputStream(new File(Environment.getExternalStorageDirectory(), zipFilename)));
                FileInputStream fis = new FileInputStream(srcFile);
                zos.putNextEntry(new ZipEntry(srcFile.getName()));
                while (true) {
                    int length = fis.read(buffer);
                    if (length <= 0) {
                        zos.closeEntry();
                        fis.close();
                        zos.close();
                        this.filename = zipFilename;
                        return;
                    }
                    zos.write(buffer, 0, length);
                }
            }
        } catch (IOException ioe) {
            System.out.println("Error creating zip file" + ioe);
        }
    }

    public Bitmap wrapVideoThumbnailWithFilm(Context context, Bitmap bitmap) {
        Bitmap filmLeft = ImageUtilities.getBitmapForFile(context, "pdf/film_strip_left_300.png");
        Bitmap filmRight = ImageUtilities.getBitmapForFile(context, "pdf/film_strip_right_300.png");
        int filmLeftWidth = filmLeft.getWidth();
        int filmRightWidth = filmRight.getWidth();
        int height = filmLeft.getHeight();
        int mainImageAdjWidth = (int) ((((float) bitmap.getWidth()) * ((float) height))
                / ((float) bitmap.getHeight()));
        Bitmap combined = Bitmap.createBitmap((filmLeftWidth + mainImageAdjWidth) + filmRightWidth, height,
                Config.ARGB_8888);
        Canvas comboImage = new Canvas(combined);
        comboImage.drawBitmap(filmLeft, 0.0f, 0.0f, null);
        comboImage.drawBitmap(bitmap, null, new Rect(filmLeftWidth, 0, filmLeftWidth + mainImageAdjWidth, height),
                null);
        comboImage.drawBitmap(filmRight, (float) (filmLeftWidth + mainImageAdjWidth), 0.0f, null);
        return combined;
    }
}