package com.thebluealliance.androidclient.binders;
import com.thebluealliance.androidclient.R;
import com.thebluealliance.androidclient.TbaLogger;
import com.thebluealliance.androidclient.helpers.PitLocationHelper;
import com.thebluealliance.androidclient.listeners.SocialClickListener;
import com.thebluealliance.androidclient.types.MediaType;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.TextAppearanceSpan;
import android.view.View;
import android.widget.TextView;
import java.util.Map;
import javax.inject.Inject;
import butterknife.Bind;
import butterknife.ButterKnife;
public class TeamInfoBinder extends AbstractDataBinder<TeamInfoBinder.Model> {
private static final int TEAM_FULL_NAME_COLLAPSED_MAX_LINES = 3;
@Inject SocialClickListener mSocialClickListener;
@Bind(R.id.content) View content;
@Bind(R.id.team_name) TextView teamName;
@Bind(R.id.team_location_container) View teamLocationContainer;
@Bind(R.id.team_location) TextView teamLocation;
@Bind(R.id.team_website_container) View teamWebsiteContainer;
@Bind(R.id.team_website_title) TextView teamWebsiteTitle;
@Bind(R.id.team_twitter_container) View teamTwitterContainer;
@Bind(R.id.team_twitter_title) TextView teamTwitterTitle;
@Bind(R.id.twitter_divider) View twitterDivider;
@Bind(R.id.team_youtube_container) View teamYoutubeContainer;
@Bind(R.id.team_youtube_title) TextView teamYoutubeTitle;
@Bind(R.id.youtube_divider) View youtubeDivider;
@Bind(R.id.team_facebook_container) View teamFbContainer;
@Bind(R.id.team_facebook_title) TextView teamFbTitle;
@Bind(R.id.facebook_divider) View facebookDivider;
@Bind(R.id.team_github_container) View teamGitHubContainer;
@Bind(R.id.team_github_title) TextView teamGitHubTitle;
@Bind(R.id.team_instagram_container) View teamInstaContainer;
@Bind(R.id.team_instagram_title) TextView teamInstaTitle;
@Bind(R.id.instagram_divider) View instagramDivider;
@Bind(R.id.team_full_name_container) View teamFullNameContainer;
@Bind(R.id.team_full_name) TextView teamFullName;
@Bind(R.id.team_next_match_label) View teamNextMatchLabel;
@Bind(R.id.team_next_match_details) View teamNextMatchDetails;
@Bind(R.id.progress) View progress;
@Bind(R.id.team_motto_container) View teamMottoContainer;
@Bind(R.id.team_motto) TextView teamMotto;
@Bind(R.id.champs_pit_location_container) View champsPitLocationContainer;
@Bind(R.id.champs_pit_location) TextView champsPitLocation;
@Inject
public TeamInfoBinder(SocialClickListener socialClickListener) {
mSocialClickListener = socialClickListener;
}
@Override
public void bindViews() {
ButterKnife.bind(this, mRootView);
}
@Override
public void updateData(@Nullable TeamInfoBinder.Model data) {
if (data == null) {
if (!isDataBound()) {
bindNoDataView();
}
return;
}
mSocialClickListener.setModelKey(data.teamKey);
if (data.nickname.isEmpty()) {
teamName.setText("Team " + data.teamNumber);
} else {
teamName.setText(data.nickname);
}
if (data.location.isEmpty()) {
// No location; hide the location view
teamLocationContainer.setVisibility(View.GONE);
} else {
// Show and populate the location view
teamLocation.setText(data.location);
// Tag is used to create an ACTION_VIEW intent for a maps application
teamLocationContainer.setTag("geo:0,0?q=" + Uri.encode(data.location));
}
teamLocationContainer.setOnClickListener(mSocialClickListener);
if (data.motto.isEmpty()) {
// No location; hide the location view
teamMottoContainer.setVisibility(View.GONE);
} else {
// Show and populate the location view
teamMotto.setText(data.motto);
}
// If the team doesn't have a defined website, create a Google search for the team name
if (data.website.isEmpty()) {
teamWebsiteContainer.setTag("https://www.google.com/search?q=" + Uri.encode(data.nickname));
teamWebsiteTitle.setText(R.string.find_event_on_google);
} else {
teamWebsiteContainer.setTag(data.website);
teamWebsiteTitle.setText(R.string.view_team_website);
}
teamWebsiteContainer.setOnClickListener(mSocialClickListener);
if (data.socialMedia.containsKey(MediaType.TWITTER_PROFILE)) {
String twitterKey = data.socialMedia.get(MediaType.TWITTER_PROFILE);
teamTwitterContainer.setVisibility(View.VISIBLE);
twitterDivider.setVisibility(View.VISIBLE);
teamTwitterContainer.setTag("https://twitter.com/" + twitterKey);
teamTwitterContainer.setOnClickListener(mSocialClickListener);
teamTwitterTitle.setText(mActivity.getString(R.string.view_team_twitter, twitterKey));
} else {
teamTwitterContainer.setVisibility(View.GONE);
twitterDivider.setVisibility(View.GONE);
}
if (data.socialMedia.containsKey(MediaType.YOUTUBE_CHANNEL)) {
String youtubeKey = data.socialMedia.get(MediaType.YOUTUBE_CHANNEL);
teamYoutubeContainer.setVisibility(View.VISIBLE);
youtubeDivider.setVisibility(View.VISIBLE);
teamYoutubeContainer.setTag("https://www.youtube.com/" + youtubeKey);
teamYoutubeContainer.setOnClickListener(mSocialClickListener);
teamYoutubeTitle.setText(mActivity.getString(R.string.view_team_youtube, youtubeKey));
} else {
teamYoutubeContainer.setVisibility(View.GONE);
youtubeDivider.setVisibility(View.GONE);
}
if (data.socialMedia.containsKey(MediaType.FACEBOOK_PROFILE)) {
String fbKey = data.socialMedia.get(MediaType.FACEBOOK_PROFILE);
teamFbContainer.setVisibility(View.VISIBLE);
facebookDivider.setVisibility(View.VISIBLE);
teamFbContainer.setTag("https://facebook.com/" + fbKey);
teamFbContainer.setOnClickListener(mSocialClickListener);
teamFbTitle.setText(mActivity.getString(R.string.view_team_fb, fbKey));
} else {
teamFbContainer.setVisibility(View.GONE);
facebookDivider.setVisibility(View.GONE);
}
if (data.socialMedia.containsKey(MediaType.GITHUB_PROFILE)) {
String githubKey = data.socialMedia.get(MediaType.GITHUB_PROFILE);
teamGitHubContainer.setVisibility(View.VISIBLE);
teamGitHubContainer.setTag("https://github.com/" + githubKey);
teamGitHubContainer.setOnClickListener(mSocialClickListener);
teamGitHubTitle.setText(mActivity.getString(R.string.view_team_github, githubKey));
} else {
teamGitHubContainer.setVisibility(View.GONE);
}
if (data.socialMedia.containsKey(MediaType.INSTAGRAM_PROFILE)) {
String instaKey = data.socialMedia.get(MediaType.INSTAGRAM_PROFILE);
teamInstaContainer.setVisibility(View.VISIBLE);
instagramDivider.setVisibility(View.VISIBLE);
teamInstaContainer.setTag("https://www.instagram.com/" + instaKey);
teamInstaContainer.setOnClickListener(mSocialClickListener);
teamInstaTitle.setText(mActivity.getString(R.string.view_team_instagram, instaKey));
} else {
teamInstaContainer.setVisibility(View.GONE);
instagramDivider.setVisibility(View.GONE);
}
if (data.fullName.isEmpty()) {
// No full name specified, hide the view
teamFullNameContainer.setVisibility(View.GONE);
} else {
// This string needs to be specially formatted
SpannableString string = new SpannableString("aka " + data.fullName);
string.setSpan(new TextAppearanceSpan(mActivity,
R.style.InfoItemLabelStyle), 0, 3, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
teamFullName.setText(string);
teamFullName.setMaxLines(TEAM_FULL_NAME_COLLAPSED_MAX_LINES);
teamFullName.setEllipsize(TextUtils.TruncateAt.END);
teamFullNameContainer.setOnClickListener((view) -> {
toggleFullTeamNameExpanded();
});
}
champsPitLocationContainer.setVisibility(View.GONE);
if (data.showPitLocation && data.pitLocation != null) {
champsPitLocationContainer.setVisibility(View.VISIBLE);
champsPitLocation.setText(data.pitLocation.getAddressString());
}
teamNextMatchLabel.setVisibility(View.GONE);
teamNextMatchDetails.setVisibility(View.GONE);
content.setVisibility(View.VISIBLE);
progress.setVisibility(View.GONE);
content.setVisibility(View.VISIBLE);
mNoDataBinder.unbindData();
setDataBound(true);
}
@Override
public void onComplete() {
View progressBar = progress;
if (progressBar != null) {
progressBar.setVisibility(View.GONE);
}
if (!isDataBound()) {
bindNoDataView();
}
}
@Override
public void onError(Throwable throwable) {
TbaLogger.e(throwable.toString());
// If we received valid data from the cache but get an error from the network operations,
// don't display the "No data" message.
if (!isDataBound()) {
bindNoDataView();
}
}
private void bindNoDataView() {
try {
content.setVisibility(View.GONE);
progress.setVisibility(View.GONE);
mNoDataBinder.bindData(mNoDataParams);
} catch (Exception e) {
e.printStackTrace();
}
}
private void toggleFullTeamNameExpanded() {
int currentMaxLines = teamFullName.getMaxLines();
if (currentMaxLines == TEAM_FULL_NAME_COLLAPSED_MAX_LINES) {
// The text view is collapsed, expand it
final int height = teamFullName.getMeasuredHeight();
teamFullName.setMaxLines(Integer.MAX_VALUE);
teamFullName.measure(
View.MeasureSpec.makeMeasureSpec(teamFullName.getMeasuredWidth(), View.MeasureSpec.AT_MOST),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
final int newHeight = teamFullName.getMeasuredHeight();
ObjectAnimator animation = ObjectAnimator.ofInt(teamFullName, "height", height, newHeight);
animation.setDuration(500);
animation.addListener(new AnimatorListenerAdapter() {
@Override public void onAnimationEnd(Animator animation) {
teamFullName.setMaxLines(Integer.MAX_VALUE);
teamFullName.setMinHeight(0);
}
});
animation.start();
} else {
// We need to collapse the text view
final int height = teamFullName.getMeasuredHeight();
// Only set max lines while we measure; max lines will be permanently
// reduced one the animation completes
teamFullName.setMaxLines(TEAM_FULL_NAME_COLLAPSED_MAX_LINES);
teamFullName.measure(
View.MeasureSpec.makeMeasureSpec(teamFullName.getMeasuredWidth(), View.MeasureSpec.AT_MOST),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
teamFullName.setMaxLines(Integer.MAX_VALUE);
final int newHeight = teamFullName.getMeasuredHeight();
ObjectAnimator animation = ObjectAnimator.ofInt(teamFullName, "height", height, newHeight);
animation.setDuration(500);
animation.addListener(new AnimatorListenerAdapter() {
@Override public void onAnimationEnd(Animator animation) {
teamFullName.setMaxLines(TEAM_FULL_NAME_COLLAPSED_MAX_LINES);
teamFullName.setMinHeight(0);
}
});
animation.start();
}
}
@Override
public void unbind(boolean unbindViews) {
super.unbind(unbindViews);
if (unbindViews) {
ButterKnife.unbind(this);
}
}
public static class Model {
public String teamKey;
public String nickname;
public String fullName;
public String location;
public String website;
public String motto;
public int teamNumber;
public Map<MediaType, String> socialMedia;
public boolean showPitLocation;
public @Nullable PitLocationHelper.TeamPitLocation pitLocation;
}
}