package cgeo.geocaching.apps.cachelist;

import cgeo.geocaching.IGeoData;
import cgeo.geocaching.R;
import cgeo.geocaching.SearchResult;
import cgeo.geocaching.activity.IAbstractActivity;
import cgeo.geocaching.apps.AbstractAppFactory;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.utils.Log;

import org.apache.commons.lang3.ArrayUtils;

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

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

public final class CacheListAppFactory extends AbstractAppFactory {
    private static CacheListApp[] apps = new CacheListApp[] {};

    private static CacheListApp[] getMultiPointNavigationApps() {
        if (ArrayUtils.isEmpty(apps)) {
            apps = new CacheListApp[] {
                    new InternalCacheListMap(),
                    new LocusCacheListApp(false),
                    new LocusCacheListApp(true) };
        }
        return apps;
    }

    /**
     * @param menu
     * @param activity
     * @param res
     * @return the added menu item (also for a sub menu, then the menu item in the parent menu is returned)
     */
    public static MenuItem addMenuItems(Menu menu,
            Activity activity, Resources res) {
        List<CacheListApp> activeApps = new ArrayList<CacheListApp>();
        for (CacheListApp app : getMultiPointNavigationApps()) {
            if (app.isInstalled(activity)) {
                activeApps.add(app);
            }
        }
        // use a new sub menu, if more than one app is available
        if (activeApps.size() > 1) {
            SubMenu subMenu = menu.addSubMenu(0, 101, 0,
                    res.getString(R.string.caches_on_map)).setIcon(
                    android.R.drawable.ic_menu_mapmode);
            for (CacheListApp app : activeApps) {
                subMenu.add(0, app.getId(), 0, app.getName());
            }
            return subMenu.getItem();
        } else if (activeApps.size() == 1) {
            return menu.add(0, activeApps.get(0).getId(), 0,
                    activeApps.get(0).getName()).setIcon(android.R.drawable.ic_menu_mapmode);
        }
        return null;
    }

    public static boolean onMenuItemSelected(final MenuItem item,
            final IGeoData geo, final List<cgCache> caches, final IAbstractActivity activity,
            final SearchResult search) {
        CacheListApp app = (CacheListApp) getAppFromMenuItem(item, apps);
        if (app != null) {
            try {
                boolean result = app.invoke(geo, caches, (Activity) activity, search);
                activity.invalidateOptionsMenuCompatible();
                return result;
            } catch (Exception e) {
                Log.e("CacheListAppFactory.onMenuItemSelected: " + e.toString());
            }
        }
        return false;
    }

}

@@ -300,53 +300,8 @@
 g;%0A%0A
-import org.apache.commons.lang3.ArrayUtils;%0A%0A
 impo
@@ -592,73 +592,49 @@
 tic 
-CacheListApp%5B%5D apps = new CacheListApp%5B%5D %7B%7D;%0A%0A    private
+class LazyHolder %7B%0A        public
  static 
 Cach
@@ -629,16 +629,22 @@
  static 
+final 
 CacheLis
@@ -654,124 +654,17 @@
 p%5B%5D 
-getMultiPointNavigationApps() %7B%0A        if (ArrayUtils.isEmpty(apps)) %7B%0A            apps = new CacheListApp%5B%5D %7B%0A    
+apps = %7B%0A
     
@@ -711,36 +711,32 @@
                 
-    
 new LocusCacheLi
@@ -757,36 +757,32 @@
                 
-   
- 
 new LocusCacheLi
@@ -796,11 +796,8 @@
 rue)
- %7D;
 %0A   
@@ -806,28 +806,8 @@
    %7D
-%0A        return apps
 ;%0A  
@@ -1035,16 +1035,22 @@
 nuItems(
+final 
 Menu men
@@ -1051,28 +1051,22 @@
 nu menu,
-%0A           
+ final
  Activit
@@ -1076,16 +1076,22 @@
 ctivity,
+ final
  Resourc
@@ -1108,16 +1108,22 @@
         
+final 
 List%3CCac
@@ -1174,16 +1174,38 @@
 istApp%3E(
+LazyHolder.apps.length
 );%0A     
@@ -1204,32 +1204,38 @@
 );%0A        for (
+final 
 CacheListApp app
@@ -1241,37 +1241,23 @@
 p : 
-getMultiPointNavigationA
+LazyHolder.a
 pps
-()
 ) %7B%0A
@@ -1435,18 +1435,22 @@
         
-if
+switch
  (active
@@ -1464,12 +1464,8 @@
 ze()
- %3E 1
 ) %7B%0A
@@ -1475,16 +1475,279 @@
         
+ case 0:%0A                return null;%0A            case 1:%0A                return menu.add(0, activeApps.get(0).getId(), 0,%0A                        activeApps.get(0).getName()).setIcon(android.R.drawable.ic_menu_mapmode);%0A            default:%0A                final
  SubMenu
@@ -1804,16 +1804,20 @@
         
+   
+ 
 res.getS
@@ -1855,37 +1855,16 @@
 setIcon(
-%0A                    
 android.
@@ -1884,32 +1884,36 @@
 _menu_mapmode);%0A
+    
             for 
@@ -1913,16 +1913,22 @@
    for (
+final 
 CacheLis
@@ -1948,24 +1948,28 @@
 tiveApps) %7B%0A
+    
             
@@ -2035,278 +2035,65 @@
     
-%7D%0A            return subMenu.getItem();%0A        %7D else if (activeApps.size() == 1) %7B%0A            return menu.add(0, activeApps.get(0).getId(), 0,%0A                    activeApps.get(0).getName()).setIcon(android.R.drawable.ic_menu_mapmode);%0A        %7D%0A        return null;
+    %7D%0A                return subMenu.getItem();%0A        %7D
 %0A   
@@ -2305,16 +2305,22 @@
         
+final 
 CacheLis
@@ -2370,16 +2370,27 @@
 m(item, 
+LazyHolder.
 apps);%0A 

use lazy holder and switch to load apps