package me.barrasso.android.volume.activities;
// Java Packages
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
// Android Packages
import android.app.ActionBar;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.os.Bundle;
import android.app.Activity;
import android.app.Fragment;
import android.support.v4.view.ViewPager;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.method.LinkMovementMethod;
import android.util.DisplayMetrics;
import android.view.*;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import com.jakewharton.salvage.RecyclingPagerAdapter;
import me.barrasso.android.volume.R;
import me.barrasso.android.volume.ui.TypefaceSpan;
import static me.barrasso.android.volume.LogUtils.LOGD;
/**
* Horizontally scrolling, paginated list of pictures and descriptions
* designed to assist the user in using this application. It uses
* Jake Wharton's {@link RecyclingPagerAdapter} to be more efficient
* (recycle {@link View}s) and to avoid {@link Fragment} creation.
*/
public final class HelpActivity extends Activity
implements ViewPager.OnPageChangeListener {
public static final String TAG = HelpActivity.class.getSimpleName();
private static final String KEY_POSITION = TAG + ":POSITION";
private HelpFragmentAdapter mAdapter = null;
private ViewPager mPager = null;
private MenuItem mDoneItem = null;
/** Makes an {@link Activity} a "popup" like a {@link Dialog}. */
public static void popup(final Activity mAct) {
if (null == mAct) return;
final Resources aRes = mAct.getResources();
if (null == aRes) return;
DisplayMetrics dm = new DisplayMetrics();
WindowManager wm = (WindowManager) mAct.getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(dm);
final int[] mWindowDims = new int[] { dm.widthPixels, dm.heightPixels };
final int mMaxWidth = aRes.getDimensionPixelSize(R.dimen.max_menu_width),
mGutter = aRes.getDimensionPixelSize(R.dimen.activity_horizontal_margin);
final boolean isBounded = (mWindowDims[0] > mMaxWidth);
mAct.requestWindowFeature(Window.FEATURE_ACTION_BAR);
mAct.requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
final Window mWindow = mAct.getWindow();
mWindow.setFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND,
WindowManager.LayoutParams.FLAG_DIM_BEHIND);
// Now get our attributes and make the window dim it's background.
final WindowManager.LayoutParams params = mWindow.getAttributes();
params.alpha = 1.0f;
params.dimAmount = 0.5f;
// Bound the height and barHeight for this overlay.
if (isBounded) {
params.width = mMaxWidth + (4 * mGutter);
// Bound to the maximum of a square.
if (mWindowDims[1] > params.width) {
params.height = params.width;
} else {
params.height = (int) (0.81f * mWindowDims[1]);
}
}
mWindow.setAttributes(params);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
popup(this);
mPager = new ViewPager(this);
mPager.setId(R.id.pager);
setContentView(mPager);
// Set up our ActionBar
final ActionBar mAB = getActionBar();
if (null != mAB) {
// Create a Spannable for a custom font face in the title.
SpannableString title = new SpannableString(getString(R.string.welcome_to));
title.setSpan(new TypefaceSpan(this, "TimeBurner_Regular.ttf"), 0, title.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
mAB.setTitle(title);
mAB.setDisplayShowTitleEnabled(true);
mAB.setDisplayHomeAsUpEnabled(true);
}
// Set our Adapter for the Pager.
mAdapter = new HelpFragmentAdapter(this);
mPager.setAdapter(mAdapter);
// We have to add the listener here, because CirclePageIndicator
// uses the default listener to know when to change state.
mPager.setOnPageChangeListener(this);
// Save the last/ current item.
if (savedInstanceState != null && savedInstanceState.containsKey(KEY_POSITION)) {
mPager.setCurrentItem(savedInstanceState.getInt(KEY_POSITION));
}
}
@Override
public void onPageScrollStateChanged(int state) { }
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { }
@Override
public void onPageSelected(int position) {
LOGD(TAG, "position=" + String.valueOf(position) + '.');
setDoneVisible(position);
}
private void setDoneVisible(final int position) {
if (mDoneItem != null) {
mDoneItem.setVisible((mAdapter != null && position == (mAdapter.getCount()-1)));
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putInt(KEY_POSITION, mPager.getCurrentItem());
super.onSaveInstanceState(outState);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Load our menu...
final MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.help, menu);
mDoneItem = menu.findItem(R.id.menu_done);
// If we have our ViewPager all set, update the "Done"
// button based on its current position.
if (mPager != null) {
setDoneVisible(mPager.getCurrentItem());
}
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.menu_done:
case android.R.id.home: {
super.onBackPressed();
return true;
}
}
return super.onOptionsItemSelected(item);
}
// Super-simple ViewHolder to store references as needed.
private static final class ViewHolder {
final TextView mText;
public ViewHolder(View view) {
mText = (TextView) view.findViewById(R.id.help_text);
}
}
/**
* {@link FragmentPagerAdapter} for {@link HelpFragment}s, to create an efficient,
* paginated help interface.
*/
private static final class HelpFragmentAdapter extends RecyclingPagerAdapter {
private final ArrayList<Entry<CharSequence, Integer>> mItems;
private final Context mContext;
public HelpFragmentAdapter(Context mContext) {
this.mContext = mContext;
final Map<CharSequence, Integer> mMappedItems = new LinkedHashMap<CharSequence, Integer>();
final Resources res = mContext.getResources();
final CharSequence[] mDescriptions = res.getTextArray(0);//R.array.help_descriptions);
final TypedArray mImages = res.obtainTypedArray(0);//R.array.help_images);
// Add items to our HashMap.
if (mDescriptions.length == mImages.length()) {
for (int i = 0; i < mDescriptions.length; ++i) {
mMappedItems.put(mDescriptions[i], mImages.getResourceId(i, 0));
}
}
mImages.recycle();
mItems = (new ArrayList<Entry<CharSequence, Integer>>(mMappedItems.entrySet()));
}
@Override
public View getView(int position, View view, ViewGroup container) {
ViewHolder mHolder;
if (view != null) {
mHolder = (ViewHolder) view.getTag();
} else {
view = makeLayout();
mHolder = new ViewHolder(view);
view.setTag(mHolder);
}
// Get the key and value from our LinkedHashMap.
final Entry<CharSequence, Integer> mEntry = mItems.get(position);
final CharSequence mMessage = mEntry.getKey();
final int mImageRes = mEntry.getValue();
// Set the values from our ViewHolder.
mHolder.mText.setText(((mMessage instanceof String) ? Html.fromHtml((String) mMessage) : mMessage));
if (mImageRes != R.id.help_text && mImageRes != 0) {
mHolder.mText.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, mImageRes);
}
return view;
}
/**
* Generates our layout in-code. Only called once, then
* we'll be sure to recycle these {@link View}s.
*/
public final View makeLayout() {
// Layout Parameters.
DisplayMetrics dm = new DisplayMetrics();
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(dm);
final int[] mWindowDims = new int[] { dm.widthPixels, dm.heightPixels };
final int mWindowWidth = mWindowDims[0],
mMaxWidth = mContext.getResources().getDimensionPixelSize(R.dimen.max_menu_width);
final int gutter = mContext.getResources().getDimensionPixelSize(R.dimen.activity_horizontal_margin);
final FrameLayout.LayoutParams mParams = new FrameLayout.LayoutParams(
((mWindowWidth > mMaxWidth) ? mMaxWidth : android.view.ViewGroup.LayoutParams.MATCH_PARENT),
android.view.ViewGroup.LayoutParams.MATCH_PARENT);
final RelativeLayout.LayoutParams mTextParams = new RelativeLayout.LayoutParams(
android.view.ViewGroup.LayoutParams.MATCH_PARENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
mTextParams.addRule(RelativeLayout.CENTER_IN_PARENT);
mParams.gravity = Gravity.CENTER;
// Main text and image.
final TextView text = new TextView(mContext);
text.setTextColor(Color.DKGRAY);
text.setId(R.id.help_text);
text.setLayoutParams(mTextParams);
text.setGravity(Gravity.CENTER_HORIZONTAL);
text.setMovementMethod(LinkMovementMethod.getInstance());
text.setLinksClickable(true);
final int mTextSize = mContext.getResources()
.getDimensionPixelSize(R.dimen.help_text_size);
text.setTextSize(mTextSize);
text.setCompoundDrawablePadding((gutter/2));
text.setPadding(gutter, gutter, gutter, gutter);
// Allow the View to Scroll vertically if necessary.
final ScrollView scroll = new ScrollView(mContext);
scroll.setLayoutParams(mParams);
scroll.setFillViewport(true);
scroll.setSmoothScrollingEnabled(true);
scroll.setVerticalScrollBarEnabled(false);
final RelativeLayout layout = new RelativeLayout(mContext);
mParams.topMargin = mParams.bottomMargin = mContext.getResources().getDimensionPixelSize(R.dimen.activity_vertical_margin);
mParams.leftMargin = mParams.rightMargin = mContext.getResources().getDimensionPixelSize(R.dimen.activity_horizontal_margin);
layout.setLayoutParams(mParams);
layout.addView(text);
scroll.addView(layout);
return scroll;
}
@Override
public int getCount() {
return mItems.size();
}
}
}