package cgeo.geocaching.apps.cache.navi;

import cgeo.geocaching.SearchResult;
import cgeo.geocaching.Settings;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.cgGeo;
import cgeo.geocaching.cgWaypoint;
import cgeo.geocaching.apps.AbstractAppFactory;
import cgeo.geocaching.geopoint.Geopoint;

import org.apache.commons.lang3.ArrayUtils;

import android.app.Activity;
import android.content.res.Resources;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;

import java.util.ArrayList;
import java.util.List;

public final class NavigationAppFactory extends AbstractAppFactory {
    private static NavigationApp[] apps = new NavigationApp[] {};

    private static NavigationApp[] getNavigationApps(Resources res) {
        if (ArrayUtils.isEmpty(apps)) {
            apps = new NavigationApp[] {
                    new CompassApp(res),
                    new RadarApp(res),
                    new InternalMap(res),
                    new StaticMapApp(res),
                    new LocusApp(res),
                    new RMapsApp(res),
                    new GoogleMapsApp(res),
                    new GoogleNavigationApp(res),
                    new StreetviewApp(res),
                    new OruxMapsApp(res) };
        }
        return apps;
    }

    public static void addMenuItems(final Menu menu, final Activity activity,
            final Resources res) {
        addMenuItems(menu, activity, res, true, false);
    }

    public static void addMenuItems(final Menu menu, final Activity activity,
            final Resources res, final boolean showInternalMap, final boolean showDefaultNavigation) {
        int defaultNavigationTool = Settings.getDefaultNavigationTool();
        for (NavigationApp app : getInstalledNavigationApps(activity, res)) {
            if ((showInternalMap || !(app instanceof InternalMap)) &&
                    (showDefaultNavigation || defaultNavigationTool != app.getId())) {
                menu.add(0, app.getId(), 0, app.getName());
            }
        }
    }

    public static List<NavigationApp> getInstalledNavigationApps(final Activity activity, final Resources res) {
        List<NavigationApp> installedNavigationApps = new ArrayList<NavigationApp>();
        for (NavigationApp app : getNavigationApps(res)) {
            if (app.isInstalled(activity)) {
                installedNavigationApps.add(app);
            }
        }
        return installedNavigationApps;
    }

    public static int getOrdinalFromId(final Activity activity, final Resources res, final int id) {
        int ordinal = 0;
        for (NavigationApp app : getInstalledNavigationApps(activity, res)) {
            if (app.getId() == id) {
                return ordinal;
            }
            ordinal++;
        }
        return 0;
    }

    public static boolean onMenuItemSelected(final MenuItem item,
            final cgGeo geo, Activity activity, Resources res,
            cgCache cache,
            final SearchResult search, cgWaypoint waypoint, final Geopoint destination) {
        NavigationApp app = (NavigationApp) getAppFromMenuItem(item, apps);
        if (app != null) {
            try {
                return app.invoke(geo, activity, res, cache,
                        search, waypoint, destination);
            } catch (Exception e) {
                Log.e(Settings.tag, "NavigationAppFactory.onMenuItemSelected: " + e.toString());
            }
        }
        return false;
    }

    public static void startDefaultNavigationApplication(final cgGeo geo, Activity activity, Resources res, cgCache cache,
            final SearchResult search, cgWaypoint waypoint, final Geopoint destination) {
        int defaultNavigationTool = Settings.getDefaultNavigationTool();
        if (defaultNavigationTool == 0) {
            return;
        }
        NavigationApp app = null;
        List<NavigationApp> installedNavigationApps = getInstalledNavigationApps(activity, res);
        for (NavigationApp navigationApp : installedNavigationApps) {
            if (navigationApp.getId() == defaultNavigationTool) {
                app = navigationApp;
                break;
            }
        }
        if (app != null) {
            try {
                app.invoke(geo, activity, res, cache, search, waypoint, destination);
            } catch (Exception e) {
                Log.e(Settings.tag, "NavigationAppFactory.startDefaultNavigationApplication: " + e.toString());
            }
        }
    }

}

@@ -3697,32 +3697,38 @@
 tion) %7B%0A        
+final 
 int defaultNavig
@@ -3780,79 +3780,8 @@
 ();%0A
-        if (defaultNavigationTool == 0) %7B%0A            return;%0A        %7D
 %0A   
@@ -3904,24 +3904,186 @@
 vity, res);%0A
+%0A        if (defaultNavigationTool == 0) %7B%0A            // assume that 0 is the compass-app%0A            app = installedNavigationApps.get(0);%0A        %7D else %7B%0A    
         for 
@@ -4148,24 +4148,28 @@
             
+    
 if (navigati
@@ -4222,24 +4222,28 @@
             
+  
+  
 app = naviga
@@ -4271,15 +4271,37 @@
     
+    
 break;%0A
+                %7D%0A
     
@@ -4312,32 +4312,33 @@
     %7D%0A        %7D%0A
+%0A
         if (app 

Fix #937: DefaultNavigation not working after install