public interface Core extends Serializable {

    public static final String PLUGIN_UI = "UIPlugin";
    public static final String PLUGIN_SUPERUSER = "SuperUserPlugin";
    public static final String PLUGIN_RECOVERY = "RecoveryPlugin";
    public static final String PLUGIN_STORAGE = "StoragePlugin";
    public static final String PLUGIN_REBOOT = "RebootPlugin";
    public static final String PLUGIN_LICENSE = "LicensePlugin";
    public static final String PLUGIN_UPDATE = "UpdatePlugin";

    public interface CoreListener {

        public void pluginStarted(String name);

        public void pluginStopped(String name);

        public void coreMessage(int resId);

        public void coreStarted();

        public void coreStopped();
    }

    public void destroy();

    public boolean isStarted();

    public Context getContext();

    public void setContext(Context context);

    public Plugin getPlugin(String name);

    public Preferences getPreferences();

    public CloudStorage getCloudStorage();

    public void setCloudStorage(int cloudStorage);

    public ONandroid getONandroid();

    public Version getVersion();

    public void moveToInstall();
} public class LicensePlugin extends Plugin {

    private static final String LICENSE_CALLBACK_CLASS = "com.beerbong.zipinst.pro.LicenseCallback";

    private ILicenseCallback mLicenseCallback;
    private boolean mPurchased = false;
    private boolean mPro = false;

    public LicensePlugin(Core core) {
        super(core, Core.PLUGIN_LICENSE);
    }

    @Override
    public void start() {
        try {
            Class<?> pClass = Class.forName(LICENSE_CALLBACK_CLASS);
            mLicenseCallback = (ILicenseCallback) pClass.newInstance();

            mPro = true;

            ((CoreImpl) getCore()).setMessage(R.string.checking_license);

            mLicenseCallback.check(this);

            mPurchased = true;
        } catch (Throwable t) {
            t.printStackTrace();
        }
        started();
    }

    @Override
    public void stop() {
        if (mLicenseCallback != null) {
            mLicenseCallback.destroy();
        }
        stopped();
    }

    public void setPurchased(boolean purchased) {
        mPurchased = purchased;
    }

    public boolean isPurchased() {
        return mPurchased;
    }

    public boolean hasProCode() {
        return mPro;
    }

} public class StoragePlugin extends Plugin {

    public static final String ROOT_ID_PRIMARY_EMULATED = "primary";

    private static boolean sScanned = false;

    private String mInternalStoragePath;
    private String mExternalStoragePath;

    public StoragePlugin(Core core) {
        super(core, Core.PLUGIN_STORAGE);
    }

    @Override
    public void start() {
        ((CoreImpl) getCore()).setMessage(R.string.reading_storage_paths);

        (new AsyncTask<Void, Void, Void>() {

            @Override
            protected Void doInBackground(Void... params) {

                if (!sScanned) {
                    sScanned = true;
                    readMounts();
                    mExternalStoragePath = externalStorage();
                }

                return (Void) null;
            }

            @Override
            protected void onPostExecute(Void result) {
                started();
            }
        }).execute((Void) null);
    }

    @Override
    public void stop() {
        stopped();
    }

    public boolean hasExternalStorage() {
        return mExternalStoragePath != null;
//        return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
    }

    public boolean isExternalStorage(String path) {
        if (mInternalStoragePath == null) {
            mInternalStoragePath = "/sdcard";
        }
        return !path.startsWith(mInternalStoragePath) && !path.startsWith("/sdcard")
                && !path.startsWith("/mnt/sdcard");
    }

    public String getExternalStoragePath() {
        return mExternalStoragePath;
    }

    public String getInternalStoragePath() {
        return mInternalStoragePath;
    }

    public String getPath(String path) {
        String filePath = new String(path);

        Preferences prefs = getCore().getPreferences();
        String internalStorage = prefs.getInternalStorage();
        String externalStorage = prefs.getExternalStorage();

        String[] internalNames = new String[] {
                mInternalStoragePath,
                "/mnt/sdcard",
                "/storage/sdcard/",
                "/sdcard",
                "/storage/sdcard0",
                "/storage/emulated/0" };
        String[] externalNames = new String[] {
                mExternalStoragePath == null ? " " : mExternalStoragePath,
                "/mnt/extSdCard",
                "/storage/extSdCard/",
                "/extSdCard",
                "/storage/sdcard1",
                "/storage/emulated/1" };
        for (int i = 0; i < internalNames.length; i++) {
            String internalName = internalNames[i];
            String externalName = externalNames[i];
            boolean external = isExternalStorage(filePath);
            if (filePath.endsWith(".sh")) {
                if (!external) {
                    if (filePath.startsWith(internalName)) {
                        if (internalName.endsWith("/")) {
                            filePath = filePath.replace(internalName, "/" + "sdcard" + "/");
                        } else {
                            filePath = filePath.replace(internalName, "/" + "sdcard");
                        }
                        break;
                    }
                }
            } else {
                if (filePath.startsWith(externalName)) {
                    if (externalName.endsWith("/")) {
                        filePath = filePath.replace(externalName, "/" + externalStorage + "/");
                    } else {
                        filePath = filePath.replace(externalName, "/" + externalStorage);
                    }
                    break;
                } else if (filePath.startsWith(internalName)) {
                    if (internalName.endsWith("/")) {
                        filePath = filePath.replace(internalName, "/" + internalStorage + "/");
                    } else {
                        filePath = filePath.replace(internalName, "/" + internalStorage);
                    }
                    break;
                }
            }
        }
        if (filePath.startsWith("//")) {
            filePath = filePath.substring(1);
        }
        return filePath;
    }

    @SuppressWarnings("deprecation")
    public double getSpaceLeft() {
        StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
        double sdAvailSize = 0;
        if (Build.VERSION.SDK_INT > 17) {
            sdAvailSize = stat.getAvailableBlocksLong() * stat.getBlockSizeLong();
        } else {
            sdAvailSize = stat.getAvailableBlocks() * stat.getBlockSize();
        }
        // One binary gigabyte equals 1,073,741,824 bytes.
        return sdAvailSize / 1073741824;
    }

    public void addFileItemToStore(String filePath) {

        Context context = getCore().getContext();

        if (filePath == null || (!filePath.endsWith(".zip") && !filePath.endsWith(".sh"))) {
            Toast.makeText(context, R.string.error_file_manager_invalid_zip, Toast.LENGTH_SHORT)
                    .show();
            return;
        }

        if (!filePath.endsWith(".zip") && !filePath.endsWith(".sh")) {
            Toast.makeText(context, R.string.error_file_manager_zip, Toast.LENGTH_SHORT).show();
            return;
        }

        String sdcardPath = new String(filePath);

        filePath = getPath(filePath);

        File file = new File(sdcardPath);
        if (!file.exists()) {
            Toast.makeText(context, R.string.error_file_manager_not_found_zip, Toast.LENGTH_LONG)
                    .show();
        } else {

            FileItemStore.addItem(filePath, sdcardPath, false, getCore().getPreferences()
                    .getZipPosition());
        }
    }

    private void readMounts() {

        Core core = getCore();

        ArrayList<String> mounts = new ArrayList<String>();
        ArrayList<String> vold = new ArrayList<String>();

        Scanner scanner = null;
        try {
            scanner = new Scanner(new File("/proc/mounts"));
            while (scanner.hasNext()) {
                String line = scanner.nextLine();
                if (line.startsWith("/dev/block/vold/")) {
                    String[] lineElements = line.split(" ");
                    String element = lineElements[1];

                    mounts.add(element);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (scanner != null) {
                scanner.close();
            }
        }
        boolean addExternal = mounts.size() == 1 && hasExternalStorage();
        if (mounts.size() == 0 || addExternal) {
            mounts.add("/mnt/sdcard");
        }

        File fstab = findFstab(core);
        if (fstab != null) {
            try {
                String path = core.getContext().getExternalCacheDir() + File.separator
                        + fstab.getName();
                SuperUserPlugin suPlugin = (SuperUserPlugin) core.getPlugin(Core.PLUGIN_SUPERUSER);
                suPlugin.run("cp " + fstab.getAbsolutePath() + " " + path);
                suPlugin.run("chmod -R 777 " + path);

                scanner = new Scanner(new File(path));
                while (scanner.hasNext()) {
                    String line = scanner.nextLine();
                    if (line.startsWith("dev_mount")) {
                        String[] lineElements = line.split(" ");
                        String element = lineElements[2];

                        if (element.contains(":")) {
                            element = element.substring(0, element.indexOf(":"));
                        }

                        if (element.toLowerCase().indexOf("usb") < 0) {
                            vold.add(element);
                        }
                    } else if (line.startsWith("/devices/platform")) {
                        String[] lineElements = line.split(" ");
                        String element = lineElements[1];

                        if (element.contains(":")) {
                            element = element.substring(0, element.indexOf(":"));
                        }

                        if (element.toLowerCase().indexOf("usb") < 0) {
                            vold.add(element);
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (scanner != null) {
                    scanner.close();
                }
            }
        }
        if (addExternal && (vold.size() == 1 && hasExternalStorage())) {
            mounts.add(vold.get(0));
        }
        if (vold.size() == 0 || (vold.size() == 1 && hasExternalStorage())) {
            vold.add("/mnt/sdcard");
        }

        for (int i = 0; i < mounts.size(); i++) {
            String mount = mounts.get(i);
            File root = new File(mount);
            if (!vold.contains(mount)
                    || (!root.exists() || !root.isDirectory() || !root.canWrite())) {
                mounts.remove(i--);
            }
        }

        for (int i = 0; i < mounts.size(); i++) {
            String mount = mounts.get(i);
            if (mount.indexOf("sdcard0") >= 0 || mount.equalsIgnoreCase("/mnt/sdcard")
                    || mount.equalsIgnoreCase("/sdcard")) {
                mInternalStoragePath = mount;
//            } else {
//                mExternalStoragePath = mount;
            }
        }

        if (mInternalStoragePath == null) {
            mInternalStoragePath = "/sdcard";
        }
    }

    private String externalStorage() {
        Context context = getCore().getContext();
        String dirPath = null;
        try {
            String[] volumePaths = null;
            ArrayList<String> volumePathsList = null;
            String path = null;
            if (Build.VERSION.SDK_INT >= 14) {
                volumePaths = volumePaths(context);
                if (volumePaths != null) {
                    volumePathsList = new ArrayList<String>();
                    path = Environment.getExternalStorageDirectory().getAbsolutePath();
                }
            }
            try {
                String primaryVolumePath = primaryVolumePath(context);
                int i = volumePaths.length;
                for (int j = 0;; j++)
                    if (j < i) {
                        String volumePath = volumePaths[j];
                        try {
                            if ((volumePath.equals(System.getenv("EMULATED_STORAGE_SOURCE")))
                                    || (volumePath.equals(System.getenv("EXTERNAL_STORAGE")))
                                    || (volumePath.equals(path))
                                    || (volumePath.equals(primaryVolumePath))
                                    || (volumePath.toLowerCase().contains("usb")))
                                continue;
                            volumePathsList.add(volumePath);
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                    } else {
                        if (volumePathsList.size() == 1) {
                            dirPath = (String) volumePathsList.get(0);
                        }
                        return dirPath;
                    }
            } catch (Exception ex) {
                ex.printStackTrace();

            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return dirPath;
    }

    private String[] volumePaths(Context context) {
        try {
            StorageManager localStorageManager = (StorageManager) context
                    .getSystemService("storage");
            return (String[]) (String[]) localStorageManager.getClass()
                    .getMethod("getVolumePaths", new Class[0])
                    .invoke(localStorageManager, new Object[0]);
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    private String primaryVolumePath(Context context) {
        try {
            StorageManager localStorageManager = (StorageManager) context
                    .getSystemService("storage");
            Object localObject = localStorageManager.getClass()
                    .getMethod("getPrimaryVolume", new Class[0])
                    .invoke(localStorageManager, new Object[0]);
            return (String) localObject.getClass().getMethod("getPath", new Class[0])
                    .invoke(localObject, new Object[0]);
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    private File findFstab(Core core) {

        File file = null;

        file = new File("/system/etc/vold.fstab");
        if (file.exists()) {
            return file;
        }

        SuperUserPlugin suPlugin = (SuperUserPlugin) core.getPlugin(Core.PLUGIN_SUPERUSER);
        CommandResult cm = suPlugin
                .run("grep -ls \"/dev/block/\" * --include=fstab.* --exclude=fstab.goldfish");
        if (cm.getOutString() != null) {
            String[] files = cm.getOutString().split("\n");
            for (int i = 0; i < files.length; i++) {
                file = new File(files[i]);
                if (file.exists()) {
                    return file;
                }
            }
        }

        return null;
    }

} public class UIPlugin extends Plugin {

    private static final String ROBOTO_THIN = "font/Roboto-Light.ttf";

    private Map<String, UIInterface> mUiInterfaces;
    private Typeface mRobotoThin;

    public UIPlugin(Core core) {
        super(core, Core.PLUGIN_UI);
    }

    @Override
    public void start() {
        ((CoreImpl) getCore()).setMessage(R.string.initializing_ui);


        (new AsyncTask<Void, Void, Void>() {

            @Override
            protected Void doInBackground(Void... params) {
                mUiInterfaces = new HashMap<String, UIInterface>();

                mRobotoThin = Typeface
                        .createFromAsset(getCore().getContext().getAssets(), ROBOTO_THIN);
                return (Void) null;
            }

            @Override
            protected void onPostExecute(Void result) {
                started();
            }
        }).execute((Void) null);
    }

    @Override
    public void stop() {
        stopped();
    }

    public void unregisterUI(UIInterface uIInterface) {
        if (mUiInterfaces != null) {
            mUiInterfaces.remove(uIInterface.getClass().getName());
        }
    }

    public void registerUI(UIInterface uIInterface) {
        boolean darkTheme = getCore().getPreferences().isDarkTheme();
        uIInterface.setTheme(darkTheme ? R.style.AppTheme_Dark
                : R.style.AppTheme);

        redraw(uIInterface);

        if (mUiInterfaces != null) {
            mUiInterfaces.put(uIInterface.getClass().getName(), uIInterface);
        }
    }

    public void redraw() {
        Iterator<String> it = mUiInterfaces.keySet().iterator();
        while (it.hasNext()) {
            String key = it.next();
            UIInterface uiInterface = mUiInterfaces.get(key);
            redraw(uiInterface);
        }
    }

    public void redraw(UIInterface uIInterface) {
        redraw(uIInterface.getMainView());
    }

    public void redraw(View view) {
        setFont(view);
    }

    private void setFont(View view) {
        if (view == null) {
            return;
        }
        if (view instanceof ViewGroup) {
            int count = ((ViewGroup) view).getChildCount();
            for (int i = 0; i < count; i++) {
                setFont(((ViewGroup) view).getChildAt(i));
            }
        } else if (view instanceof TextView) {
            ((TextView) view).setTypeface(mRobotoThin);
        }
    }

} public class FragmentAbout extends UIPreferenceFragment {

    private static final String DONATE_URL = "http://forum.xda-developers.com/donatetome.php?u=1806623";
    private static final String PRO_URL = "https://play.google.com/store/apps/details?id=com.beerbong.zipinst";

    private static final String PREFERENCE_VERSION = "about_version";
    private static final String PREFERENCE_SITE = "about_pref";
    private static final String PREFERENCE_LICENSE = "license_pref";
    private static final String PREFERENCE_CHANGELOG = "changelog_pref";
    private static final String PREFERENCE_UPDATE = "updates_pref";
    private static final String PREFERENCE_DONATE = "donate_pref";

    @Override
    public int[] getVisibleMenuItems() {
        return null;
    }

    @Override
    public int getContentViewId() {
        return R.layout.fragment_about;
    }

    @Override
    public void create(boolean isNew) {

        Preference pref = findPreference(PREFERENCE_VERSION);
        pref.setSummary(getCore().getVersion().toString());

        LicensePlugin plugin = (LicensePlugin) getCore().getPlugin(Core.PLUGIN_LICENSE);
        boolean purchased = plugin.isPurchased();

        pref = findPreference(PREFERENCE_DONATE);
        pref.setTitle(purchased ? R.string.donate_title
                : R.string.become_a_pro);

        if (purchased) {
            PreferenceCategory cat = (PreferenceCategory) findPreference("about_category");
            cat.removePreference(findPreference(PREFERENCE_UPDATE));
        }
    }

    @Override
    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {

        String key = preference.getKey();

        if (PREFERENCE_LICENSE.equals(key)) {
            showDocument("license.html", R.string.license_title, R.string.license_error);
        } else if (PREFERENCE_CHANGELOG.equals(key)) {
            showDocument("changelog.html", R.string.changelog_title, R.string.changelog_error);
        } else if (PREFERENCE_SITE.equals(key)) {
            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getCore().getContext()
                    .getResources().getString(R.string.about_zip_summary))));
        } else if (PREFERENCE_DONATE.equals(key)) {
            LicensePlugin plugin = (LicensePlugin) getCore().getPlugin(Core.PLUGIN_LICENSE);
            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(plugin.isPurchased() ? DONATE_URL : PRO_URL)));
        } else if (PREFERENCE_UPDATE.equals(key)) {
            UpdatePlugin plugin = (UpdatePlugin) getCore().getPlugin(Core.PLUGIN_UPDATE);
            plugin.checkApplication();
        } else {
            return super.onPreferenceTreeClick(preferenceScreen, preference);
        }

        return true;
    }

    @Override
    public void restore(Bundle savedInstanceState) {
    }

    @Override
    public void save(Bundle outState) {
    }

    @Override
    public int getTitle() {
        return R.string.about_title;
    }

    private void showDocument(String document, final int title, int onError) {
        final Context context = getCore().getContext();

        String data = Files.readAssets(context, document);

        if (data == null) {
            Toast.makeText(context, onError, Toast.LENGTH_LONG).show();
            return;
        }

        WebView webView = new WebView(context);

        webView.loadDataWithBaseURL(null, data, "text/html", "utf-8", null);
        webView.setWebViewClient(new WebViewClient() {

            @Override
            public void onPageFinished(WebView view, String url) {
                AlertDialog.Builder alert = new AlertDialog.Builder(context); 
                alert.setTitle(title);
                alert.setView(view);
                alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.dismiss();
                    }
                });
                alert.show();
            }
        });
    }

} public class FragmentBackupRestore extends UIFragment implements ONandroidFinishListener {

    private static final String STORAGE_BACKUPS = "STORAGE_BACKUPS";
    private static final String CLOUD_BACKUPS = "CLOUD_BACKUPS";

    private class BackupItemsAdapterHolder implements FileItemsAdapterHolder {

        @Override
        public boolean useDragAndDrop() {
            return true;
        }

        @Override
        public boolean canRemove() {
            return true;
        }

        @Override
        public boolean showPath() {
            return false;
        }

        @Override
        public boolean showSize() {
            return true;
        }

        @Override
        public boolean showDate() {
            return false;
        }

        @Override
        public int getItemLayoutId() {
            return R.layout.item_backup;
        }

    }

    private Switch mSwitchOnandroid;

    private String mBackupFolder;

    private DragSortListView mStorageList;
    private ProgressBar mStorageProgress;
    private TextView mStorageEmpty;
    private List<FileItem> mStorageBackups;

    private ActionMode mActionMode;
    private ActionMode.Callback mActionStorageCallback;
    private ActionMode.Callback mActionCloudCallback;
    private DragSortItemView mSelectedView;
    private int mSelectedPosition;

    private CloudStorage mCloudStorage;

    private LinearLayout mCloudLayout;
    private DragSortListView mCloudList;
    private ProgressBar mCloudProgress;
    private TextView mCloudTitle;
    private TextView mCloudEmpty;
    private List<FileItem> mCloudBackups;
    private boolean mWaitingLogin;

    @Override
    public int[] getVisibleMenuItems() {
        return new int[] {
                R.id.menu_backup,
                R.id.menu_cloud,
                R.id.menu_refresh
        };
    }

    @Override
    public void onOptionsItemSelected(int id) {
        switch (id) {
            case R.id.menu_backup :
                Preferences prefs = getCore().getPreferences();
                RebootPlugin rPlugin = (RebootPlugin) getCore().getPlugin(Core.PLUGIN_REBOOT);
                if (prefs.isUseONandroid()) {
                    if (!getCore().getONandroid().isConfigured()) {
                        getCore().getONandroid().startWizard();
                    } else {
                        rPlugin.showBackupDialog();
                    }
                } else {
                    rPlugin.showBackupDialog();
                }
                break;
            case R.id.menu_refresh :
                refreshStorageBackups();
                if (mCloudStorage != null) {
                    mCloudStorage.refresh();
                }
                break;
            case R.id.menu_cloud :
                new CloudPicker(getCore().getContext(), new CloudPicker.CloudPickerListener() {

                    @Override
                    public void cloudStorageSelected(int id) {
                        mWaitingLogin = true;
                        getCore().getPreferences().setCloudStorage(id);
                        prepareCloudStorage();
                    }
                }).show();
                break;
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mWaitingLogin && mCloudStorage != null) {
            mCloudStorage.refresh();
        }
        mWaitingLogin = false;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (mCloudStorage != null) {
            mCloudStorage.onActivityResult(requestCode, resultCode, data);
        }
    }

    @Override
    public int getContentViewId() {
        return R.layout.fragment_backuprestore;
    }

    @Override
    public View getMainView(View rootView) {
        return rootView.findViewById(R.id.backuprestore_layout);
    }

    @Override
    public void create(boolean isNew) {

        View mainView = getMainView();

        final Preferences prefs = getCore().getPreferences();

        getCore().getONandroid().setONandroidFinishListener(this);

        mActionStorageCallback = new ActionMode.Callback() {

            @Override
            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                MenuInflater inflater = mode.getMenuInflater();
                inflater.inflate(R.menu.storage_backups, menu);
                return true;
            }

            @Override
            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                return false;
            }

            @Override
            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
                boolean ret = false;
                final String backup = mStorageBackups.get(mSelectedPosition).getName();
                switch (item.getItemId()) {
                    case R.id.menu_restore:
                        RebootPlugin rPlugin = (RebootPlugin) getCore().getPlugin(Core.PLUGIN_REBOOT);
                        rPlugin.showRestoreDialog(backup);
                        mode.finish();
                        break;
                    case R.id.menu_delete:
                        final Context context = getCore().getContext();
                        String message = context.getResources().getString(R.string.delete_backup_confirm,
                                backup);
                        Dialog.dialog(context, message, R.string.alert_delete_title, true,
                                new OnDialogClosedListener() {

                                    @Override
                                    public void dialogOk() {
                                        ((Activity) context).runOnUiThread(new Runnable() {

                                            @Override
                                            public void run() {
                                                final String toDelete = mBackupFolder + backup;
                
                                                new IndeterminateDialog(context, context.getResources().getString(
                                                        R.string.alert_deleting_folder, new Object[] {
                                                            backup
                                                        }), new IndeterminateDialogCallback() {
                
                                                    @Override
                                                    public void executeIndeterminate() {
                                                        boolean deleted = Files.recursiveDelete(new File(toDelete));
                                                        if (!deleted) {
                                                            SuperUserPlugin sPlugin = (SuperUserPlugin) getCore()
                                                                    .getPlugin(
                                                                            Core.PLUGIN_SUPERUSER);
                                                            sPlugin.run("rm -r " + toDelete);
                                                        }
                                                    }
                
                                                    @Override
                                                    public void finishedIndeterminate() {
                                                        mStorageBackups.remove(mSelectedPosition);
                                                        redrawStorageBackups();
                                                    }
                
                                                });
                                            }
                                        });
                                    }

                                    @Override
                                    public void dialogCancel() {
                                        redrawStorageBackups();
                                    }
                                });
                        mode.finish();
                        ret = true;
                        break;
                    case R.id.menu_sync:
                        FileItem it = mStorageBackups.get(mSelectedPosition);
                        SuperUserPlugin suPlugin = (SuperUserPlugin) getCore().getPlugin(Core.PLUGIN_SUPERUSER);
                        suPlugin.run("chmod -R 777 " + it.getPath());
                        mCloudStorage.zipIt(it.getPath());
                        mode.finish();
                        break;
                }
                if (mSelectedView != null) {
                    mSelectedView.setListSelected(false);
                }
                mSelectedView = null;
                return ret;
            }

            @Override
            public void onDestroyActionMode(ActionMode mode) {
                if (mSelectedView != null) {
                    mSelectedView.setListSelected(false);
                }
                mSelectedView = null;
                mActionMode = null;
            }
        };

        mActionCloudCallback = new ActionMode.Callback() {

            @Override
            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                MenuInflater inflater = mode.getMenuInflater();
                inflater.inflate(R.menu.cloud_backups, menu);
                return true;
            }

            @Override
            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                return false;
            }

            @Override
            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
                boolean ret = false;
                final CloudEntry entry = (CloudEntry) mCloudBackups.get(mSelectedPosition);
                switch (item.getItemId()) {
                    case R.id.menu_delete:
                        final Context context = getCore().getContext();
                        String message = context.getResources().getString(R.string.delete_backup_confirm,
                                entry.getName());
                        Dialog.dialog(context, message, R.string.alert_delete_title, true,
                                new OnDialogClosedListener() {

                                    @Override
                                    public void dialogOk() {
                                        mCloudStorage.remove(entry);
                                    }

                                    @Override
                                    public void dialogCancel() {
                                        redrawCloudBackups();
                                    }
                                });
                        mode.finish();
                        ret = true;
                        break;
                    case R.id.menu_sync:
                        CloudEntry it = (CloudEntry) mCloudBackups.get(mSelectedPosition);
                        mCloudStorage.download(it);
                        mode.finish();
                        break;
                }
                if (mSelectedView != null) {
                    mSelectedView.setListSelected(false);
                }
                mSelectedView = null;
                return ret;
            }

            @Override
            public void onDestroyActionMode(ActionMode mode) {
                if (mSelectedView != null) {
                    mSelectedView.setListSelected(false);
                }
                mSelectedView = null;
                mActionMode = null;
            }
        };

        mSwitchOnandroid = (Switch) mainView.findViewById(R.id.switch_onandroid);
        mSwitchOnandroid.setChecked(prefs.isUseONandroid());
        mSwitchOnandroid.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                prefs.setUseONandroid(isChecked);
                if (isChecked) {
                    getCore().getONandroid().startWizard();
                }
            }

        });

        RecoveryPlugin rPlugin = (RecoveryPlugin) getCore().getPlugin(Core.PLUGIN_RECOVERY);
        mBackupFolder = rPlugin.getBackupDir(true);

        Resources res = getCore().getContext().getResources();

        mStorageList = (DragSortListView) mainView.findViewById(R.id.storage_backups_list);
        mStorageList.setUiInterface(this);
        mStorageList.setOnItemLongClickListener(new OnItemLongClickListener() {

            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                if (mActionMode != null) {
                    return false;
                }

                mActionMode = getActivity().startActionMode(mActionStorageCallback);
                mSelectedView = (DragSortItemView) view;
                mSelectedView.setListSelected(true);
                mSelectedPosition = position;
                return true;
            }
        });
        mStorageProgress = (ProgressBar) mainView.findViewById(R.id.storage_backups_progress);
        mStorageEmpty = (TextView) mainView.findViewById(R.id.backups_storage_empty);

        mStorageEmpty.setText(res.getString(R.string.backups_folder_empty, mBackupFolder));

        mCloudLayout = (LinearLayout) mainView.findViewById(R.id.cloud_layout);

        mCloudList = (DragSortListView) mainView.findViewById(R.id.cloud_backups_list);
        mCloudList.setUiInterface(this);
        mCloudList.setOnItemLongClickListener(new OnItemLongClickListener() {

            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                if (mActionMode != null) {
                    return false;
                }

                mActionMode = getActivity().startActionMode(mActionCloudCallback);
                mSelectedView = (DragSortItemView) view;
                mSelectedView.setListSelected(true);
                mSelectedPosition = position;
                return true;
            }
        });
        mCloudProgress = (ProgressBar) mainView.findViewById(R.id.cloud_backups_progress);
        mCloudTitle = (TextView) mainView.findViewById(R.id.title_cloud);
        mCloudEmpty = (TextView) mainView.findViewById(R.id.backups_cloud_empty);

        prepareCloudStorage();

        if (isNew) {
            refreshStorageBackups();
            if (mCloudStorage != null) {
                mCloudStorage.refresh();
            }
        }
    }

    @Override
    public void restore(Bundle savedInstanceState) {
        mStorageBackups = (List<FileItem>) savedInstanceState.getSerializable(STORAGE_BACKUPS);
        redrawStorageBackups();
        mCloudBackups = (List<FileItem>) savedInstanceState.getSerializable(CLOUD_BACKUPS);
        redrawCloudBackups();
    }

    @Override
    public void save(Bundle outState) {
        outState.putSerializable(STORAGE_BACKUPS, (Serializable) mStorageBackups);
        outState.putSerializable(CLOUD_BACKUPS, (Serializable) mCloudBackups);
    }

    @Override
    public int getTitle() {
        return R.string.backuprestore_title;
    }

    @Override
    public void oNandroidFinished() {
        refreshStorageBackups();
    }

    private void prepareCloudStorage() {
        mCloudStorage = getCore().getCloudStorage();
        if (mCloudStorage == null) {
            mCloudLayout.setVisibility(View.GONE);
        } else {

            Resources res = getCore().getContext().getResources();

            mCloudLayout.setVisibility(View.VISIBLE);

            mCloudTitle.setText(res.getString(R.string.backups_in_cloud, res.getString(mCloudStorage.getName())));
            mCloudEmpty.setText(res.getString(R.string.backups_cloud_empty, res.getString(mCloudStorage.getName())));

            mCloudStorage.setCloudStorageListener(new CloudStorageListener() {

                @Override
                public void cloudStorageLoading() {
                    mCloudProgress.setVisibility(View.VISIBLE);
                    mCloudList.setVisibility(View.GONE);
                    mCloudEmpty.setVisibility(View.GONE);
                }

                @Override
                public void cloudStorageLoaded() {

                    List<CloudEntry> entries = (List<CloudEntry>) mCloudStorage.getEntries();
                    mCloudBackups = new ArrayList<FileItem>();
                    if (entries != null) {
                        mCloudBackups.addAll(entries);
                    }

                    redrawCloudBackups();
                }

                @Override
                public void cloudDownloadComplete() {
                    refreshStorageBackups();
                }

            });
        }
        
    }

    private void refreshStorageBackups() {

        mSelectedView = null;
        mSelectedPosition = -1;

        new AsyncTask<Void, Void, Void>() {

            @Override
            protected Void doInBackground(Void... params) {

                Core core = getCore();

                ((Activity) core.getContext()).runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        mStorageProgress.setVisibility(View.VISIBLE);
                        mStorageList.setVisibility(View.GONE);
                        mStorageEmpty.setVisibility(View.GONE);
                    }

                });

                RecoveryPlugin rPlugin = (RecoveryPlugin) core.getPlugin(Core.PLUGIN_RECOVERY);
                SuperUserPlugin suPlugin = (SuperUserPlugin) core.getPlugin(Core.PLUGIN_SUPERUSER);

                String[] backups = rPlugin.getBackupList();
                mStorageBackups = new ArrayList<FileItem>();

                if (backups != null) {
                    for (String backup : backups) {
                        CommandResult cmd = suPlugin.run("ls -lR " + mBackupFolder + backup);
                        long size = 0;
                        if (cmd.success()) {
                            try {
                                String s = cmd.getOutString();
                                String[] lines = s.split("\n");
                                for (String line : lines) {
                                    while (line.indexOf("  ") >= 0) {
                                        line = line.replace("  ", " ");
                                    }
                                    String[] split2 = line.split(" ");
                                    if (split2.length < 3) {
                                        continue;
                                    }
                                    try {
                                        size += Long.parseLong(split2[3]);
                                    } catch (NumberFormatException ex) {
                                        // ignore
                                    }
                                }
                            } catch (Exception ex) {
                                ex.printStackTrace();
                            }
                        }
                        FileItem item = new FileItem(backup, backup, mBackupFolder + backup, false);
                        item.setSize(size);
                        item.setImageAttr(R.attr.sdcardIcon);
                        mStorageBackups.add(item);
                    }
                }
                Collections.sort(mStorageBackups, new Comparator<FileItem>() {

                    @Override
                    public int compare(FileItem lhs, FileItem rhs) {
                        String name1 = lhs.getName();
                        String name2 = rhs.getName();
                        return name2.compareTo(name1);
                    }
                });

                return null;
            }

            @Override
            protected void onPostExecute(Void result) {
                redrawStorageBackups();
            }

        }.execute((Void) null);
    }

    private void redrawStorageBackups() {

        mStorageProgress.setVisibility(View.GONE);
        mStorageList.setVisibility(View.VISIBLE);
        mStorageEmpty.setVisibility(mStorageBackups.size() > 0 ? View.GONE : View.VISIBLE);

        Core core = getCore();

        mStorageList.setAdapter(new FileItemsAdapter(core, new BackupItemsAdapterHolder(),
                mStorageBackups));

        redraw();
    }

    private void redrawCloudBackups() {

        if (mCloudStorage == null) {
            return;
        }

        mCloudProgress.setVisibility(View.GONE);
        mCloudList.setVisibility(View.VISIBLE);
        mCloudEmpty.setVisibility(mCloudBackups.size() > 0 ? View.GONE : View.VISIBLE);

        Core core = getCore();

        mCloudList.setAdapter(new FileItemsAdapter(core, new BackupItemsAdapterHolder(), mCloudBackups));

        redraw();
    }

} public class FragmentGoo extends UIFragment implements URLStringReaderListener {

    private static final String NAVIGATE_ALL = "http://goo.im/json2&path=%s";
    private static final String NAVIGATE_COMPATIBLE = "http://goo.im/json2&path=%s&ro_board=%s";
    private static final String LOGIN_URL = "http://goo-inside.me/salt";
    private static final String ROOT = "/devs";
    private static final String PATH = "goo_path";
    private static final String FILES = "goo_files";

    private class GooItemsAdapterHolder implements FileItemsAdapterHolder {

        @Override
        public boolean useDragAndDrop() {
            return true;
        }

        @Override
        public boolean canRemove() {
            return true;
        }

        @Override
        public boolean showPath() {
            return false;
        }

        @Override
        public boolean showSize() {
            return true;
        }

        @Override
        public boolean showDate() {
            return false;
        }

        @Override
        public int getItemLayoutId() {
            return R.layout.item_goo;
        }

    }

    private IndeterminateDialog mDialog;
    private DragSortListView mList;
    private Switch mSwitchCompatible;
    private TextView mNavigating;
    private String mDevice;
    private String mPath;
    private List<FileItem> mFiles;
    private MenuItem mLoginItem;

    @Override
    public int[] getVisibleMenuItems() {
        return new int[] {R.id.menu_login};
    }

    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        mLoginItem = menu.findItem(R.id.menu_login);
        mLoginItem.setTitle(getCore().getPreferences().isLogged() ? R.string.menu_logout : R.string.menu_login);
    }

    @Override
    public void onOptionsItemSelected(int id) {
        if (id == R.id.menu_login) {
            Preferences prefs = getCore().getPreferences();
            if (prefs.isLogged()) {
                prefs.logout();
                Dialog.toast(getCore().getContext(), R.string.logged_out);
                mLoginItem.setTitle(R.string.menu_login);
            } else {
                showLoginDialog();
            }
        }
    }

    @Override
    public int getContentViewId() {
        return R.layout.fragment_goo;
    }

    @Override
    public View getMainView(View rootView) {
        return rootView.findViewById(R.id.goo_layout);
    }

    @Override
    public void create(boolean isNew) {

        mDevice = SystemProperties.getProperty("ro.product.device");

        View mainView = getMainView();

        mList = (DragSortListView) mainView.findViewById(R.id.file_list);
        mSwitchCompatible = (Switch) mainView.findViewById(R.id.switch_compatible);
        mNavigating = (TextView) mainView.findViewById(R.id.navigating_folder);

        mSwitchCompatible.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                mPath = ROOT;
                browse();
            }

        });

        mList.setUiInterface(this);
        mList.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                final FileItem item = mFiles.get(position);
                if (item.getKey() == null) {
                    mPath = item.getPath();
                    browse();
                } else {
                    String message = getCore()
                            .getContext()
                            .getResources()
                            .getString(R.string.goo_download_summary,
                                    new Object[] { item.getName() });
                    Dialog.dialog(getCore().getContext(), message, R.string.goo_download_title,
                            true, R.string.new_version_download, android.R.string.cancel,
                            new OnDialogClosedListener() {

                                @Override
                                public void dialogOk() {
                                    new DownloadFile(getCore(), item.getPath(), item.getName(),
                                            item.getMd5());
                                }

                                @Override
                                public void dialogCancel() {
                                }

                            });
                }
            }

        });

        if (isNew) {
            mPath = ROOT;
            mNavigating.setText(getCore().getContext().getResources()
                    .getString(R.string.navigating_folder, mPath));
            browse();
        }
    }

    @Override
    public void restore(Bundle savedInstanceState) {
        mFiles = (List<FileItem>) savedInstanceState.getSerializable(FILES);
        mPath = savedInstanceState.getString(PATH);
        redrawFiles();
    }

    @Override
    public void save(Bundle outState) {
        outState.putString(PATH, mPath);
        outState.putSerializable(FILES, (Serializable) mFiles);
    }

    @Override
    public int getTitle() {
        return R.string.goo_title;
    }

    @Override
    public void onReadEnd(String buffer) {

        mFiles = new ArrayList<FileItem>();

        try {

            JSONObject object = (JSONObject) new JSONTokener(buffer).nextValue();
            JSONArray list = object.getJSONArray("list");

            if (!mPath.equals(ROOT)) {
                String path = mPath.substring(0, mPath.lastIndexOf("/"));
                FileItem item = new FileItem(null, getCore().getContext().getResources()
                        .getString(R.string.up_a_level), path, false);
                item.setImageAttr(R.attr.folderIcon);
                mFiles.add(item);
            }

            for (int i = 0; i < list.length(); i++) {

                JSONObject result = list.getJSONObject(i);
                String fileName = result.optString("filename");

                if (fileName != null && !"".equals(fileName.trim())) {

                    if (mSwitchCompatible.isChecked()
                            && !mDevice.equals(result.optString("ro_board"))) {
                        continue;
                    }

                    String path = result.optString("path");

                    FileItem item = new FileItem(fileName, fileName, "http://goo.im" + path, false);
                    item.setMd5(result.optString("md5"));
                    item.setSize(result.optLong("filesize"));
                    item.setImageAttr(R.attr.fileIcon);
                    mFiles.add(item);

                } else {

                    String folder = result.optString("folder");
                    String folderName = folder.substring(folder.lastIndexOf("/") + 1);

                    FileItem item = new FileItem(null, folderName, folder, false);
                    item.setImageAttr(R.attr.folderIcon);
                    mFiles.add(item);
                }
            }
            redrawFiles();
        } catch (Exception ex) {
            ex.printStackTrace();
            Dialog.toast(getCore().getContext(), R.string.goo_browse_error);
        }
        mDialog.dismiss();
    }

    @Override
    public void onReadError(Exception ex) {
        mDialog.dismiss();
        ex.printStackTrace();
        Dialog.toast(getCore().getContext(), R.string.goo_browse_error);
    }

    private void redrawFiles() {
        mNavigating.setText(getCore().getContext().getResources()
                .getString(R.string.navigating_folder, mPath));

        mList.setAdapter(new FileItemsAdapter(getCore(), new GooItemsAdapterHolder(), mFiles));
    }

    private void browse() {
        String folder = mSwitchCompatible.isChecked() ? String.format(NAVIGATE_COMPATIBLE, mPath,
                mDevice) : String.format(NAVIGATE_ALL, mPath);
        new URLStringReader(this).execute(folder);
        mDialog = new IndeterminateDialog(getCore().getContext(), R.string.goo_browse_searching,
                null);
    }

    public void showLoginDialog() {

        final Preferences prefs = getCore().getPreferences();

        LayoutInflater inflater = ((Activity) getCore().getContext()).getLayoutInflater();
        View view = inflater.inflate(R.layout.dialog_login, null);
        final EditText username = (EditText) view.findViewById(R.id.username);
        final EditText password = (EditText) view.findViewById(R.id.password);

        username.setText(prefs.getLoginUserName());

        AlertDialog.Builder builder = new AlertDialog.Builder(getCore().getContext())
                .setTitle(R.string.goo_login)
                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

                    public void onClick(DialogInterface dialog, int whichButton) {
                        String user = username.getText() == null ? "" : username.getText()
                                .toString();
                        String pass = password.getText() == null ? "" : password.getText()
                                .toString();

                        prefs.setLoginUserName(user);

                        try {
                            mDialog = new IndeterminateDialog(getCore().getContext(), R.string.goo_loging,
                                    null);
                            String path = LOGIN_URL + "&username="
                                    + URLEncoder.encode(user, "UTF-8") + "&password="
                                    + URLEncoder.encode(pass, "UTF-8");
                            new URLStringReader(new URLStringReaderListener() {

                                @Override
                                public void onReadEnd(String buffer) {
                                    mDialog.dismiss();
                                    if (buffer != null && buffer.length() == 32) {
                                        prefs.login(buffer);
                                        Dialog.toast(getCore().getContext(), R.string.logged_in);
                                        mLoginItem.setTitle(R.string.menu_logout);
                                    } else if (buffer != null) {
                                        Dialog.toast(getCore().getContext(), R.string.logged_invalid);
                                    } else {
                                        Dialog.toast(getCore().getContext(), R.string.logged_down);
                                    }
                                }

                                @Override
                                public void onReadError(Exception ex) {
                                    mDialog.dismiss();
                                    ex.printStackTrace();
                                    Dialog.toast(getCore().getContext(), R.string.logged_error);
                                }
                            }).execute(path);
                        } catch (UnsupportedEncodingException ex) {
                            // should never get here
                        }
                        dialog.dismiss();
                    }
                })
                .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {

                    public void onClick(DialogInterface dialog, int whichButton) {
                        dialog.dismiss();
                    }
                });
        builder.setView(view);
        builder.create().show();
    }

} public class FragmentInstall extends UIFragment implements OnItemClickListener,
        FileItemStoreListener, FileItemsAdapterHolder {

    private DragSortListView mFileList;
    private TextView mHelp;

    private DragSortListView.DropListener mDropListener = new DragSortListView.DropListener() {

        public void drop(int from, int to) {
            FileItemStore.move(from, to);
            redrawItems();
        }
    };

    @Override
    public int getContentViewId() {
        return R.layout.fragment_install;
    }

    @Override
    public View getMainView(View rootView) {
        return rootView.findViewById(R.id.install_layout);
    }

    @Override
    public int getTitle() {
        return R.string.install_title;
    }

    @Override
    public void create(boolean isNew) {

        mFileList = (DragSortListView) getMainView().findViewById(R.id.file_list);
        mFileList.setUiInterface(this);
        mFileList.setOnItemClickListener(this);
        mFileList.setDropListener(mDropListener);
        mFileList.setRemoveListener(new DragSortListView.RemoveListener() {

            @Override
            public void remove(int which) {
                FileItem item = FileItemStore.getItem(which);
                removeItem(item);
            }
        });

        mHelp = (TextView) getMainView().findViewById(R.id.install_fragment_help);

        redrawItems();

        if (isNew) {
            FileItemStore.setFileItemStoreListener(this);
        }
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        FileItem item = FileItemStore.getItem(position);
        showInfoDialog(item);
    }

    @Override
    public int[] getVisibleMenuItems() {
        RecoveryPlugin rPlugin = (RecoveryPlugin) getCore().getPlugin(Core.PLUGIN_RECOVERY);
        int[] list = new int[] {
                R.id.menu_add_zip,
                R.id.menu_install,
                0,
                0,
                0
        };
        if (getCore().getPreferences().getRules().size() > 0) {
            list[2] = R.id.menu_apply_rules;
        }
        if (rPlugin.hasRecoveryBlock()) {
            list[3] = R.id.menu_install_recovery;
        }
        if (rPlugin.hasBootBlock()) {
            list[4] = R.id.menu_install_boot;
        }
        return list;
    }

    @Override
    public void restore(Bundle savedInstanceState) {
    }

    @Override
    public void save(Bundle outState) {
    }

    @Override
    public void storeChanged() {
        redrawItems();
    }

    public void removeItem(FileItem item) {

        FileItemStore.removeItem(item.getKey());

        redrawItems();

    }

    public void redrawItems() {

        mHelp.setVisibility(FileItemStore.size() > 0 ? View.GONE : View.VISIBLE);

        mFileList.setAdapter(new FileItemsAdapter(getCore(), this, FileItemStore.getItems()));

        redraw();
    }

    @Override
    public boolean useDragAndDrop() {
        return getCore().getPreferences().isUseDragAndDrop();
    }

    @Override
    public boolean canRemove() {
        return true;
    }

    @Override
    public boolean showPath() {
        return true;
    }

    @Override
    public boolean showSize() {
        return false;
    }

    @Override
    public boolean showDate() {
        return false;
    }

    @Override
    public int getItemLayoutId() {
        return R.layout.item_file;
    }

    @Override
    public void onOptionsItemSelected(int id) {
        switch (id) {
            case R.id.menu_add_zip:
                addZip();
                break;
            case R.id.menu_install:
                RebootPlugin rPlugin = (RebootPlugin) getCore().getPlugin(Core.PLUGIN_REBOOT);
                rPlugin.checkFilesAndMd5();
                break;
            case R.id.menu_apply_rules:
                applyRules();
                break;
            case R.id.menu_install_boot:
                selectImage(true);
                break;
            case R.id.menu_install_recovery:
                new RecoveryPicker(getCore().getContext(), new RecoveryPickerClicked() {

                    @Override
                    public void onRecoveryPickerClicked(int id) {
                        switch (id) {
                            case RecoveryPicker.ZIP:
                                selectImage(false);
                                break;
                            case RecoveryPicker.TWRP:
                                getTwrpUrl();
                                break;
                        }
                    }
                }).show();
                break;
        }
    }

    private void showInfoDialog(final FileItem item) {
        Context context = getCore().getContext();
        AlertDialog.Builder alert = new AlertDialog.Builder(context);
        alert.setTitle(context.getResources().getString(R.string.alert_file_title,
                new Object[] { item.getName() }));
        View view = LayoutInflater.from(context).inflate(R.layout.dialog_fileinfo,
                (ViewGroup) ((Activity) context).findViewById(R.id.fileinfo_dialog_layout));
        alert.setView(view);

        String path = item.getPath();
        File file = new File(path);

        String message = context.getResources().getString(
                R.string.alert_file_summary,
                new Object[] { (file.getParent() == null ? "" : file.getParent()) + "/",
                        Strings.formatSize(file.length()),
                        Strings.formatDate(file.lastModified()) });
        ((TextView)view.findViewById(R.id.fileinfo_text)).setText(message);

        CheckBox cbDelete = (CheckBox) view.findViewById(R.id.delete);
        cbDelete.setChecked(item.isDelete());
        cbDelete.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                item.setDelete(isChecked);
                redrawItems();
            }
            
        });

        alert.setPositiveButton(R.string.alert_file_close, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int whichButton) {
                dialog.dismiss();
            }
        });
        alert.setNeutralButton(R.string.alert_file_md5, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int whichButton) {
                dialog.dismiss();
                showMd5Dialog(item);
            }
        });

        alert.show();
    }

    private void showMd5Dialog(final FileItem item) {
        final Context context = getCore().getContext();

        AlertDialog.Builder alert = new AlertDialog.Builder(context);
        alert.setTitle(R.string.alert_md5_title);
        alert.setMessage(R.string.alert_md5_summary);

        final EditText input = new EditText(context);
        alert.setView(input);
        input.selectAll();

        alert.setPositiveButton(R.string.alert_md5_ok, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int whichButton) {
                dialog.dismiss();

                final ProgressDialog pDialog = new ProgressDialog(context);
                pDialog.setIndeterminate(true);
                pDialog.setMessage(context.getResources().getString(R.string.alert_md5_loading));
                pDialog.setCancelable(false);
                pDialog.setCanceledOnTouchOutside(false);
                pDialog.show();

                (new Thread() {

                    public void run() {

                        String path = item.getPath();
                        File file = new File(path);
                        final String md5 = Files.md5(file);

                        pDialog.dismiss();

                        final String text = input.getText() == null ? null : input.getText()
                                .toString();

                        getActivity().runOnUiThread(new Runnable() {

                            public void run() {
                                showMd5(md5, text);
                            }
                        });
                    }
                }).start();
            }
        });
        alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        alert.show();
    }

    private void showMd5(String md5, String text) {
        Context context = getCore().getContext();
        AlertDialog.Builder alert = new AlertDialog.Builder(context);
        if (text == null || "".equals(text.trim())) {
            alert.setMessage(md5);
        } else {
            if (md5.equals(text)) {
                alert.setMessage(context.getResources().getString(R.string.alert_md5_match));
            } else {
                alert.setMessage(context.getResources().getString(R.string.alert_md5_no_match,
                        new Object[] { text, md5 }));
            }
        }
        alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int whichButton) {
                dialog.dismiss();
            }
        });
        alert.show();
    }

    private void addZip() {
        Preferences prefs = getCore().getPreferences();
        Context context = getCore().getContext();
        if (prefs.isUseFolder()) {
            File folder = new File(prefs.getFolder());
            if (!folder.exists() || !folder.isDirectory()) {
                Toast.makeText(context, R.string.error_folder, Toast.LENGTH_SHORT).show();
            } else {
                new FolderPicker(context,
                        new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                FolderPicker picker = (FolderPicker) dialog;
                                StoragePlugin sPlugin = (StoragePlugin) getCore()
                                        .getPlugin(Core.PLUGIN_STORAGE);
                                sPlugin.addFileItemToStore(picker.getPath());
                            }
                        }, prefs.getFolder(), new String[] { "zip" },
                        null,
                        true).show();
            }
        } else {
            Intent intent = new Intent(context, RequestFileActivity.class);
            context.startActivity(intent);
        }
    }

    private void selectImage(final boolean isBoot) {
        Preferences prefs = getCore().getPreferences();
        Context context = getCore().getContext();
        File folder = new File(prefs.getFolder());
        if (!folder.exists() || !folder.isDirectory()) {
            Toast.makeText(context, R.string.error_folder, Toast.LENGTH_SHORT).show();
        } else {
            FolderPicker p = new FolderPicker(context, new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    FolderPicker picker = (FolderPicker) dialog;
                    installImage(picker.getPath(), isBoot);
                }
            }, prefs.getFolder(), new String[] { "img" }, null,
                    true);
            try {
                p.show();
            } catch (BadTokenException ex) {
                // ignore
            }
        }
    }

    private void getTwrpUrl() {
        final Context context = getCore().getContext();
        String board = SystemProperties.getProperty("ro.product.device");
        new URLStringReader(new URLStringReaderListener() {

            @Override
            public void onReadEnd(final String buffer) {
                try {
                    if (buffer != null && !"false".equals(buffer)) {
                        ((Activity) context).runOnUiThread(new Runnable() {

                            public void run() {
                                try {
                                    JSONObject result = (JSONObject) new JSONTokener(buffer).nextValue();
                                    new DownloadFile(getCore(),
                                            "http://goo.im" + result.getString("path"),
                                            result.getString("filename"), result.getString("md5"), new DownloadTask.OnDownloadFinishListener() {
            
                                                @Override
                                                public void onDownloadFinish(File file) {
                                                    installImage(file.getAbsolutePath(), false);
                                                }

                                                @Override
                                                public void onDownloadError(Exception ex) {
                                                    Dialog.error(context, R.string.downloading_error, null);
                                                }
                                    });

                                } catch (Exception ex) {
                                    ex.printStackTrace();
                                }
                            }
                        });
                    } else {
                        Dialog.toast(context, R.string.picker_recovery_no_recovery_found);
                    }
                } catch (Exception ex) {
                    System.out.println(buffer);
                    ex.printStackTrace();
                }
            }

            @Override
            public void onReadError(Exception ex) {
                Dialog.toast(context, R.string.picker_recovery_error_twrp);
            }
        }).execute("http://goo.im/json2&action=recovery&ro_board=" + board);
    }

    private void installImage(final String path, final boolean isBoot) {
        final Context context = getCore().getContext();
        int titleId = -1;
        String message = "";
        if (isBoot) {
            titleId = R.string.flashboot_confirm_title;
            message = context.getResources()
                    .getString(R.string.flashboot_confirm_message, path);
        } else {
            titleId = R.string.flashrecovery_confirm_title;
            message = context.getResources()
                    .getString(R.string.flashrecovery_confirm_message, path);
        }
        Dialog.dialog(context, message, titleId, true, new OnDialogClosedListener() {

            @Override
            public void dialogOk() {
                RecoveryPlugin rPlugin = (RecoveryPlugin) getCore().getPlugin(Core.PLUGIN_RECOVERY);
                if (isBoot) {
                    rPlugin.installBoot(path);
                    Dialog.toast(context, R.string.flashboot_installed);
                } else {
                    rPlugin.installRecovery(path);
                    Dialog.toast(context, R.string.flashrecovery_installed);
                }
            }

            @Override
            public void dialogCancel() {
            }

        });
    }

    public void applyRules() {
        FileItemStore.removeItems();
        StoragePlugin sPlugin = (StoragePlugin) getCore().getPlugin(Core.PLUGIN_STORAGE);
        Preferences prefs = getCore().getPreferences();
        List<Rule> rules = prefs.getRules();
        if (rules.size() > 0) {
            File folder = new File(prefs.getFolder());
            File[] files = folder.listFiles();

            if (files == null) {
                return;
            }

            Arrays.sort(files, new Comparator<File>() {

                @Override
                public int compare(File lhs, File rhs) {
                    String name1 = lhs.getName().toLowerCase();
                    String name2 = rhs.getName().toLowerCase();
                    return name1.compareTo(name2);
                }

            });

            for (Rule rule : rules) {
                for (File file : files) {
                    String fileName = file.getName();
                    if (fileName.toLowerCase().endsWith(".zip")
                            && !file.isDirectory()
                            && rule.apply(fileName)) {

                        sPlugin.addFileItemToStore(file.getAbsolutePath());
                    }
                }
            }
        }
    }

} public class FragmentRecovery extends UIPreferenceFragment {

    private static final String PREFERENCE_BACKUP = "recovery_fragment_backup";
    private static final String PREFERENCE_RESTORE = "recovery_fragment_restore";
    private static final String PREFERENCE_DELETE = "recovery_fragment_delete";
    private static final String PREFERENCE_WIPE_DATA = "recovery_fragment_wipe_data";
    private static final String PREFERENCE_WIPE_CACHES = "recovery_fragment_wipe_caches";
    private static final String PREFERENCE_FIX_PERMISSIONS = "recovery_fragment_fix_permissions";
    private static final String PREFERENCE_REBOOT = "recovery_fragment_reboot";

    private int mSelectedBackup;

    @Override
    public int[] getVisibleMenuItems() {
        return null;
    }

    @Override
    public int getContentViewId() {
        return R.layout.fragment_recovery;
    }

    @Override
    public void create(boolean isNew) {
    }

    @Override
    public void restore(Bundle savedInstanceState) {
    }

    @Override
    public void save(Bundle outState) {
    }

    @Override
    public int getTitle() {
        return R.string.recovery_fragment_title;
    }

    @Override
    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {

        final String key = preference.getKey();

        final Core core = getCore();
        final Context context = core.getContext();
        Resources res = context.getResources();

        final RebootPlugin rebootPlugin = (RebootPlugin) core.getPlugin(Core.PLUGIN_REBOOT);
        if (PREFERENCE_BACKUP.equals(key)) {
            rebootPlugin.showBackupDialog();
            return true;
        } else if (PREFERENCE_RESTORE.equals(key)) {
            rebootPlugin.showRestoreDialog();
            return true;
        } else if (PREFERENCE_DELETE.equals(key)) {
            showDeleteDialog();
            return true;
        }

        String message = "";
        if (PREFERENCE_WIPE_DATA.equals(key)) {
            message = res.getString(R.string.recovery_fragment_reboot,
                    res.getString(R.string.recovery_fragment_wipe_data));
        } else if (PREFERENCE_WIPE_CACHES.equals(key)) {
            message = res.getString(R.string.recovery_fragment_reboot,
                    res.getString(R.string.recovery_fragment_wipe_caches));
        } else if (PREFERENCE_FIX_PERMISSIONS.equals(key)) {
            message = res.getString(R.string.recovery_fragment_reboot,
                    res.getString(R.string.recovery_fragment_fix_permissions));
        } else if (PREFERENCE_REBOOT.equals(key)) {
            message = res.getString(R.string.recovery_fragment_reboot_question);
        }

        new AlertDialog.Builder(context)
                .setTitle(R.string.recovery_fragment_title)
                .setMessage(message)
                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

                    public void onClick(DialogInterface dialog, int whichButton) {
                        if (PREFERENCE_WIPE_DATA.equals(key)) {
                            rebootPlugin.simpleReboot(true, false, false);
                        } else if (PREFERENCE_WIPE_CACHES.equals(key)) {
                            rebootPlugin.simpleReboot(false, true, false);
                        } else if (PREFERENCE_FIX_PERMISSIONS.equals(key)) {
                            rebootPlugin.simpleReboot(false, false, true);
                        } else if (PREFERENCE_REBOOT.equals(key)) {
                            rebootPlugin.simpleReboot();
                        }
                        dialog.dismiss();
                    }
                })
                .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {

                    public void onClick(DialogInterface dialog, int whichButton) {
                        dialog.dismiss();
                    }
                }).show();

        return true;
    }

    private void showDeleteDialog() {

        Core core = getCore();
        final Context context = core.getContext();

        AlertDialog.Builder alert = new AlertDialog.Builder(context);
        alert.setTitle(R.string.alert_delete_title);

        RecoveryPlugin rPlugin = (RecoveryPlugin) core.getPlugin(Core.PLUGIN_RECOVERY);
        final String backupFolder = rPlugin.getBackupDir(true);
        final String[] backups = rPlugin.getBackupList();
        mSelectedBackup = backups.length > 0 ? 0 : -1;

        alert.setSingleChoiceItems(backups, mSelectedBackup, new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int which) {
                mSelectedBackup = which;
            }
        });

        alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int whichButton) {
                dialog.dismiss();

                if (mSelectedBackup >= 0) {
                    final String toDelete = backupFolder + backups[mSelectedBackup];

                    final ProgressDialog pDialog = new ProgressDialog(context);
                    pDialog.setIndeterminate(true);
                    pDialog.setMessage(context.getResources().getString(
                            R.string.alert_deleting_folder, new Object[] {
                                backups[mSelectedBackup]
                            }));
                    pDialog.setCancelable(false);
                    pDialog.setCanceledOnTouchOutside(false);
                    pDialog.show();

                    (new Thread() {

                        public void run() {

                            boolean deleted = Files.recursiveDelete(new File(toDelete));
                            if (!deleted) {
                                SuperUserPlugin sPlugin = (SuperUserPlugin) getCore().getPlugin(
                                        Core.PLUGIN_SUPERUSER);
                                sPlugin.run("rm -r " + toDelete);
                            }

                            pDialog.dismiss();
                        }
                    }).start();
                }
            }
        });

        alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        alert.show();

    }

} public class FragmentRules extends UIFragment implements OnItemClickListener,
        FileItemsAdapterHolder {

    private DragSortListView.DropListener mDropListener = new DragSortListView.DropListener() {

        public void drop(int from, int to) {
            moveRule(from, to);
            redrawRules();
        }
    };

    private DragSortListView mRuleList;
    private TextView mHelp;

    @Override
    public int[] getVisibleMenuItems() {
        return new int[] { R.id.menu_add_rule };
    }

    @Override
    public void onOptionsItemSelected(int id) {
        if (id == R.id.menu_add_rule) {
            showAddRuleDialog();
        }
    }

    @Override
    public int getContentViewId() {
        return R.layout.fragment_rules;
    }

    @Override
    public View getMainView(View rootView) {
        return rootView.findViewById(R.id.rules_layout);
    }

    @Override
    public void create(boolean isNew) {

        mRuleList = (DragSortListView) getMainView().findViewById(R.id.rules_list);
        mRuleList.setUiInterface(this);
        mRuleList.setOnItemClickListener(this);
        mRuleList.setDropListener(mDropListener);
        mRuleList.setRemoveListener(new DragSortListView.RemoveListener() {

            @Override
            public void remove(int which) {
                Preferences prefs = getCore().getPreferences();
                prefs.removeRule(which);
                redrawRules();
            }
        });

        mHelp = (TextView) getMainView().findViewById(R.id.rules_fragment_help);

        redrawRules();
    }

    @Override
    public void restore(Bundle savedInstanceState) {
    }

    @Override
    public void save(Bundle outState) {
    }

    @Override
    public int getTitle() {
        return R.string.rules_title;
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    }

    public void redrawRules() {

        Preferences prefs = getCore().getPreferences();
        List<Rule> rules = prefs.getRules();
        List<FileItem> array = new ArrayList<FileItem>();
        array.addAll(rules);

        mHelp.setVisibility(rules.size() > 0 ? View.GONE : View.VISIBLE);

        mRuleList.setAdapter(new FileItemsAdapter(getCore(), this, array));

        redraw();
    }

    @Override
    public boolean useDragAndDrop() {
        return true;
    }

    @Override
    public boolean canRemove() {
        return true;
    }

    @Override
    public boolean showPath() {
        return true;
    }

    @Override
    public boolean showSize() {
        return false;
    }

    @Override
    public boolean showDate() {
        return false;
    }

    @Override
    public int getItemLayoutId() {
        return R.layout.item_file;
    }

    private void moveRule(int from, int to) {
        if (from == to) {
            return;
        }
        Preferences prefs = getCore().getPreferences();
        List<Rule> rules = prefs.getRules();
        Rule toMove = rules.get(from);
        while (rules.indexOf(toMove) != to) {
            int i = rules.indexOf(toMove);
            Collections.swap(rules, i, to < from ? i - 1 : i + 1);
        }
        prefs.setRules(rules);
    }

    public void showAddRuleDialog() {

        final Preferences prefs = getCore().getPreferences();

        LayoutInflater inflater = ((Activity) getCore().getContext()).getLayoutInflater();
        View view = inflater.inflate(R.layout.dialog_rules, null);
        final Spinner spinner = (Spinner) view.findViewById(R.id.rule_rule);
        final EditText editText = (EditText) view.findViewById(R.id.rule_input);

        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
                getCore().getContext(), R.array.rule_options, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(adapter);

        AlertDialog.Builder builder = new AlertDialog.Builder(getCore().getContext())
                .setTitle(R.string.alert_rules_title)
                .setPositiveButton(R.string.alert_rules_add, new DialogInterface.OnClickListener() {

                    public void onClick(DialogInterface dialog, int whichButton) {
                        String text = editText.getText().toString();
                        if (text != null && !"".equals(text)) {
                            prefs.addRule(text, spinner.getSelectedItemPosition());
                            redrawRules();
                        }
                        dialog.dismiss();
                    }
                })
                .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {

                    public void onClick(DialogInterface dialog, int whichButton) {
                        dialog.dismiss();
                    }
                });
        builder.setView(view);
        builder.create().show();
    }

} public class FragmentSettings extends UIPreferenceFragment implements OnPreferenceChangeListener {

    private static final String PREFERENCE_CATEGORY_RECOVERY = "settings_recovery";
    private static final String PREFERENCE_CATEGORY_UPDATE = "settings_update";
    private static final String PREFERENCE_RECOVERY = "recovery";
    private static final String PREFERENCE_INTERNAL_SDCARD = "internalsdcard";
    private static final String PREFERENCE_EXTERNAL_SDCARD = "externalsdcard";
    private static final String PREFERENCE_FORCE_EXTERNAL_SDCARD = "mountextsdcard";
    private static final String PREFERENCE_FORCE_DATA_MEDIA = "forcedatamedia";
    private static final String PREFERENCE_BACKUP_EXTERNAL_SDCARD = "backupextsdcard";
    private static final String PREFERENCE_DAD = "draganddrop";
    private static final String PREFERENCE_DARK_THEME = "darktheme";
    private static final String PREFERENCE_CHECK_EXISTS = "checkexists";
    private static final String PREFERENCE_CHECK_UPDATE_STARTUP = "updateonstartup";
    private static final String PREFERENCE_CHECK_MD5 = "checkmd5";
//    private static final String PREFERENCE_OVERRIDE_LIST = "overridelist";
//    private static final String PREFERENCE_AUTOLOAD_LIST = "autoloadlist";
    private static final String PREFERENCE_DOWNLOAD_PATH = "downloadpath";
    private static final String PREFERENCE_ZIP_POSITION = "zipposition";
    private static final String PREFERENCE_OPTIONS = "show-options";
    private static final String PREFERENCE_SPACE_LEFT = "spaceleft";
    private static final String PREFERENCE_SYSTEMWIPE_ALERT = "wipesystemalert";
    private static final String PREFERENCE_USE_FOLDER = "usefolder";
    private static final String PREFERENCE_FOLDER = "folder";
    private static final String PREFERENCE_CHECK_ROOT = "checkroot";
    private static final String PREFERENCE_TIME_NOTIFICATIONS = "time_notifications";
    private static final String PREFERENCE_CHECK_ROM_UPDATES = "check_rom_updates";

    private Preference mRecovery;
    private Preference mInternalSdcard;
    private Preference mExternalSdcard;
    private CheckBoxPreference mForceExternalSdcard;
    private CheckBoxPreference mForceDataMedia;
    private CheckBoxPreference mBackupExternalSdcard;
    private CheckBoxPreference mDad;
    private CheckBoxPreference mDarkTheme;
    private CheckBoxPreference mCheckExists;
    private CheckBoxPreference mCheckMd5;
    //    private CheckBoxPreference mOverrideList;
    //    private CheckBoxPreference mAutoloadList;
    private CheckBoxPreference mSystemWipeAlert;
    private CheckBoxPreference mUpdatesOnStartup;
    private Preference mDownloadPath;
    private ListPreference mZipPosition;
    private MultiSelectListPreference mOptions;
    private ListPreference mSpaceLeft;
    private CheckBoxPreference mUseFolder;
    private Preference mFolder;
    private Preference mCheckRom;
    private ListPreference mCheckTime;

    private RomUpdater mRomUpdater;

    @Override
    public int getContentViewId() {
        return R.layout.fragment_settings;
    }

    @Override
    public void create(boolean isNew) {

        mRecovery = findPreference(PREFERENCE_RECOVERY);
        mInternalSdcard = findPreference(PREFERENCE_INTERNAL_SDCARD);
        mExternalSdcard = findPreference(PREFERENCE_EXTERNAL_SDCARD);
        mForceExternalSdcard = (CheckBoxPreference) findPreference(PREFERENCE_FORCE_EXTERNAL_SDCARD);
        mForceDataMedia = (CheckBoxPreference) findPreference(PREFERENCE_FORCE_DATA_MEDIA);
        mBackupExternalSdcard = (CheckBoxPreference) findPreference(PREFERENCE_BACKUP_EXTERNAL_SDCARD);
        mDad = (CheckBoxPreference) findPreference(PREFERENCE_DAD);
        mDarkTheme = (CheckBoxPreference) findPreference(PREFERENCE_DARK_THEME);
        mCheckExists = (CheckBoxPreference) findPreference(PREFERENCE_CHECK_EXISTS);
        mCheckMd5 = (CheckBoxPreference) findPreference(PREFERENCE_CHECK_MD5);
        //        mOverrideList = (CheckBoxPreference) findPreference(PREFERENCE_OVERRIDE_LIST);
        //        mAutoloadList = (CheckBoxPreference) findPreference(PREFERENCE_AUTOLOAD_LIST);
        mDownloadPath = findPreference(PREFERENCE_DOWNLOAD_PATH);
        mZipPosition = (ListPreference) findPreference(PREFERENCE_ZIP_POSITION);
        mOptions = (MultiSelectListPreference) findPreference(PREFERENCE_OPTIONS);
        mSpaceLeft = (ListPreference) findPreference(PREFERENCE_SPACE_LEFT);
        mSystemWipeAlert = (CheckBoxPreference) findPreference(PREFERENCE_SYSTEMWIPE_ALERT);
        mUpdatesOnStartup = (CheckBoxPreference) findPreference(PREFERENCE_CHECK_UPDATE_STARTUP);
        mUseFolder = (CheckBoxPreference) findPreference(PREFERENCE_USE_FOLDER);
        mFolder = findPreference(PREFERENCE_FOLDER);
        mCheckRom = findPreference(PREFERENCE_CHECK_ROM_UPDATES);
        mCheckTime = (ListPreference) findPreference(PREFERENCE_TIME_NOTIFICATIONS);

        Preferences prefs = getCore().getPreferences();

        mForceExternalSdcard.setChecked(prefs.isForceExternalStorage());
        mForceDataMedia.setChecked(prefs.isForceDataMedia());
        mBackupExternalSdcard.setChecked(prefs.isBackupExternalStorage());
        mDad.setChecked(prefs.isUseDragAndDrop());
        mDarkTheme.setChecked(prefs.isDarkTheme());
        mCheckExists.setChecked(prefs.isCheckExists());
        mCheckMd5.setChecked(prefs.isCheckMD5());
//        mOverrideList.setChecked(prefs.isOverrideList());
//        mAutoloadList.setChecked(prefs.isAutoloadList());
        mZipPosition.setValue(prefs.getZipPosition());
        mZipPosition.setOnPreferenceChangeListener(this);
        mOptions.setValues(prefs.getShowOptions());
        mSpaceLeft.setValue(String.valueOf(prefs.getSpaceLeft()));
        mSpaceLeft.setOnPreferenceChangeListener(this);
        mSystemWipeAlert.setChecked(prefs.isShowSystemWipeAlert());
        mUseFolder.setChecked(prefs.isUseFolder());
        mUpdatesOnStartup.setChecked(prefs.isCheckUpdatesStartup());
        mCheckTime.setValue(String.valueOf(prefs.getTimeNotifications()));

        mRomUpdater = new RomUpdater(getCore());

        StoragePlugin sPlugin = (StoragePlugin) getCore().getPlugin(Core.PLUGIN_STORAGE);
        if (!sPlugin.hasExternalStorage()) {
            PreferenceCategory category = (PreferenceCategory) findPreference(PREFERENCE_CATEGORY_RECOVERY);
            category.removePreference(mExternalSdcard);
            category.removePreference(mForceExternalSdcard);
            category.removePreference(mBackupExternalSdcard);
        }

        LicensePlugin lPlugin = (LicensePlugin) getCore().getPlugin(Core.PLUGIN_LICENSE);
        PreferenceCategory category = (PreferenceCategory) findPreference(PREFERENCE_CATEGORY_UPDATE);
        if (lPlugin.isPurchased()) {
            category.removePreference(mUpdatesOnStartup);
        }
        if (!mRomUpdater.canUpdate()) {
            category.removePreference(mCheckRom);
            category.removePreference(mCheckTime);
        }

        updateSummaries();
    }

    @Override
    public void restore(Bundle savedInstanceState) {
    }

    @Override
    public void save(Bundle outState) {
    }

    @Override
    public int getTitle() {
        return R.string.settings_title;
    }

    @Override
    public int[] getVisibleMenuItems() {
        return null;
    }

    @Override
    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
        String key = preference.getKey();

        final Preferences prefs = getCore().getPreferences();

        if (PREFERENCE_RECOVERY.equals(key)) {

            selectRecovery();

        } else if (PREFERENCE_INTERNAL_SDCARD.equals(key)) {

            selectSdcard(true);

        } else if (PREFERENCE_EXTERNAL_SDCARD.equals(key)) {

            selectSdcard(false);

        } else if (PREFERENCE_DAD.equals(key)) {

            boolean useDad = ((CheckBoxPreference) preference).isChecked();
            prefs.setUseDragAndDrop(useDad);

            FileItemStore.removeItems();

        } else if (PREFERENCE_DARK_THEME.equals(key)) {

            boolean darkTheme = ((CheckBoxPreference) preference).isChecked();
            prefs.setDarkTheme(darkTheme);

            showRestartDialog();

        } else if (PREFERENCE_CHECK_EXISTS.equals(key)) {

            boolean checkExists = ((CheckBoxPreference) preference).isChecked();
            prefs.setCheckExists(checkExists);

        } else if (PREFERENCE_CHECK_UPDATE_STARTUP.equals(key)) {

            boolean checkUpdate = ((CheckBoxPreference) preference).isChecked();
            prefs.setCheckUpdatesStartup(checkUpdate);

        } else if (PREFERENCE_CHECK_MD5.equals(key)) {

            boolean checkMd5 = ((CheckBoxPreference) preference).isChecked();
            prefs.setCheckMD5(checkMd5);

//        } else if (PREFERENCE_OVERRIDE_LIST.equals(key)) {
//
//            boolean overrideList = ((CheckBoxPreference) preference).isChecked();
//            pManager.setOverrideList(overrideList);
//
//        } else if (PREFERENCE_AUTOLOAD_LIST.equals(key)) {
//
//            boolean autoloadList = ((CheckBoxPreference) preference).isChecked();
//            pManager.setAutoloadList(autoloadList);

        } else if (PREFERENCE_DOWNLOAD_PATH.equals(key)) {

            pickFolder(prefs.getDownloadPath(), new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    FolderPicker picker = (FolderPicker) dialog;
                    prefs.setDownloadPath(picker.getPath());
                    updateSummaries();
                }

            });

        } else if (PREFERENCE_FOLDER.equals(key)) {

            pickFolder(prefs.getFolder(), new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    FolderPicker picker = (FolderPicker) dialog;
                    prefs.setFolder(picker.getPath());
                    updateSummaries();
                }

            });

        } else if (PREFERENCE_SYSTEMWIPE_ALERT.equals(key)) {

            boolean showAlert = ((CheckBoxPreference) preference).isChecked();
            prefs.setShowSystemWipeAlert(showAlert);

        } else if (PREFERENCE_CHECK_ROOT.equals(key)) {

            SuperUserPlugin sPlugin = (SuperUserPlugin) getCore().getPlugin(Core.PLUGIN_SUPERUSER);
            showCheckRootDialog(sPlugin.test());

        } else if (PREFERENCE_CHECK_ROM_UPDATES.equals(key)) {

            mRomUpdater.check();

        }

        return true;
    }

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        String key = preference.getKey();

        Preferences prefs = getCore().getPreferences();

        if (PREFERENCE_SPACE_LEFT.equals(key)) {

            prefs.setSpaceLeft(Double.parseDouble(newValue.toString()));

        } else if (PREFERENCE_ZIP_POSITION.equals(key)) {

            prefs.setZipPosition((String)newValue);

        } else if (PREFERENCE_TIME_NOTIFICATIONS.equals(key)) {

            long time = Long.parseLong((String)newValue);
            prefs.setTimeNotifications(time);
            SystemProperties.setAlarm(getCore().getContext(), time, false);

        }
        return false;
    }

    private void updateSummaries() {
        RecoveryPlugin rPlugin = (RecoveryPlugin) getCore().getPlugin(Core.PLUGIN_RECOVERY);
        RecoveryInfo info = rPlugin.getRecovery();
        Preferences prefs = getCore().getPreferences();
        mRecovery.setSummary(getResources().getText(R.string.recovery_summary) + " ("
                + info.getName() + ")");
        mInternalSdcard.setSummary(getResources().getText(R.string.internalsdcard_summary) + " ("
                + prefs.getInternalStorage() + ")");
        mExternalSdcard.setSummary(getResources().getText(R.string.externalsdcard_summary) + " ("
                + prefs.getExternalStorage() + ")");
        mDownloadPath.setSummary(prefs.getDownloadPath());
        mFolder.setSummary(prefs.getFolder());
    }

    private void pickFolder(String defaultValue, DialogInterface.OnClickListener listener) {
        new FolderPicker(getCore().getContext(), listener, defaultValue).show();
    }

    private void selectSdcard(final boolean internal) {
        final Context context = getCore().getContext();
        final Preferences prefs = getCore().getPreferences();
        
        final EditText input = new EditText(context);
        input.setText(internal ? prefs.getInternalStorage() : prefs.getExternalStorage());

        new AlertDialog.Builder(context)
                .setTitle(R.string.sdcard_alert_title)
                .setMessage(R.string.sdcard_alert_summary)
                .setView(input)
                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

                    public void onClick(DialogInterface dialog, int whichButton) {
                        String value = input.getText().toString();

                        if (value == null || "".equals(value.trim())) {
                            Toast.makeText(context, R.string.sdcard_alert_error,
                                    Toast.LENGTH_SHORT).show();
                            dialog.dismiss();
                            return;
                        }

                        if (value.startsWith("/")) {
                            value = value.substring(1);
                        }

                        if (internal) {
                            prefs.setInternalStorage(value);
                        } else {
                            prefs.setExternalStorage(value);
                        }
                        updateSummaries();
                        dialog.dismiss();
                    }
                })
                .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {

                    public void onClick(DialogInterface dialog, int whichButton) {
                        dialog.dismiss();
                    }
                }).show();
    }

    private void selectRecovery() {
        Context context = getCore().getContext();

        View view = LayoutInflater.from(context).inflate(R.layout.dialog_recovery, null);

        RadioButton cbCwmbased = (RadioButton) view.findViewById(R.id.cwmbased);
        RadioButton cbCwm = (RadioButton) view.findViewById(R.id.cwm);
        RadioButton cbTwrp = (RadioButton) view.findViewById(R.id.twrp);
        RadioButton cb4ext = (RadioButton) view.findViewById(R.id.fourext);

        final RadioGroup mGroup = (RadioGroup) view.findViewById(R.id.recovery_radio_group);

        final RecoveryPlugin rPlugin = (RecoveryPlugin) getCore().getPlugin(Core.PLUGIN_RECOVERY);
        RecoveryInfo info = rPlugin.getRecovery();
        switch (info.getId()) {
            case RecoveryInfo.RECOVERY_CWM_BASED:
                cbCwmbased.setChecked(true);
                break;
            case RecoveryInfo.RECOVERY_CWM:
                cbCwm.setChecked(true);
                break;
            case RecoveryInfo.RECOVERY_TWRP:
                cbTwrp.setChecked(true);
                break;
            case RecoveryInfo.RECOVERY_4EXT:
                cb4ext.setChecked(true);
                break;
        }

        new AlertDialog.Builder(context).setTitle(R.string.recovery_alert_title)
                .setMessage(R.string.recovery_alert_summary).setView(view)
                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

                    public void onClick(DialogInterface dialog, int whichButton) {

                        int id = mGroup.getCheckedRadioButtonId();

                        switch (id) {
                            case R.id.cwmbased:
                                id = RecoveryInfo.RECOVERY_CWM_BASED;
                                break;
                            case R.id.cwm:
                                id = RecoveryInfo.RECOVERY_CWM;
                                break;
                            case R.id.twrp:
                                id = RecoveryInfo.RECOVERY_TWRP;
                                break;
                            case R.id.fourext:
                                id = RecoveryInfo.RECOVERY_4EXT;
                                break;
                        }

                        rPlugin.setRecovery(id);

                        updateSummaries();

                        dialog.dismiss();
                    }
                })
                .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {

                    public void onClick(DialogInterface dialog, int whichButton) {
                        dialog.dismiss();
                    }
                }).show();
    }

    private void showRestartDialog() {
        final Context context = getCore().getContext();
        AlertDialog.Builder alert = new AlertDialog.Builder(context);
        alert.setTitle(R.string.restart_needed);
        alert.setMessage(R.string.restart_needed_theme_message);
        alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int whichButton) {

                dialog.dismiss();

                Intent intent = new Intent(context, MainActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
                context.startActivity(intent);
                getActivity().finish();

            }
        });
        alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int whichButton) {
                dialog.dismiss();
            }
        });
        alert.show();
    }

    private void showCheckRootDialog(boolean granted) {
        AlertDialog.Builder alert = new AlertDialog.Builder(getCore().getContext());
        alert.setTitle(R.string.checkroot_title);
        alert.setMessage(granted ? R.string.checkroot_yes : R.string.checkroot_no);
        alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int whichButton) {

                dialog.dismiss();
            }
        });
        alert.show();
    }

} public class DownloadFile {

    public DownloadFile(Core core, String url, String fileName, String md5) {
        this(core, url, fileName, md5, null);
    }

    public DownloadFile(Core core, String url, String fileName, String md5, DownloadTask.OnDownloadFinishListener listener) {

        Context context = core.getContext();

        final ProgressDialog progressDialog = new ProgressDialog(context);

        if (fileName == null) {
            fileName = url.substring(url.lastIndexOf("/") + 1);
            if (fileName.indexOf("?") >= 0) {
                fileName = fileName.substring(0, fileName.indexOf("?"));
            }
            if (!fileName.contains(".zip") && !fileName.contains(".apk")) {
                fileName = "unknown-file-name.zip";
            }
        }

        final DownloadTask downloadFile = new DownloadTask(core, progressDialog, url, fileName, md5, listener);

        progressDialog.setTitle(R.string.download);
        progressDialog.setMessage(context.getResources().getString(R.string.downloading,
                new Object[] { url, core.getPreferences().getDownloadPath() }));
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.setCancelable(false);
        progressDialog.setProgress(0);
        progressDialog.setButton(Dialog.BUTTON_NEGATIVE,
                context.getResources().getString(android.R.string.cancel),
                new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        downloadFile.detach();
                        downloadFile.cancel(true);
                    }
                });

        downloadFile.attach(progressDialog);
        progressDialog.show();
        downloadFile.execute();
    }
} public class Downloads {

    private static List<DownloadTask> sList = new ArrayList<DownloadTask>();

    public static void addDownloadTask(DownloadTask task) {
        sList.add(task);
    }

    public static void removeDownloadTask(DownloadTask task) {
        sList.remove(task);
    }

    public static void cancelAll() {
        int size = sList.size();
        for (int i = size - 1; i >= 0; i--) {
            DownloadTask task = (DownloadTask) sList.get(i);
            task.detach();
            task.cancel(true);
        }
    }
} public class Menus {

    public static void onPrepareOptionsMenu(Menu menu, IFragment fragment) {
        if (fragment == null) {
            return;
        }
        for (int i = 0; menu != null && i < menu.size(); i++) {
            MenuItem item = menu.getItem(i);
            boolean visible = false;
            int[] visibleMenuItems = fragment.getVisibleMenuItems();
            if (visibleMenuItems != null) {
                for (int id : visibleMenuItems) {
                    if (id != 0 && item.getItemId() == id) {
                        visible = true;
                        break;
                    }
                }
            }
            item.setVisible(visible);
        }
    }
} public class FileItemStore {

    public interface FileItemStoreListener {

        public void storeChanged();
    }

    private static FileItemStoreListener sListener;
    private static List<FileItem> sList = new ArrayList<FileItem>();

    public static void setFileItemStoreListener(FileItemStoreListener listener) {
        sListener = listener;
    }

    public static int size() {
        return sList.size();
    }

    public static List<FileItem> getItems() {
        return sList;
    }

    public static String[] getPaths() {
        String[] paths = new String[sList.size()];
        int i = 0;
        for (FileItem item : sList) {
            paths[i] = item.getPath();
            i++;
        }
        return paths;
    }

    public static FileItem getItem(int i) {
        return sList.get(i);
    }

    public static void addItem(String realPath, String sdcardPath, boolean delete, String zipPosition) {

        sList.remove(realPath);

        FileItem item = new FileItem(realPath, sdcardPath.substring(sdcardPath.lastIndexOf("/") + 1),
                sdcardPath, delete);

        if ("first".equals(zipPosition)) {
            sList.add(0, item);
        } else {
            sList.add(item);
        }

        if (sListener != null) {
            sListener.storeChanged();
        }
    }

    public static void removeItems() {
        sList.clear();
        if (sListener != null) {
            sListener.storeChanged();
        }
    }

    public static void removeItem(String key) {
        int size = size(), i = 0;
        for (; i < size; i++) {
            if (key.equals(sList.get(i).getKey())) {
                sList.remove(i);
                return;
            }
        }
        if (sListener != null) {
            sListener.storeChanged();
        }
    }

    public static void move(int from, int to) {
        if (from == to)
            return;
        FileItem toMove = sList.get(from);
        while (sList.indexOf(toMove) != to) {
            int i = sList.indexOf(toMove);
            Collections.swap(sList, i, to < from ? i - 1 : i + 1);
        }
        if (sListener != null) {
            sListener.storeChanged();
        }
    }

    private FileItemStore() {
    }
} public interface IFragment {

    public int[] getVisibleMenuItems();

    public void onOptionsItemSelected(int id);

    public void onPrepareOptionsMenu(Menu menu);
} public abstract class UIActivity extends Activity implements UIInterface, Serializable {

    private Core mCore;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        CoreFactory.init(this);

        mCore = CoreFactory.getCore();

        ((UIPlugin) mCore.getPlugin(Core.PLUGIN_UI)).registerUI(this);

        super.onCreate(savedInstanceState);

        int resId = getContentViewId();
        if (resId != 0) {
            setContentView(resId);
        }

        create(savedInstanceState == null);

        if (savedInstanceState != null) {
            restore(savedInstanceState);
        }

        redraw();

    }

    @Override
    protected void onResume() {
        super.onResume();

        CoreFactory.init(this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        ((UIPlugin) mCore.getPlugin(Core.PLUGIN_UI)).unregisterUI(this);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        save(outState);
    }

    @Override
    public View getMainView(View rootView) {
        return getMainView();
    }

    @Override
    public void redraw() {
        ((UIPlugin) mCore.getPlugin(Core.PLUGIN_UI)).redraw(this);
    }

    public void moveToStart() {
    }

    protected Core getCore() {
        return mCore;
    }

} public class Dialog extends android.app.Dialog {

    public interface OnDialogClosedListener {

        public void dialogOk();

        public void dialogCancel();
    }

    public interface WizardListener {

        public void wizardNextStep();

        public void wizardCancelled();

        public void wizardFinished();

        public boolean wizardIsLastStep();

        public boolean wizardIsContinueEnabled();
    }

    public static void alert(Context context, int messageId, OnDialogClosedListener listener) {
        alert(context, context.getResources().getString(messageId), listener);
    }

    public static void alert(Context context, String message, OnDialogClosedListener listener) {
        dialog(context, message, R.string.alert_title, false, listener);
    }

    public static void error(Context context, int messageId, OnDialogClosedListener listener) {
        error(context, context.getResources().getString(messageId), listener);
    }

    public static void error(Context context, String message, OnDialogClosedListener listener) {
        dialog(context, message, R.string.error_title, false, listener);
    }

    public static void dialog(Context context, String message, int titleId, boolean showCancel,
            final OnDialogClosedListener listener) {
        dialog(context, message, titleId, showCancel, android.R.string.ok, android.R.string.cancel,
                listener);
    }

    public static void dialog(Context context, String message, int titleId, boolean showCancel,
            int okId, int cancelId, final OnDialogClosedListener listener) {
        AlertDialog.Builder alert = new AlertDialog.Builder(context);
        alert.setTitle(titleId);
        alert.setMessage(message);
        alert.setCancelable(false);
        alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int whichButton) {
                dialog.dismiss();

                if (listener != null) {
                    listener.dialogOk();
                }
            }
        });
        if (showCancel) {
            alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {

                public void onClick(DialogInterface dialog, int whichButton) {
                    dialog.dismiss();

                    if (listener != null) {
                        listener.dialogCancel();
                    }
                }
            });
        }
        alert.show();
    }

    public static AlertDialog wizard(Context context, int titleId, int layoutId, final WizardListener listener) {
        return wizard(context, titleId, layoutId, R.string.wizard_finish, listener);
    }

    public static AlertDialog wizard(Context context, int titleId, int layoutId, final int finishId, final WizardListener listener) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(titleId);
        builder.setCancelable(false);
        View view = LayoutInflater.from(context).inflate(layoutId, null);
        builder.setView(view);
        builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int whichButton) {
                dialog.dismiss();

                listener.wizardCancelled();
            }
        });
        builder.setPositiveButton(R.string.wizard_continue, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int whichButton) {
            }
        });
        final AlertDialog alertDialog = builder.create();
        alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {

            @Override
            public void onShow(DialogInterface dialog) {
                Button b = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
                b.setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        if (listener.wizardIsLastStep()) {
                            alertDialog.dismiss();
                            listener.wizardFinished();
                        } else {
                            listener.wizardNextStep();
                            Button button = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
                            if (listener.wizardIsLastStep()) {
                                button.setText(finishId);
                            }
                            button.setEnabled(listener.wizardIsContinueEnabled());
                            button.invalidate();
                        }
                    }
                });
            }
        });
        alertDialog.show();
        listener.wizardNextStep();
        Button button = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
        button.setText(listener.wizardIsLastStep() ? finishId : R.string.wizard_continue);
        button.setEnabled(listener.wizardIsContinueEnabled());
        button.invalidate();
        return alertDialog;
    }

    public static AlertDialog customDialog(Context context, int layoutId, int titleId, int okButtonTextId,
            boolean showCancel, final OnDialogClosedListener listener) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(titleId);
        View view = LayoutInflater.from(context).inflate(layoutId, null);
        builder.setView(view);
        builder.setCancelable(false);
        builder.setPositiveButton(okButtonTextId, new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int whichButton) {
                dialog.dismiss();

                if (listener != null) {
                    listener.dialogOk();
                }
            }
        });
        if (showCancel) {
            builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {

                public void onClick(DialogInterface dialog, int whichButton) {
                    dialog.dismiss();

                    if (listener != null) {
                        listener.dialogCancel();
                    }
                }
            });
        }
        AlertDialog alertDialog = builder.create();
        alertDialog.show();
        return alertDialog;
    }

    public static void toast(final Context context, final int resourceId) {
        toast(context, context.getResources().getString(resourceId));
    }

    public static void toast(final Context context, final String message) {
        ((Activity) context).runOnUiThread(new Runnable() {

            public void run() {
                Toast.makeText(context, message, Toast.LENGTH_LONG).show();
            }
        });
    }

    private Dialog(Context context) {
        super(context);
    }
} public class DrawerAdapter extends ArrayAdapter<DrawerItem> {

    public DrawerAdapter(Context context, List<DrawerItem> items) {
        super(context, R.layout.drawer_list_item, items);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LinearLayout itemView;
        DrawerItem item = getItem(position);

        if (convertView == null) {
            itemView = new LinearLayout(getContext());
            LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
                    Context.LAYOUT_INFLATER_SERVICE);
            vi.inflate(R.layout.drawer_list_item, itemView, true);
        } else {
            itemView = (LinearLayout) convertView;
        }
        TextView text = (TextView) itemView.findViewById(R.id.text);
        ImageView icon = (ImageView) itemView.findViewById(R.id.icon);

        text.setText(item.getText());
        if (item.isChecked()) {
            if (item.getSelectedIcon() != null) {
                icon.setImageDrawable(item.getSelectedIcon());
            } else if (item.getIcon() != null) {
                icon.setImageDrawable(item.getIcon());
            }
        } else {
            if (item.getIcon() != null) {
                icon.setImageDrawable(item.getIcon());
            }
        }

        return itemView;
    }

} public class DrawerItem {

    private Class<?> mFragmentClass;
    private String mText;
    private Drawable mIcon;
    private Drawable mSelectedIcon;
    private boolean mChecked = false;

    public DrawerItem(Context context, Class<?> fragmentClass, int text, int icon, int selectedIcon) {

        mFragmentClass = fragmentClass;

        mText = context.getResources().getString(text);

        if (icon != 0) {
            TypedArray ta = context.getTheme().obtainStyledAttributes(new int[] { icon });
            mIcon = ta.getDrawable(0);
            ta.recycle();
        }

        if (selectedIcon != 0) {
            TypedArray ta = context.getTheme().obtainStyledAttributes(new int[] { selectedIcon });
            mSelectedIcon = ta.getDrawable(0);
            ta.recycle();
        }
    }

    public void setChecked(boolean checked) {
        mChecked = checked;
    }

    public boolean isChecked() {
        return mChecked;
    }

    public Class<?> getFragmentClass() {
        return mFragmentClass;
    }

    public String getText() {
        return mText;
    }

    public Drawable getIcon() {
        return mIcon;
    }

    public Drawable getSelectedIcon() {
        return mSelectedIcon;
    }

} public interface OnDialogClosedListener {

    public void dialogOk();

    public void dialogCancel();
}
import java.util.ArrayList;
import java.util.List;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import com.beerbong.zipinst.core.Core;
import com.beerbong.zipinst.core.plugins.license.LicensePlugin;
import com.beerbong.zipinst.core.plugins.storage.StoragePlugin;
import com.beerbong.zipinst.core.plugins.ui.UIPlugin;
import com.beerbong.zipinst.fragment.FragmentAbout;
import com.beerbong.zipinst.fragment.FragmentBackupRestore;
import com.beerbong.zipinst.fragment.FragmentGoo;
import com.beerbong.zipinst.fragment.FragmentInstall;
import com.beerbong.zipinst.fragment.FragmentRecovery;
import com.beerbong.zipinst.fragment.FragmentRules;
import com.beerbong.zipinst.fragment.FragmentSettings;
import com.beerbong.zipinst.http.DownloadFile;
import com.beerbong.zipinst.http.Downloads;
import com.beerbong.zipinst.io.Menus;
import com.beerbong.zipinst.store.FileItemStore;
import com.beerbong.zipinst.ui.IFragment;
import com.beerbong.zipinst.ui.UIActivity;
import com.beerbong.zipinst.ui.widget.Dialog;
import com.beerbong.zipinst.ui.widget.DrawerAdapter;
import com.beerbong.zipinst.ui.widget.DrawerItem;
import com.beerbong.zipinst.ui.widget.Dialog.OnDialogClosedListener;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
/*
 * Copyright 2014 ZipInstaller Project
 *
 * This file is part of ZipInstaller.
 *
 * ZipInstaller is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * ZipInstaller is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ZipInstaller.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.beerbong.zipinst;




public class MainActivity extends UIActivity {

    public static final String BUNDLE_FILE_PATHS = "bundle_file_paths";
    public static final String BUNDLE_URL = "bundle_url";
    public static final String BUNDLE_NAME = "bundle_name";
    public static final String BUNDLE_MD5 = "bundle_md5";

    private static final String SELECTED_ITEM = "SELECTED_ITEM";

    private List<DrawerItem> mItems;
    private IFragment[] mFragments;
    private IFragment mFragment;
    private int mSelectedItem;

    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    private ActionBarDrawerToggle mDrawerToggle;

    private CharSequence mDrawerTitle;
    private CharSequence mTitle;

    private AdView mAdView;

    @Override
    public void create(boolean isNew) {

        Context context = getCore().getContext();

        mItems = new ArrayList<DrawerItem>();
        // TODO create selected icons (orange and blue)
        mItems.add(new DrawerItem(context, FragmentInstall.class, R.string.install_title, R.attr.flashIcon, 0));
        mItems.add(new DrawerItem(context, FragmentRules.class, R.string.rules_title, R.attr.acceptIcon, 0));
        mItems.add(new DrawerItem(context, FragmentBackupRestore.class, R.string.backuprestore_title, R.attr.backupRestoreIcon, 0));
        mItems.add(new DrawerItem(context, FragmentRecovery.class, R.string.recovery_fragment_title, R.attr.gridIcon, 0));
        mItems.add(new DrawerItem(context, FragmentGoo.class, R.string.goo_title, R.attr.webIcon, 0));
        mItems.add(new DrawerItem(context, FragmentSettings.class, R.string.settings_title, R.attr.settingsIcon, 0));
        mItems.add(new DrawerItem(context, FragmentAbout.class, R.string.about_title, R.attr.starIcon, 0));