package com.cradle.iitc_mobile.share;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;

import com.cradle.iitc_mobile.Log;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

public class IntentGenerator {
    private static final String EXTRA_FLAG_IS_DEFAULT = "IITCM_IS_DEFAULT";
    private static final String EXTRA_FLAG_TITLE = "IITCM_TITLE";
    private static final HashSet<ComponentName> KNOWN_COPY_HANDLERS = new HashSet<ComponentName>();

    static {
        if (KNOWN_COPY_HANDLERS.isEmpty()) {

            KNOWN_COPY_HANDLERS.add(new ComponentName(
                    "com.google.android.apps.docs",
                    "com.google.android.apps.docs.app.SendTextToClipboardActivity"));

            KNOWN_COPY_HANDLERS.add(new ComponentName(
                    "com.aokp.romcontrol",
                    "com.aokp.romcontrol.ShareToClipboard"));
        }
    }

    public static String getTitle(final Intent intent) throws IllegalArgumentException {
        if (intent.hasExtra(EXTRA_FLAG_TITLE)) return intent.getStringExtra(EXTRA_FLAG_TITLE);

        throw new IllegalArgumentException("Got an intent not generated by IntentGenerator!\n"
                + "Intent:\n" + intent.toString() + "\n"
                + "Extras:\n" + intent.getExtras().toString());
    }

    public static boolean isDefault(final Intent intent) {
        return intent.hasExtra(EXTRA_FLAG_IS_DEFAULT) && intent.getBooleanExtra(EXTRA_FLAG_IS_DEFAULT, false);
    }

    private final Context mContext;

    private final PackageManager mPackageManager;

    public IntentGenerator(final Context context) {
        mContext = context;
        mPackageManager = mContext.getPackageManager();
    }

    private boolean containsCopyIntent(final List<Intent> targets) {
        for (final Intent intent : targets) {
            for (final ComponentName handler : KNOWN_COPY_HANDLERS) {
                if (handler.equals(intent.getComponent())) return true;
            }
        }
        return false;
    }

    private ArrayList<Intent> resolveTargets(final Intent intent) {
        final String packageName = mContext.getPackageName();
        final List<ResolveInfo> activityList = mPackageManager.queryIntentActivities(intent, 0);
        final ResolveInfo defaultTarget = mPackageManager.resolveActivity(intent, 0);

        final ArrayList<Intent> list = new ArrayList<Intent>(activityList.size());

        for (final ResolveInfo resolveInfo : activityList) {
            final ActivityInfo activity = resolveInfo.activityInfo;
            final ComponentName component = new ComponentName(activity.packageName, activity.name);

            // remove IITCm from list (we only want other apps)
            if (activity.packageName.equals(packageName)) continue;

            // bug in package manager. not exported activities shouldn't even appear here
            // (usually you would have to compare the package name as well, but since we ignore our own activities,
            // this isn't necessary)
            if (!activity.exported) continue;

            final Intent targetIntent = new Intent(intent)
                    .setComponent(component)
                    .putExtra(EXTRA_FLAG_TITLE, activity.loadLabel(mPackageManager));

            if (resolveInfo.activityInfo.name.equals(defaultTarget.activityInfo.name) &&
                    resolveInfo.activityInfo.packageName.equals(defaultTarget.activityInfo.packageName)) {
                targetIntent.putExtra(EXTRA_FLAG_IS_DEFAULT, true);
            }

            list.add(targetIntent);
        }

        return list;
    }

    public void cleanup(final Intent intent) {
        intent.removeExtra(EXTRA_FLAG_IS_DEFAULT);
        intent.removeExtra(EXTRA_FLAG_TITLE);
    }

    public ArrayList<Intent> getBrowserIntents(final String title, final String url) {
        final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url))
                .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);

        return resolveTargets(intent);
    }

    public ArrayList<Intent> getGeoIntents(final String title, final String mLl, final int mZoom) {
        final Intent intent = new Intent(android.content.Intent.ACTION_VIEW,
                Uri.parse(String.format("geo:%s?z=%d", mLl, mZoom)))
                .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);

        final ArrayList<Intent> targets = resolveTargets(intent);

        // According to https://developer.android.com/guide/components/intents-common.html, markers can be labeled.
        // Unfortunately, only Google Maps supports this, most other apps fail
        for (final Intent target : targets) {
            final ComponentName cn = target.getComponent();
            if ("com.google.android.apps.maps".equals(cn.getPackageName())) {
                try {
                    final String encodedTitle = URLEncoder.encode(title, "UTF-8");
                    target.setData(Uri.parse(String.format("geo:0,0?q=%s%%20(%s)&z=%d", mLl, encodedTitle, mZoom)));
                } catch (final UnsupportedEncodingException e) {
                    Log.w(e);
                }
                break;
            }
        }

        return targets;
    }

    public ArrayList<Intent> getShareIntents(final String title, final String text) {
        final Intent intent = new Intent(Intent.ACTION_SEND)
                .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
                .setType("text/plain")
                .putExtra(Intent.EXTRA_TEXT, text)
                .putExtra(Intent.EXTRA_SUBJECT, title);

        final ArrayList<Intent> targets = resolveTargets(intent);

        if (!containsCopyIntent(targets)) {
            // add SendToClipboard intent in case Drive is not installed
            targets.add(new Intent(intent).setComponent(new ComponentName(mContext, SendToClipboard.class)));
        }

        return targets;
    }
}

@@ -6067,103 +6067,397 @@
     
-targets.add(new Intent(intent).setComponent(new ComponentName(mContext, SendToClipboard.class))
+Intent copyToClipboardIntent = new Intent(intent);%0A            copyToClipboardIntent.setComponent(new ComponentName(mContext, SendToClipboard.class));%0A            ResolveInfo activity = mPackageManager.resolveActivity(copyToClipboardIntent, 0);%0A            copyToClipboardIntent.putExtra(EXTRA_FLAG_TITLE, activity.loadLabel(mPackageManager));%0A            targets.add(copyToClipboardIntent
 );%0A 

add EXTRA_FLAG_TITLE to own copy2clipboard intent too (should fix #777)