// ==UserScript==
// @name           OWA Search
// @namespace      http://kode.lurtgjort.no/
// @description    Adds search functionality to Outlook Web Access
// @author         havard@gulldahl.no
// @include        https://*/exchange/*,DanaInfo=*
// @include        https://*/exchange/*/,DanaInfo=*?cmd=Contents*
// ==/UserScript==

var buttonbar, contentpane;

// Add Search box UI to FRAMES['name'] == 'navbar'


var _search_ui_img = 'data:';
var _search_href = '.';

var _search_ui = '<TD class="nbButton"><FORM action="." STYLE="height:26px;" TARGET="top" OnSubmit="return false;"><IMG src="' +
_search_ui_img +
'" width="24" height="24" alt="" border="0"><INPUT type="text" id="GM_OWA_SEARCH" name="GM_OWA_SEARCH" size="10" value="Search..." OnFocus="if(this.value==this.defaultValue)this.value=String();" OnBlur="if(this.value==String())this.value=this.defaultValue;"><INPUT type="button" value="Go" OnClick="top.viewer.location=\'%s&amp;GM_OWA_SEARCH=\'+this.form[\'GM_OWA_SEARCH\'].value;"></FORM></TD>';

// Search results page UI at FRAMES['name'] == 'viewer'

function parse_search(search_url)
{
    var urlObj = new Object();

    search_url.replace(
        new RegExp( "([^?=&]+)(=([^&]*))?", "g" ),
        function( $0, $1, $2, $3 ){
            urlObj[$1] = $3;
        }
    );
    return urlObj;
}

function first_inner_text(node)
{
    if(! node.hasChildren && node.nodeType == node.TEXT_NODE)
        return node.nodeValue;
    return first_inner_text(node.firstChild);
}

function get_page_url(current_location, page)
{
    var ret = new String();
    current_location.search.replace(
        new RegExp('Page=([0-9]+)(&GM_OWA_SEARCH=.+)?'),
        function ($0, $1) {
            if(page == undefined) //get next page
                page = parseInt($1)+1;
            ret = current_location.protocol + '//' +
                  current_location.hostname +
                  current_location.pathname+'?Cmd=contents&Page='+page;
        }
    );
//     GM_log("get_page_url: "+page);
    return ret;
}

window.addEventListener(
    'load',
    function() {

        // is this the top frameset? if so, there's no ?Cmd=... in the url
        if(document.location.search.indexOf('?Cmd') == -1) {
          try {
            var _frames = document.getElementsByTagName('frame');
            buttonbar = _frames[0].contentDocument;
            contentpane = _frames[1].contentDocument;
            // Add Search box UI to FRAMES['name'] == 'navbar'
            // Get the href of inbox, which is the first button
            _search_href = buttonbar.body.firstChild.getElementsByTagName('a')[0]['href']
            var row = buttonbar.body.firstChild.insertRow(-1);
            row.innerHTML = _search_ui.replace('%s', _search_href);
          } catch(e) {alert(e)}; // not the frameset document
        } else if(document.location.search.toUpperCase().indexOf('GM_OWA_SEARCH') != -1) {
          // do search
            GM_log(document.location.pathname + document.location.search);
            var params = parse_search(document.location.search);
//             alert(params);
//             alert(params['gm_owa_search']);
            //get header bar
            var stop_search = document.createElement('div');
            stop_search.style.visibility = 'hidden';
            stop_search.id = 'GM_OWA_STOP_SEARCH';
            stop_search.innerHTML = 'false';
            document.body.appendChild(stop_search);

            xp_headerbar = document.evaluate(
                "//table[@class='tblFolderBar']",
                document,
                null,
                XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
                null);
//             alert(headerbar);
            table = xp_headerbar.snapshotItem(0);
            // get url of next page from flipper
            nexturl = table.rows[0].cells[1].getElementsByTagName('a')[1]['href'];
            lasttext = table.rows[0].cells[1].getElementsByTagName('b')[1].innerHTML;
            lastpage = parseInt(lasttext.replace(/[^\d]/g, ''));
            // delete page flipper
            table.rows[0].deleteCell(1);
            // write nice text in header
            var headcell = table.rows[0].cells[0];
            headcell.getElementsByTagName('b')[1].innerHTML = " : Searching for %s...".replace('%s', params['GM_OWA_SEARCH']);
            var stopbutn = document.createElement('span');
            stopbutn.innerHTML = '<INPUT type="button" id="GM_OWA_STOPBUTTON" value="Stop search" OnClick="document.getElementById(\'GM_OWA_STOP_SEARCH\').innerHTML = \'true\'">';
            headcell.appendChild(stopbutn);
            // get all mails
            var re = new RegExp(params['GM_OWA_SEARCH'], 'i');

            allmails = document.evaluate(
                "//table//table[not(@class)]//tr",
                document,
                null,
                XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
                null);
            // for each one, look for the regexp `owa_search'
            for (var i = 1; i < allmails.snapshotLength; i++) {
                thismail = allmails.snapshotItem(i);
                _from = first_inner_text(thismail.cells[5]);
                _subject = first_inner_text(thismail.cells[6]);
                if((_from.search(re) == -1) && (_subject.search(re) == -1)) {
                    // not a hit, hiding row
                    thismail.style.display = 'none';
                }
            }
            // add iframe cache
            allmailtable = document.getElementsByTagName('table')[3];

            var cache = document.createElement('iframe');
            cache.id='GM_OWA_CACHE';
            cache.style.visibility = 'hidden';
            cache.style.position = 'absolute';
            document.body.appendChild(cache);
            document.addEventListener('DOMFrameContentLoaded',
                function() {
                treemails = cache.contentDocument.evaluate(
                    "//table//table[not(@class)]//tr",
                    cache.contentDocument,
                    null,
                    XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
                    null);
                // for each one, look for the regexp `owa_search'

                for (var i = 2; i < treemails.snapshotLength; i++) {
                    thismail = treemails.snapshotItem(i);
                    _from = first_inner_text(thismail.cells[5]);
    //                 alert(_from);
                    _subject = first_inner_text(thismail.cells[6]);
                    if((_from.search(re) != -1) || (_subject.search(re) != -1)) {
                        // a hit, adding row to table
//                         alert('found hit!');
                        row = allmailtable.insertRow(-1);
                        row.innerHTML = thismail.innerHTML;
                    }
                }

                // get next document
                GM_log('current cache: '+cache.contentWindow.location.search);
                cacheparams = parse_search(cache.contentWindow.location.search);
                GM_log('stopping search: '+stop_search.innerHTML);
                if(stop_search.innerHTML == 'false' && parseInt(cacheparams['Page']) < 9) {
                    cache.contentWindow.location.href =
                         get_page_url(cache.contentWindow.location)
                }
            }, false);


            //start searching thru pages
            cache.contentWindow.location.href = get_page_url(window.location, 2);

        }

    },
    true);


