package info.guardianproject.util;

import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.CharacterStyle;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.text.util.Linkify;
import android.text.util.Linkify.TransformFilter;
import android.widget.TextView;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class LinkifyHelper {

    private static Pattern geo = Pattern.compile("geo:[-0-9.]+,[-0-9.]+[^ \t\n\"\':]*");
    private static Pattern market = Pattern.compile("market:[^ \t\n\"\':,]+");
    private static Pattern openpgp4fpr = Pattern.compile("openpgp4fpr:[A-Za-z0-9]+");
    private static Pattern xmpp = Pattern.compile("xmpp:[^ \t\n\"\':,]+");
    private static Pattern twitterHandle = Pattern.compile("@([A-Za-z0-9_-]+)");
    private static Pattern hashtag = Pattern.compile("#([A-Za-z0-9_-]+)");
    private static Pattern bridge = Pattern.compile("bridge:[^ \t\n\"\':,]+");

    static TransformFilter returnMatchFilter = new TransformFilter() {
        @Override
        public final String transformUrl(final Matcher match, String url) {
            return match.group(1);
        }
    };

    /* Right now, if there is no app to handle */
    public static void addLinks(TextView text, SpanConverter<URLSpan, ClickableSpan> converter) {
        Linkify.addLinks(text, Linkify.ALL);
        Linkify.addLinks(text, geo, null);
        Linkify.addLinks(text, market, null);
        Linkify.addLinks(text, openpgp4fpr, null);
        Linkify.addLinks(text, xmpp, null);
        Linkify.addLinks(text, twitterHandle, "https://twitter.com/", null, returnMatchFilter);
        Linkify.addLinks(text, hashtag, "https://twitter.com/hashtag/", null, returnMatchFilter);
        text.setText(replaceAll(text.getText(), URLSpan.class, converter));
    }

    /**
     * These are clickable links that will always be safe to click on, whether
     * or not ChatSecure is using Tor or not.
     *
     * @param text
     */
    public static void addTorSafeLinks(TextView text) {
        Linkify.addLinks(text, bridge, null);
    }

    /**
     * Do not create this static utility class.
     */
    private LinkifyHelper() {
    }

    // thanks to @commonsware https://stackoverflow.com/a/11417498
    public static <A extends CharacterStyle, B extends CharacterStyle> Spannable replaceAll(
            CharSequence original, Class<A> sourceType, SpanConverter<A, B> converter) {
        SpannableString result = new SpannableString(original);
        A[] spans = result.getSpans(0, result.length(), sourceType);

        for (A span : spans) {
            int start = result.getSpanStart(span);
            int end = result.getSpanEnd(span);
            int flags = result.getSpanFlags(span);

            result.removeSpan(span);
            result.setSpan(converter.convert(span), start, end, flags);
        }

        return (result);
    }

    public interface SpanConverter<A extends CharacterStyle, B extends CharacterStyle> {
        B convert(A span);
    }
}

@@ -427,16 +427,146 @@
 lper %7B%0A%0A
+    private static Pattern bitcoin = Pattern.compile(%22bitcoin:%5B1-9a-km-zA-HJ-NP-Z%5D%7B27,34%7D(%5C%5C?%5Ba-zA-Z0-9$%5C%5C-_.+!*'(),%25:;@&=%5D*)?%22);%0A
     priv
@@ -706,16 +706,18 @@
 %22market:
+//
 %5B%5E %5Ct%5Cn%5C
@@ -713,32 +713,34 @@
 ://%5B%5E %5Ct%5Cn%5C%22%5C':,
+%3C%3E
 %5D+%22);%0A    privat
@@ -810,17 +810,22 @@
 Za-z0-9%5D
-+
+%7B8,40%7D
 %22);%0A    
@@ -885,24 +885,26 @@
 %5E %5Ct%5Cn%5C%22%5C':,
+%3C%3E
 %5D+%22);%0A    pr
@@ -1045,32 +1045,32 @@
 Za-z0-9_-%5D+)%22);%0A
-
     private stat
@@ -1126,16 +1126,18 @@
 %5Cn%5C%22%5C':,
+%3C%3E
 %5D+%22);%0A%0A 

improve regexps for linkifying and add bitcoin: for payments