var fieldRenderers = {};

fieldRenderers['hidden'] = function ( field , i18n )
{
    return '';
}

fieldRenderers['label'] = function ( field , i18n )
{
    var html = '<label class="form-label" for="field_' + escapeHTML ( field.name ) + '">' + escapeHTML ( getI18n ( field.label , i18n ) ) + '</label>';
    html += '<p>' + formatValue ( field.value ) + '</p><input type="hidden" id="field_' + escapeHTML ( field.name ) + '" value="' + escapeHTML ( field.value ) + '" />';
    return html;
}

fieldRenderers['camera_capture'] = fieldRenderers['camera_capture_input'] = function ( field , i18n )
{
    var html = '<label class="form-label" for="field_' + escapeHTML ( field.name ) + '">' + escapeHTML ( getI18n ( field.label , i18n ) ) + ( field.mandatory ? ' *' : '' ) + '</label>';
    html += '<p><input type="file" name="' + field.name + '" accept="image/*" id="field_' + escapeHTML ( field.name ) + '"' + ( field.type == 'camera_capture_input' ? '' : ' style="display: none"' ) + '><a href="#" title="' + escapeHTML ( getI18n ( 'popup.initiated.activate_camera' ) ) + '" class="activate_camera"><span>' + escapeHTML ( getI18n ( 'popup.initiated.activate_camera' ) ) + '</span></a><a href="#" title="' + escapeHTML ( getI18n ( 'popup.initiated.take_picture' ) ) + '" class="take_picture" style="display: none;"><span>' + escapeHTML ( getI18n ( 'popup.initiated.take_picture' ) ) + '</span></a><a href="#" title="' + escapeHTML ( getI18n ( 'popup.initiated.clear_picture' ) ) + '" class="clear_picture" style="display: none;"><span>' + escapeHTML ( getI18n ( 'popup.initiated.clear_picture' ) ) + '</span></a></p>';
    html += "</div>";
    return html;
}

fieldRenderers['checkbox'] = function ( field , i18n )
{
    var html = '<input class="form-control" type="' + escapeHTML ( field.type ) + '" id="field_' + escapeHTML ( field.name ) + '"';
    if ( typeof field.value != 'undefined' )
    {
        html += ' value="' + escapeHTML ( field.value ) + '"'
    }
    if ( typeof field.attributes != 'undefined' )
    {
        for ( var key in field.attributes )
        {
            if ( key.match ( /^[a-z0-9]+$/i ) )
            {
                html += ' ' + escapeHTML ( key ) + '="' + escapeHTML ( field.attributes[key] ) + '"';
            }
        }
    }
    html += ' />';
    html += '<label class="form-label" for="field_' + escapeHTML ( field.name ) + '">' + escapeHTML ( getI18n ( field.label , i18n ) ) + ( field.mandatory ? ' *' : '' ) + '</label>';
    return html;
}

fieldRenderers['default'] = function ( field , i18n )
{
    var html = '<label class="form-label" for="field_' + escapeHTML ( field.name ) + '">' + escapeHTML ( getI18n ( field.label , i18n ) ) + ( field.mandatory ? ' *' : '' ) + '</label>';
    html += '<input class="form-control" type="' + escapeHTML ( field.type ) + '" id="field_' + escapeHTML ( field.name ) + '"';
    if ( typeof field.value != 'undefined' )
    {
        html += ' value="' + escapeHTML ( field.value ) + '"'
    }
    if ( typeof field.attributes != 'undefined' )
    {
        for ( var key in field.attributes )
        {
            if ( key.match ( /^[a-z0-9]+$/i ) )
            {
                html += ' ' + escapeHTML ( key ) + '="' + escapeHTML ( field.attributes[key] ) + '"';
            }
        }
    }
    if ( field.verified )
    {
        html += ' ' + getVerifiedFieldAttributes ( field );
    }
    html += ' />';
    if ( field.verified )
    {
        html += getVerifiedFieldButton ( field );
    }
    return html;
}

