package be.iminds.ilabt.jfed.experimenter_gui.ui;

import be.iminds.ilabt.jfed.experimenter_gui.util.BrowserUtil;
import javafx.scene.control.Hyperlink;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import org.nibor.autolink.LinkExtractor;
import org.nibor.autolink.LinkSpan;
import org.nibor.autolink.LinkType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import javax.inject.Singleton;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.Iterator;

/**
 * User: twalcari
 * Date: 9/30/2015
 * Time: 10:01
 */
@Singleton
public class TextFlowUtil {

    private static final Logger LOG = LoggerFactory.getLogger(TextFlowUtil.class);
    private static final LinkExtractor LINK_EXTRACTOR = LinkExtractor.builder()
            .linkTypes(Collections.singleton(LinkType.URL))
            .build();
    private final BrowserUtil browserUtil;


    @Inject
    TextFlowUtil(BrowserUtil browserUtil) {
        this.browserUtil = browserUtil;
    }

    public TextFlow textWithUrlsToTextFlow(String text) {
        TextFlow result = new TextFlow();


        Iterable<LinkSpan> links = LINK_EXTRACTOR.extractLinks(text);
        Iterator<LinkSpan> it = links.iterator();
        int pos = 0;

        while (it.hasNext()) {
            LinkSpan linkSpan = it.next();

            String textBeforeLink = text.substring(pos, linkSpan.getBeginIndex());
            if (!textBeforeLink.isEmpty())
                result.getChildren().add(new Text(textBeforeLink));

            String urlString = text.substring(linkSpan.getBeginIndex(), linkSpan.getEndIndex());
            try {
                URL url = new URL(urlString);
                final Hyperlink hyperlink = new Hyperlink(urlString);
                hyperlink.setOnAction(event -> browserUtil.openUrlInBrowser(url));
                result.getChildren().add(hyperlink);
            } catch (MalformedURLException e) {
                LOG.warn("Could not parse URL! reverting to normal text");
                result.getChildren().add(new Text(urlString));
            }
            pos = linkSpan.getEndIndex();
        }

        //handle the rest of the string
        String rest = text.substring(pos);
        if (!rest.isEmpty())
            result.getChildren().add(new Text(rest));
        return result;
    }


}
