var ebirdx = function() {

    var $ = jQuery;
    var exform = $('#exform form');
    var extable = $('#extable');
    
    var exfilter = function() {
        //extable.hide();
        
        var birdinc = $('select[name=birdinc]',exform).val() == 'true';
        var birdany = $('select[name=birdany]',exform).val() == 'true';
        var birdwords = $('input[name=birdwords]',exform).val().replace(/^\s+|\s+$/g,'').replace(/\s+/g,' ').split(' ');
        for ( var ww=0; ww < birdwords.length; ++ww ) { 
            birdwords[ww] = birdwords[ww].toLowerCase(); }
            
        var locinc = $('select[name=locinc]',exform).val() == 'true';
        var locany = $('select[name=locany]',exform).val() == 'true';
        var locwords = $('input[name=locwords]',exform).val().replace(/^\s+|\s+$/g,'').replace(/\s+/g,' ').split(' ');
        for ( var ww=0; ww < locwords.length; ++ww ) { 
            locwords[ww] = locwords[ww].toLowerCase(); }
            
        var isbad = function( tt, words, any, inc ) {
            if ( words.length === 1 && words[0] === '' ) { return false; }
            tt = tt.toLowerCase();
            var bad;
            if (any ) {
                bad = true;
                for ( var ww=0; ww < words.length; ++ww ) {
                    if (tt.search(words[ww]) >= 0) { bad = false; break; }
                }
            } else {
                for ( var ww=0; ww < words.length; ++ww ) {
                    if (tt.search(words[ww]) < 0) { break; }
                }
                bad = (ww != words.length);
            }
            return inc ? bad : !bad;
        };
        
        var ldate = '';
        var lloc = '';
        var ind2 = false;
        var cnt = 0;
        $('tr',extable).each(function() {
            var tr = $(this);
            var td = $('td',tr);
            if ( td.length <= 1 ) { return; }
            var btext = $('.extext', td[1]).text();
            var loc = $('.extext', td[2]);
            var badbird = isbad( btext, birdwords, birdany, birdinc );
            if ( !badbird ) { badbird = isbad( loc.text(), locwords, locany, locinc ); }

            if ( badbird ) { 
                tr.addClass('exhide');//$('td',tr).css('font-style','italic');//tr.hide();
            } else {
                var date = $('.extext', td[0]);
                tr.removeClass('exhide');//$('td',tr).css('font-style','normal');//tr.show();
                if ( ! (tr.hasClass('exhidevc') || tr.hasClass('exhideco')) ) { // whole table hidden
                    cnt++;
                    if (ind2) { tr.addClass('ind2'); ind2 = false; }
                    else { tr.removeClass('ind2'); ind2 = true; }
                    if ( $.data(this,lockey) === lloc && date.text() === ldate) { loc.hide(); }//css('display','none'); }
                    else { lloc = $.data(this,lockey); loc.show(); } //css('display','inline'); }
                    if (date.text() === ldate) { date.hide(); } //css('display','none'); }
                    else { ldate = date.text(); date.show(); } //css('display','inline'); }
                }
            }
        });
        
        $('#obscnt').text(cnt+'');
        //extable.show();
        return;
    }; /// exfilter
    var doexfilter = function(postfn) {
        $('#exmsg').text('filtering...').show();
        setTimeout(function(){
            exfilter();
            $('#exmsg').hide();
            if (postfn) { postfn(); }
        },0);
    };
    
    var exformat = function() {
        var ind2 = false;
        var cnt = 0;
        var ldate = '';
        var lloc = '';
        $('tr',extable).each(function() {
            var tr = $(this);
            var td = $('td',tr);
            if ( td.length <= 1 ) return;
            if ( ! (tr.hasClass('exhide') || tr.hasClass('exhidevc') || tr.hasClass('exhideco')) ){
                cnt++;
                var loc = $('.extext', td[2]);
                var date = $('.extext', td[0]);
                if (ind2) { tr.addClass('ind2'); ind2 = false; }
                else { tr.removeClass('ind2'); ind2 = true; }
                if ( $.data(this,lockey) === lloc && date.text() === ldate) { loc.hide(); }//css('display','none'); }
                else { lloc = $.data(this,lockey); loc.show(); } //css('display','inline'); }
                if (date.text() === ldate) { date.hide(); } //css('display','none'); }
                else { ldate = date.text(); date.show(); } //css('display','inline'); }
            }
        });
        
        $('#obscnt').text(cnt+'');
    }; /// exformat
    
    var ascch = '&nbsp;'+$('<span>&darr;</span>').text();
    var dscch = '&nbsp;'+$('<span>&uarr;</span>').text();
    var dureg = new RegExp( '('+ascch+'|'+dscch+')$' );
    
    var sortalpha = function(rows,col,asc) {
        rows.sort(function(a, b) {
            var keyA = $('td.'+col,a).text().toLowerCase();
            var keyB = $('td.'+col,b).text().toLowerCase();
            if (keyA < keyB) return asc?-1:1;
            if (keyA > keyB) return asc?1:-1;
            return 0;
        });
    };
    var sortnum = function(rows,col,asc) {
        rows.sort(function(a, b) {
            var keyA = $('td.'+col,a).text()*1;
            var keyB = $('td.'+col,b).text()*1;
            if (keyA < keyB) return asc?-1:1;
            if (keyA > keyB) return asc?1:-1;
            return 0;
        });
    };
    var sortloc = function(rows,col,asc) {
        rows.sort(function(a, b) {
            var keyA = $.data(a,lockey);
            var keyB = $.data(b,lockey);
            if (keyA < keyB) return asc?-1:1;
            if (keyA > keyB) return asc?1:-1;
            return 0;
        });
    };
    var sortchild = function(rows,col,asc) {
        rows.sort(function(a, b) {
            var keyA = $('td.'+col,a).children().length;
            var keyB = $('td.'+col,b).children().length;
            if (keyA < keyB) return asc?-1:1;
            if (keyA > keyB) return asc?1:-1;
            return 0;
        });
    };
    var sortex = function(head,col,fn) {
        var hdch = head.html();
        hdch = hdch.substr(hdch.length-ascch.length);
        var asc = hdch==ascch ? false : hdch==dscch ? true : (col!='col1'&&col!='col5');
        $('th',headtr).each(function(){ 
            var $$=$(this); $$.html( $$.html().replace(dureg,'') ); });
        head.html( head.html()+(asc?ascch:dscch) );
        fn(exrows,col,asc);
        $.each(exrows, function(index, row) { extable.append(row); }); 
        exformat();
    };
    var dosortex = function(head,col,fn,postfn) {
        $('#exmsg').text('sorting...').show();
        setTimeout(function(){
            sortex(head,col,fn);
            $('#exmsg').hide();
            if (postfn) { postfn(); }
        },0);
    };
    
    // initial tweaks for sorting
    
    $('th',headtr).each(function() { // fix trailing whitespace for sort indicator
        $(this).html( $(this).html().replace(/[\s]*$/,'') ); });
    
    var exrows = $('tr',extable);
    if ( exrows.length > 2 ) {
        exrows.addClass('exobs');
        $(exrows[0]).removeClass('exobs');
        var headtr = $(exrows[1]);
        headtr.removeClass('exobs');
        exrows = $('tr.exobs',extable);
        
        var lockey = 'lockey';
        exrows.each(function(ndx){
            var $$ = $(this);
            if ( $$.children().length < 5 ) {
                $$.removeClass('exobs');
                return;
            }
            var td = $($$.children()[2]);//$('td.col3',this); //
            var href = /=.*$/.exec($('a',td).attr('href'))[0];
            $.data(this,lockey,td.text()+href);
            $$.addClass($('span.exco',td).text().replace(': ','').replace(' ',''));
            if ( $($$.children()[1]).hasClass('exvc') ) { $$.addClass('exvc'); }
        });
        
        dosortex($('#datehead',extable),'col1',sortalpha,function(){
            if ( $.trim($('input[name=birdwords]',exform).val()) !== '' 
                    || $.trim($('input[name=locwords]',exform).val()) !== '' ) {
                doexfilter( function(){extable.show();} );
            } else { 
                extable.show(); 
            }
        });
    }
        
    // install event handlers
    
    exform.keydown( function(ee) { if (ee.keyCode == 13) { ee.preventDefault(); doexfilter(); } }); 
    $('input[name=apply]',exform).click(function(ee) { ee.preventDefault(); doexfilter(); });
    
    $('input[name=showco]',exform).click(function() { $('span.exco',exrows).toggleClass('exhide'); });
    if ( $('input[name=showco]',exform).attr("checked") ) { $('span.exco', exrows).removeClass('exhide'); }
    
    $('input[name=taxorder]',exform)
        .click(function(ee){ ee.preventDefault(); dosortex($('#taxorderhead',extable),'col6',sortnum); });
    
    $('.excochk input',exform).click(function() {
        var $$ = $(this); 
        if ( $(this).parent().css('font-weight') == 'bold' ) {
            $('tr.'+$$.parent().text().replace(' ',''),extable).toggleClass('exhideco'); 
            exformat(); 
        }
    });
    $('.excochk input',exform).each(function() {
        if ( $(this).attr('checked') ) { $(this).parent().css('font-weight','bold' ); } });
        
    $('input[name=excludecommon]',exform).click(function() {
        var $$ = $(this); $('tr.exvc',extable).toggleClass('exhidevc'); exformat(); });
    if ( $('input[name=excludecommon]',exform).attr('checked') ) {
        $('tr.exvc',extable).addClass('exhidevc'); exformat(); }
        
    $('#datehead',extable)
        .click(function(ee){ dosortex($(this),'col1',sortalpha); })
        .hover(function(){ $(this).css({'cursor':'pointer'}); },
            function(){ $(this).css({'cursor':''}); });
    $('#namehead',extable)
        .click(function(ee){ dosortex($(this),'col2',sortalpha); })
        .hover(function(){ $(this).css({'cursor':'pointer'}); },
            function(){ $(this).css({'cursor':''}); });
    $('#lochead',extable)
        .click(function(ee){ dosortex($(this),'col3',sortloc); })
        .hover(function(){ $(this).css({'cursor':'pointer'}); },
            function(){ $(this).css({'cursor':''}); });
    $('#numhead',extable)
        .click(function(ee){ dosortex($(this),'col4',sortnum); })
        .hover(function(){ $(this).css({'cursor':'pointer'}); },
            function(){ $(this).css({'cursor':''}); });
    $('#confhead',extable)
        .click(function(ee){ dosortex($(this),'col5',sortchild); })
        .hover(function(){ $(this).css({'cursor':'pointer'}); },
            function(){ $(this).css({'cursor':''}); });
};