var fieldActivators = {};
fieldActivators['camera_capture'] = fieldActivators['camera_capture_input'] = function ( field , i18n )
{
    jQuery ( 'div#initiated div#content section.new-claim form div#div_' + field.name + ' p a.activate_camera' ).click ( function ()
    {
        activateCamera ( field );
        return false;
    } );
    jQuery ( 'div#initiated div#content section.new-claim form div#div_' + field.name + ' p a.take_picture' ).click ( function ()
    {
        takePicture ( field );
        return false;
    } );
    jQuery ( 'div#initiated div#content section.new-claim form div#div_' + field.name + ' p a.clear_picture' ).click ( function ()
    {
        clearPicture ( field );
        return false;
    } );
    jQuery ( 'div#initiated div#content section.new-claim form div#div_' + field.name + ' p input[type=file]' ).change ( function ()
    {
        showInputFile ( field );
        return false;
    } );
    return;
}

fieldActivators['default'] = function ( field , i18n )
{
    if ( field.verified )
    {
        jQuery ( 'input#field_' + escapeHTML ( field.name ) )[0].showingValues = false;
        jQuery ( 'input#field_' + escapeHTML ( field.name ) )[0].toggleValues = function() {
            jQuery ( 'div.agnia-selector' ).remove()
            if ( this.showingValues )
            {
                this.showingValues = false;
                return;
            }
            this.showingValues = true;

            var jQueryElement = jQuery ( this );
            var dataType = jQueryElement.data ( 'type' )
            var fieldName = field.name;
            var pos = jQueryElement.offset();
            if ( jQueryElement.data ( 'unverified' ) == true )
            {
                var fieldKey = jQueryElement.attr ( 'data-fieldKey' );
                if ( jQueryElement.val() != '' && ( typeof fieldKey == 'undefined' || fieldKey == '' ) )
                {
                    jQueryElement.val ( '' );
                }

            }
            if ( typeof wallet.data.attributes[dataType] != 'undefined' && wallet.data.attributes[dataType].length > 0 )
            {
                var element = document.createElement ( 'div' );
                element.classList.add("agnia-selector");
                element.style = 'position: absolute !important; z-index: 2147483647 !important; display: block !important; opacity: 1 !important; visibility: visible !important; transform: none !important; clip: auto !important; clip-path: none !important; filter: none !important; mask: none !important; top: ' + ( pos.top + jQueryElement.height() + 10 ) + 'px !important; left: ' + pos.left + 'px !important; box-shadow: 0 2px 6px #3C4A54 !important;';
            
                var dl = document.createElement ( 'dl' );
                var dd;
                for ( var i = 0 ; i < wallet.data.attributes[dataType].length ; i++ )
                {
                    dd = document.createElement (  'dd' );
                    dd.dataset._agniaFieldKey = wallet.data.attributes[dataType][i].key;
                    dd.onclick = verifiedValueSelected;
                    dd.innerText = getClaimDescription ( wallet.data.attributes[dataType][i] );
                    dl.appendChild ( dd );
                }
                element.appendChild ( dl );
                element.onclick = function ( event )
                {
                    event.stopPropagation();
                }
                element.agniaData = wallet.data.attributes[dataType];
                element.agniaDataType = dataType;
                element.agniaFieldElement = fieldName;
                document.body.appendChild ( element );

            }
        };
        if ( field.unverified )
        {
            jQuery ( 'input#field_' + escapeHTML ( field.name ) ).keypress ( function() {
                jQuery ( 'div.agnia-selector' ).remove()
            } );
        }
    }
}
function verifiedValueSelected ()
{
    var fieldName = jQuery ( 'div.agnia-selector' )[0].agniaFieldElement;
    var dataType = jQuery ( 'div.agnia-selector' )[0].agniaDataType;
    var selectedKey = this.dataset['_agniaFieldKey'];
    if (typeof selectedKey != 'undefined' && selectedKey != null )
    {
        for ( var i = 0 ; i < wallet.data.attributes[dataType].length ; i++ )
        {
            if ( wallet.data.attributes[dataType][i].key == selectedKey )
            {
                jQuery ( '#field_' + fieldName ).val ( getClaimDescription ( wallet.data.attributes[dataType][i] ) );
                if ( jQuery ( '#field_' + fieldName ).data ( 'unverified' ) == true )
                {
                    jQuery ( '#field_' + fieldName ).attr ( 'readonly' , true );
                }
                jQuery ( 'input#field_' + fieldName ).attr ( 'data-fieldKey' , selectedKey );
                jQuery ( 'div#div_' + fieldName + ' a.edit-field i.fas' ).attr ( 'title' , escapeHTML ( getI18n ( 'popup.initiated.delete_field' ) ) );
                jQuery ( 'div#div_' + fieldName + ' a.edit-field' ).addClass ( 'remove-field' );
                jQuery ( 'div#div_' + fieldName + ' a.edit-field i.fas' ).removeClass ( 'fa-plus' );
                jQuery ( 'div#div_' + fieldName + ' a.edit-field i.fas' ).addClass ( 'fa-minus' );
                jQuery ( 'div#div_' + fieldName + ' div#field-values' ).remove();
                break;
            }
        }
    }
    else
    {
        jQuery ( '#field_' + fieldName ).val ( '' );
        if ( jQuery ( '#field_' + fieldName ).data ( 'unverified' ) == true )
        {
            jQuery ( '#field_' + fieldName ).attr ( 'readonly' , false );
        }
        jQuery ( 'input#field_' + fieldName ).attr ( 'data-fieldKey' , '' );
    }
    jQuery ( '#field_' + fieldName )[0].showingValues = false;
    jQuery ( 'div.agnia-selector' ).remove()
    return false;
}

