/*
 * 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 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);

    // TODO: This shouldn't just return null - maybe it needs to wait for a cursor to be supplied?
    //       See b/7103023
    @Override
    public Fragment getItem(int position) {
        if (mCursor != null && moveCursorTo(position)) {
            return getItem(mContext, mCursor, position);
        }
        return null;
    }

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

    @Override
    public Object instantiateItem(View container, int position) {
        if (mCursor == null) {
            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 mCursor != null;
    }

    /**
     * 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 (mCursor != null && 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 (mCursor != null && 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);
        } else {
            mRowIDColumn = -1;
        }

        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;
        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 (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;
    }
}
