/*
 * PiAnoS (Picture Annotation System), A fingerprint examiner training tool
 * Copyright (C) 2011-2021 University of Lausanne, Switzerland
 * https://ips-labs.unil.ch/pianos
 * 
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option) any
 * later version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see http://www.gnu.org/licenses/.
 */

// ----------------------------
// Shared UI classes
// ----------------------------
function Pianos4_FilterDialog( url, filters, onOK )
{
    assert( filters !== null );
    
    this.show = function()
    {
        init();
        buildUI();
        setFilter( filters );
        
        pianos.dialog( main, {
            title: 'Results filter',
            width: 600,
            modal: true,
            buttons: {
                'Stop filtering': function()
                {
                    $( this ).dialog( 'close' );
                    onOK( null );
                },
                'Cancel': function()
                {
                    $( this ).dialog( 'close' );
                },
                'OK': function()
                {
                    var newFilter = getFilter();
                    $( this ).dialog( 'close' );
                    onOK( isFilterPassthrough( newFilter ) ? null : newFilter );
                },
            },
            close: function()
            {
                $( this ).remove();
            },
        } );
        var bpane = main.parents( '.ui-dialog' ).find( '.ui-dialog-buttonpane .ui-dialog-buttonset' );
        bpane.css( 'width', '100%' );
        bpane.find( '.ui-button:first' ).css( 'float', 'left' );
        bpane.find( ':not(.ui-button:first)' ).css( 'float', 'right' );
        
    }

    this.getFilterAsString = function()
    {
        if( columns === null )
            init();
        return filterToString( filters );
    }

    this.isItemActive = function( item )
    {
        if( columns === null )
            init();
        return !isColumnPassthrough( filters, item );
    }

    var self = this;
    var columns = null;
    var main = null;
    
    var init = function()
    {
        columns = {
            user: [
                'User', 'text'
            ],
            group: [
                'Group', 'text'
            ],
            progress: [
                'Progress', 'combo', null
            ],
            analysis: [
                'Analysis', 'combo', null
            ],
            comparison: [
                'Comparison', 'combo', null
            ],
        };
        columns.progress[ 2 ] = {};
        for( var i in Pianos4Constants.acev.progress )
        {
            var item = Pianos4Constants.acev.progress[ i ];
            columns.progress[ 2 ][ item.id ] = item.label;
        }
        columns.analysis[ 2 ] = {};
        for( var i in Pianos4Constants.conclusions.analysis.value )
        {
            var item = Pianos4Constants.conclusions.analysis.value[ i ];
            columns.analysis[ 2 ][ item.id ] = item.label;
        }
        columns.comparison[ 2 ] = {};
        for( var i in Pianos4Constants.conclusions.comparison.decision_step1 )
        {
            var item = Pianos4Constants.conclusions.comparison.decision_step1[ i ];
            columns.comparison[ 2 ][ item.id ] = item.label;
        }
    }

    var filterToString = function( filter )
    {
        var rv = [];
        for( var i in columns )
        {
            var col = columns[ i ];
            if( i in filter )
            {
                var value = null;
                if( col[ 1 ] == 'text' )
                {
                    value = $.trim( filter[ i ] );
                    if( value.length == 0 )
                        value = null;
                } else if( col[ 1 ] == 'combo' )
                {
                    var index = parseInt( filter[ i ] );
                    if( index >= 0 )
                    {
                        assert( index in col[ 2 ] );
                        value = col[ 2 ][ index ];
                    }
                }
                if( value !== null )
                    rv.push( i + '=' + value );
            }
        }
        return rv.join( ', ' );
    }

    var filterToHTML = function( filter )
    {
        var text = filterToString( filter );
        if( text.length == 0 )
            return $( '<span />' ).css( 'font-style', 'italic' ).text( 'None' );
        else
            return $( '<span />' ).text( text );
    }

    var buildUI = function()
    {
        main = $( '<div />' ).append( $( '<div />' ).text( 'Current filter: ' ).append( $( '<span />' ).addClass( 'cur_filter' ).append( filterToHTML( filters ) ) ) ).append( $( '<div />' )
            .text( 'New filter: ' ).append( $( '<span />' ).addClass( 'new_filter' ).append( filterToHTML( filters ) ) ) );
        
        var id_base = 'pianos4_filter_opt_' + ( new Date().getTime() )

        var form = $( '<form />' )/* .attr('action','?action=export').attr('enctype','multipart/form-data').attr('method','post') */.appendTo( main );
        
        var useTable = false;
        if( useTable )
        {
            var table = $( '<table />' ).css( 'width', '100%' ).css( 'font-size', '80%' );
            var head = $( '<thead />' ).appendTo( table );
            var htr = $( '<tr />' ).appendTo( head );
            var body = $( '<tbody />' ).appendTo( table );
            var tr = $( '<tr />' ).appendTo( body );
            var addHeader = function()
            {
                return $( '<th />' ).appendTo( htr );
            };
            var addCell = function()
            {
                return $( '<td />' ).appendTo( tr );
            };
            form.append( table );
        } else
        {
            var wrapper = $( '<div />' ).appendTo( form ).css( 'font-size', '80%' );
            var lines = [];
            var curcell = 0;
            var addHeader = function()
            {
                var div = $( '<div />' ).appendTo( wrapper ).css( 'margin', '0.5em 0 0.5em 0' );
                lines.push( div );
                return $( '<span />' ).appendTo( div ).css( 'text-align', 'right' ).css( 'display', 'inline-block' ).css( 'width', '10em' ).css( 'margin-right', '1em' );
            };
            var addCell = function()
            {
                assert( curcell in lines );
                var div = lines[ curcell++ ];
                return $( '<span />' ).appendTo( div );
            };
        }
        
        for( var i in columns )
            addHeader().text( columns[ i ][ 0 ] );
        
        for( var i in columns )
        {
            var col = columns[ i ];
            var cell = addCell();
            var element = null;
            if( col[ 1 ] == 'text' )
            {
                element = $( '<input />' );
                cell.append( element );
            } else if( col[ 1 ] == 'combo' )
            {
                element = $( '<select />' )
                var sel = element.appendTo( cell );
                $( '<option />' ).attr( 'value', -1 ).html( '<span style="font-style:italic">No filter</span>' ).appendTo( sel );
                for( var j in col[ 2 ] )
                    $( '<option />' ).attr( 'value', j ).text( col[ 2 ][ j ] ).appendTo( sel );
            }
            assert( element );
            element.attr( 'name', i ).attr( 'id', id_base + '_' + i ).on( 'change', function( e )
            {
                main.find( '.new_filter' ).html( '' ).append( filterToHTML( getFilter() ) );
            } );
        }
    }

    var getFilter = function()
    {
        var data = main.find( 'form' ).serializeArray();
        log( data );
        var ret = {};
        for( var i in data )
        {
            var item = data[ i ];
            assert( !( item.name in ret ) );
            assert( item.name in columns );
            var col = columns[ item.name ];
            var v = null;
            if( col[ 1 ] == 'text' )
                v = $.trim( item.value );
            else if( col[ 1 ] == 'combo' )
                v = parseInt( item.value );
            assert( v != null );
            ret[ item.name ] = v;
        }
        return ret;
    }

    var setFilter = function( filter )
    {
        for( var i in filter )
        {
            assert( i in columns );
            var col = columns[ i ];
            var elem = main.find( 'form [name=' + i + ']' );
            elem.val( filter[ i ] );
        }
    }

    // Returns true if the given filter is useless (i.e. will
    // always match)
    var isFilterPassthrough = function( filter )
    {
        for( var i in filter )
        {
            if( !isColumnPassthrough( filter, i ) )
                return false;
        }
        return true;
    }
    var isColumnPassthrough = function( filter, i )
    {
        assert( i in columns );
        var col = columns[ i ];
        if( col[ 1 ] == 'text' )
        {
            if( filter[ i ].length )
                return false;
        } else if( col[ 1 ] == 'combo' )
        {
            if( filter[ i ] >= 0 )
                return false;
        } else
        {
            assert( false );
        }
        return true;
    }
}