function getVerifiedFieldAttributes ( field )
{
    var html = 'data-type="' + escapeHTML ( field['data-type'] ) + '" id="field_' + escapeHTML ( field.name ) + '"';
    if ( !field.unverified )
    {
        html += ' readonly'
    }
    else
    {
        html += ' data-unverified="true"';
    }
    return html;
}

function getVerifiedFieldButton ( field )
{
    var html = ( typeof wallet == 'undefined' || typeof wallet.data == 'undefined' || typeof wallet.data.attributes == 'undefined' || typeof wallet.data.attributes[field['data-type']] == 'undefined' || wallet.data.attributes[field['data-type']].length < 1 ) ? '' : ' <a class="edit-field" title="' + escapeHTML ( getI18n ( 'popup.initiated.edit_field' ) ) + '" data-fieldName="' + escapeHTML ( field.name ) + '"><i class="fas fa-plus"></i></a>';
    return html;
}

/* function verifiedFieldRenderer ( field , i18n )
{
    var html = '<label class="form-label" for="field_' + escapeHTML ( field.name ) + '">' + escapeHTML ( getI18n ( field.label , i18n ) ) + ( field.mandatory ? ' *' : '' ) + '</label>';
    html += '<input class="form-control" type="text" data-type="' + escapeHTML ( field['data-type'] ) + '" id="field_' + escapeHTML ( field.name ) + '" readonly /> <a class="edit-field" title="' + escapeHTML ( getI18n ( 'popup.initiated.edit_field' ) ) + '" data-fieldName="' + escapeHTML ( field.name ) + '"><i class="fas fa-plus"></i></a>';
    return html;
}*/

function paintField ( field , i18n)
{
    var type = typeof fieldRenderers[field.type] != 'undefined' ? field.type : 'default';
    var html;
    html = fieldRenderers[type] ( field , i18n );
    if ( typeof html != 'undefined' && html != null && html != '' )
    {
        html = '<div class="form-group form-group-grid" id="div_' + escapeHTML ( field.name ) + '">' + html + '</div>';
    }
    return html;
}

