/*
* Copyright (C) 2005-2015 Alfresco Software Limited.
*
* This file is part of Alfresco Mobile for Android.
*
* 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 org.alfresco.mobile.android.application.fragments;
import java.lang.ref.WeakReference;
import org.alfresco.mobile.android.application.R;
import org.alfresco.mobile.android.application.activity.MainActivity;
import org.alfresco.mobile.android.application.fragments.builder.AlfrescoFragmentBuilder;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
public final class FragmentDisplayer
{
// ///////////////////////////////////////////////////////////////////////////
// CONSTANTS
// ///////////////////////////////////////////////////////////////////////////
private static final String TAG = FragmentDisplayer.class.getSimpleName();
protected static final int ACTION_ADD = 0;
protected static final int ACTION_REPLACE = 1;
protected static final int ACTION_REMOVE = 2;
protected static final int ACTION_CLEAN = 3;
public static final int PANEL_LEFT = -100;
public static final int PANEL_CENTRAL = -200;
public static final int PANEL_DIALOG = -300;
// ///////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
// ///////////////////////////////////////////////////////////////////////////
private FragmentDisplayer()
{
}
public static Creator with(FragmentActivity activity)
{
return new Creator(activity);
}
public static Creator load(AlfrescoFragmentBuilder builder)
{
return new Creator(builder);
}
// ///////////////////////////////////////////////////////////////////////////
// UTILITY
// ///////////////////////////////////////////////////////////////////////////
public static void clearCentralPane(FragmentActivity a)
{
if (DisplayUtils.hasCentralPane(a))
{
FragmentDisplayer.with(a).remove(DisplayUtils.getCentralFragmentId(a));
FragmentDisplayer.with(a).remove(android.R.id.tabcontent);
}
}
// ///////////////////////////////////////////////////////////////////////////
// BUILDER
// ///////////////////////////////////////////////////////////////////////////
public static final int[] SLIDE = new int[] { R.anim.anim_slide_in_right, R.anim.anim_slide_out_left,
R.anim.anim_slide_in_left, R.anim.anim_slide_out_right };
public static class Creator
{
private int action;
private AlfrescoFragmentBuilder builder;
private int targetId;
private WeakReference<FragmentActivity> activity;
private WeakReference<Fragment> fragmentRef;
private boolean backStack = true;
private int[] animation = SLIDE;
private String tag;
private boolean hasAnimation = true;
// ///////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
// ///////////////////////////////////////////////////////////////////////////
protected Creator()
{
}
public Creator(AlfrescoFragmentBuilder builder)
{
this();
this.activity = new WeakReference<>(builder.getActivity());
this.builder = builder;
this.action = ACTION_REPLACE;
this.backStack = builder.hasBackStack();
}
public Creator(FragmentActivity activity)
{
this();
this.activity = new WeakReference<>(activity);
}
// ///////////////////////////////////////////////////////////////////////////
// SETTERS
// ///////////////////////////////////////////////////////////////////////////
public Creator back(boolean hasBackStack)
{
this.backStack = hasBackStack;
return this;
}
public Creator load(Fragment frag)
{
this.fragmentRef = new WeakReference<Fragment>(frag);
this.action = ACTION_ADD;
return this;
}
public Creator replace(Fragment frag)
{
this.fragmentRef = new WeakReference<Fragment>(frag);
this.action = ACTION_REPLACE;
return this;
}
public Creator animate(int[] animation)
{
this.animation = animation;
if (animation == null)
{
hasAnimation = false;
}
return this;
}
public Creator removeAll()
{
this.action = ACTION_CLEAN;
hasAnimation = false;
return this;
}
// ///////////////////////////////////////////////////////////////////////////
// EXECUTION
// ///////////////////////////////////////////////////////////////////////////
public void into(int targetId)
{
this.targetId = targetId;
execute();
}
public void asDialog()
{
this.targetId = PANEL_DIALOG;
execute();
}
public void remove(Fragment fr)
{
try
{
this.fragmentRef = new WeakReference<Fragment>(fr);
this.action = ACTION_REMOVE;
this.backStack = false;
execute();
}
catch (Exception e)
{
// Specific use case in Honeycomb. Sometimes the fragment has
// not been added and we must force the add.
FragmentTransaction t2 = activity.get().getSupportFragmentManager().beginTransaction();
t2.add(fr, fr.getTag());
t2.remove(fr);
t2.commit();
}
}
public void remove(String fragmentTag)
{
remove(activity.get().getSupportFragmentManager().findFragmentByTag(fragmentTag));
}
public void remove(int viewId)
{
remove(activity.get().getSupportFragmentManager().findFragmentById(viewId));
}
// ///////////////////////////////////////////////////////////////////////////
// Creation
// ///////////////////////////////////////////////////////////////////////////
private void execute()
{
try
{
if (activity.get() instanceof MainActivity && DisplayUtils.hasCentralPane(activity.get())
&& targetId == PANEL_LEFT)
{
FragmentDisplayer.clearCentralPane(activity.get());
}
Fragment frag = null;
// Create Fragment
if (builder != null)
{
frag = builder.createFragment();
}
else if (fragmentRef != null)
{
frag = fragmentRef.get();
}
// If null we consider the fragment creation is done elsewhere.
if (frag == null) { return; }
// Create Tag based on Fragment className
tag = frag.getClass().getName();
//Special case : Show as Dialog
if (PANEL_DIALOG == targetId)
{
if (frag instanceof DialogFragment)
{
((DialogFragment) frag).show(activity.get().getSupportFragmentManager(), tag);
}
return;
}
// Create Transaction
FragmentTransaction transaction = activity.get().getSupportFragmentManager().beginTransaction();
// Set Animation
if (hasAnimation)
{
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB_MR2
&& android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH)
{
transaction.setCustomAnimations(animation[0], animation[1]);
}
else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH)
{
transaction.setCustomAnimations(animation[0], animation[1], animation[2], animation[3]);
}
}
// Define target
switch (targetId)
{
case PANEL_LEFT:
targetId = DisplayUtils.getLeftFragmentId(activity.get());
break;
case PANEL_CENTRAL:
targetId = DisplayUtils.getFragmentPlace(activity.get());
break;
default:
break;
}
switch (action)
{
case ACTION_ADD:
transaction.add(targetId, frag, tag);
break;
case ACTION_REPLACE:
transaction.replace(targetId, frag, tag);
break;
case ACTION_REMOVE:
hasAnimation = false;
transaction.remove(frag);
break;
case ACTION_CLEAN:
break;
default:
break;
}
// BackStack
if (backStack)
{
transaction.addToBackStack(tag);
}
// Commit
transaction.commit();
}
catch (Exception e)
{
Log.w(TAG, Log.getStackTraceString(e));
}
}
}
}