jscape.dropzone = jscape.dropzone || {};

/** @class */
jscape.dropzone.DropZoneApplication = jscape.Application.extend(
    /** @lends {jscape.dropzone.DropZoneApplication.prototype} */
{
    uploadFormRequired: false,

    /** @constructor */
    initialize: function(fileUploadMetadataRequired) {
        this._super();
        this.uploadFormRequired = !!fileUploadMetadataRequired;
    },

    /** @override */
    onReady: function() {
        this._super();

        this.view = new jscape.dropzone.DropZoneView();
        this.view.show(this);
    },

    onUploadFile: function (mode, files, items) {
        var controller = new jscape.storage.UploadFileController(this.uploadFormRequired);
        return controller.start(mode, files, null, items)
                .done($.proxy(this._fireMessage, this, window.R.string.STORAGE_SUCCESS_UPLOAD))
                .fail(function (error) {
                          if (error && error.force) {
                              $.messager.alert(window.R.string.APPLICATION_TITLE,
                                               error.message || window.R.string.STORAGE_ERROR_UPLOAD,
                                               "error");
                          }
                      });
    },

    /** @override */
    _destroy: function() {
        this._super();
        this.controller = null;
    },

    _fireMessage: function(message) {
        if (message) {
            $(document).triggerHandler("broadcast", [message]);
        }
    }
});

/** @class */
jscape.dropzone.DropZoneView = Class.extend(
    /** @lends {jscape.dropzone.DropZoneView.prototype} */
{
    /** @constructor */
    initialize: function() {
        this.panel = $("#viewpane");

        this.uploadMode = $("#uploadmodemenu");
        this.uploadButton = this.uploadMode.length
                ? $("a[role=button][name=upload]", this.panel).splitbutton({plain: false, menu: "#uploadmodemenu", onClick: $.proxy(this._onClick$UploadButton, this)})
                : $("a[role=button][name=upload]", this.panel).linkbutton({onClick: $.proxy(this._onClick$UploadButton, this)});

        this.dropzone = $(".dropzone", this.panel).width("97%").height("97%");
        var dz = this.dropzone;

        $(window)
                .on("dragenter dragover", function (e) {
                        var dt = e.originalEvent.dataTransfer;
                        if ($.inArray("Files", dt.types) == -1) {
                            return;
                        }
                        e.stopPropagation();
                        e.preventDefault();
                        dz.addClass("hover");

                        if ($(e.target).hasClass("dropzone")) {
                            dt.effectAllowed = "copyMove";
                            dt.dropEffect = "move";
                        } else {
                            dt.effectAllowed = "none";
                            dt.dropEffect = "none";
                        }
                    })
                .on("dragleave", function (e) {
                        e.stopPropagation();
                        e.preventDefault();

                        if (e.originalEvent.clientX <= 0 || e.originalEvent.clientY <= 0) {
                            dz.removeClass("hover");
                        }
                    })
                .on("drop", $.proxy(function (e) {
                        if ($.inArray("Files", e.originalEvent.dataTransfer.types) == -1) {
                            return;
                        }
                        e.preventDefault();
                        e.stopPropagation();

                        if ($(e.target).hasClass("dropzone")) {
                            $(e.target).removeClass("hover");
                            this._onDrop$File(e.originalEvent.dataTransfer);
                        }
                    }, this));
    },

    show: function (listener) {
        this.listener = listener || jscape.dropzone.DropZoneView.LISTENER;
        this.panel.css({visibility: "visible"});
    },

    _onClick$UploadButton: function() {
        this.listener.onUploadFile(this._uploadMode());
    },

    _onDrop$File: function (dataTransfer) {
        var files = dataTransfer.files;
        if (files && files.length) {
            this.listener.onUploadFile(this._uploadMode(), files, dataTransfer.items);
        }
    },

    _uploadMode: function() {
        return this.uploadMode.length ? this.uploadMode.find(":checked").val() : null;
    }
});