/**
 * Copyright (C) 2013 by Raphael Michel under the MIT license:
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), 
 * to deal in the Software without restriction, including without limitation 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
 * and/or sell copies of the Software, and to permit persons to whom the Software 
 * is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in 
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 * DEALINGS IN THE SOFTWARE.
 */
package de.geeksfactory.opacclient.barcode;

import android.app.Activity;
import android.support.v7.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.net.Uri;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import de.geeksfactory.opacclient.R;
import de.geeksfactory.opacclient.utils.CompatibilityUtils;

public class BarcodeScanIntegrator {
    public static final int REQUEST_CODE_QRDROID = 0x0000094c;
    public static final int REQUEST_CODE_ZXING = 0x0000094d;

    private Activity ctx = null;

    public BarcodeScanIntegrator(Activity ctx) {
        this.ctx = ctx;
    }

    public static ScanResult parseActivityResult(int requestCode,
                                                 int resultCode, Intent idata) {
        if (resultCode != Activity.RESULT_OK || idata == null
                || idata.getExtras() == null) {
            return null;
        }
        if (requestCode == REQUEST_CODE_QRDROID) {
            String result = idata.getExtras().getString("la.droid.qr.result");
            return new ScanResult(result, null);
        } else if (requestCode == REQUEST_CODE_ZXING) {

            String contents = idata.getStringExtra("SCAN_RESULT");
            String formatName = idata.getStringExtra("SCAN_RESULT_FORMAT");
            return new ScanResult(contents, formatName);

        } else {
            return null;
        }
    }

    private static Collection<String> list(String... values) {
        return Collections.unmodifiableCollection(Arrays.asList(values));
    }

    public void initiateScan() {
        PackageManager pm = ctx.getPackageManager();
        // TODO: We should probably use PackageManager.getInstalledPackages() and iterate through
        // all of them to avoid those try/catch-blocks
        try {
            pm.getPackageInfo("com.google.zxing.client.android", 0);
            initiate_scan_zxing();
            return;
        } catch (NameNotFoundException e) {
        }
        try {
            pm.getPackageInfo("com.srowen.bs.android", 0);
            initiate_scan_zxing();
            return;
        } catch (NameNotFoundException e) {
        }
        try {
            pm.getPackageInfo("com.srowen.bs.android.simple", 0);
            initiate_scan_zxing();
            return;
        } catch (NameNotFoundException e) {
        }
        try {
            pm.getPackageInfo("com.srowen.bs.android.simple", 0);
            initiate_scan_zxing();
            return;
        } catch (NameNotFoundException e) {
        }
        try {
            pm.getPackageInfo("la.droid.qr", 0);
            initiate_scan_qrdroid();
            return;
        } catch (NameNotFoundException e) {
        }
        try {
            pm.getPackageInfo("la.droid.qr.priva", 0);
            initiate_scan_qrdroid();
            return;
        } catch (NameNotFoundException e) {
        }
        download_dialog();
    }

    public void download_dialog() {
        AlertDialog.Builder downloadDialog = new AlertDialog.Builder(ctx);
        downloadDialog.setTitle(R.string.barcode_title);
        downloadDialog.setMessage(R.string.barcode_desc);
        downloadDialog.setPositiveButton(R.string.barcode_gplay,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Uri uri = Uri
                                .parse("market://details?id=com.google.zxing.client.android");
                        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                        try {
                            ctx.startActivity(intent);
                        } catch (ActivityNotFoundException anfe) {
                            // Hmm, market is not installed
                        }
                    }
                });
        downloadDialog.setNeutralButton(R.string.barcode_amazon,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Uri uri = Uri
                                .parse("http://www.amazon.com/gp/mas/dl/android?p=com.google" +
                                        ".zxing.client.android");
                        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                        ctx.startActivity(intent);
                    }
                });
        downloadDialog.setNegativeButton(R.string.no,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                    }
                });
        AlertDialog alert = downloadDialog.create();
        alert.show();
    }

    public void initiate_scan_zxing() {
        /*final Collection<String> desiredBarcodeFormats = list("UPC_A", "UPC_E",
                "EAN_8", "EAN_13", "CODE_39", "CODE_93", "CODE_128");*/

        Intent intentScan = new Intent("com.google.zxing.client.android.SCAN");
        intentScan.addCategory(Intent.CATEGORY_DEFAULT);

        // check which types of codes to scan for
        /*if (desiredBarcodeFormats != null) {
            // set the desired barcode types
            StringBuilder joinedByComma = new StringBuilder();
            for (String format : desiredBarcodeFormats) {
                if (joinedByComma.length() > 0) {
                    joinedByComma.append(',');
                }
                joinedByComma.append(format);
            }
            intentScan.putExtra("SCAN_FORMATS", joinedByComma.toString());
        }*/

        String targetAppPackage = findTargetAppPackage(intentScan);
        if (targetAppPackage == null) {
            download_dialog();
            return;
        }
        intentScan.setPackage(targetAppPackage);
        intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intentScan.addFlags(CompatibilityUtils.getNewDocumentIntentFlag());
        ctx.startActivityForResult(intentScan, REQUEST_CODE_ZXING);
    }

    private String findTargetAppPackage(Intent intent) {
        final Collection<String> targetApplications = list(
                "com.google.zxing.client.android", "com.srowen.bs.android",
                "com.srowen.bs.android.simple");
        PackageManager pm = ctx.getPackageManager();
        List<ResolveInfo> availableApps = pm.queryIntentActivities(intent,
                PackageManager.MATCH_DEFAULT_ONLY);
        if (availableApps != null) {
            for (ResolveInfo availableApp : availableApps) {
                String packageName = availableApp.activityInfo.packageName;
                if (targetApplications.contains(packageName)) {
                    return packageName;
                }
            }
        }
        return null;
    }

    public void initiate_scan_qrdroid() {
        Intent qrDroid = new Intent("la.droid.qr.scan");
        qrDroid.putExtra("la.droid.qr.complete", true);
        ctx.startActivityForResult(qrDroid, REQUEST_CODE_QRDROID);
    }

    public static class ScanResult {
        private final String contents;
        private final String formatName;

        public ScanResult(String contents, String formatName) {
            this.contents = contents;
            this.formatName = formatName;
        }

        /**
         * @return raw content of barcode
         */
        public String getContents() {
            return contents;
        }

        /**
         * @return name of format, like "QR_CODE", "UPC_A". See {@code BarcodeFormat} for more
         * format names.
         */
        public String getFormatName() {
            return formatName;
        }
    }
}

@@ -4912,35 +4912,25 @@
 ?id=com.
-google.zxing.client
+srowen.bs
 .android

Update barcode scanner link