package app.create.rpg;
import java.util.ArrayList;
import java.util.Iterator;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.app.Fragment.SavedState;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBar.Tab;
import android.support.v7.app.ActionBar.TabListener;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.view.ViewGroup;
public class CustomPagerAdapter extends PagerAdapter implements OnPageChangeListener, TabListener {
public abstract static class FragmentCreator implements Parcelable {
long id;
public FragmentCreator() { }
public FragmentCreator(Parcel source) { }
public abstract Fragment newInstance (Context context);
public abstract String getTitle (Context context);
public abstract Class<?> getFragmentClass ();
public boolean isFromThis (Fragment frag) { return getFragmentClass().equals(frag.getClass()); } // No subclass, must match exactly
@Override public int describeContents() { return 0; }
@Override public void writeToParcel(Parcel dest, int flags) { }
public static final Creator<FragmentCreator> CREATOR = null;
}
private final FragmentManager mFragmentManager;
private final ViewPager mViewPager;
private final ActionBar mActionBar;
private final FragmentEmpty mEmptyPage;
private FragmentTransaction mCurTransaction = null;
private ArrayList<Object> mCache = new ArrayList<Object>();
private ArrayList<FragmentCreator> mCreators = new ArrayList<FragmentCreator>();
private Fragment mCurrentPrimaryItem = null;
public CustomPagerAdapter(ActionBarActivity act) {
mFragmentManager = act.getSupportFragmentManager();
mActionBar = act.getSupportActionBar();
mEmptyPage = new FragmentEmpty();
mViewPager = (ViewPager) act.findViewById(R.id.viewPager);
mViewPager.setOnPageChangeListener(this);
mViewPager.setAdapter(this);
}
public void addPage (final FragmentCreator info, boolean bSelect) {
int i = 0;
for (Iterator<FragmentCreator> it = mCreators.iterator(); it.hasNext(); ++i) {
FragmentCreator item = it.next();
if (item.equals(info)) {
if (!bSelect) return;
mViewPager.setCurrentItem(i);
if (mActionBar.getSelectedNavigationIndex() != i)
mActionBar.setSelectedNavigationItem(i);
return;
}
}
mCreators.add(info);
mCache.add(null);
notifyDataSetChanged();
mActionBar.addTab(mActionBar.newTab()
.setTag(info)
.setTabListener(CustomPagerAdapter.this)
.setText(info.getTitle(mViewPager.getContext())), bSelect);
}
public void removePage (final FragmentCreator info) {
int idx = mCreators.indexOf(info);
if (idx == -1) return;
mCreators.remove(idx);
mCache.remove(idx);
notifyDataSetChanged();
mActionBar.removeTabAt(idx);
}
public void removePage (final Fragment frag) {
int idx = mCache.indexOf(frag);
if (idx == -1) return;
mCreators.remove(idx);
mCache.remove(idx);
notifyDataSetChanged();
mActionBar.removeTabAt(idx);
}
public Fragment getFragmentByCreator (FragmentCreator creator) {
int i = mCreators.indexOf(creator);
if (i < 0) return null;
Object o = mCache.get(i);
if (o instanceof Fragment) return (Fragment) o;
return null;
}
public Fragment getItem(int position) {
if (mCreators.isEmpty())
return mEmptyPage;
return mCreators.get(position).newInstance(mViewPager.getContext());
}
@Override
public int getCount() {
return mCreators.isEmpty() ? 1 : mCreators.size();
}
@Override
public int getItemPosition(Object object) {
if (mCreators.isEmpty() && !object.equals(mEmptyPage))
return POSITION_NONE;
int i = 0;
for (Iterator<FragmentCreator> it = mCreators.iterator(); it.hasNext(); ++i) {
if (it.next().getFragmentClass().equals(object.getClass()))
return i;
}
return POSITION_NONE;
}
@Override
public void onTabReselected(final Tab tab, FragmentTransaction ft) {
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_POSITIVE) {
removePage((FragmentCreator) tab.getTag());
notifyDataSetChanged();
}
}
};
new AlertDialog.Builder(mViewPager.getContext())
.setMessage(R.string.str_ask_close_page)
.setNegativeButton(android.R.string.no, listener)
.setPositiveButton(android.R.string.yes, listener)
.show();
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if (mViewPager.getCurrentItem() != tab.getPosition())
mViewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) { }
@Override
public void onPageScrollStateChanged(int arg0) { }
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) { }
@Override
public void onPageSelected(int arg0) {
if (mActionBar.getSelectedNavigationIndex() != arg0)
mActionBar.setSelectedNavigationItem(arg0);
}
@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
Bundle bundle = (Bundle) arg0;
bundle.setClassLoader(arg1);
int i = 0, s = mViewPager.getCurrentItem();
mCreators = bundle.getParcelableArrayList("creators");
mCache.clear();
mCache.addAll(bundle.getParcelableArrayList("states"));
notifyDataSetChanged();
mActionBar.removeAllTabs();
for (FragmentCreator item : mCreators) {
mActionBar.addTab(mActionBar.newTab()
.setTag(item).setTabListener(this).setText(item.getTitle(mViewPager.getContext()))
, i++ == s);
}
}
@Override
public Parcelable saveState() {
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("creators", mCreators);
int c = mCache.size();
ArrayList<Parcelable> state = new ArrayList<Parcelable>(c);
for (int i = 0; i < c; ++i) {
Object o = mCache.get(i);
if (o instanceof Fragment)
o = mFragmentManager.saveFragmentInstanceState((Fragment) o);
state.add((Parcelable) o);
}
bundle.putParcelableArrayList("states", state);
return bundle;
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return ((Fragment) arg1).getView() == arg0;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
if (mCurTransaction == null)
mCurTransaction = mFragmentManager.beginTransaction();
if (object.equals(mEmptyPage)) {
// Yeah, that's the empty indicator
mCurTransaction.remove(mEmptyPage);
return;
}
// Convert my fragment into just a state xD
if (mCreators.size() > position && mCreators.get(position).getFragmentClass().equals(object))
mCache.set(position, mFragmentManager.saveFragmentInstanceState((Fragment) object));
// Remove it
mCurTransaction.remove((Fragment) object);
}
@Override
public void finishUpdate(ViewGroup container) {
if (mCurTransaction != null) {
mCurTransaction.commitAllowingStateLoss();
mCurTransaction = null;
mFragmentManager.executePendingTransactions();
}
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
if (mCreators.isEmpty()) {
// This is empty so just add a page
if (!mEmptyPage.isAdded()) {
if (mCurTransaction == null)
mCurTransaction = mFragmentManager.beginTransaction();
mCurTransaction.add(container.getId(), mEmptyPage);
}
return mEmptyPage;
}
Object cache = null;
if (mCache.size() > position) {
cache = mCache.get(position);
if (cache instanceof Fragment) {
// We already have instantiated this fragment, so just return it
return cache;
}
}
if (mCurTransaction == null)
mCurTransaction = mFragmentManager.beginTransaction();
Fragment frag = getItem(position); // New fragment!
if (cache instanceof SavedState) { // Let's restore its state!
frag.setInitialSavedState((SavedState) cache);
}
// Now save the frag into the cache!
while (mCache.size() <= position) mCache.add(null);
frag.setMenuVisibility(false);
mCurTransaction.add(container.getId(), frag);
mCache.set(position, frag);
return frag;
}
@Override
public void setPrimaryItem(ViewGroup 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;
}
}
}