function activateField ( field , i18n )
{
    var type = typeof fieldRenderers[field.type] != 'undefined' ? field.type : 'default';
    if ( typeof fieldActivators[type] != 'undefined' )
    {
        fieldActivators[type] ( field , i18n );
    }
}


var valueReaders = {};
valueReaders['hidden'] = async function ( field , i18n )
{
    return field.value;
}
valueReaders['camera_capture'] = async function ( field , i18n )
{
    var input = jQuery ( 'input#field_' + field.name )[0];
    if ( input.files.length == 0 )
    {
        return '';
    }
    var value = {};
    value['name'] = input.files[0].name;
    value['type'] = input.files[0].type;
    value['data'] = await blobToData ( input.files[0] );
    value['data'] = value['data'].substring ( value['data'].indexOf ( ',' ) + 1 );
    return value;
}
valueReaders['default'] = async function ( field , i18n )
{
    return jQuery ( 'input#field_' + field.name ).val();
}

async function getValue ( field )
{
    if ( typeof valueReaders[field.type] != 'undefined' )
    {
        return await valueReaders[field.type] ( field );
    }
    else
    {
        return await valueReaders['default'] ( field );
    }
}

function getVerifiedField ( field )
{
    return jQuery ( 'input#field_' + field.name ).attr ( 'data-fieldKey' );
}

function clearErrors()
{
    formError = false;
    jQuery ( 'div.error_message p.invalid-feedback' ).remove();
    jQuery ( '.error_message' ).removeClass ( 'error_message')
}

function showError ( selector , message )
{
    formError = true;
    jQuery ( selector ).addClass ( 'error_message' );
    jQuery ( selector ).append ( '<p class="invalid-feedback">' + escapeHTML ( message ) + '</p>' );
}

function showFieldError ( field , message )
{
    showError ( 'div#initiated div#div_' + escapeHTML ( field.name ) , message );
}

async function getFieldValue ( field )
{
    var value = await getValue ( field );
    if ( field.mandatory && ( typeof value == 'undefined' || value == null || value == '' ) )
    {
        showFieldError ( field , getI18n ( 'errors.field_required' ) );
        return false;
    }
    else if ( !( typeof value == 'undefined' || value == null || value == '' ) && typeof field.validator != 'undefined' && typeof ( validators[field.validator] ) && !validators[field.validator] ( value ) )
    {
        showFieldError ( field , getI18n ( field.validator , validatorsI18N ) );
        return false;
    }
    else
    {
        return value;
    }
}

function formatValue ( value )
{
    if ( typeof value == 'object' )
    {
        if ( typeof value['type'] != 'undefined' && typeof value['data'] != 'undefined' && typeof value['name'] != 'undefined' )
        {
            if ( value['content-type'].indexOf ( 'image/' ) == 0 )
            {
                return ( '<img src="data:' + value['content-type'] + ';base64,' + value['data'] + '" height="200">' );
            }
            else
            {
                return ( value.name );
            }
        }
        else if ( typeof value['type'] != 'undefined' && typeof value['file_key'] != 'undefined' && typeof value['name'] != 'undefined' )
        {
            if ( value['type'].indexOf ( 'image/' ) == 0 )
            {
                return ( '<img data-file-key=' + value['file_key'] + ' height="200">' );
            }
            else
            {
                return ( value.name );
            }
        }
        else if ( typeof value['description'] != 'undefined' )
        {
            return escapeHTML ( value['description'] );
        }
        else
        {
            return 'object';
        }
    }
    else if ( value.constructor == String && /^\d{4}\-\d{1,2}\-\d{1,2}$/.test ( value ) )
    {
        return new Date ( value ).toLocaleDateString ( undefined , { year: "numeric", month: "2-digit", day: "2-digit" } );
    }
    else
    {
        return escapeHTML ( value );
    }
}

