/* globals $ */

let OcrFileformatAPI = function OcrFileformatAPI(endpoint) {
    this.endpoint = endpoint;
};

OcrFileformatAPI.prototype.urlFor = function urlFor(action, params) {
    params || (params = {});
    let url = this.endpoint + '?do=' + action;
    for (let paramName of Object.keys(params)) {
        url += '&' + paramName + '=' + params[paramName];
    }
    return url;
};

OcrFileformatAPI.prototype.updateFormats = function updateFormats(cb) {
    let self = this;
    this.request('list', null, null, function(err, formats) {
        self.formats = formats;
        cb(err);
    });
};

OcrFileformatAPI.prototype.request = function request(endpoint, query, formData, cb) {
    let ajaxCall = {
        type: 'GET',
        url: window.api.urlFor(endpoint, query),
        success: function(data) {
            cb(null, data);
        },
        error: function(xhr) {
            cb(xhr.responseText);
        },
    };
    if (formData) {
        ajaxCall.type = 'POST';
        ajaxCall.data = formData;
        ajaxCall.processData =  false;
        ajaxCall.contentType = false;
    }
    $.ajax(ajaxCall);
};

function escapeHTML(str) {
    return str.
        replace(/&/g, '&amp;').
        replace(/</g, '&lt;').
        replace(/"/g, '&quot;').
        replace(/'/g, '&#39;').
        replace(/\//g, '&#x2F;').
        replace(/>/g, '&gt;');
}

function onChangeFormat() {
    if ($("#transform-from option").length == 1) {
        Object.keys(window.api.formats.transform).forEach(function(from) {
            $("#transform-from").append($("<option>").append(from));
        });
        $("#transform-from").removeAttr('disabled');
    }
    let selectedFrom = $("#transform-from").val();
    $("#transform-to").attr('disabled', selectedFrom === null);
    if (selectedFrom) {
        $("#transform-to option").slice(1).remove();
        window.api.formats.transform[selectedFrom].forEach(function(to) {
            $("#transform-to").append($("<option>").append(to));
        });
    }
    if ($("#validate-format option").length == 1) {
        window.api.formats.validate.forEach(function(format) {
            $("#validate-format").append($("<option>").append(format));
        });
    }
}

function submit(tabName, params) {
    let pane = $("#" + tabName);
    let input = pane.find(".input .active input");
    let formData;
    let url = input.val();
    if (input.attr('type') === 'file') {
        formData = new FormData();
        formData.append('file', input.prop('files')[0]);
    } else {
        params.url = url;
    }
    $("button .spinning", pane).removeClass('hidden');
    window.api.request(tabName, params, formData, function(err, data) {
        pane.find("button .spinning").addClass('hidden');
        if (err) {
            return $.notify(err, 'error');
        }
        if (url)  {
            pane.find(".result a.download").attr('href', url);
        }
        pane.find(".result pre code").html(escapeHTML(data));
        pane.find(".result").removeClass('hidden');
        /* global Prism*/
        Prism.highlightAll();
    });
}

function maybeEnableSubmit() {
    let el = $(".tab-pane.active");
    let inputSet = !!$(".input .active input", el).val();
    let selects = $(".formats select", el);
    let formatsSet = selects.length == selects.map(function() { return $(this).val(); }).length;
    $("button", el).attr('disabled', !(inputSet && formatsSet));
}

function hashRoute() {
    let hash = window.location.hash;
    let pageTab = hash.replace(/-.*/, '');
    $("a[data-toggle='tab'][href='" + pageTab + "']").tab('show');
    $("a[data-toggle='tab'][href='" + hash + "']").tab('show');
}

$(function() {
    $.notify.defaults({position: 'bottom right'});
    const api = window.api = new OcrFileformatAPI('ocr-fileformat.php');
    $.notify("Loading formats", 'info');
    api.updateFormats(function(err) {
        if (err) {
            $.notify("Error loading formats", "error");
            return;
        }
        $.notify("Loaded formats", 'success');

        $("#transform-from").on('change', onChangeFormat);

        $("a").on('shown.bs.tab', maybeEnableSubmit);
        $(":input").on('input change', maybeEnableSubmit);
        $(".tab-pane").on('shown.bs.tab', maybeEnableSubmit);

        $("#validate-submit").on('click', function() {
            submit('validate', {format: $("#validate-format").val()});
        });
        $("#transform-submit").on('click', function() {
            submit('transform', {from: $("#transform-from").val(), to: $("#transform-to").val() });
        });

        $("a[data-toggle='tab']").on('click tap', function() { window.location.hash = $(this).attr('href'); });

        $(window).on('hashchange', hashRoute);

        onChangeFormat();
        hashRoute();
    });
});

@@ -2364,39 +2364,29 @@
     
-let url = input.val();%0A    if (
+const isFileUpload = 
 inpu
@@ -2410,16 +2410,38 @@
 = 'file'
+;%0A    if (isFileUpload
 ) %7B%0A    
@@ -2562,19 +2562,27 @@
 s.url = 
-url
+input.val()
 ;%0A    %7D%0A
@@ -2850,130 +2850,724 @@
     
-if (url)  %7B%0A            pane.find(%22.result a.download%22).attr('href', url);%0A        %7D%0A        pane.find(%22.result pre code%22)
+const resultDataContainer = pane.find('.result pre code');%0A        const outputFormat = $(%22#transform-to%22).val();%0A        if (isFileUpload) %7B%0A            const basename = input.val().replace(/.*%5C%5C/, ''); // C:%5Cfakepath%5Cbla.foo -%3E bla.foo%0A            const extension = outputFormat === 'text' ? 'text'%0A                : outputFormat === 'hocr' ? 'html'%0A                : outputFormat + '.xml';%0A            pane.find(%22.result a.download%22)%0A                .attr('download', %60$%7Bbasename%7D.$%7Bextension%7D%60)%0A                .attr('href', %60data:text/plain;charset=utf-8,$%7BencodeURIComponent(data)%7D%60);%0A        %7D else %7B%0A            pane.find(%22.result a.download%22).attr('href', input.val());%0A        %7D%0A        resultDataContainer
 .htm
@@ -5407,12 +5407,35 @@
     %7D);%0A%7D);%0A
+%0A/* vim: set sw=4 : */%0A

Support download of transformed uploads, fix #65