// (C) Copyright 2020 Hewlett-Packard Enterprise Company, L.P.

define(['jquery'], function() {
    (function($) {

        // ### hpTextFormat
        //
        // Formats text using a simplifed Markdown syntax.
        //
        // Usage:
        //
        //     $('#my-element').hpTextFormat(text);
        //
        // Syntax:
        //
        // Lines beginning with '* ' are converted to `<ul><li>`.
        // Lines followed by a blank line, or the last line, are enclosed in a `<p>`.
        // Lines not followed by a blank line are enclosed in a `<div>`.
        // '[label](url)' will generate an anchor to url with the label.
        // Text wrapped in '*' will be wrapped in `<em></em>`.
        
        $.fn.hpTextFormat = function(string) {
          
            // '[name](url)'
            var aRegexp = new RegExp('\\[(.+?)\\]\\(([^\)]+)\\)', 'g');
            var aPlaceholder = '__A_A__';
            // '*term*'
            var emRegexp = new RegExp('\\*(.+?)\\*', 'g');
            var emPlaceholder = '__EM_EM__';
            var placeholderRegexp = new RegExp('__([A-Z]+?)_[A-Z]+?__');
            
            function formatText(container, line) {
                var links = [], ems = [], spans, span;
                
                // look for [label](url) and put them in links, replace with _A_A_
                var parsed = line.replace(aRegexp, function (m, label, href) {
                    links.push($('<a></a>').text(label).attr('href', href));
                    return aPlaceholder;
                });
                
                // look for [label](url) and put them in links, replace with _EM_EM_
                parsed = parsed.replace(emRegexp, function (m, term) {
                    ems.push($('<em></em>').text(term));
                    return emPlaceholder;
                });
                
                if (ems.length > 0 || links.length > 0) {
                    var nextLink = 0;
                    var nextEm = 0;
                    
                    // build DOM content accounting for placeholders
                    var index = parsed.search(placeholderRegexp);
                    while (index !== -1) {
                        span = $('<span></span>').text(parsed.slice(0, index));
                        container.append(span);
                        if (parsed.lastIndexOf(aPlaceholder, index) === index) {
                            container.append(links[nextLink]);
                            nextLink += 1;
                            parsed = parsed.slice(index + aPlaceholder.length);
                        } else if (parsed.lastIndexOf(emPlaceholder, index) === index) {
                            container.append(ems[nextEm]);
                            nextEm += 1;
                            parsed = parsed.slice(index + emPlaceholder.length);
                        }
                        index = parsed.search(placeholderRegexp);
                    }
                    span = $('<span></span>').text(parsed);
                    container.append(span);
                    
                } else {
                
                    // no links, just securely insert
                    container.text(line);
                }
            }
          
            function format(elem) {
                var lines = string.split(/\n/);
                var line, index = 0, length = lines.length;
                var tmpElem, listElem, pElem;
                
                elem.empty();
                
                while (index < length) {
                    line = lines[index];
                    // starts with '*', list
                    if (line.lastIndexOf('* ', 0) >= 0) {
                        pElem = null;
                        if (! listElem) {
                            listElem = $('<ul></ul>');
                            elem.append(listElem);
                        }
                        tmpElem = $('<li></li>');
                        formatText(tmpElem, line.slice(1));
                        listElem.append(tmpElem);
                    // blank line
                    } else if (line.length === 0) {
                        pElem = null;
                    // text line
                    } else {
                        listElem = null;
                        if (! pElem) {
                            pElem = $('<p></p>');
                            elem.append(pElem);
                        }
                        // last line, blank line follows, or list follows
                        if ((length - 1) === index || lines[index+1].length === 0 ||
                            lines[index+1].lastIndexOf('* ', 0) >= 0) {
                            tmpElem = $('<span></span>');
                            formatText(tmpElem, line);
                            pElem.append(tmpElem);
                        // regular line
                        } else {
                            tmpElem = $('<span></span>');
                            formatText(tmpElem, line);
                            pElem.append(tmpElem, '<br/>');
                        }
                    }
                    index += 1;
                }
            }
            
            // pluginify
            var ret;
            this.each(function() {
                var $elem = $(this);
                
                if (undefined !== string && null !== string) {
                    format($elem);
                }
                
                ret = ret ? ret.add($elem) : $elem;
            });
            return ret;
        };
    }(jQuery));
});
