<script type="text/x-red" data-template-name="cheerio">
    <div class="form-row">
        <label for="node-input-tag"><i class="fa fa-filter"></i> Selector</label>
        <input type="text" id="node-input-tag" placeholder="h1" title="Elements selector">
    </div>
    <div class="form-row">
        <label for="node-input-ret"><i class="fa fa-sign-out"></i> Output</span></label>
        <select id="node-input-ret" style="width:70%">
            <option value="html">html</option>
            <option value="text">text</option>
            <option value="object">map to objects</option>
        </select>
    </div>
    <div class="form-row">
        <label for="node-input-as">&nbsp;</label>
        <select id="node-input-as" style="width:70%">
            <option value="single">as a single message containing an array</option>
            <option value="multi">as multiple messages, one for each element</option>
        </select>
    </div>
    <div class="form-row">
        <input id="node-input-xmlMode" type="checkbox" style="width: auto; vertical-align: top;">
        <label for="node-input-xmlMode" style="width: auto;">XML mode</label>
        <input id="node-input-decodeEntities" type="checkbox" style="width: auto; vertical-align: top;">
        <label for="node-input-decodeEntities" style="width: auto;">Decode entities</label>
        <input id="node-input-lowerCaseTags" type="checkbox" style="width: auto; vertical-align: top;">
        <label for="node-input-lowerCaseTags" style="width: auto;">Lower case tags</label>
        <input id="node-input-lowerCaseAttributeNames" type="checkbox" style="width: auto; vertical-align: top;">
        <label for="node-input-lowerCaseAttributeNames" style="width: auto;">Lower attribute names</label>
        <input id="node-input-recognizeCDATA" type="checkbox" style="width: auto; vertical-align: top;">
        <label for="node-input-recognizeCDATA" style="width: auto;">Recognize CDATA</label>
    </div>
    
    <div class="form-row">
        <div id="node-input-mapping-container-div" style="border-radius: 5px; height: 320px; padding: 5px; border: 1px solid #ccc; overflow-y:scroll;">
        <ol id="node-input-mapping-container" style=" list-style-type:none; margin: 0;">
        </ol>
        </div>
        <a href="#" class="btn btn-mini" id="node-input-add-mapping" style="margin-top: 4px;"><i class="fa fa-plus"></i> Add</a>
    </div>
    <br/>
    <div class="form-row">
        <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
        <input type="text" id="node-input-name" style="width:70%" placeholder="name">
    </div>
</script>

<script type="text/x-red" data-help-name="cheerio">
    <p>Extracts elements from an xml/html document held in <code>msg.payload</code> using CSS selectors.</p>
    <h3>Inputs</h3>
    <dl class="message-properties">
        <dt>payload <span class="property-type">string</span></dt>
        <dd>the html string from which to extract elements.</dd>
    </dl>
    <h3>Output</h3>
    <dl class="message-properties">
        <dt>payload <span class="property-type">array | string</span></dt>
        <dd>the result can be either a single message with a payload containing an array of the matched elements, or multiple
           messages that each contain a matched element.</dd>
    </dl>
    <h3>Details</h3>
    <p>This node supports a combination of CSS and jQuery selectors. See the
    <a href="https://github.com/fb55/CSSselect#user-content-supported-selectors" target="_blank">css-select documentation</a> for more information
    on the supported syntax.</p>
     <p>Output can be plain text, html or complex mapping to objects using sub selectors.</p>
</script>

<script type="text/javascript">
    RED.nodes.registerType('cheerio', {
        category: 'function',
        color: "#DEBD5C",
        defaults: {
            name: {value: ""},
            tag: {value: ""},
            ret: {value: "html"},
            as: {value: "single"},
            map: {value:[{search:"",replace:"", ret: "html", attr: ""}]},
            xmlMode: {value: false},
            decodeEntities: {value: false},
            lowerCaseTags: {value: false},
            lowerCaseAttributeNames: {value: false},
            recognizeCDATA: {value: false},
            recognizeSelfClosing: {value: false}
        },
        inputs: 1,
        outputs: 1,
        icon: "parser-html.png",
        label: function () {
            return this.name || this.tag || "cheerio";
        },
        labelStyle: function () {
            return this.name ? "node_label_italic" : "";
        },
        oneditprepare: function() {

            function generateRow(mapping) {
                var container = $('<li/>',{style:"margin:0; padding:8px 0px; border-bottom: 1px solid #ccc;"});
                var row = $('<div/>').appendTo(container);
                var searchField = $('<input/>',{class:"node-input-mapping-search",type:"text",style:"margin-left: 5px; width: 20%;",placeholder:"Selector", title:"Sub elements selector"}).appendTo(row);
                var retField = $('<select></select>',{class:"node-input-mapping-ret",style:"margin-left: 5px; width: 20%;", title:"Return"}).appendTo(row);
                $('<option value="text">text</option><option value="html">html</option><option value="attribute">attribute</option>').appendTo(retField);
                var attrField = $('<input/>',{class:"node-input-mapping-attr",type:"text",style:"margin-left: 5px; width: 20%;",placeholder:"Attribute", title:"Attribute name"}).appendTo(row);
                $('<span/>',{class:"fa fa-arrow-right",style:"margin: 5px"}).appendTo(row);
                var replaceField = $('<input/>',{class:"node-input-mapping-replace",type:"text",style:"width: 20%;",placeholder:"Field", title: 'Output field'}).appendTo(row);
                searchField.val(mapping.search);
                retField.val(mapping.ret);
                attrField.val(mapping.attr);
                replaceField.val(mapping.replace);

                var deleteButton = $('<a/>',{href:"#",class:"btn btn-mini", style:"margin-left: 5px;"}).appendTo(row);
                $('<i/>',{class:"fa fa-remove"}).appendTo(deleteButton);

                deleteButton.click(function() {
                    container.css({"background":"#fee"});
                    container.fadeOut(300, function() {
                        $(this).remove();
                    });
                });

                $("#node-input-mapping-container").append(container);
            }

            $("#node-input-add-mapping").click(function() {
                generateRow({search:"",replace:"", ret: "html", attr:""});
                $("#node-input-mapping-container-div").scrollTop($("#node-input-mapping-container-div").get(0).scrollHeight);
            });

            for(var i=0; i<this.map.length; i++) {
                var mapping = this.map[i];
                generateRow(mapping);
            }

            function mapperDialogResize(ev,ui) {
                $("#node-input-mapping-container-div").css("height",(ui.size.height-300)+"px");
            };

            $( "#dialog" ).on("dialogresize", mapperDialogResize);
            $( "#dialog" ).one("dialogopen", function(ev) {
                var size = $( "#dialog" ).dialog('option','sizeCache-mapper');
                if (size) {
                    mapperDialogResize(null,{size:size});
                }
            });
            $( "#dialog" ).one("dialogclose", function(ev,ui) {
                $( "#dialog" ).off("dialogresize",mapperDialogResize);
            });
        },
        oneditsave: function() {
            var map = $("#node-input-mapping-container").children();
            var node = this;
            node.map = [];
            map.each(function() {
                var mapping = $(this);
                node.map.push({
                    search: mapping.find(".node-input-mapping-search").val(),
                    ret: mapping.find(".node-input-mapping-ret").val(),
                    replace: mapping.find(".node-input-mapping-replace").val(),
                    attr:  mapping.find(".node-input-mapping-attr").val()
                });
            });
        }
    });
</script>