define([
    'jquery',
    'bitbucket/internal/widget/drag-drop-file-target'
], function(
    $,
    DragDropFileTarget
) {

    'use strict';

    module('image-tools-drag-drop-file-target', {
        setup: function() {
            this.$el = $('<div />').appendTo('#qunit-fixture');
        },
        teardown: function () {
            delete this.$el;
            $('#qunit-fixture').empty();
        }
    });

    function assertActive($el, activeClass, event) {
        ok($el.hasClass(activeClass || "active-drop-target"), "Should be active after " + event);
    }
    function assertInactive($el, activeClass, event) {
        ok(!$el.hasClass(activeClass || "active-drop-target"), "Should be inactive after " + event);
    }

    function getDropEvent($el, files) {
        return new $.Event("drop", {
            originalEvent : {
                target : $el[0],
                preventDefault : $.noop,
                dataTransfer : {
                    files : files || []
                }
            }
        });
    }

    test("DragDropFileTarget defaults", function() {
        var target = new DragDropFileTarget(this.$el[0]);

        equal(this.$el.attr('data-upload-prompt'), "Drag a file here to upload", "Sets prompt in CSS-accessible data attribute.");

        assertInactive(this.$el, null, "init");

        target.$target.trigger('dragover');
        assertActive(this.$el, null, "dragover");

        target.$target.trigger('dragend');
        assertInactive(this.$el, null, "dragend");

        target.$target.trigger('dragover');
        assertActive(this.$el, null, "dragover");

        target.$target.trigger('dragleave');
        assertInactive(this.$el, null, "dragleave");

        target.$target.trigger('dragover');
        assertActive(this.$el, null, "dragover");

        target.$target.trigger(getDropEvent(this.$el));
        assertInactive(this.$el, null, "drop");
    });

    test("DragDropFileTarget with handler and custom options", function() {
        var prompt = 'do thing';
        var activeClass = 'test';
        var handleFilesSpy = sinon.spy();
        var target = new DragDropFileTarget(this.$el, {
            activeDropTargetClass: activeClass,
            uploadPrompt: prompt,
            clientFileHandler: {
                handleFiles : handleFilesSpy
            }
        });

        equal(this.$el.attr('data-upload-prompt'), prompt, "Sets prompt in CSS-accessible data attribute.");

        assertInactive(this.$el, activeClass, "init");
        ok(!handleFilesSpy.called, "Spy shouldn't be called yet.");

        target.$target.trigger('dragover');
        assertActive(this.$el, activeClass, "dragover");
        ok(!handleFilesSpy.called, "Spy shouldn't be called yet.");

        target.$target.trigger('dragend');
        assertInactive(this.$el, activeClass, "dragend");
        ok(!handleFilesSpy.called, "Spy shouldn't be called yet.");

        target.$target.trigger('dragover');
        assertActive(this.$el, activeClass, "dragover");
        ok(!handleFilesSpy.called, "Spy shouldn't be called yet.");

        target.$target.trigger('dragleave');
        assertInactive(this.$el, activeClass, "dragleave");
        ok(!handleFilesSpy.called, "Spy shouldn't be called yet.");

        target.$target.trigger('dragover');
        assertActive(this.$el, activeClass, "dragover");
        ok(!handleFilesSpy.called, "Spy shouldn't be called yet.");

        var files = [];
        target.$target.trigger(getDropEvent(this.$el, files));
        assertInactive(this.$el, activeClass, "drop");
        ok(handleFilesSpy.calledWith(files, this.$el[0]), "Spy should be called with provided info.");
    });
});