package info.guardianproject.securereaderinterface;
import java.util.ArrayList;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.Log;
import android.util.SparseArray;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import info.guardianproject.securereaderinterface.uiutil.AnimationHelpers;
import info.guardianproject.securereaderinterface.uiutil.UIHelpers;
import info.guardianproject.securereaderinterface.views.ExpandingFrameLayout;
import info.guardianproject.securereaderinterface.views.FullScreenStoryItemView;
import info.guardianproject.securereaderinterface.views.ExpandingFrameLayout.ExpansionListener;
import info.guardianproject.securereaderinterface.views.ExpandingFrameLayout.SwipeListener;
import info.guardianproject.securereaderinterface.views.StoryListView.StoryListListener;
import info.guardianproject.securereaderinterface.R;
import com.tinymission.rss.Item;
public class ItemExpandActivity extends FragmentActivityWithMenu implements StoryListListener
{
public static String LOGTAG = "Big Buffalo";
private ExpandingFrameLayout mFullStoryView;
private FullScreenStoryItemView mFullView;
private ListView mFullListStories;
private int mFullOpeningOffset;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
@Override
protected void onResume()
{
super.onResume();
configureActionBarForFullscreen(isInFullScreenMode());
}
@Override
public boolean onPrepareOptionsMenu(Menu menu)
{
boolean ret = super.onPrepareOptionsMenu(menu);
configureActionBarForFullscreen(isInFullScreenMode());
return ret;
}
@Override
public void onStoryClicked(ArrayList<Item> stories, int index, View storyView)
{
if (storyView != null)
openStoryFullscreen(stories, index, (ListView) storyView.getParent(), storyView);
}
public void openStoryFullscreen(ArrayList<Item> stories, int index, ListView listStories, View storyView)
{
FrameLayout screenFrame = getTopFrame();
if (stories != null && screenFrame != null)
{
// Remove old view (if set) from view tree
//
removeFullStoryView();
// Disable drag of the left side menu
//
mLeftSideMenu.setDragEnabled(false);
mFullView = new FullScreenStoryItemView(this);
mFullStoryView = new ExpandingFrameLayout(this, mFullView);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT,
Gravity.LEFT | Gravity.TOP);
// params.topMargin = UIHelpers.getStatusBarHeight(this);
mFullStoryView.setLayoutParams(params);
screenFrame.addView(mFullStoryView);
mFullView.setStory(stories, index, getStoredPositions((ViewGroup) storyView));
this.prepareFullScreenView(mFullView);
mFullListStories = listStories;
// // Get screen position of the story view
int[] locationLv = new int[2];
mFullListStories.getLocationOnScreen(locationLv);
int[] location = new int[2];
if (storyView != null)
storyView.getLocationOnScreen(location);
else
location = locationLv;
// Get from top and bottom
int[] locationTopFrame = new int[2];
screenFrame.getLocationOnScreen(locationTopFrame);
int fromClip = Math.max(0, locationLv[1] - location[1]);
int fromTop = location[1] - locationTopFrame[1] - params.topMargin;
int fromHeight = (storyView != null) ? storyView.getHeight() : listStories.getHeight();
mFullOpeningOffset = location[1] - locationLv[1];
mFullStoryView.setSwipeListener(new SwipeListener()
{
@Override
public void onSwipeUp()
{
// Only once
mFullStoryView.setSwipeListener(null);
exitFullScreenMode();
}
@Override
public void onSwipeDown()
{
mFullStoryView.post(new Runnable()
{
@Override
public void run()
{
mFullStoryView.showActionBar(getSupportActionBar().getHeight());
}
});
}
});
mFullStoryView.setExpansionListener(new ExpansionListener()
{
@Override
public void onExpanded()
{
configureActionBarForFullscreen(true);
// Minimize overdraw by hiding list
mFullListStories.setVisibility(View.INVISIBLE);
}
@Override
public void onCollapsed()
{
removeFullStoryView();
mLeftSideMenu.setDragEnabled(true);
}
});
mFullStoryView.setCollapsedSize(fromClip, fromTop, fromHeight);
}
}
private void getStoredPositionForViewWithId(ViewGroup parent, int viewId, SparseArray<Rect> positions)
{
View view = parent.findViewById(viewId);
if (view != null)
{
Rect rect = UIHelpers.getRectRelativeToView(parent, view);
rect.offset(0, view.getPaddingTop());
rect.bottom -= view.getPaddingBottom();
positions.put(view.getId(), rect);
}
}
private SparseArray<Rect> getStoredPositions(ViewGroup viewGroup)
{
if (viewGroup == null || viewGroup.getChildCount() == 0)
return null;
SparseArray<Rect> positions = new SparseArray<Rect>();
getStoredPositionForViewWithId(viewGroup, R.id.layout_media, positions);
getStoredPositionForViewWithId(viewGroup, R.id.tvTitle, positions);
getStoredPositionForViewWithId(viewGroup, R.id.tvContent, positions);
getStoredPositionForViewWithId(viewGroup, R.id.layout_source, positions);
getStoredPositionForViewWithId(viewGroup, R.id.layout_author, positions);
return positions;
}
protected void prepareFullScreenView(FullScreenStoryItemView fullView)
{
}
private FrameLayout getTopFrame()
{
try
{
FrameLayout parent = (FrameLayout) (((FrameLayout) getWindow().getDecorView()).getChildAt(0));
return parent;
}
catch (Exception ex)
{
Log.e(LOGTAG, "Failed to get top level frame: " + ex.toString());
}
return null;
}
private void removeFullStoryView()
{
if (mFullStoryView != null)
{
try
{
AnimationHelpers.fadeOut(mFullStoryView, 500, 0, true);
mFullStoryView = null;
}
catch (Exception ex)
{
Log.e(LOGTAG, "Failed to remove full story view from view tree: " + ex.toString());
}
}
}
@Override
public void onBackPressed()
{
if (isInFullScreenMode())
{
exitFullScreenMode();
}
else
{
// If the user is not currently in full screen story mode, allow the
// system to handle the
// Back button. This calls finish() on this activity and pops the
// back stack.
super.onBackPressed();
}
}
protected void configureActionBarForFullscreen(boolean b)
{
}
private boolean isInFullScreenMode()
{
return (mFullStoryView != null);
}
@Override
public void onResync()
{
}
@Override
public void onHeaderCreated(View headerView, int resIdHeader)
{
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case android.R.id.home:
if (isInFullScreenMode())
{
exitFullScreenMode();
return true;
}
}
return super.onOptionsItemSelected(item);
}
private void exitFullScreenMode()
{
configureActionBarForFullscreen(false);
// getSupportActionBar().hide();
// getSupportActionBar().show();
mFullStoryView.post(new Runnable()
{
// Reason for post? We need to give the call above
// (configureActionBar...) a chance
// to do all layout changes it needs to do. This is
// because in collapse() below we
// take a snapshot of the screen and need to have valid
// data.
@Override
public void run()
{
scrollToCurrentItem();
updateList();
mFullListStories.post(new Runnable()
{
@Override
public void run()
{
mFullListStories.setVisibility(View.VISIBLE);
if (mFullView != null)
mFullView.onBeforeCollapse();
if (mFullStoryView != null)
mFullStoryView.collapse();
}
});
}
});
}
private void scrollToCurrentItem()
{
// Try to find index of current item, so that we can
// scroll the
// list to the actual story the user was reading
// while in full screen mode.
Item currentItem = mFullView.getCurrentStory();
if (currentItem != null && mFullListStories.getAdapter() != null)
{
ListAdapter adapter = mFullListStories.getAdapter();
for (int iItem = 0; iItem < adapter.getCount(); iItem++)
{
if (adapter.getItemId(iItem) == currentItem.getDatabaseId())
{
mFullListStories.setSelectionFromTop(iItem, mFullOpeningOffset);
break;
}
}
}
}
/**
* Called before we collapse the full screen view. This is to update all
* list view items that are visible. We might have loaded media etc while in
* full screen mode, so we need to pick that up in the list.
*/
private void updateList()
{
if (mFullListStories == null || mFullListStories.getCount() == 0)
return;
if (mFullListStories.getAdapter() != null && mFullListStories.getAdapter() instanceof BaseAdapter)
{
((BaseAdapter) mFullListStories.getAdapter()).notifyDataSetChanged();
}
}
@Override
public void onListViewUpdated(ListView newList)
{
// List view has been recreated (probably due to orientation change).
// Remember the new one!
mFullListStories = newList;
if (isInFullScreenMode() && mFullListStories != null)
mFullListStories.setVisibility(View.INVISIBLE);
}
}