/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.printspooler.ui;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.os.Handler;
import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.print.PageRange;
import android.print.PrintAttributes.MediaSize;
import android.print.PrintAttributes.Margins;
import android.print.PrintDocumentInfo;
import android.support.v7.widget.RecyclerView.Adapter;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.util.Log;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.View.MeasureSpec;
import android.widget.TextView;
import com.android.printspooler.R;
import com.android.printspooler.model.OpenDocumentCallback;
import com.android.printspooler.model.PageContentRepository;
import com.android.printspooler.model.PageContentRepository.PageContentProvider;
import com.android.printspooler.util.PageRangeUtils;
import com.android.printspooler.widget.PageContentView;
import com.android.printspooler.widget.PreviewPageFrame;
import dalvik.system.CloseGuard;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * This class represents the adapter for the pages in the print preview list.
 */
public final class PageAdapter extends Adapter<ViewHolder> {
    private static final String LOG_TAG = "PageAdapter";

    private static final int MAX_PREVIEW_PAGES_BATCH = 50;

    private static final boolean DEBUG = false;

    private static final PageRange[] ALL_PAGES_ARRAY = new PageRange[] {
            PageRange.ALL_PAGES
    };

    private static final int INVALID_PAGE_INDEX = -1;

    private static final int STATE_CLOSED = 0;
    private static final int STATE_OPENED = 1;
    private static final int STATE_DESTROYED = 2;

    private final CloseGuard mCloseGuard = CloseGuard.get();

    private final SparseArray<Void> mBoundPagesInAdapter = new SparseArray<>();
    private final SparseArray<Void> mConfirmedPagesInDocument = new SparseArray<>();

    private final PageClickListener mPageClickListener = new PageClickListener();

    private final Context mContext;
    private final LayoutInflater mLayoutInflater;

    private final ContentCallbacks mCallbacks;
    private final PageContentRepository mPageContentRepository;
    private final PreviewArea mPreviewArea;

    // Which document pages to be written.
    private PageRange[] mRequestedPages;
    // Pages written in the current file.
    private PageRange[] mWrittenPages;
    // Pages the user selected in the UI.
    private PageRange[] mSelectedPages;

    private BitmapDrawable mEmptyState;
    private BitmapDrawable mErrorState;

    private int mDocumentPageCount = PrintDocumentInfo.PAGE_COUNT_UNKNOWN;
    private int mSelectedPageCount;

    private int mPreviewPageMargin;
    private int mPreviewPageMinWidth;
    private int mPreviewListPadding;
    private int mFooterHeight;

    private int mColumnCount;

    private MediaSize mMediaSize;
    private Margins mMinMargins;

    private int mState;

    private int mPageContentWidth;
    private int mPageContentHeight;

    public interface ContentCallbacks {
        public void onRequestContentUpdate();
        public void onMalformedPdfFile();
        public void onSecurePdfFile();
    }

    public interface PreviewArea {
        public int getWidth();
        public int getHeight();
        public void setColumnCount(int columnCount);
        public void setPadding(int left, int top, int right, int bottom);
    }

    public PageAdapter(Context context, ContentCallbacks callbacks, PreviewArea previewArea) {
        mContext = context;
        mCallbacks = callbacks;
        mLayoutInflater = (LayoutInflater) context.getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);
        mPageContentRepository = new PageContentRepository(context);

        mPreviewPageMargin = mContext.getResources().getDimensionPixelSize(
                R.dimen.preview_page_margin);

        mPreviewPageMinWidth = mContext.getResources().getDimensionPixelSize(
                R.dimen.preview_page_min_width);

        mPreviewListPadding = mContext.getResources().getDimensionPixelSize(
                R.dimen.preview_list_padding);

        mColumnCount = mContext.getResources().getInteger(
                R.integer.preview_page_per_row_count);

        mFooterHeight = mContext.getResources().getDimensionPixelSize(
                R.dimen.preview_page_footer_height);

        mPreviewArea = previewArea;

        mCloseGuard.open("destroy");

        setHasStableIds(true);

