/*
 * Copyright (C) 2011 Google Inc.
 * Licensed to 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.ex.photo.adapters;

import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Context;
import android.database.Cursor;
import android.util.Log;
import android.util.SparseIntArray;
import android.view.View;

import com.android.ex.photo.provider.PhotoContract;

import java.util.HashMap;

/**
 * Page adapter for use with an BaseCursorLoader. Unlike other cursor adapters, this has no
 * observers for automatic refresh. Instead, it depends upon external mechanisms to provide
 * the update signal.
 */
public abstract class BaseCursorPagerAdapter extends BaseFragmentPagerAdapter {
    private static final String TAG = "BaseCursorPagerAdapter";

    Context mContext;
    private boolean mDataValid;
    private Cursor mCursor;
    private int mRowIDColumn;
    /** Mapping of row ID to cursor position */
    private SparseIntArray mItemPosition;
    /** Mapping of instantiated object to row ID */
    private HashMap<Object, Integer> mObjectRowMap = new HashMap<Object, Integer>();

    /**
     * Constructor that always enables auto-requery.
     *
     * @param c The cursor from which to get the data.
     * @param context The context
     */
    public BaseCursorPagerAdapter(Context context, FragmentManager fm, Cursor c) {
        super(fm);
        init(context, c);
    }

    /**
     * Makes a fragment for the data pointed to by the cursor
     *
     * @param context Interface to application's global information
     * @param cursor The cursor from which to get the data. The cursor is already
     * moved to the correct position.
     * @return the newly created fragment.
     */
    public abstract Fragment getItem(Context context, Cursor cursor, int position);

    @Override
    public Fragment getItem(int position) {
        if (mDataValid && moveCursorTo(position)) {
            return getItem(mContext, mCursor, position);
        }
        return null;
    }

    @Override
    public int getCount() {
        if (mDataValid && mCursor != null) {
            return mCursor.getCount();
        } else {
            return 0;
        }
    }

    @Override
    public Object instantiateItem(View container, int position) {
        if (!mDataValid) {
            throw new IllegalStateException("this should only be called when the cursor is valid");
        }

        final Integer rowId;
        if (moveCursorTo(position)) {
            rowId = mCursor.getString(mRowIDColumn).hashCode();
        } else {
            rowId = null;
        }

        // Create the fragment and bind cursor data
        final Object obj = super.instantiateItem(container, position);
        if (obj != null) {
            mObjectRowMap.put(obj, rowId);
        }
        return obj;
    }

    @Override
    public void destroyItem(View container, int position, Object object) {
        mObjectRowMap.remove(object);

        super.destroyItem(container, position, object);
    }

    @Override
    public int getItemPosition(Object object) {
        final Integer rowId = mObjectRowMap.get(object);
        if (rowId == null || mItemPosition == null) {
            return POSITION_NONE;
        }

        final int position = mItemPosition.get(rowId, POSITION_NONE);
        return position;
    }

    /**
     * @return true if data is valid
     */
    public boolean isDataValid() {
        return mDataValid;
    }

    /**
     * Returns the cursor.
     */
    public Cursor getCursor() {
        return mCursor;
    }

    /**
     * Returns the data item associated with the specified position in the data set.
     */
    public Object getDataItem(int position) {
        if (mDataValid && moveCursorTo(position)) {
            return mCursor;
        } else {
            return null;
        }
    }

    /**
     * Returns the row id associated with the specified position in the list.
     */
    public long getItemId(int position) {
        if (mDataValid && moveCursorTo(position)) {
            return mCursor.getString(mRowIDColumn).hashCode();
        } else {
            return 0;
        }
    }

    /**
     * Swap in a new Cursor, returning the old Cursor.
     *
     * @param newCursor The new cursor to be used.
     * @return Returns the previously set Cursor, or null if there was not one.
     * If the given new Cursor is the same instance is the previously set
     * Cursor, null is also returned.
     */
    public Cursor swapCursor(Cursor newCursor) {
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            Log.v(TAG, "swapCursor old=" + (mCursor == null ? -1 : mCursor.getCount()) +
                    "; new=" + (newCursor == null ? -1 : newCursor.getCount()));
        }

        if (newCursor == mCursor) {
            return null;
        }
        Cursor oldCursor = mCursor;
        mCursor = newCursor;
        if (newCursor != null) {
            mRowIDColumn = newCursor.getColumnIndex(PhotoContract.PhotoViewColumns.URI);
            mDataValid = true;
        } else {
            mRowIDColumn = -1;
            mDataValid = false;
        }

        setItemPosition();
        notifyDataSetChanged();     // notify the observers about the new cursor
        return oldCursor;
    }

    /**
     * Converts the cursor into a CharSequence. Subclasses should override this
     * method to convert their results. The default implementation returns an
     * empty String for null values or the default String representation of
     * the value.
     *
     * @param cursor the cursor to convert to a CharSequence
     * @return a CharSequence representing the value
     */
    public CharSequence convertToString(Cursor cursor) {
        return cursor == null ? "" : cursor.toString();
    }

    @Override
    protected String makeFragmentName(int viewId, int index) {
        if (moveCursorTo(index)) {
            return "android:pager:" + viewId + ":" + mCursor.getString(mRowIDColumn).hashCode();
        } else {
            return super.makeFragmentName(viewId, index);
        }
    }

    /**
     * Moves the cursor to the given position
     *
     * @return {@code true} if the cursor's position was set. Otherwise, {@code false}.
     */
    private boolean moveCursorTo(int position) {
        if (mCursor != null && !mCursor.isClosed()) {
            return mCursor.moveToPosition(position);
        }
        return false;
    }

    /**
     * Initialize the adapter.
     */
    private void init(Context context, Cursor c) {
        boolean cursorPresent = c != null;
        mCursor = c;
        mDataValid = cursorPresent;
        mContext = context;
        mRowIDColumn = cursorPresent
                ? mCursor.getColumnIndex(PhotoContract.PhotoViewColumns.URI) : -1;
    }

    /**
     * Sets the {@link #mItemPosition} instance variable with the current mapping of
     * row id to cursor position.
     */
    private void setItemPosition() {
        if (!mDataValid || mCursor == null || mCursor.isClosed()) {
            mItemPosition = null;
            return;
        }

        SparseIntArray itemPosition = new SparseIntArray(mCursor.getCount());

        mCursor.moveToPosition(-1);
        while (mCursor.moveToNext()) {
            final int rowId = mCursor.getString(mRowIDColumn).hashCode();
            final int position = mCursor.getPosition();

            itemPosition.append(rowId, position);
        }
        mItemPosition = itemPosition;
    }
}
