package com.dozuki.ifixit.ui.topic_view;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import com.dozuki.ifixit.ui.BaseSearchMenuDrawerActivity;
import com.dozuki.ifixit.R;
import com.dozuki.ifixit.model.topic.TopicNode;
import com.dozuki.ifixit.ui.LoadingFragment;
import com.dozuki.ifixit.util.api.ApiCall;
import com.dozuki.ifixit.util.api.ApiEvent;
import com.dozuki.ifixit.util.api.Api;
import com.squareup.otto.Subscribe;
public class TopicActivity extends BaseSearchMenuDrawerActivity
implements TopicSelectedListener, FragmentManager.OnBackStackChangedListener {
private static final String ROOT_TOPIC = "ROOT_TOPIC";
private static final String TOPIC_LIST_VISIBLE = "TOPIC_LIST_VISIBLE";
protected static final long TOPIC_LIST_HIDE_DELAY = 1;
private static final String TOPIC_TAG = "TOPIC_TAG";
private static final String TOPIC_LOADING = "TOPIC_LOADING_TAG";
private TopicViewFragment mTopicView;
private FrameLayout mTopicViewOverlay;
private TopicNode mRootTopic;
private int mBackStackSize = 0;
private boolean mDualPane;
private boolean mHideTopicList;
private boolean mTopicListVisible;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.topics);
FrameLayout topicViewContainer = (FrameLayout) findViewById(R.id.topic_view_fragment_container);
mDualPane = topicViewContainer != null;
mTopicViewOverlay = (FrameLayout) findViewById(R.id.topic_view_overlay);
mHideTopicList = mTopicViewOverlay != null;
if (savedInstanceState != null) {
mRootTopic = (TopicNode) savedInstanceState.getSerializable(ROOT_TOPIC);
mTopicListVisible = savedInstanceState.getBoolean(TOPIC_LIST_VISIBLE);
} else {
mTopicListVisible = true;
}
if (mDualPane) {
mTopicView = (TopicViewFragment) getSupportFragmentManager().findFragmentByTag(TOPIC_TAG);
if (mTopicView == null) {
mTopicView = new TopicViewFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.topic_view_fragment_container, mTopicView, TOPIC_TAG)
.commit();
}
}
if (mRootTopic == null) {
showLoading(R.id.topic_list_fragment);
Api.call(this, ApiCall.categories());
}
if (!mTopicListVisible && !mHideTopicList) {
getSupportFragmentManager().popBackStack();
}
if (mTopicView != null && mTopicListVisible && mHideTopicList && mTopicView.isDisplayingTopic()) {
hideTopicListWithDelay();
}
getSupportFragmentManager().addOnBackStackChangedListener(this);
// Reset backstack size
mBackStackSize = -1;
onBackStackChanged();
if (mTopicViewOverlay != null) {
mTopicViewOverlay.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (mTopicListVisible && mTopicView.isDisplayingTopic()) {
hideTopicList();
return true;
} else {
return false;
}
}
});
}
}
@Subscribe
public void onCategories(ApiEvent.Categories event) {
hideLoading();
if (!event.hasError()) {
if (mRootTopic == null) {
mRootTopic = event.getResult();
onTopicSelected(mRootTopic);
}
} else {
Api.getErrorDialog(this, event).show();
}
}
@Subscribe
public void onTopic(ApiEvent.Topic event) {
hideTopicLoading();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable(ROOT_TOPIC, mRootTopic);
outState.putBoolean(TOPIC_LIST_VISIBLE, mTopicListVisible);
}
@Override
public void onBackStackChanged() {
int backStackSize = getSupportFragmentManager().getBackStackEntryCount();
if (mBackStackSize > backStackSize) {
setTopicListVisible();
}
mBackStackSize = backStackSize;
}
@Override
public void onTopicSelected(TopicNode topic) {
if (topic.isLeaf()) {
if (mDualPane) {
showTopicLoading(topic.getDisplayName());
mTopicView.setTopicNode(topic);
if (mHideTopicList) {
hideTopicList();
}
} else {
Intent intent = new Intent(this, TopicViewActivity.class);
Bundle bundle = new Bundle();
bundle.putSerializable(TopicViewActivity.TOPIC_KEY, topic);
intent.putExtras(bundle);
startActivity(intent);
}
} else {
if (mDualPane && !topic.isRoot()) {
showTopicLoading(topic.getDisplayName());
mTopicView.setTopicNode(topic);
}
changeTopicListView(new TopicListFragment(topic), !topic.isRoot());
}
}
protected boolean isDualPane() {
return mDualPane;
}
private void hideTopicList() {
hideTopicList(false);
}
private void hideTopicList(boolean delay) {
mTopicViewOverlay.setVisibility(View.INVISIBLE);
mTopicListVisible = false;
changeTopicListView(new Fragment(), true, delay);
}
private void hideTopicListWithDelay() {
// Delay this slightly to make sure the animation is played.
new Handler().postAtTime(new Runnable() {
public void run() {
hideTopicList(true);
}
}, SystemClock.uptimeMillis() + TOPIC_LIST_HIDE_DELAY);
}
private void setTopicListVisible() {
if (mTopicViewOverlay != null) {
mTopicViewOverlay.setVisibility(View.VISIBLE);
}
mTopicListVisible = true;
}
private void changeTopicListView(Fragment fragment, boolean addToBack) {
changeTopicListView(fragment, addToBack, false);
}
private void changeTopicListView(Fragment fragment, boolean addToBack, boolean delay) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
int inAnim, outAnim;
if (delay) {
inAnim = R.anim.slide_in_right_delay;
outAnim = R.anim.slide_out_left_delay;
} else {
inAnim = R.anim.slide_in_right;
outAnim = R.anim.slide_out_left;
}
ft.setCustomAnimations(inAnim, outAnim,
R.anim.slide_in_left, R.anim.slide_out_right);
ft.replace(R.id.topic_list_fragment, fragment);
if (addToBack) {
ft.addToBackStack(null);
}
// ft.commit();
// commitAllowingStateLoss doesn't throw an exception if commit() is
// run after the fragments parent already saved its state. Possibly
// fixes the IllegalStateException crash in FragmentManagerImpl.checkStateLoss()
ft.commitAllowingStateLoss();
}
/////////////////////////////////////////////////////
// HELPERS
/////////////////////////////////////////////////////
public void showTopicLoading(String topicName) {
mTopicView = (TopicViewFragment) getSupportFragmentManager().findFragmentByTag(TOPIC_TAG);
if (mTopicView != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.hide(mTopicView);
ft.add(R.id.topic_view_fragment_container,
new LoadingFragment(getString(R.string.loading_topic, topicName)), TOPIC_LOADING);
ft.commit();
}
}
public void hideTopicLoading() {
// Do not re-set mTopicView with this fragment reference
Fragment frag = getSupportFragmentManager().findFragmentByTag(TOPIC_TAG);
if (frag != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment loading = getSupportFragmentManager().findFragmentByTag(TOPIC_LOADING);
if (loading != null) {
ft.remove(loading);
}
ft.show(frag);
ft.commit();
}
}
}