        mState = STATE_CLOSED;
        if (DEBUG) {
            Log.i(LOG_TAG, "STATE_CLOSED");
        }
    }

    public void onOrientationChanged() {
        mColumnCount = mContext.getResources().getInteger(
                R.integer.preview_page_per_row_count);
        notifyDataSetChanged();
    }

    public boolean isOpened() {
        return mState == STATE_OPENED;
    }

    public int getFilePageCount() {
        return mPageContentRepository.getFilePageCount();
    }

    public void open(ParcelFileDescriptor source, final Runnable callback) {
        throwIfNotClosed();
        mState = STATE_OPENED;
        if (DEBUG) {
            Log.i(LOG_TAG, "STATE_OPENED");
        }
        mPageContentRepository.open(source, new OpenDocumentCallback() {
            @Override
            public void onSuccess() {
                notifyDataSetChanged();
                callback.run();
            }

            @Override
            public void onFailure(int error) {
                switch (error) {
                    case OpenDocumentCallback.ERROR_MALFORMED_PDF_FILE: {
                        mCallbacks.onMalformedPdfFile();
                    } break;

                    case OpenDocumentCallback.ERROR_SECURE_PDF_FILE: {
                        mCallbacks.onSecurePdfFile();
                    } break;
                }
            }
        });
    }

    public void update(PageRange[] writtenPages, PageRange[] selectedPages,
            int documentPageCount, MediaSize mediaSize, Margins minMargins) {
        boolean documentChanged = false;
        boolean updatePreviewAreaAndPageSize = false;
        boolean clearSelectedPages = false;

        // If the app does not tell how many pages are in the document we cannot
        // optimize and ask for all pages whose count we get from the renderer.
        if (documentPageCount == PrintDocumentInfo.PAGE_COUNT_UNKNOWN) {
            if (writtenPages == null) {
                // If we already requested all pages, just wait.
                if (!Arrays.equals(ALL_PAGES_ARRAY, mRequestedPages)) {
                    mRequestedPages = ALL_PAGES_ARRAY;
                    mCallbacks.onRequestContentUpdate();
                }
                return;
            } else {
                documentPageCount = mPageContentRepository.getFilePageCount();
                if (documentPageCount <= 0) {
                    return;
                }
            }
        }

        if (mDocumentPageCount != documentPageCount) {
            mDocumentPageCount = documentPageCount;
            documentChanged = true;
            clearSelectedPages = true;
        }

        if (mMediaSize == null || !mMediaSize.equals(mediaSize)) {
            mMediaSize = mediaSize;
            updatePreviewAreaAndPageSize = true;
            documentChanged = true;

            clearSelectedPages = true;
        }

        if (mMinMargins == null || !mMinMargins.equals(minMargins)) {
            mMinMargins = minMargins;
            updatePreviewAreaAndPageSize = true;
            documentChanged = true;

            clearSelectedPages = true;
        }

        if (clearSelectedPages) {
            mSelectedPages = PageRange.ALL_PAGES_ARRAY;
            mSelectedPageCount = documentPageCount;
            setConfirmedPages(mSelectedPages, documentPageCount);
            updatePreviewAreaAndPageSize = true;
            documentChanged = true;
        } else if (!Arrays.equals(mSelectedPages, selectedPages)) {
            mSelectedPages = selectedPages;
            mSelectedPageCount = PageRangeUtils.getNormalizedPageCount(
                    mSelectedPages, documentPageCount);
            setConfirmedPages(mSelectedPages, documentPageCount);
            updatePreviewAreaAndPageSize = true;
            documentChanged = true;
        }

        // If *all pages* is selected we need to convert that to absolute
        // range as we will be checking if some pages are written or not.
        if (writtenPages != null) {
            // If we get all pages, this means all pages that we requested.
            if (PageRangeUtils.isAllPages(writtenPages)) {
                writtenPages = mRequestedPages;
            }
            if (!Arrays.equals(mWrittenPages, writtenPages)) {
                // TODO: Do a surgical invalidation of only written pages changed.
                mWrittenPages = writtenPages;
                documentChanged = true;
            }
        }

        if (updatePreviewAreaAndPageSize) {
            updatePreviewAreaPageSizeAndEmptyState();
        }

        if (documentChanged) {
            notifyDataSetChanged();
        }
    }

    public void close(Runnable callback) {
        throwIfNotOpened();
        mState = STATE_CLOSED;
        if (DEBUG) {
            Log.i(LOG_TAG, "STATE_CLOSED");
        }
        mPageContentRepository.close(callback);
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View page = mLayoutInflater.inflate(R.layout.preview_page, parent, false);
        return new MyViewHolder(page);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        if (DEBUG) {
            Log.i(LOG_TAG, "Binding holder: " + holder + " with id: " + getItemId(position)
                    + " for position: " + position);
        }

        MyViewHolder myHolder = (MyViewHolder) holder;

        PreviewPageFrame page = (PreviewPageFrame) holder.itemView;
        page.setOnClickListener(mPageClickListener);

        page.setTag(holder);

        myHolder.mPageInAdapter = position;

        final int pageInDocument = computePageIndexInDocument(position);
        final int pageIndexInFile = computePageIndexInFile(pageInDocument);

        PageContentView content = (PageContentView) page.findViewById(R.id.page_content);

        LayoutParams params = content.getLayoutParams();
        params.width = mPageContentWidth;
        params.height = mPageContentHeight;

        PageContentProvider provider = content.getPageContentProvider();

        if (pageIndexInFile != INVALID_PAGE_INDEX) {
            if (DEBUG) {
                Log.i(LOG_TAG, "Binding provider:"
                        + " pageIndexInAdapter: " + position
                        + ", pageInDocument: " + pageInDocument
                        + ", pageIndexInFile: " + pageIndexInFile);
            }

            provider = mPageContentRepository.acquirePageContentProvider(
                    pageIndexInFile, content);
            mBoundPagesInAdapter.put(position, null);
        } else {
            onSelectedPageNotInFile(pageInDocument);
        }
        content.init(provider, mEmptyState, mErrorState, mMediaSize, mMinMargins);

        if (mConfirmedPagesInDocument.indexOfKey(pageInDocument) >= 0) {
            page.setSelected(true, false);
        } else {
            page.setSelected(false, false);
        }

        page.setContentDescription(mContext.getString(R.string.page_description_template,
                pageInDocument + 1, mDocumentPageCount));

        TextView pageNumberView = (TextView) page.findViewById(R.id.page_number);
        String text = mContext.getString(R.string.current_page_template,
                pageInDocument + 1, mDocumentPageCount);
        pageNumberView.setText(text);
    }

    @Override
    public int getItemCount() {
        return mSelectedPageCount;
    }

    @Override
    public long getItemId(int position) {
        return computePageIndexInDocument(position);
    }

    @Override
    public void onViewRecycled(ViewHolder holder) {
        MyViewHolder myHolder = (MyViewHolder) holder;
        PageContentView content = (PageContentView) holder.itemView
                .findViewById(R.id.page_content);
        recyclePageView(content, myHolder.mPageInAdapter);
        myHolder.mPageInAdapter = INVALID_PAGE_INDEX;
    }

    public PageRange[] getRequestedPages() {
        return mRequestedPages;
    }

    public PageRange[] getSelectedPages() {
        PageRange[] selectedPages = computeSelectedPages();
        if (!Arrays.equals(mSelectedPages, selectedPages)) {
            mSelectedPages = selectedPages;
            mSelectedPageCount = PageRangeUtils.getNormalizedPageCount(
                    mSelectedPages, mDocumentPageCount);
            updatePreviewAreaPageSizeAndEmptyState();
            notifyDataSetChanged();
        }
        return mSelectedPages;
    }

    public void onPreviewAreaSizeChanged() {
        if (mMediaSize != null) {
            updatePreviewAreaPageSizeAndEmptyState();
            notifyDataSetChanged();
        }
    }

    private void updatePreviewAreaPageSizeAndEmptyState() {
        if (mMediaSize == null) {
            return;
        }

        final int availableWidth = mPreviewArea.getWidth();
        final int availableHeight = mPreviewArea.getHeight();

        // Page aspect ratio to keep.
        final float pageAspectRatio = (float) mMediaSize.getWidthMils()
                / mMediaSize.getHeightMils();

        // Make sure we have no empty columns.
        final int columnCount = Math.min(mSelectedPageCount, mColumnCount);
        mPreviewArea.setColumnCount(columnCount);

        // Compute max page width.
        final int horizontalMargins = 2 * columnCount * mPreviewPageMargin;
        final int horizontalPaddingAndMargins = horizontalMargins + 2 * mPreviewListPadding;
        final int pageContentDesiredWidth = (int) ((((float) availableWidth
                - horizontalPaddingAndMargins) / columnCount) + 0.5f);

        // Compute max page height.
        final int pageContentDesiredHeight = (int) ((pageContentDesiredWidth
                / pageAspectRatio) + 0.5f);

        // If the page does not fit entirely in a vertical direction,
        // we shirk it but not less than the minimal page width.
        final int pageContentMinHeight = (int) (mPreviewPageMinWidth / pageAspectRatio + 0.5f);
        final int pageContentMaxHeight = Math.max(pageContentMinHeight,
                availableHeight - 2 * (mPreviewListPadding + mPreviewPageMargin) - mFooterHeight);

        mPageContentHeight = Math.min(pageContentDesiredHeight, pageContentMaxHeight);
        mPageContentWidth = (int) ((mPageContentHeight * pageAspectRatio) + 0.5f);

        final int totalContentWidth = columnCount * mPageContentWidth + horizontalMargins;
        final int horizontalPadding = (availableWidth - totalContentWidth) / 2;

        final int rowCount = mSelectedPageCount / columnCount
                + ((mSelectedPageCount % columnCount) > 0 ? 1 : 0);
        final int totalContentHeight = rowCount * (mPageContentHeight + mFooterHeight + 2
                * mPreviewPageMargin);

        final int verticalPadding;
        if (mPageContentHeight + mFooterHeight + mPreviewListPadding
                + 2 * mPreviewPageMargin > availableHeight) {
            verticalPadding = Math.max(0,
                    (availableHeight - mPageContentHeight - mFooterHeight) / 2
                            - mPreviewPageMargin);
        } else {
            verticalPadding = Math.max(mPreviewListPadding,
                    (availableHeight - totalContentHeight) / 2);
        }

        mPreviewArea.setPadding(horizontalPadding, verticalPadding,
                horizontalPadding, verticalPadding);

        // Now update the empty state drawable, as it depends on the page
        // size and is reused for all views for better performance.
        LayoutInflater inflater = LayoutInflater.from(mContext);
        View loadingContent = inflater.inflate(R.layout.preview_page_loading, null, false);
        loadingContent.measure(MeasureSpec.makeMeasureSpec(mPageContentWidth, MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(mPageContentHeight, MeasureSpec.EXACTLY));
        loadingContent.layout(0, 0, loadingContent.getMeasuredWidth(),
                loadingContent.getMeasuredHeight());

        Bitmap loadingBitmap = Bitmap.createBitmap(mPageContentWidth, mPageContentHeight,
                Bitmap.Config.ARGB_8888);
        loadingContent.draw(new Canvas(loadingBitmap));

        // Do not recycle the old bitmap if such as it may be set as an empty
        // state to any of the page views. Just let the GC take care of it.
        mEmptyState = new BitmapDrawable(mContext.getResources(), loadingBitmap);

        // Now update the empty state drawable, as it depends on the page
        // size and is reused for all views for better performance.
        View errorContent = inflater.inflate(R.layout.preview_page_error, null, false);
        errorContent.measure(MeasureSpec.makeMeasureSpec(mPageContentWidth, MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(mPageContentHeight, MeasureSpec.EXACTLY));
        errorContent.layout(0, 0, errorContent.getMeasuredWidth(),
                errorContent.getMeasuredHeight());

        Bitmap errorBitmap = Bitmap.createBitmap(mPageContentWidth, mPageContentHeight,
                Bitmap.Config.ARGB_8888);
        errorContent.draw(new Canvas(errorBitmap));

        // Do not recycle the old bitmap if such as it may be set as an error
        // state to any of the page views. Just let the GC take care of it.
        mErrorState = new BitmapDrawable(mContext.getResources(), errorBitmap);
    }

    private PageRange[] computeSelectedPages() {
        ArrayList<PageRange> selectedPagesList = new ArrayList<>();

        int startPageIndex = INVALID_PAGE_INDEX;
        int endPageIndex = INVALID_PAGE_INDEX;

        final int pageCount = mConfirmedPagesInDocument.size();
        for (int i = 0; i < pageCount; i++) {
            final int pageIndex = mConfirmedPagesInDocument.keyAt(i);
            if (startPageIndex == INVALID_PAGE_INDEX) {
                startPageIndex = endPageIndex = pageIndex;
            }
            if (endPageIndex + 1 < pageIndex) {
                PageRange pageRange = new PageRange(startPageIndex, endPageIndex);
                selectedPagesList.add(pageRange);
                startPageIndex = pageIndex;
            }
            endPageIndex = pageIndex;
        }

        if (startPageIndex != INVALID_PAGE_INDEX
                && endPageIndex != INVALID_PAGE_INDEX) {
            PageRange pageRange = new PageRange(startPageIndex, endPageIndex);
            selectedPagesList.add(pageRange);
        }

        PageRange[] selectedPages = new PageRange[selectedPagesList.size()];
        selectedPagesList.toArray(selectedPages);

        return selectedPages;
    }

    public void destroy(Runnable callback) {
        mCloseGuard.close();
        mState = STATE_DESTROYED;
        if (DEBUG) {
            Log.i(LOG_TAG, "STATE_DESTROYED");
        }
        mPageContentRepository.destroy(callback);
    }

    @Override
    protected void finalize() throws Throwable {
        try {
            if (mState != STATE_DESTROYED) {
                mCloseGuard.warnIfOpen();
                destroy(null);
            }
        } finally {
            super.finalize();
        }
    }

    private int computePageIndexInDocument(int indexInAdapter) {
        int skippedAdapterPages = 0;
        final int selectedPagesCount = mSelectedPages.length;
        for (int i = 0; i < selectedPagesCount; i++) {
            PageRange pageRange = PageRangeUtils.asAbsoluteRange(
                    mSelectedPages[i], mDocumentPageCount);
            skippedAdapterPages += pageRange.getSize();
            if (skippedAdapterPages > indexInAdapter) {
                final int overshoot = skippedAdapterPages - indexInAdapter - 1;
                return pageRange.getEnd() - overshoot;
            }
        }
        return INVALID_PAGE_INDEX;
    }

    private int computePageIndexInFile(int pageIndexInDocument) {
        if (!PageRangeUtils.contains(mSelectedPages, pageIndexInDocument)) {
            return INVALID_PAGE_INDEX;
        }
        if (mWrittenPages == null) {
            return INVALID_PAGE_INDEX;
        }

        int indexInFile = INVALID_PAGE_INDEX;
        final int rangeCount = mWrittenPages.length;
        for (int i = 0; i < rangeCount; i++) {
            PageRange pageRange = mWrittenPages[i];
            if (!pageRange.contains(pageIndexInDocument)) {
                indexInFile += pageRange.getSize();
            } else {
                indexInFile += pageIndexInDocument - pageRange.getStart() + 1;
                return indexInFile;
            }
        }
        return INVALID_PAGE_INDEX;
    }

    private void setConfirmedPages(PageRange[] pagesInDocument, int documentPageCount) {
        mConfirmedPagesInDocument.clear();
        final int rangeCount = pagesInDocument.length;
        for (int i = 0; i < rangeCount; i++) {
            PageRange pageRange = PageRangeUtils.asAbsoluteRange(pagesInDocument[i],
                    documentPageCount);
            for (int j = pageRange.getStart(); j <= pageRange.getEnd(); j++) {
                mConfirmedPagesInDocument.put(j, null);
            }
        }
    }

    private void onSelectedPageNotInFile(int pageInDocument) {
        PageRange[] requestedPages = computeRequestedPages(pageInDocument);
        if (!Arrays.equals(mRequestedPages, requestedPages)) {
            mRequestedPages = requestedPages;
            if (DEBUG) {
                Log.i(LOG_TAG, "Requesting pages: " + Arrays.toString(mRequestedPages));
            }

            // This call might come from a recylerview that is currently updating. Hence delay to
            // after the update
            (new Handler(Looper.getMainLooper())).post(new Runnable() {
                @Override public void run() {
                    mCallbacks.onRequestContentUpdate();
                }
            });
        }
    }

    private PageRange[] computeRequestedPages(int pageInDocument) {
        if (mRequestedPages != null &&
                PageRangeUtils.contains(mRequestedPages, pageInDocument)) {
            return mRequestedPages;
        }

        List<PageRange> pageRangesList = new ArrayList<>();

        int remainingPagesToRequest = MAX_PREVIEW_PAGES_BATCH;
        final int selectedPagesCount = mSelectedPages.length;

        // We always request the pages that are bound, i.e. shown on screen.
        PageRange[] boundPagesInDocument = computeBoundPagesInDocument();

        final int boundRangeCount = boundPagesInDocument.length;
        for (int i = 0; i < boundRangeCount; i++) {
            PageRange boundRange = boundPagesInDocument[i];
            pageRangesList.add(boundRange);
        }
        remainingPagesToRequest -= PageRangeUtils.getNormalizedPageCount(
                boundPagesInDocument, mDocumentPageCount);

        final boolean requestFromStart = mRequestedPages == null
                || pageInDocument > mRequestedPages[mRequestedPages.length - 1].getEnd();

        if (!requestFromStart) {
            if (DEBUG) {
                Log.i(LOG_TAG, "Requesting from end");
            }

            // Reminder that ranges are always normalized.
            for (int i = selectedPagesCount - 1; i >= 0; i--) {
                if (remainingPagesToRequest <= 0) {
                    break;
                }

                PageRange selectedRange = PageRangeUtils.asAbsoluteRange(mSelectedPages[i],
                        mDocumentPageCount);
                if (pageInDocument < selectedRange.getStart()) {
                    continue;
                }

                PageRange pagesInRange;
                int rangeSpan;

                if (selectedRange.contains(pageInDocument)) {
                    rangeSpan = pageInDocument - selectedRange.getStart() + 1;
                    rangeSpan = Math.min(rangeSpan, remainingPagesToRequest);
                    final int fromPage = Math.max(pageInDocument - rangeSpan - 1, 0);
                    rangeSpan = Math.max(rangeSpan, 0);
                    pagesInRange = new PageRange(fromPage, pageInDocument);
                } else {
                    rangeSpan = selectedRange.getSize();
                    rangeSpan = Math.min(rangeSpan, remainingPagesToRequest);
                    rangeSpan = Math.max(rangeSpan, 0);
                    final int fromPage = Math.max(selectedRange.getEnd() - rangeSpan - 1, 0);
                    final int toPage = selectedRange.getEnd();
                    pagesInRange = new PageRange(fromPage, toPage);
                }

                pageRangesList.add(pagesInRange);
                remainingPagesToRequest -= rangeSpan;
            }
        } else {
            if (DEBUG) {
                Log.i(LOG_TAG, "Requesting from start");
            }

            // Reminder that ranges are always normalized.
            for (int i = 0; i < selectedPagesCount; i++) {
                if (remainingPagesToRequest <= 0) {
                    break;
                }

                PageRange selectedRange = PageRangeUtils.asAbsoluteRange(mSelectedPages[i],
                        mDocumentPageCount);
                if (pageInDocument > selectedRange.getEnd()) {
                    continue;
                }

                PageRange pagesInRange;
                int rangeSpan;

                if (selectedRange.contains(pageInDocument)) {
                    rangeSpan = selectedRange.getEnd() - pageInDocument + 1;
                    rangeSpan = Math.min(rangeSpan, remainingPagesToRequest);
                    final int toPage = Math.min(pageInDocument + rangeSpan - 1,
                            mDocumentPageCount - 1);
                    pagesInRange = new PageRange(pageInDocument, toPage);
                } else {
                    rangeSpan = selectedRange.getSize();
                    rangeSpan = Math.min(rangeSpan, remainingPagesToRequest);
                    final int fromPage = selectedRange.getStart();
                    final int toPage = Math.min(selectedRange.getStart() + rangeSpan - 1,
                            mDocumentPageCount - 1);
                    pagesInRange = new PageRange(fromPage, toPage);
                }

                if (DEBUG) {
                    Log.i(LOG_TAG, "computeRequestedPages() Adding range:" + pagesInRange);
                }
                pageRangesList.add(pagesInRange);
                remainingPagesToRequest -= rangeSpan;
            }
        }

        PageRange[] pageRanges = new PageRange[pageRangesList.size()];
        pageRangesList.toArray(pageRanges);

        return PageRangeUtils.normalize(pageRanges);
    }

    private PageRange[] computeBoundPagesInDocument() {
        List<PageRange> pagesInDocumentList = new ArrayList<>();

        int fromPage = INVALID_PAGE_INDEX;
        int toPage = INVALID_PAGE_INDEX;

        final int boundPageCount = mBoundPagesInAdapter.size();
        for (int i = 0; i < boundPageCount; i++) {
            // The container is a sparse array, so keys are sorted in ascending order.
            final int boundPageInAdapter = mBoundPagesInAdapter.keyAt(i);
            final int boundPageInDocument = computePageIndexInDocument(boundPageInAdapter);

            if (fromPage == INVALID_PAGE_INDEX) {
                fromPage = boundPageInDocument;
            }

            if (toPage == INVALID_PAGE_INDEX) {
                toPage = boundPageInDocument;
            }

            if (boundPageInDocument > toPage + 1) {
                PageRange pageRange = new PageRange(fromPage, toPage);
                pagesInDocumentList.add(pageRange);
                fromPage = toPage = boundPageInDocument;
            } else {
                toPage = boundPageInDocument;
            }
        }

        if (fromPage != INVALID_PAGE_INDEX && toPage != INVALID_PAGE_INDEX) {
            PageRange pageRange = new PageRange(fromPage, toPage);
            pagesInDocumentList.add(pageRange);
        }

        PageRange[] pageInDocument = new PageRange[pagesInDocumentList.size()];
        pagesInDocumentList.toArray(pageInDocument);

        if (DEBUG) {
            Log.i(LOG_TAG, "Bound pages: " + Arrays.toString(pageInDocument));
        }

        return pageInDocument;
    }

    private void recyclePageView(PageContentView page, int pageIndexInAdapter) {
        PageContentProvider provider = page.getPageContentProvider();
        if (provider != null) {
            page.init(null, mEmptyState, mErrorState, mMediaSize, mMinMargins);
            mPageContentRepository.releasePageContentProvider(provider);
        }
        mBoundPagesInAdapter.remove(pageIndexInAdapter);
        page.setTag(null);
    }

    public void startPreloadContent(PageRange pageRangeInAdapter) {
        final int startPageInDocument = computePageIndexInDocument(pageRangeInAdapter.getStart());
        final int startPageInFile = computePageIndexInFile(startPageInDocument);
        final int endPageInDocument = computePageIndexInDocument(pageRangeInAdapter.getEnd());
        final int endPageInFile = computePageIndexInFile(endPageInDocument);
        if (startPageInDocument != INVALID_PAGE_INDEX && endPageInDocument != INVALID_PAGE_INDEX) {
            mPageContentRepository.startPreload(startPageInFile, endPageInFile);
        }
    }

    public void stopPreloadContent() {
        mPageContentRepository.stopPreload();
    }

    private void throwIfNotOpened() {
        if (mState != STATE_OPENED) {
            throw new IllegalStateException("Not opened");
        }
    }

    private void throwIfNotClosed() {
        if (mState != STATE_CLOSED) {
            throw new IllegalStateException("Not closed");
        }
    }

    private final class MyViewHolder extends ViewHolder {
        int mPageInAdapter;

        private MyViewHolder(View itemView) {
            super(itemView);
        }
    }

    private final class PageClickListener implements OnClickListener {
        @Override
        public void onClick(View view) {
            PreviewPageFrame page = (PreviewPageFrame) view;
            MyViewHolder holder = (MyViewHolder) page.getTag();
            final int pageInAdapter = holder.mPageInAdapter;
            final int pageInDocument = computePageIndexInDocument(pageInAdapter);
            if (mConfirmedPagesInDocument.indexOfKey(pageInDocument) < 0) {
                mConfirmedPagesInDocument.put(pageInDocument, null);
                page.setSelected(true, true);
            } else {
                if (mConfirmedPagesInDocument.size() <= 1) {
                    return;
                }
                mConfirmedPagesInDocument.remove(pageInDocument);
                page.setSelected(false, true);
            }
        }
    }
}
