"use strict";
XML.ignoreWhitespace = false;
XML.prettyPrinting = false;
var INFO =
<plugin name="findhere" version="0.0.2" href="http://www.slimeden.com/2011/04/firefox/findhere" summary="Find from the start of current screen" xmlns={NS}>
    <author email="wuxiaoshan@gmail.com">Xiao Shan</author>
    <license href="http://people.freebsd.org/~phk/">BEER-WARE</license>
    <project name="Pentadactyl" minVersion="1.0"/>
    <p>
        This plugin makes inner find from the start of current screen.
    </p>
    <item>
        <tags>'findhere' 'fh'</tags>
        <spec>:find[here] :fh</spec>
        <description>
            <p>Find forward from the start of current viewport.</p>
        </description>
    </item>
    <item>
        <tags>'findhere!' 'fh!'</tags>
        <spec>:find[here]! :fh!</spec>
        <description>
            <p>Find backward from the start of current viewport.</p>
        </description>
    </item>
</plugin>;

(function() {
    function moveCaret(elem) {
	    let doc = elem.ownerDocument;
	    let win = new XPCNativeWrapper(window.content.window);
	    let sel =  win.getSelection();
	    let r = doc.createRange();

	    sel.removeAllRanges();
	    r.selectNodeContents(elem);
	    sel.addRange(r);
		r.setEnd(r.startContainer, r.startOffset);

	    modes.push(modes.CARET);
	    modes.pop();
    }

    function findFirstTarget(){
        var win = content;
	    var doc = win.document;

        var offsets = { left: 0, right: 0, top: 0, bottom: 0 };
        offsets.right  = win.innerWidth  - offsets.right;
        offsets.bottom = win.innerHeight - offsets.bottom;

        function isVisible(elem) {
            let rect = elem.getBoundingClientRect();
            if (!rect || !rect.width || !rect.height ||
                rect.top < offsets.top || rect.bottom > offsets.bottom ||
                rect.left < offsets.left || rect.right > offsets.right) {
                return false;
            }

            let computedStyle = doc.defaultView.getComputedStyle(elem, null);
            if (computedStyle.visibility != "visible" || computedStyle.display == "none") {
                return false;
            }
            return true;
        }

        hints.addMode(
	        '/',
	        'Mode used to position the text element',
	        function (elem) {}
	    );

        var mode = hints.modes['/'];
        var res = mode.matcher(doc);
        for (let elem in res) {
            if (isVisible(elem) && (!mode.filter || mode.filter(elem))) {
                return elem;
            }
        }
    };

    group.commands.add(
        ["find[here]", "fh"],
        "Find from the start of current viewport",
        function(args){
            var firstTarget = findFirstTarget();
            if(firstTarget) {
                moveCaret(firstTarget); 
            }

            if(args.bang) {
                rangefinder.openPrompt(modes.FIND_BACKWARD);
            } else {
                rangefinder.openPrompt(modes.FIND_FORWARD);
            }
        }, 
        {
            literal: 0,
            bang: true
        }, 
        true
    );

    let match = options['extendedhinttags'].toString().match(/\[\/\]:([^,]*)/);
    if(match && match[1] != "*") {
        dactyl.echoerr('The [/] mode exists already.');
        dactyl.echoerr("'findhere' can not set eht for [/] mode.");
    } else {
        dactyl.execute("set eht+=[/]:*");
    }

})();

