/*
 * Copyright (C) 2015 IRSTEA
 * All rights reserved.
 */
(function($, Translator) {

    var formatFileSize = function(size) {
            var unit;
            if(size > 1000000000) {
                size = (size/1000000000).toFixed(2);
                unit = 'Gi';
            } else if(size > 1000000) {
                size = (size/1000000).toFixed(2);
                unit = 'Mi';
            } else if(size > 1000) {
                size = (size/1000).toFixed(2);
                unit ='Ki';
            } else {
                unit = '';
            }
            return Translator.trans('file_size(%size%,%unit%)', {size:size, unit:unit}, 'file_upload');
        },
        formatBitrate = function(rate) {
            return formatFileSize(rate) + '/s';
        };

    $.blueimp.fileupload.prototype._formatFileSize = formatFileSize;
    $.blueimp.fileupload.prototype._formatBitrate = formatBitrate;

    /** Plugin irsteaFileUpload.
     */
    $.fn.irsteaFileUpload = function(options) {

        var $this             = $(this),
            $button           = $this.find('.fileinput-button'),
            $entries          = $this.find('.fileinput-entries'),
            nextIndex         = $entries.find('.fileinput-entry').length,
            createUrl         = options.createUrl,
            uploadPrototype   = options.uploadPrototype,
            downloadPrototype = options.downloadPrototype,
            csrfQuery         = '?token=' + options.csrfToken;

        delete options.createUrl;
        delete options.uploadPrototype;
        delete options.downloadPrototype;
        delete options.csrfToken;

        if(options.acceptFileTypes) {
            options.acceptFileTypes = new RegExp('^' + options.acceptFileTypes + '$');
        }

        var showError = function(entry, message) {
                var $this = $(entry);
                if(message) {
                    $this.find('.error').text(Translator.trans(message));
                }
                $this.addClass('alert alert-danger');
                $this.find('.error').show();
                $this.find('.icon')
                    .removeClass('fa-circle-o-notch fa-spin fa-file-o')
                    .addClass('fa-exclamation-triangle');
                $this.find('.description').remove();
                $this.find('.id').remove();
            },
            updateDisplay = function() {
                var hasEntry = false;
                $entries.find('.fileinput-entry').each(function() {
                    var data = $(this).data('data');
                    if(data && data.files.error) {
                        showError(this, data.files[0].error);
                    }
                    hasEntry = true;
                });
                $button.toggle(options.multiple || !hasEntry);
            };

        updateDisplay();

        // Activation
        $button.fileupload($.extend(
            options,
            {
                type: 'PUT',
                autoUpload: true,
                formData: {},
                multipart: false,
                uploadTemplateId: null,
                downloadTemplateId: null,
                filesContainer: $this.find('.fileinput-entries'),
                dropZone: $this,
                i18n: Translator.trans,
                uploadTemplate: function(data) {
                    var rows = $();
                    $.each(data.files, function (index, file) {
                        var row = $(uploadPrototype);
                        rows = rows.add(row);
                        row.find('.name').text(file.name);
                        if (file.error) {
                            showError(row, file.error);
                            return;
                        }
                        row.find('.size').text(formatFileSize(file.size));
                    });
                    return rows;
                },
                downloadTemplate: function(data) {
                    var rows = $();
                    $.each(data.files, function (index, file) {
                        var row = $(downloadPrototype.replace(/__index__/g, nextIndex++));
                        rows = rows.add(row);
                        if (file.error) {
                            row.find('.name').text(file.name);
                            showError(row, file.error);
                            return;
                        }
                        row.find('.size').text(formatFileSize(file.size));
                        row.find('.name a')
                            .text(file.name)
                            .prop('href', file.url + csrfQuery);
                        row.find('.delete')
                            .attr('data-type', file.delete_type)
                            .attr('data-url', file.delete_url + csrfQuery);
                        row.find('input.id')
                            .val(file.id);
                        if(file.icon && file.icon !== 'file') {
                            row.find('.icon')
                                .removeClass('fa-file-o')
                                .addClass('fa-file-'+file.icon+'-o');
                        }
                    });
                    return rows;
                },
                submit: function (e, data) {
                    var $this = $(this),
                        file = data.files[0];
                    $.post(
                        createUrl,
                        { file: { name: file.name, size: file.size, type: file.type, lastModified: file.lastModified } },
                        function(response) {
                            file.icon = response.icon;
                            data.url = response.put_url + csrfQuery;
                            data.delete_url = response.delete_url;
                            data.delete_type = response.delete_type;
                            data.jqXHR = $this.fileupload('send', data);
                        }
                    )
                        .fail(function(jqXHR, textStatus, errorThrown) {
                            file.error = textStatus === "error" ? errorThrown : ('Error #' + jqXHR.status);
                            data.files.error = true;
                            showError(data.context, file.error);
                        })
                        .always(updateDisplay);
                    return false;
                },
                progress: function (e, data) {
                    if(!data.context || e.isDefaultPrevented()) {
                        return;
                    }
                    var percent = data.loaded / data.total * 100,
                        percentText = percent.toFixed(1);
                    data.context.each(function () {
                        var $this = $(data.context);
                        $this.find('.progress').show();
                        $this.find('.progress-bar').css('width', percent + '%').attr('aria-valuenow', percentText);
                        $this.find('.progress-text').show().html(percentText + '% ('+formatBitrate(data.bitrate)+')');
                    });
                },
                getFilesFromResponse: function(data) {
                    var files = [];
                    $.each(data.files, function(index, file) {
                        files.push($.extend(file, data.result.files[index]));
                    });
                    return files;
                },
            }
        )).bind({
            fileuploadfailed: function (e, data) {
                if(data.delete_url) {
                    $.ajax(data.delete_url + csrfQuery, { type: data.delete_type });
                }
            },
            fileuploadadded: updateDisplay,
            fileuploadfinished: updateDisplay,
            fileuploaddestroyed: updateDisplay,
            fileuploadprocessalways: updateDisplay
        });

        if(options.disabled || options.readonly) {
            $button.fileupload('disable');
        }

    };

})(jQuery, Translator);