package cgeo.geocaching.maps;

import cgeo.geocaching.models.Route;
import cgeo.geocaching.storage.extension.Trackfiles;
import cgeo.geocaching.utils.functions.Action2;

import android.app.Activity;
import android.net.Uri;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.ArrayList;

public class Tracks {

    private final ArrayList<Track> data = new ArrayList<>();

    private static class Track {
        private final Trackfiles trackfile;
        private Route route;

        Track(final Trackfiles trackfile) {
            this.trackfile = trackfile;
            this.route = null;
        }
    }

    public interface UpdateTrack {
        void updateRoute(String key, Route route);
    }

    public Tracks() {
        for (Trackfiles trackfile : Trackfiles.getTrackfiles()) {
            data.add(new Track(trackfile));
        }
    }

    public Tracks(final RouteTrackUtils routeTrackUtils, final UpdateTrack updateTrack) {
        this();
        for (Track track : data) {
            routeTrackUtils.reloadTrack(track.trackfile, updateTrack);
        }
        routeTrackUtils.setTracks(this);
    }

    public void setRoute(@NonNull final String key, final Route route) {
        for (Track track : data) {
            if (track.trackfile.getKey().equals(key)) {
                track.route = route;
            }
        }
    }

    public void resumeAllTracks(final Action2<String, Boolean> resumeTrack) {
        for (Track track : data) {
           resumeTrack.call(track.trackfile.getKey(), false);
        }
    }

    public void traverse(final Action2<String, Route> action) {
        for (Track track : data) {
            action.call(track.trackfile.getKey(), track.route);
        }
    }

    public String add(final Activity activity, final Uri uri, final UpdateTrack updateTrack) {
        final String key = Trackfiles.createTrackfile(activity, uri);
        for (Trackfiles trackfile : Trackfiles.getTrackfiles()) {
            if (trackfile.getKey().equals(key)) {
                data.add(new Track(trackfile));
                return key;
            }
        }
        return null;
    }

    public void remove(@NonNull final String key) {
        for (Track track : data) {
            if (track.trackfile.getKey().equals(key)) {
                Trackfiles.removeTrackfile(track.trackfile.getKey());
                data.remove(track);
                break;
            }
        }
    }

    public String getDisplayname(@NonNull final String key) {
        for (Track track : data) {
            if (track.trackfile.getKey().equals(key)) {
                return track.trackfile.getDisplayname();
            }
        }
        return null;
    }

    public Route getRoute(@NonNull final String key) {
        for (Track track : data) {
            if (track.trackfile.getKey().equals(key)) {
                return track.route;
            }
        }
        return null;
    }

    public void hide(@NonNull final String key, final boolean hide) {
        Trackfiles.hide(key, hide);
    }

    @Nullable
    public Trackfiles getTrackfile(@NonNull final String key) {
        for (Track track : data) {
            if (track.trackfile.getKey().equals(key)) {
                return track.trackfile;
            }
        }
        return null;
    }
}

@@ -114,16 +114,61 @@
 kfiles;%0A
+import cgeo.geocaching.utils.AndroidRxUtils;%0A
 import c
@@ -816,119 +816,46 @@
     
-for (Trackfiles trackfile : Trackfiles.getTrackfiles()) %7B%0A            data.add(new Track(trackfile));%0A        %7D
+getListOfTrackfilesInBackground(null);
 %0A   
@@ -960,24 +960,58 @@
     
-this();%0A
+getListOfTrackfilesInBackground(() -%3E %7B%0A  
         
 for 
@@ -998,32 +998,34 @@
  -%3E %7B%0A          
+  
 for (Track track
@@ -1027,32 +1027,36 @@
 track : data) %7B%0A
+    
             rout
@@ -1110,34 +1110,42 @@
 Track);%0A        
+   
+ 
 %7D%0A
+    
         routeTra
@@ -1169,16 +1169,422 @@
 (this);%0A
+        %7D);%0A    %7D%0A%0A    private void getListOfTrackfilesInBackground(@Nullable final Runnable runAfterLoad) %7B%0A        AndroidRxUtils.refreshScheduler.scheduleDirect(() -%3E %7B%0A            for (Trackfiles trackfile : Trackfiles.getTrackfiles()) %7B%0A                data.add(new Track(trackfile));%0A            %7D%0A            if (runAfterLoad != null) %7B%0A                runAfterLoad.run();%0A            %7D%0A        %7D);%0A
     %7D%0A%0A 

put tracks initialization into background thread (rel. to #12873)