/*
* Licensed Materials - Property of IBM
* © Copyright IBM Corporation 2015. All Rights Reserved.
*/
package com.ibm.mil.readyapps.telco.activities;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.NotificationCompat;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.ibm.mil.cafejava.CafeJava;
import com.ibm.mil.readyapps.telco.BuildConfig;
import com.ibm.mil.readyapps.telco.R;
import com.ibm.mil.readyapps.telco.analytics.AnalyticsCnsts;
import com.ibm.mil.readyapps.telco.analytics.GestureListener;
import com.ibm.mil.readyapps.telco.analytics.NavTracker;
import com.ibm.mil.readyapps.telco.baseplan.BasePlan;
import com.ibm.mil.readyapps.telco.baseplan.BasePlanModelImpl;
import com.ibm.mil.readyapps.telco.hotspots.HotSpotActivity;
import com.ibm.mil.readyapps.telco.mydata.DataFragment;
import com.ibm.mil.readyapps.telco.myplan.MyPlanFragment;
import com.ibm.mil.readyapps.telco.myplan.MyPlanPresenter;
import com.ibm.mil.readyapps.telco.mytalk.TalkFragment;
import com.ibm.mil.readyapps.telco.mytext.TextFragment;
import com.ibm.mil.readyapps.telco.offers.Offer;
import com.ibm.mil.readyapps.telco.onboarding.OnboardingActivity;
import com.ibm.mil.readyapps.telco.recharge.RechargeActivity;
import com.ibm.mil.readyapps.telco.utils.Currency;
import com.ibm.mil.readyapps.telco.utils.FontCache;
import com.ibm.mil.readyapps.telco.utils.PlanConstants;
import com.ibm.mil.readyapps.telco.utils.TelcoChallengeHandler;
import com.ibm.mil.readyapps.telco.utils.TwitterHelper;
import com.ibm.mqa.MQA;
import com.ibm.mqa.config.Configuration;
import com.twitter.sdk.android.core.identity.TwitterAuthClient;
import com.worklight.common.WLAnalytics;
import com.worklight.wlclient.api.WLClient;
import com.worklight.wlclient.api.WLResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import butterknife.ButterKnife;
import butterknife.Bind;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
import rx.subjects.PublishSubject;
/**
* Main landing Activity of app that contains all the tab bar fragments.
*/
@SuppressWarnings("unused")
public class MainActivity extends AppCompatActivity implements TabLayout.OnTabSelectedListener {
public static Context context;
public static final int MY_PLAN = 0;
private static final String TAG = MainActivity.class.getName();
private static final int DATA = 1;
private static final int TALK = 2;
private static final int TEXT = 3;
private GestureDetectorCompat detector;
public static final PublishSubject<Integer> tabChangeStream = PublishSubject.create();
List<ImageView> tabImages;
@Bind(R.id.toolbar) Toolbar toolbar;
@Bind(R.id.tab_layout) TabLayout tabLayout;
@Bind(R.id.view_pager) ViewPager viewPager;
@Bind(R.id.main_activity_fab) FloatingActionButton floatingActionButton;
@Bind(R.id.current_plan_total) TextView currentPlanTotal;
@Bind(R.id.plan_tab_image) ImageView planTabImage;
@Bind(R.id.data_tab_image) ImageView dataTabImage;
@Bind(R.id.talk_tab_image) ImageView talkTabImage;
@Bind(R.id.text_tab_image) ImageView textTabImage;
private MyPlanPresenter myPlanPresenter;
private Intent rechargeIntent;
private TwitterAuthClient twitterAuthClient;
private ViewPagerAdapter pagerAdapter;
/**
* Responsible for setting up tab layout with fragments
* and other various setup tasks.
*
* @param savedInstanceState previous state of activity
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
detector = new GestureDetectorCompat(this, new GestureListener());
ButterKnife.bind(this);
setSupportActionBar(toolbar);
tabImages = Arrays.asList(planTabImage, dataTabImage, talkTabImage, textTabImage);
rechargeIntent = new Intent(MainActivity.this, RechargeActivity.class);
twitterAuthClient = new TwitterAuthClient();
pagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
pagerAdapter.addTabFragment(new TabFragment(getString(R.string.my_plan), new MyPlanFragment()));
pagerAdapter.addTabFragment(new TabFragment(getString(R.string.data), new DataFragment()));
pagerAdapter.addTabFragment(new TabFragment(getString(R.string.talk), new TalkFragment()));
pagerAdapter.addTabFragment(new TabFragment(getString(R.string.text), new TextFragment()));
viewPager.setAdapter(pagerAdapter);
viewPager.setOffscreenPageLimit(3);
tabLayout.setupWithViewPager(viewPager);
tabLayout.setOnTabSelectedListener(this);
updateTabText(pagerAdapter);
floatingActionButton.setBackgroundTintList(getResources().getColorStateList(R.color.orange));
context = this;
updateFABForMyPlanTab();
setImageHighlight(planTabImage);
subscribeForToolbarCostUpdates();
// configure and start MQA
String MQA_KEY = getString(R.string.mqaKey);
Configuration configuration = new Configuration.Builder(this)
.withAPIKey(MQA_KEY)
.withMode(MQA.Mode.MARKET)
.withReportOnShakeEnabled(true)
.build();
// Only want to start an MQA session when sending out a signed release build
Boolean startMQA = !BuildConfig.DEBUG;
if (startMQA) {
MQA.startNewSession(this, configuration);
}
// connect to MFP and register ChallengeHandler
CafeJava.connect(this)
.subscribe(new Action1<WLResponse>() {
@Override public void call(WLResponse wlResponse) {
Log.d(TAG, "Connection succeeded: " + wlResponse.getResponseText());
WLClient.getInstance().registerChallengeHandler(new TelcoChallengeHandler());
}
}, new Action1<Throwable>() {
@Override public void call(Throwable throwable) {
Log.d(TAG, "Connection failed: " + throwable.getMessage());
}
});
WLAnalytics.setContext(this);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
try {
return super.dispatchTouchEvent(ev);
} catch (Throwable t) {
t.printStackTrace();
return false;
}
}
@Override
protected void onStart(){
super.onStart();
updateTabText(pagerAdapter);
}
/**
* Programmatically take away all caps for tab bar titles.
*
* @param pagerAdapter needed so we know how many tabs to loop through
*/
private void updateTabText(ViewPagerAdapter pagerAdapter) {
Typeface font = FontCache.get("Roboto-Regular.ttf", context);
for (int i = 0; i < pagerAdapter.getCount(); i++) {
TextView tv = (TextView) (((LinearLayout) ((LinearLayout) tabLayout.getChildAt(0)).getChildAt(i)).getChildAt(0));
tv.setAllCaps(false);
tv.setTypeface(font);
}
}
/**
* Listen for any updates to Base Plan so the
* ToolBar cost can be updated accordingly.
*/
private void subscribeForToolbarCostUpdates() {
new BasePlanModelImpl().getBasePlanStream()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<BasePlan>() {
@Override
public void call(BasePlan basePlan) {
setToolbarText(basePlan);
}
});
}
/**
* Actually update the cost TextView with updated BasePlan info.
*
* @param basePlan the updated BasePlan object with new cost info
*/
private void setToolbarText(BasePlan basePlan) {
double totalCost = basePlan.getTotalCost();
String localizedTotalCost = Currency.localize(totalCost, false);
currentPlanTotal.setText(localizedTotalCost);
}
/**
* Called every time a tab is selected. Useful for updating FAB
* to respond appropriately depending on which tab is active,
* and updating view of tabs to show active tab.
*
* @param tab the tab that was selected
*/
@Override
public void onTabSelected(final TabLayout.Tab tab) {
int tabPosition = tab.getPosition();
viewPager.setCurrentItem(tabPosition, true);
tabChangeStream.onNext(tabPosition);
@AnalyticsCnsts.Page String page = null;
switch (tabPosition) {
case MY_PLAN:
page = AnalyticsCnsts.MYPLAN;
updateFABForMyPlanTab();
setImageHighlight(planTabImage);
break;
case DATA:
page = AnalyticsCnsts.MYDATA;
rechargeIntent.putExtra(RechargeActivity.TYPE_BUNDLE_KEY, PlanConstants.DATA);
updateFABForDataTalkText();
setImageHighlight(dataTabImage);
break;
case TALK:
page = AnalyticsCnsts.MYTALK;
rechargeIntent.putExtra(RechargeActivity.TYPE_BUNDLE_KEY, PlanConstants.TALK);
updateFABForDataTalkText();
setImageHighlight(talkTabImage);
break;
case TEXT:
page = AnalyticsCnsts.MYTEXT;
rechargeIntent.putExtra(RechargeActivity.TYPE_BUNDLE_KEY, PlanConstants.TEXT);
updateFABForDataTalkText();
setImageHighlight(textTabImage);
break;
}
NavTracker.getInstance().setScreen(page);
}
/**
* Empty override. Necessary because implementing TabLayout.OnTabSelectedListener.
*
* @param tab the tab that was unselected
*/
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
/**
* Empty override. Necessary because implementing TabLayout.OnTabSelectedListener.
*
* @param tab the tab that was reselected
*/
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
/**
* Highlight the active tab image while dimming all other tab images.
*
* @param tabImageToHighlight the tab image to highlight
*/
private void setImageHighlight(ImageView tabImageToHighlight) {
for (ImageView image : tabImages) {
if (image == tabImageToHighlight) {
image.setAlpha((float) 1.0);
} else {
image.setAlpha((float) 0.5);
}
}
}
/**
* Inflate the overflow menu for MainActivity.
*
* @param menu the menu to inflate
* @return true if you want menu to be shown, false otherwise
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
/**
* Callback method for when user taps an option in overflow menu.
*
* @param item the item that was tapped
* @return true for tap event to be consumed by this method,
* false to allow falling through to other item click functions
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_walkthrough) {
Intent intent = new Intent(this, OnboardingActivity.class);
intent.putExtra(OnboardingActivity.COMING_FROM_OVERFLOW, true);
startActivity(intent);
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Update the FAB image and click listener for My Plan tab.
*/
private void updateFABForMyPlanTab() {
floatingActionButton.setImageResource(R.drawable.wifi_white);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
NavTracker.getInstance().setScreen(AnalyticsCnsts.WIFI);
startActivity(new Intent(MainActivity.this, HotSpotActivity.class));
}
});
}
/**
* Update the FAB image and click listener for Data/Talk/Text tabs.
*/
private void updateFABForDataTalkText() {
floatingActionButton.setImageResource(R.drawable.recharge_white);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view
) {
NavTracker.getInstance().setScreen(AnalyticsCnsts.RECHARGE);
startActivity(rechargeIntent);
}
});
}
/**
* Set the presenter being used by MyPlan.
*
* @param presenter the presenter being used
*/
public void setMyPlanPresenter(MyPlanPresenter presenter) {
myPlanPresenter = presenter;
}
/**
* Generates a hotspot system notification.
*
* @param item the menu item to select
*/
public void generateHotspotNotification(MenuItem item) {
Intent intent = new Intent(this, HotSpotActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setContentTitle(getString(R.string.hotspot_notification_title))
.setContentText(getString(R.string.hotspot_notification_body))
.setSmallIcon(R.drawable.ic_stat_acme_transparent)
.setColor(getResources().getColor(R.color.dark_indigo))
.setAutoCancel(true)
.setContentIntent(pIntent);
int mNotificationId = 2;
NotificationManager notificationManager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(mNotificationId, mBuilder.build());
}
/**
* Generates a demo offer and a system notification about said offer.
*
* @param item the menu item to select
*/
public void generateDemoOffer(MenuItem item) {
Offer offerToAdd = new Offer(getString(R.string.unlimited_sundays),
getString(R.string.offer_recharge),
R.drawable.recharge,
5.00, "recharge", false, false, true);
if (myPlanPresenter != null) {
myPlanPresenter.addOffer(offerToAdd);
}
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(getString(R.string.recharge_notification)))
.setContentTitle(getString(R.string.offer_notification_title))
.setContentText(getString(R.string.recharge_notification))
.setSmallIcon(R.drawable.ic_stat_acme_transparent)
.setColor(getResources().getColor(R.color.dark_indigo))
.setAutoCancel(true)
.setContentIntent(pIntent);
int mNotificationId = 1;
NotificationManager notificationManager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(mNotificationId, mBuilder.build());
}
/**
* Update user's Twitter status if already granted the app access,
* or ask for access and then Tweet (if access granted) otherwise.
*
* @param status the Twitter status update for the user
*/
public void tryToTweet(final String status) {
if (TwitterHelper.alreadyAuthorized()) {
TwitterHelper.tweet(status);
} else {
TwitterHelper.authorizeThenTweet(this, twitterAuthClient, status);
}
}
/**
* Needed by Twitter SDK to callback after asking for authorization of app.
*
* @param requestCode the type of request
* @param resultCode the result of the authorization
* @param data any data attached to authorization
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
twitterAuthClient.onActivityResult(requestCode, resultCode, data);
}
/**
* Set up the ViewPager with Fragments
*/
private static class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<TabFragment> fragmentList = new ArrayList<>();
/**
* Initialize a ViewPagerAdapter with the support fragment manager.
*
* @param fragmentManager the fragment manager to init with
*/
public ViewPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
/**
* Get the fragment associated with a position.
*
* @param position the position of fragment we want to retrieve
* @return the fragment at the specified position
*/
@Override public Fragment getItem(int position) {
return fragmentList.get(position).getFragment();
}
/**
* Returns the number of fragments in the ViewPager.
*
* @return the number of fragments
*/
@Override public int getCount() {
return fragmentList.size();
}
/**
* Add a TabFragment instance to the ViewPagerAdapter.
*
* @param tabFragment the TabFragment to add
*/
public void addTabFragment(TabFragment tabFragment) {
fragmentList.add(tabFragment);
}
/**
* Automatically set the titles of the TabLayout.
*
* @param position the position we want the title for
* @return the title for the specified position
*/
@Override
public CharSequence getPageTitle(int position) {
return fragmentList.get(position).getTitle();
}
}
/**
* Helper class for having a Fragment with a tab title.
*/
private static class TabFragment {
private final String title;
private final Fragment fragment;
public TabFragment(String title, Fragment fragment) {
this.title = title;
this.fragment = fragment;
}
public String getTitle() {
return title;
}
public Fragment getFragment() {
return fragment;
}
}
@Override
public boolean onTouchEvent(MotionEvent event){
this.detector.onTouchEvent(event);
return super.onTouchEvent(event);
}
}