var AnalisisSEO = {
    title: '',
    url: '',
    sitename: '',
    // configuración default
    baseConfig: {
        // nombre de los inputs o textarea a analizar
        nameTitular: 'seo_titulo',
        nameDescripcion: 'seo_descripcion',
        nameSlug: '_url',
        nameCuerpo: 'VTXT_CUERPO',

        cantProblemas: 0,
        cantSugerencias: 0,
        cantResultados: 0,

        // variables de config para analizar
        minCaracteresTitular: 25,
        maxCaracteresTitular: 60,
        minPalabrasTitular: 3,
        maxPalabrasTitular: 10,

        minCaracteresSlug: 4,
        maxCaracteresSlug: 90,

        minCaracteresDescripcion: 120,
        maxCaracteresDescripcion: 156,
        minPalabrasDescripcion: 20,
        maxPalabrasDescripcion: 26,

        minPalabrasCuerpo: 250,
        maxPalabrasCuerpo: 5000,
        minCaracteresCuerpo: 1500,
        maxCaracteresCuerpo: 30000,
    },
    // objeto que contendrá la configuración final
    // luego de inicializar.
    settings: {},
    init: function(config) {
        // hacemos merge de la configuración.
        AnalisisSEO.internal.cargarConfig(config);

        $('#analizar-articulo').on('click', function() {
            $('#seo-problemas, #seo-resultados, #seo-mejoras').html("");
            AnalisisSEO.settings.cantProblemas = 0;
            AnalisisSEO.settings.cantSugerencias = 0;
            AnalisisSEO.settings.cantResultados = 0;
            AnalisisSEO.actions.analizarTitular(AnalisisSEO.settings.nameTitular);

            AnalisisSEO.actions.analizarSlug();

            AnalisisSEO.actions.analizarDescripcion();
            // AnalisisSEO.actions.analizarKeywords();
            AnalisisSEO.actions.analizarCuerpo();
            $('#cantidad-problemas-seo').html('('+AnalisisSEO.settings.cantProblemas+')');
            $('#cantidad-sugerencias-seo').html('('+AnalisisSEO.settings.cantSugerencias+')');
            $('#cantidad-resultados-seo').html('('+AnalisisSEO.settings.cantResultados+')');
            $('#resultado-analisis-seo').collapse('show');
            return false;
        });

        $('#preview-google').on('click', function(){
            $('#seleccion-preview-mobile').prop('checked', true);
            $('#seleccion-preview-desktop').prop('checked', false);
            AnalisisSEO.actions.getGooglePreview();
            return false;
        });
        $('#preview-google-close').on('click', function() {
            $('#modal-google').modal('hide');
            $('#seleccion-preview-mobile').prop('checked', true);
            $('#seleccion-preview-desktop').prop('checked', false);
            return false;
        });

        $('#preview-facebook').on('click', function(){
            AnalisisSEO.actions.getFacebookPreview();
            return false;
        });
        $('#preview-facebook-close').on('click', function() {
            $('#modal-facebook').modal('hide');
            return false;
        });

        $('#analisis-pagespeed').on('click', function(){
            AnalisisSEO.actions.getPageSpeedAnalysis();
            return false;
        });
        $('#pagespeed-close').on('click', function() {
            $('#modal-pagespeed').modal('hide');
            return false;
        });
    },
    actions: {
        /**
         * Aplica análisis de largo y legibilidad al titular.
         */
        analizarTitular: function() {
            // Otros análisis verifican el largo en píxeles del titular como aparecerá en el resultado de google :(
            let minCaracteresTitular = AnalisisSEO.settings.minCaracteresTitular;
            let maxCaracteresTitular = AnalisisSEO.settings.maxCaracteresTitular;
            let minPalabrasTitular = AnalisisSEO.settings.minPalabrasTitular;
            let maxPalabrasTitular = AnalisisSEO.settings.maxPalabrasTitular;

            // atributo name del tag que contiene el titular.
            let nameTitularSEO = AnalisisSEO.settings.nameTitular;

            let problemas = [];
            let sugerencias = [];
            let titular = '';
            // si no han ingresado un titular SEO, lo avisamos como sugerencia.
            if (typeof $("input[name="+nameTitularSEO+"]") !== 'undefined' && $("input[name="+nameTitularSEO+"]").val()) {
                titular = $("input[name="+nameTitularSEO+"]").val();
            } else {
                titular = $('#_txt_titular').val();
                sugerencias.push("No ingresó un titular SEO, se usará el titular del artículo para el análisis. El titular SEO se usa de preferencia para mostrar en Google y otros buscadores.");
            }
            if (titular.length < minCaracteresTitular) {
                problemas.push("El titular contiene " + titular.length + " caracteres. El mínimo sugerido es de "+ minCaracteresTitular + ". Puede ser ambiguo de interpretar.");
            }
            if (titular.length > maxCaracteresTitular) {
                problemas.push("El titular contiene " + titular.length + " caracteres. El máximo sugerido es de " + maxCaracteresTitular + ". Es posible que resulte abreviado en los resultados de búsqueda en Google.");
            }
            let palabras = titular.split(' ');
            if (palabras.length < minPalabrasTitular) {
                problemas.push("El titular contiene " + palabras.length + " palabras. El mínimo sugerido es de " + minPalabrasTitular + ". Puede ser ambiguo de interpretar.");
            }
            if (palabras.length > maxPalabrasTitular) {
                problemas.push("El titular contiene " + palabras.length + " palabras. El máximo sugerido es de " + maxPalabrasTitular + ".");
            }
            // presentamos resultados. Esto podría extraerse a otro método.
            if (problemas.length > 0) {
                problemas.forEach(function(item, index) {
                    $('#seo-problemas').append("<li class='list-group-item'><span class='fas fa-circle txtnextred'> </span> Titular: " + item + "</li>");
                });
                AnalisisSEO.settings.cantProblemas += problemas.length;
            } else {
                $('#seo-resultados').append("<li class='list-group-item'><span class='fas fa-circle txtnextgreen'> </span> Titular: Tu titular tiene un largo aceptable y es legible.</li>");
                AnalisisSEO.settings.cantResultados +=1;
            }
            if (sugerencias.length > 0) {
                sugerencias.forEach(function(item, index) {
                    $('#seo-mejoras').append("<li class='list-group-item'><span class='fas fa-circle txtnextyellow'> </span> Titular: " + item + "</li>");
                });
                AnalisisSEO.settings.cantSugerencias += sugerencias.length;
            }
            return true;
        },

        /**
         * Analiza la legibilidad y largo del slug.
         */
        analizarSlug: function() {
            let problemas = [];
            let sugerencias = [];
            let resultados = [];

            let minCaracteresSlug = AnalisisSEO.settings.minCaracteresSlug;
            let maxCaracteresSlug = AnalisisSEO.settings.maxCaracteresSlug;
            // atributo name del tag que contiene el slug.
            let nameSlugSEO = AnalisisSEO.settings.nameSlug;

            if (nameSlugSEO != '_slug' && typeof $("input[name="+nameSlugSEO+"]") !== 'undefined') {
                nameSlugSEO = '_slug';
            }

            if (typeof $("input[name="+nameSlugSEO+"]") === 'undefined' || typeof $("input[name="+nameSlugSEO+"]").val() === 'undefined') {
                // problemas.push("Slug: No se encontró el campo slug.");
                // si el slug no existe entonces el usuario probablemente no puede modificar gran cosa.
                return false;
            }

            let slug = $("input[name="+nameSlugSEO+"]").val();

            if (slug.length < minCaracteresSlug) {
                problemas.push("Slug: El texto del enlace contiene " + slug.length + " caracteres. El mínimo sugerido es de "+ minCaracteresSlug + ". Puede ser ambiguo de interpretar.");
            }
            if (slug.length > maxCaracteresSlug) {
                problemas.push("Slug: El texto del enlace contiene " + slug.length + " caracteres. El máximo sugerido es de " + maxCaracteresSlug + ". El enlace al artículo debería ser legible como un titular.");
            }

            // presentamos resultados. Esto podría extraerse a otro método.
            if (problemas.length > 0) {
                problemas.forEach(function(item, index) {
                    $('#seo-problemas').append("<li class='list-group-item'><span class='fas fa-circle txtnextred'> </span> Slug: " + item + "</li>");
                });
                AnalisisSEO.settings.cantProblemas += problemas.length;
            } else {
                $('#seo-resultados').append("<li class='list-group-item'><span class='fas fa-circle txtnextgreen'> </span> Slug: El texto de la URL tiene un largo aceptable y es legible.</li>");
                AnalisisSEO.settings.cantResultados +=1;
            }
            return true;
        },

        /**
         * Analiza el largo y legibilidad de la descripción.
         */
        analizarDescripcion: function() {
            // el atributo name del tag que contiene el texto de la descripción.
            let nameDescripcionSEO = AnalisisSEO.settings.nameDescripcion;

            let minCaracteresDescripcion = AnalisisSEO.settings.minCaracteresDescripcion;
            let maxCaracteresDescripcion = AnalisisSEO.settings.maxCaracteresDescripcion;
            let minPalabrasDescripcion = AnalisisSEO.settings.minPalabrasDescripcion;
            let maxPalabrasDescripcion = AnalisisSEO.settings.maxPalabrasDescripcion;

            let problemas = [];
            let sugerencias = [];
            let resultados = [];

            let descripcion = '';
            // si no han ingresado una descripción SEO, lo avisamos como sugerencia.
            if (typeof $("textarea[name="+nameDescripcionSEO+"]") !== 'undefined' && $("textarea[name="+nameDescripcionSEO+"]").val()) {
                descripcion = $("textarea[name="+nameDescripcionSEO+"]").val();
            } else {
                descripcion = $('textarea[name=_txt_bajada]').val();
                if (typeof descripcion === 'undefined') {
                    descripcion = '';
                }
                sugerencias.push("No ingresó una descripcion SEO, se usará la bajada del artículo para el análisis. La descripcion SEO se usa de preferencia para mostrar en Google y otros buscadores.");
            }
            if (descripcion.length < minCaracteresDescripcion) {
                problemas.push("La descripción contiene " + descripcion.length + " caracteres. El mínimo sugerido es de "+ minCaracteresDescripcion + ". Puede ser ambiguo de interpretar.");
            }
            if (descripcion.length > maxCaracteresDescripcion) {
                problemas.push("La descripción contiene " + descripcion.length + " caracteres. El máximo sugerido es de " + maxCaracteresDescripcion + ". Es posible que resulte abreviado en los resultados de búsqueda en Google.");
            }
            let palabras = descripcion.split(' ');
            if (palabras.length < minPalabrasDescripcion) {
                problemas.push("La descripción contiene " + palabras.length + " palabras. El mínimo sugerido es de " + minPalabrasDescripcion + ". Puede ser ambiguo de interpretar.");
            }
            if (palabras.length > maxPalabrasDescripcion) {
                problemas.push("La descripción contiene " + palabras.length + " palabras. El máximo sugerido es de " + maxPalabrasDescripcion + ".");
            }

            // presentamos resultados. Esto podría extraerse a otro método.
            if (problemas.length > 0) {
                problemas.forEach(function(item, index) {
                    $('#seo-problemas').append("<li class='list-group-item'><span class='fas fa-circle txtnextred'> </span> Descripción: " + item + "</li>");
                });
                AnalisisSEO.settings.cantProblemas +=problemas.length;
            } else {
                $('#seo-resultados').append("<li class='list-group-item'><span class='fas fa-circle txtnextgreen'> </span> Descripción: Tu descripción tiene un largo aceptable y es legible.</li>");
                AnalisisSEO.settings.cantResultados +=1;
            }
            if (sugerencias.length > 0) {
                sugerencias.forEach(function(item, index) {
                    $('#seo-mejoras').append("<li class='list-group-item'><span class='fas fa-circle txtnextyellow'> </span> Descripción: " + item + "</li>");
                });
                AnalisisSEO.settings.cantSugerencias +=sugerencias.length;
            }
            return true;
        },

        /**
         * TODO: Método por implementar
         */
        analizarKeywords: function() {
            console.log('analiza Keywords');
            return true;
        },

        /**
         * Analiza el cuerpo del artículo por legibilidad, largo, y contenido.
         */
        analizarCuerpo: function() {
            // el atributo name del tag que contiene el texto del cuerpo.
            let nameCuerpo = AnalisisSEO.settings.nameCuerpo;

            let minPalabrasCuerpo = AnalisisSEO.settings.minPalabrasCuerpo;
            let maxPalabrasCuerpo = AnalisisSEO.settings.maxPalabrasCuerpo;
            let minCaracteresCuerpo = AnalisisSEO.settings.minCaracteresCuerpo;
            let maxCaracteresCuerpo = AnalisisSEO.settings.maxCaracteresCuerpo;

            let problemas = [];
            let sugerencias = [];
            let resultados = [];

            let cuerpo = '';

            if (typeof $("textarea[name="+nameCuerpo+"]") !== 'undefined' && typeof $("textarea[name="+nameCuerpo+"]").val() !== 'undefined') {
                cuerpo = tinymce.get(nameCuerpo).getContent();
            } else if (typeof $("textarea[name=VTXT_CUERPO]") !== 'undefined' && typeof $("textarea[name=VTXT_CUERPO]").val() !== 'undefined') {
                cuerpo = tinymce.get("VTXT_CUERPO").getContent();
            } else if (typeof $("textarea[name=vtxt_cuerpo]") !== 'undefined' && typeof $("textarea[name=vtxt_cuerpo]").val() !== 'undefined') {
                cuerpo = tinymce.get("vtxt_cuerpo").getContent();
            } else {
                problemas.push('No se encontró el campo de cuerpo de texto.');
                return false;
            }
            if (cuerpo.length < minCaracteresCuerpo) {
                problemas.push("El cuerpo de texto contiene " + cuerpo.length + " caracteres. El mínimo sugerido es de "+ minCaracteresCuerpo + ".");
            }
            if (cuerpo.length > maxCaracteresCuerpo) {
                problemas.push("El cuerpo de texto contiene " + cuerpo.length + " caracteres. El máximo sugerido es de " + maxCaracteresCuerpo + ".");
            }
            let palabras = cuerpo.split(' ');
            if (palabras.length < minPalabrasCuerpo) {
                problemas.push("El cuerpo de texto contiene " + palabras.length + " palabras. El mínimo sugerido es de " + minPalabrasCuerpo + ".");
            }
            if (palabras.length > maxPalabrasCuerpo) {
                problemas.push("El cuerpo de texto contiene " + palabras.length + " palabras. El máximo sugerido es de " + maxPalabrasCuerpo + ".");
            }

            // análisis de enlaces
            let enlaces = AnalisisSEO.internal.contarEnlaces(cuerpo);
            if (enlaces["internos"] == 0) {
                sugerencias.push("No se encontraron enlaces internos en el cuerpo de texto. Los enlaces internos mejoran la visibilidad de tus otras páginas y hacen tu sitio más navegable.");
            }
            if (enlaces["externos"] == 0) {
                if (enlaces['nofollow'] != 0) {
                    sugerencias.push("Solamente se encontraron enlaces externos con atributo nofollow. Estos enlaces no ayudan a mejorar el ranking de este documento en resultados de búsqueda.");
                } else {
                    sugerencias.push("No se encontraron enlaces externos en el cuerpo de texto. Los enlaces externos ayudan a mejorar el ranking de tu documento en resultados de búsqueda.");
                }
            } else if (enlaces['nofollow'] > enlaces['externos']) {
                sugerencias.push("Hay pocos enlaces externos sin atributo nofollow en tu texto. Los enlaces externos ayudan a mejorar el ranking de tu documento en resultados de búsqueda.");
            }

            let imagenes = AnalisisSEO.internal.contarImagenes(cuerpo);
            if (imagenes["imagenes"] == 0) {
                sugerencias.push("No se encontraron imágenes en el cuerpo de texto. Las imágenes pueden hacer más legible tu texto.");
            } else if (imagenes['con_alt'] < imagenes['imagenes']) {
                sugerencias.push("Algunas imágenes no incluyen el atributo ALT. Agregar el atributo ALT a cada imagen hace más accesible tu texto.");
            } else {
                resultados.push("Todas tus imágenes incluyen un atributo ALT. Tu documento es más legible y accesible.");
            }

            if (enlaces['internos'] != 0 && enlaces['externos'] > enlaces['nofollow']) {
                resultados.push("Tu texto contiene enlaces internos y externos, esto mejora la navegación de tu sitio y el ranking de este documento.");
            }

            // presentamos resultados. Esto podría extraerse a otro método.
            if (problemas.length > 0) {
                problemas.forEach(function(item, index) {
                    $('#seo-problemas').append("<li class='list-group-item'><span class='fas fa-circle txtnextred'> </span> Cuerpo: " + item + "</li>");
                });
                AnalisisSEO.settings.cantProblemas += problemas.length;
            } else {
                resultados.push("El cuerpo de texto tiene un largo aceptable ("+palabras.length+" palabras) y es legible.");
            }

            if (sugerencias.length > 0) {
                sugerencias.forEach(function(item, index) {
                    $('#seo-mejoras').append("<li class='list-group-item'><span class='fas fa-circle txtnextyellow'> </span> Cuerpo: " + item + "</li>");
                });
                AnalisisSEO.settings.cantSugerencias += sugerencias.length;
            }

            if (resultados.length > 0) {
                resultados.forEach(function(item, index) {
                    $('#seo-resultados').append("<li class='list-group-item'><span class='fas fa-circle txtnextgreen'> </span> Cuerpo: " + item + "</li>");
                });
                AnalisisSEO.settings.cantResultados += resultados.length;
            }
            return true;
        },
        /**
         * Envía los datos necesarios al servidor de SEO para simular la preview en google.
         */
        getGooglePreview: function() {
            let titular = $("input[name="+AnalisisSEO.settings.nameTitular+"]").val();
            if (typeof titular === 'undefined' || titular == '') {
                titular = $('#_txt_titular').val();
            }
            let descripcion = $("textarea[name="+AnalisisSEO.settings.nameDescripcion+"]").val();
            if (typeof descripcion === 'undefined' || descripcion == '') {
                descripcion = $('textarea[name=_txt_bajada]').val();
                if (typeof descripcion === 'undefined') {
                    descripcion = '';
                }
            }
            let link = Admin.publicHost;
            let rel_url = ''
            if (typeof $('#_url') !== 'undefined' && typeof $('#_url').val() !== 'undefined' && $('#_url').val() != '') {
                rel_url = $('#_url').val();
            } else {
                rel_url = $('#_slug').val();
            }
            if (! rel_url.startsWith('/')) {
                rel_url = '/' + rel_url;
            }
            link = link + rel_url;
            let pubdate = $('input[name=_FECHAPSHRT]').val();
            if (pubdate == '') {
                let date = new Date();
                let month = '' + (date.getMonth() + 1);
                let day = '' + date.getDate();
                let year = date.getFullYear();
                if (month.length < 2) {
                    month = '0' + month;
                }
                if (day.length < 2) {
                    day = '0' + day;
                }
                pubdate = [day, month, year].join('-');
            }

            let favicon = '';

            // limpieza de resultados
            $('#google-preview-mobile, #google-preview-desktop, #modal-google-mensaje').html('').hide();

            let url = "/cgi-cpn/seo/prontus_get_google_preview.cgi?_prontus_id=" + Admin.prontus_id
            + "&title=" + encodeURIComponent(titular)
            + "&link=" + encodeURIComponent(link)
            + "&pubdate=" + encodeURIComponent(pubdate)
            + "&descripcion=" + encodeURIComponent(descripcion)
            + "&favicon=" + encodeURIComponent(favicon);

            $('#modal-google').modal('show');
            $.ajax({
                url: url,
                type: "get",
                dataType: 'json'
            }).done(function(data, textStatus) {
                $('#modal-google-mensaje').hide();
                $('#google-preview-mobile, #google-preview-desktop').hide();
                if (data.status == 0) {
                    $('#modal-google-mensaje').html(data.msg).show();
                } else {
                    if (typeof data.mobile == 'undefined' || data.desktop == 'undefined') {
                        $('#modal-google-mensaje').hide();
                    } else {
                        data.mobile = data.mobile.replaceAll('&amp;', '&');
                        data.desktop = data.desktop.replaceAll('&amp;', '&');
                        $('#google-preview-mobile').contents().find('html').html(data.mobile);
                        $('#google-preview-desktop').contents().find('html').html(data.desktop);
                        $('#google-preview-mobile').show();
                    }
                }
                $('#modal-google .modal-google-gears').hide();
                $('input[name=google-preview-tipo]').on('change', function() {
                    let tipo = $(this).val();
                    $('#google-preview-mobile, #google-preview-desktop').hide();
                    if (tipo == 'desktop') {
                        AnalisisSEO.internal.truncarTexto('.PreviewRecorte_TitleBounded', 600);
                        AnalisisSEO.internal.truncarTexto('.PreviewRecorte_DesktopDescription', 600);
                    }
                    $('#google-preview-'+tipo).show();
                });
            }).fail(function(data, textStatus) {
                $('#modal-google .modal-google-gears').hide();
                $('#google-preview-mobile, #google-preview-desktop').hide()
                $('#modal-google-mensaje').html("Ocurrió un error comunicando con el servidor SEO. Código de error ["+data.status+"]: "+ data.msg + ", " + data.statusText).show();
            });

            return false;
        },
        /**
         * Envía los datos necesarios al servidor de SEO para simular la preview en facebook.
         */
         getFacebookPreview: function() {
            let titular = $("#redes_titulo").val();
            if (typeof titular === 'undefined' || titular == '') {
                titular = $('#_txt_titular').val();
            }
            let descripcion = $("#redes_descripcion").val();
            if (typeof descripcion === 'undefined' || descripcion == '') {
                descripcion = $('textarea[name=_txt_bajada]').val();
                if (typeof descripcion === 'undefined') {
                    descripcion = '';
                }
            }
            let link = Admin.publicHost;
            let rel_url = ''
            if (typeof $('#_url') !== 'undefined' && typeof $('#_url').val() !== 'undefined' && $('#_url').val() != '') {
                rel_url = $('#_url').val();
            } else {
                rel_url = $('#_slug').val();
            }
            if (! rel_url.startsWith('/')) {
                rel_url = '/' + rel_url;
            }
            link = link + rel_url;

            let imagen = '';
            let imagen_input = "fotofija_redes_seo_1200x685";
            if (typeof $('input[name='+imagen_input+']') !== 'undefined' && typeof $('input[name='+imagen_input+']').val() !== 'undefined' && $('input[name='+imagen_input+']').val() != '') {
                imagen = Admin.publicHost+$('input[name='+imagen_input+']').val();
            }

            // limpieza de resultados
            $('#facebook-preview, #modal-facebook-mensaje').html('').hide();

            let url = "/cgi-cpn/seo/prontus_get_facebook_preview.cgi?_prontus_id=" + Admin.prontus_id
            + "&titular=" + encodeURIComponent(titular)
            + "&link=" + encodeURIComponent(link)
            + "&descripcion=" + encodeURIComponent(descripcion)
            + "&imagen=" + encodeURIComponent(imagen);

            $('#modal-facebook').modal('show');
            $.ajax({
                url: url,
                type: "get",
                dataType: 'json'
            }).done(function(data, textStatus) {
                $('#modal-facebook-mensaje').hide();
                $('#facebook-preview').hide();
                if (data.status == 0) {
                    $('#modal-facebook-mensaje').html(data.msg).show();
                } else {
                    if (typeof data.facebook == 'undefined') {
                        $('#modal-facebook-mensaje').hide();
                    } else {
                        // las entities vienen doblemente encodeadas: si pasé "Descripción", vuelve "Descrip&amp;oacute;n".
                        data.facebook = data.facebook.replaceAll('&amp;', '&');
                        $('#facebook-preview').contents().find('html').html(data.facebook);
                        $('#facebook-preview').show();
                        $('#modal-facebook').modal('handleUpdate');
                    }
                }
                $('#modal-facebook .modal-facebook-gears').hide();
            }).fail(function(data, textStatus) {
                $('#modal-facebook .modal-facebook-gears').hide();
                $('#facebook-preview').hide()
                $('#modal-facebook-mensaje').html("Ocurrió un error comunicando con el servidor SEO. Código de error ["+data.status+"]: "+ data.msg + ", " + data.statusText).show();
            });

            return false;
        },
        /**
         * Envía los datos necesarios al servidor de SEO para obtener resultados de pagespeed.
         */
         getPageSpeedAnalysis: function() {
            let link = Admin.publicHost;
            let rel_url = ''
            if (typeof $('#_url') !== 'undefined' && typeof $('#_url').val() !== 'undefined' && $('#_url').val() != '') {
                rel_url = $('#_url').val();
            } else {
                rel_url = $('#_slug').val();
            }
            if (! rel_url.startsWith('/')) {
                rel_url = '/' + rel_url;
            }
            link = link + rel_url;

            // limpieza de resultados
            $('#pagespeed, #modal-pagespeed-mensaje').html('').hide();
            $('.modal-google-gears').show();
            let url = "/cgi-cpn/seo/prontus_get_google_pagespeed.cgi?_prontus_id=" + Admin.prontus_id
            + "&url=" + encodeURIComponent(link);

            $('#modal-pagespeed').modal('show');
            $.ajax({
                url: url,
                type: "get",
                dataType: 'json'
            }).done(function(data, textStatus) {
                $('#modal-pagespeed-mensaje').html('').hide();
                if (data.status == 0) {
                    $('#modal-pagespeed-mensaje').html(data.msg).show();
                } else {
                    if (typeof data.pagespeed == '') {
                        $('#modal-pagespeed-mensaje').html('No se encontraron datos.').hide();
                    } else {
                        document.getElementById('pagespeed').src = data.url;
                        $('#pagespeed').show();
                    }
                }
                $('#modal-pagespeed .modal-google-gears').hide();
            }).fail(function(data, textStatus) {
                $('#modal-pagespeed .modal-google-gears').hide();
                $('#pagespeed').hide();
                $('#modal-pagespeed-mensaje').html("Ocurrió un error comunicando con el servidor SEO. Código de error ["+data.status+"]: "+ data.msg + ", " + data.statusText).show();
            });

            return false;
        },
    },

    internal: {
        /**
         * Analiza un bloque HTML y devuelve la cantidad de enlaces internos y externos que encuentra.
         * @param {string} html bloque HTML a analizar
         */
        contarEnlaces: function(html) {
            let enlaces = {'internos': 0, 'externos': 0, 'nofollow': 0};
            let el = document.createElement('html');
            el.innerHTML = '<html><head><title>Analisis de HTML</title></head><body>'+html+'</body></html>';
            let link_list = el.getElementsByTagName('a');
            $(link_list).each(function(item, index) {
                if (AnalisisSEO.internal.esLinkExterno(link_list[item])) {
                    if (AnalisisSEO.internal.esLinkNoFollow(link_list[item])) {
                        enlaces['nofollow'] += 1;
                    } else {
                        enlaces['externos'] += 1;
                    }
                } else {
                    enlaces['internos'] += 1;
                }
            });
            return enlaces;
        },
        /**
         * Redimensiona un bloque a un ancho especificado truncando el texto.
         * @param {string} selector el bloque a considerar
         * @param {int} px_width el ancho en pixeles
         */
        truncarTexto: function(selector, px_width) {
            jQuery(selector).each(function() {
                var text = jQuery(this).text();
                var widthOriginal = jQuery(this).width();
                var widthEmpty = jQuery(this).text('').width();
                jQuery(this).text(text);
                if(widthOriginal >= widthEmpty){
                    var width = (parseInt(px_width, 10)) + 'px';
                    jQuery(this).css('maxWidth', width);
                    jQuery(this).text(text + '...');
                }
            });
        },
        /**
         * Analiza un bloque HTML y devuelve la cantidad de imágenes encontradas y si c/u contiene el atributo alt
         * @param {string} html bloque HTML a analizar
         */
        contarImagenes: function(html) {
            let imagenes = {'imagenes': 0, 'con_alt':0};
            let el = document.createElement('html');
            el.innerHTML = '<html><head><title>Analisis de HTML</title></head><body>'+html+'</body></html>';
            let image_list = el.getElementsByTagName('img');
            $(image_list).each(function(item, index) {
                imagenes['imagenes'] +=1;
                if($(image_list[item]).attr('alt') != '') {
                    imagenes['con_alt'] += 1;
                }
            });
            return imagenes;
        },

        /**
         * Analiza un enlace y devuelve si es interno o externo.
         * @param {string} link_element un enlace relativo o absoluto.
         */
        esLinkExterno: function(link_element) {
            return (link_element.host !== window.location.host);
        },

        /**
         * Analiza un enlace y devuelve si es un link con atributo nofollow.
         * @param {string} link_element un enlace relativo o absoluto.
         */
        esLinkNoFollow: function(link_element) {
            return ($(link_element).attr('rel') == 'nofollow');
        },

        /**
         * Obtiene la configuración y evalúa los valores pasados.
         */
        cargarConfig: function(config) {
            AnalisisSEO.settings = $.extend(AnalisisSEO.baseConfig, config);

            // revisamos que no queden valores vacíos.
            let nombres = Object.keys(AnalisisSEO.settings);
            for (let nombre in nombres) {
                if (AnalisisSEO.settings[nombre] == '' && typeof AnalisisSEO.baseConfig[nombre] !== 'undefined') {
                    AnalisisSEO.settings[nombre] = AnalisisSEO.baseConfig[nombre];
                }
            }
        },
        /**
         * Devuelve una URL temporal para un bloque de código.
         * @param {string} code un bloque de código HTML
         * @param {string} type el mimetype, e.g. text/html
         */
        getBlobURL: function(code, type) {
            const blob = new Blob([code], { type })
            return window.URL.createObjectURL(blob)
        }

    }
};
