package com.truckmuncher.app.customer; import android.database.Cursor; import android.graphics.Color; import android.net.Uri; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import com.google.android.gms.maps.model.LatLng; import com.google.maps.android.SphericalUtil; import com.squareup.picasso.Picasso; import com.truckmuncher.app.R; import com.truckmuncher.app.data.Contract; import com.truckmuncher.app.data.PublicContract; import com.truckmuncher.app.data.sql.WhereClause; import java.text.DecimalFormat; import java.util.List; import butterknife.ButterKnife; import butterknife.InjectView; import butterknife.OnClick; import timber.log.Timber; import static com.guava.common.base.Preconditions.checkNotNull; import static com.truckmuncher.app.data.sql.WhereClause.Operator.EQUALS; public class TruckHeaderFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> { private static final double METERS_TO_MILES = 0.000621371; private static final String ARG_TRUCK_ID = "truck_id"; private static final String ARG_LOCATION = "location"; @InjectView(R.id.truck_name) TextView truckName; @InjectView(R.id.truck_keywords) TextView truckKeywords; @InjectView(R.id.distance_from_location) TextView distanceFromLocation; @InjectView(R.id.truck_image) ImageView truckImage; @InjectView(R.id.header) View headerView; private OnTruckHeaderClickListener truckHeaderClickListener; private LatLng referenceLocation; // TODO use a dynamic user location instead of a static one public static TruckHeaderFragment newInstance(@NonNull String truckId, LatLng userLocation) { Bundle args = new Bundle(); args.putString(ARG_TRUCK_ID, checkNotNull(truckId)); args.putParcelable(ARG_LOCATION, userLocation); TruckHeaderFragment fragment = new TruckHeaderFragment(); fragment.setArguments(args); return fragment; } @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_truck_header, container, false); ButterKnife.inject(this, view); referenceLocation = getArguments().getParcelable(ARG_LOCATION); return view; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); getLoaderManager().initLoader(0, null, this); } @Override public void onDestroyView() { ButterKnife.reset(this); super.onDestroyView(); } @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { String truckId = getArguments().getString(ARG_TRUCK_ID); WhereClause whereClause = new WhereClause.Builder() .where(PublicContract.Truck.ID, EQUALS, truckId) .build(); Uri uri; String[] projection; // Necessary for trucks that are approved by haven't gone into serving mode at all yet. // This should only be when accessing a truck via deep linking or from the all trucks list, // so the location isn't needed anyway. if (referenceLocation == null) { uri = Contract.TRUCK_PROPERTIES_URI; projection = TruckQuery.PROJECTION; } else { uri = PublicContract.TRUCK_URI; projection = TruckQueryWithLocation.PROJECTION; } return new CursorLoader(getActivity(), uri, projection, whereClause.selection, whereClause.selectionArgs, null); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { if (cursor.moveToFirst()) { // Split the keywords and format them in a way that is user friendly String keywordsString = cursor.getString(TruckQuery.KEYWORDS); List<String> keywords = PublicContract.convertStringToList(keywordsString); StringBuilder builder = new StringBuilder(); for (int i = 0; i < keywords.size(); i++) { builder.append(keywords.get(i)); if (i < keywords.size() - 1) { builder.append(", "); } } String truckName = cursor.getString(TruckQuery.NAME); String truckKeywords = builder.toString(); String imageUrl = cursor.getString(TruckQuery.IMAGE_URL); String secondaryColor = cursor.getString(TruckQuery.COLOR_SECONDARY); LatLng truckLocation = referenceLocation == null ? null : new LatLng(cursor.getDouble(TruckQueryWithLocation.LATITUDE), cursor.getDouble(TruckQueryWithLocation.LONGITUDE)); onTruckDataLoaded(truckName, truckKeywords, imageUrl, secondaryColor, truckLocation); } else { // Invalid truck String truckId = getArguments().getString(ARG_TRUCK_ID); Timber.w(new IllegalStateException("Tried to load an invalid truck with id " + truckId), ""); } } @Override public void onLoaderReset(Loader<Cursor> loader) { // No-op } @OnClick(R.id.header) void onHeaderClick() { if (truckHeaderClickListener != null) { truckHeaderClickListener.onTruckHeaderClick(getArguments().getString(ARG_TRUCK_ID)); } } public void setOnTruckHeaderClickListener(OnTruckHeaderClickListener listener) { truckHeaderClickListener = listener; } private void onTruckDataLoaded(String name, String keywords, String imageUrl, String headerColor, LatLng truckLocation) { if (TextUtils.isEmpty(imageUrl)) { truckImage.setVisibility(View.GONE); } else { Picasso.with(getActivity()) .load(imageUrl) .fit() .centerInside() .transform(new CircleTransform()) .into(truckImage); } if (headerColor != null) { headerView.setBackgroundColor(Color.parseColor(headerColor)); int textColor = ColorCorrector.calculateTextColor(headerColor); truckName.setTextColor(textColor); truckKeywords.setTextColor(textColor); } truckName.setText(name); truckKeywords.setText(keywords); if (referenceLocation != null) { // distance in meters double delta = SphericalUtil.computeDistanceBetween(truckLocation, referenceLocation); // convert to miles delta *= METERS_TO_MILES; distanceFromLocation.setText(new DecimalFormat("0.0").format(delta) + " mi"); distanceFromLocation.setVisibility(View.VISIBLE); } else { distanceFromLocation.setVisibility(View.GONE); } } public interface OnTruckHeaderClickListener { void onTruckHeaderClick(String currentTruck); } interface TruckQuery { String[] PROJECTION = new String[]{ PublicContract.Truck.NAME, PublicContract.Truck.IMAGE_URL, PublicContract.Truck.KEYWORDS, PublicContract.Truck.COLOR_SECONDARY, }; int NAME = 0; int IMAGE_URL = 1; int KEYWORDS = 2; int COLOR_SECONDARY = 3; } interface TruckQueryWithLocation { String[] PROJECTION = new String[]{ PublicContract.Truck.NAME, PublicContract.Truck.IMAGE_URL, PublicContract.Truck.KEYWORDS, PublicContract.Truck.COLOR_SECONDARY, PublicContract.Truck.LATITUDE, PublicContract.Truck.LONGITUDE }; int NAME = 0; int IMAGE_URL = 1; int KEYWORDS = 2; int COLOR_SECONDARY = 3; int LATITUDE = 4; int LONGITUDE = 5; } }