/*
 * 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.app.FragmentTransaction;
import android.os.Parcelable;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.util.Log;
import android.util.LruCache;
import android.view.View;

/**
 * NOTE: This is a direct copy of {@link FragmentPagerAdapter} with four very important
 * modifications.
 * <p>
 * <ol>
 * <li>The method {@link #makeFragmentName(int, int)} is declared "protected"
 * in our class. We need to be able to re-define the fragment's name according to data
 * only available to sub-classes.</li>
 * <li>The method {@link #isViewFromObject(View, Object)} has been reimplemented to search
 * the entire view hierarchy for the given view.</li>
 * <li>In method {@link #destroyItem(View, int, Object)}, the fragment is detached and
 * added to a cache. If the fragment is evicted from the cache, it will be deleted.
 * An album may contain thousands of photos and we want to avoid having thousands of
 * fragments.</li>
 * </ol>
 */
public abstract class BaseFragmentPagerAdapter extends PagerAdapter {
    /** The default size of {@link #mFragmentCache} */
    private static final int DEFAULT_CACHE_SIZE = 5;
    private static final String TAG = "FragmentPagerAdapter";
    private static final boolean DEBUG = false;

    private final FragmentManager mFragmentManager;
    private FragmentTransaction mCurTransaction = null;
    private Fragment mCurrentPrimaryItem = null;
    /** A cache to store detached fragments before they are removed  */
    private LruCache<String, Fragment> mFragmentCache = new FragmentCache(DEFAULT_CACHE_SIZE);

    public BaseFragmentPagerAdapter(FragmentManager fm) {
        mFragmentManager = fm;
    }

    /**
     * Return the Fragment associated with a specified position.
     */
    public abstract Fragment getItem(int position);

    @Override
    public void startUpdate(View container) {
    }

    @Override
    public Object instantiateItem(View container, int position) {
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }

        // Do we already have this fragment?
        String name = makeFragmentName(container.getId(), position);

        // Remove item from the cache
        mFragmentCache.remove(name);

        Fragment fragment = mFragmentManager.findFragmentByTag(name);
        if (fragment != null) {
            if (DEBUG) Log.v(TAG, "Attaching item #" + position + ": f=" + fragment);
            mCurTransaction.attach(fragment);
        } else {
            fragment = getItem(position);
            if(fragment == null) {
                if (DEBUG) Log.e(TAG, "NPE workaround for getItem(). See b/7103023");
                return null;
            }
            if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment);
            mCurTransaction.add(container.getId(), fragment,
                    makeFragmentName(container.getId(), position));
        }
        if (fragment != mCurrentPrimaryItem) {
            fragment.setMenuVisibility(false);
        }

        return fragment;
    }

    @Override
    public void destroyItem(View container, int position, Object object) {
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }
        if (DEBUG) Log.v(TAG, "Detaching item #" + position + ": f=" + object
                + " v=" + ((Fragment)object).getView());

        Fragment fragment = (Fragment) object;
        String name = fragment.getTag();
        if (name == null) {
            // We prefer to get the name directly from the fragment, but, if the fragment is
            // detached before the add transaction is committed, this could be 'null'. In
            // that case, generate a name so we can still cache the fragment.
            name = makeFragmentName(container.getId(), position);
        }

        mFragmentCache.put(name, fragment);
        mCurTransaction.detach(fragment);
    }

    @Override
    public void setPrimaryItem(View container, int position, Object object) {
        Fragment fragment = (Fragment) object;
        if (fragment != mCurrentPrimaryItem) {
            if (mCurrentPrimaryItem != null) {
                mCurrentPrimaryItem.setMenuVisibility(false);
            }
            if (fragment != null) {
                fragment.setMenuVisibility(true);
            }
            mCurrentPrimaryItem = fragment;
        }

    }

    @Override
    public void finishUpdate(View container) {
        if (mCurTransaction != null) {
            mCurTransaction.commitAllowingStateLoss();
            mCurTransaction = null;
            mFragmentManager.executePendingTransactions();
        }
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        // Ascend the tree to determine if the view is a child of the fragment
        View root = ((Fragment) object).getView();
        for (Object v = view; v instanceof View; v = ((View) v).getParent()) {
            if (v == root) {
                return true;
            }
        }
        return false;
    }

    @Override
    public Parcelable saveState() {
        return null;
    }

    @Override
    public void restoreState(Parcelable state, ClassLoader loader) {
    }

    /** Creates a name for the fragment */
    protected String makeFragmentName(int viewId, int index) {
        return "android:switcher:" + viewId + ":" + index;
    }

    /**
     * A cache of detached fragments.
     */
    private class FragmentCache extends LruCache<String, Fragment> {
        public FragmentCache(int size) {
            super(size);
        }

        @Override
        protected void entryRemoved(boolean evicted, String key,
                Fragment oldValue, Fragment newValue) {
            // remove the fragment if it's evicted OR it's replaced by a new fragment
            if (evicted || (newValue != null && oldValue != newValue)) {
                mCurTransaction.remove(oldValue);
            }
        }
    }
}
