package fr.free.nrw.commons.nearby;


import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ProgressBar;
import android.widget.TextView;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import fr.free.nrw.commons.R;

public class NearbyListFragment extends ListFragment {

    private LatLng mLatestLocation;
    private int mImageSize;
    private boolean mItemClicked;
    ArrayAdapter mAdapter;

    List<Place> places;

    private static final String TAG = "NearbyListFragment";

    public NearbyListFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        Log.d(TAG, "NearbyListFragment created");

        View view = inflater.inflate(R.layout.fragment_nearby, container, false);

        places = loadAttractionsFromLocation(mLatestLocation);

        // Create a progress bar to display while the list loads
        ProgressBar progressBar = new ProgressBar(getActivity());
        progressBar.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT));
        progressBar.setIndeterminate(true);
        getListView().setEmptyView(progressBar);
        // Must add the progress bar to the root of the layout
        ViewGroup root = (ViewGroup) view.getRootView();
        root.addView(progressBar);

        mAdapter = new NearbyAdapter(getActivity(), places);
        setListAdapter(mAdapter);

        return view;
    }



    private static List<Place> loadAttractionsFromLocation(final LatLng curLatLng) {
        //String closestCity = TouristAttractions.getClosestCity(curLatLng);
        //if (closestCity != null) {
        List<Place> places = NearbyPlaces.get();
        if (curLatLng != null) {
            Collections.sort(places,
                    new Comparator<Attraction>() {
                        @Override
                        public int compare(Attraction lhs, Attraction rhs) {
                            double lhsDistance = SphericalUtil.computeDistanceBetween(
                                    lhs.location, curLatLng);
                            double rhsDistance = SphericalUtil.computeDistanceBetween(
                                    rhs.location, curLatLng);
                            return (int) (lhsDistance - rhsDistance);
                        }
                    }
            );
        }
        return places;
        //}
        //return null;
    }

    private class NearbyAdapter extends ArrayAdapter {

        public List<Place> placesList;
        private Context mContext;

        public NearbyAdapter(Context context, List<Place> places) {
            super(context, 0);
            mContext = context;
            placesList = places;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // Get the data item for this position
            Place place = (Place) getItem(position);
            // Check if an existing view is being reused, otherwise inflate the view
            if (convertView == null) {
                convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_place, parent, false);
            }

            // Lookup view for data population
            TextView tvName = (TextView) convertView.findViewById(R.id.tvName);
            TextView tvDesc = (TextView) convertView.findViewById(R.id.tvDesc);

            // Populate the data into the template view using the data object
            tvName.setText(place.name);
            tvDesc.setText(place.description);

            // Return the completed view to render on screen
            return convertView;
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public int getItemCount() {
            return placesList == null ? 0 : placesList.size();
        }

        @Override
        public void onItemClick(View view, int position) {
            if (!mItemClicked) {
                mItemClicked = true;
                View heroView = view.findViewById(android.R.id.icon);
                DetailActivity.launch(
                        getActivity(), mAdapter.mAttractionList.get(position).name, heroView);
            }
        }
    }
}

@@ -1200,24 +1200,76 @@
 r, false);%0A%0A
+        //Load from data source (NearbyPlaces.java)%0A
         plac
@@ -1978,18 +1978,20 @@
 ;%0A    %7D%0A
-%0A%0A
+    
 %0A    pri
@@ -2072,121 +2072,8 @@
 ) %7B%0A
-        //String closestCity = TouristAttractions.getClosestCity(curLatLng);%0A        //if (closestCity != null) %7B
 %0A   
@@ -2223,26 +2223,21 @@
 parator%3C
-Attraction
+Place
 %3E() %7B%0A  
@@ -2315,34 +2315,24 @@
 are(
-Attraction lhs, Attraction
+Place lhs, Place
  rhs
@@ -2380,38 +2380,24 @@
 sDistance = 
-SphericalUtil.
 computeDista
@@ -2523,22 +2523,8 @@
 e = 
-SphericalUtil.
 comp
@@ -2779,37 +2779,933 @@
     
+%7D%0A%0A
     
-//%7D%0A        //return null
+private static double computeDistanceBetween(LatLng from, LatLng to) %7B%0A        return computeAngleBetween(from, to) * 6371009.0D;%0A    %7D%0A%0A    private static double computeAngleBetween(LatLng from, LatLng to) %7B%0A        return distanceRadians(Math.toRadians(from.latitude), Math.toRadians(from.longitude), Math.toRadians(to.latitude), Math.toRadians(to.longitude));%0A    %7D%0A%0A%0A    private static double distanceRadians(double lat1, double lng1, double lat2, double lng2) %7B%0A        return arcHav(havDistance(lat1, lat2, lng1 - lng2));%0A    %7D%0A%0A    private static double arcHav(double x) %7B%0A        return 2.0D * Math.asin(Math.sqrt(x));%0A    %7D%0A%0A    private static double havDistance(double lat1, double lat2, double dLng) %7B%0A        return hav(lat1 - lat2) + hav(dLng) * Math.cos(lat1) * Math.cos(lat2);%0A    %7D%0A%0A    private static double hav(double x) %7B%0A        double sinHalf = Math.sin(x * 0.5D);%0A        return sinHalf * sinHalf
 ;%0A  

Modify loadAttractionsFromLocation and copy over MathUtil methods