describe('TooltipManager', function() {
    'use strict';
    var PAGE_X = 100,
        PAGE_Y = 100,
        WIDTH = 100,
        HEIGHT = 100,
        DELTA = 10,
        showTooltip;

    beforeEach(function() {
        setFixtures(sandbox({
            id: 'test-id',
            'data-tooltip': 'some text here.'
        }));
        this.element = $('#test-id');

        this.tooltip = new TooltipManager(document.body);
        jasmine.clock().install();
        // Set default dimensions to make testing easer.
        $('.tooltip').height(HEIGHT).width(WIDTH);

        // Re-write default jasmine-jquery to consider opacity.
        jasmine.addMatchers({
            toBeVisible: function() {
                return {
                    compare: function(actual) {
                        return {
                            pass: actual.is(':visible') || parseFloat(actual.css('opacity'))
                        };
                    }
                };
            },

            toBeHidden: function() {
                return {
                    compare: function(actual) {
                        return {
                            pass: actual.is(':hidden') || !parseFloat(actual.css('opacity'))
                        };
                    }
                };
            }
        });
    });

    afterEach(function() {
        this.tooltip.destroy();
        jasmine.clock().uninstall();
    });

    showTooltip = function(element) {
        element.trigger($.Event('mouseover', {
            pageX: PAGE_X,
            pageY: PAGE_Y
        }));
        jasmine.clock().tick(500);
    };

    it('can destroy itself', function() {
        showTooltip(this.element);
        expect($('.tooltip')).toBeVisible();
        this.tooltip.destroy();
        expect($('.tooltip')).not.toExist();
        showTooltip(this.element);
        expect($('.tooltip')).not.toExist();
    });

    it('should be shown when mouse is over the element', function() {
        showTooltip(this.element);
        expect($('.tooltip')).toBeVisible();
        expect($('.tooltip').text()).toBe('some text here.');
    });

    it('should be hidden when mouse is out of the element', function() {
        showTooltip(this.element);
        expect($('.tooltip')).toBeVisible();
        this.element.trigger($.Event('mouseout'));
        jasmine.clock().tick(50);
        expect($('.tooltip')).toBeHidden();
    });

    it('should be hidden when user clicks on the element', function() {
        showTooltip(this.element);
        expect($('.tooltip')).toBeVisible();
        this.element.trigger($.Event('click'));
        jasmine.clock().tick(50);
        expect($('.tooltip')).toBeHidden();
    });

    it('can be configured to show when user clicks on the element', function() {
        this.element.attr('data-tooltip-show-on-click', true);
        this.element.trigger($.Event('click'));
        expect($('.tooltip')).toBeVisible();
    });

    it('can be be triggered manually', function() {
        this.tooltip.openTooltip(this.element);
        expect($('.tooltip')).toBeVisible();
    });

    it('should moves correctly', function() {
        showTooltip(this.element);
        expect($('.tooltip')).toBeVisible();
        // PAGE_X - 0.5 * WIDTH
        // 100 - 0.5 * 100 = 50
        expect(parseInt($('.tooltip').css('left'))).toBe(50);
        // PAGE_Y - (HEIGHT + 15)
        // 100 - (100 + 15) = -15
        expect(parseInt($('.tooltip').css('top'))).toBe(-15);
        this.element.trigger($.Event('mousemove', {
            pageX: PAGE_X + DELTA,
            pageY: PAGE_Y + DELTA
        }));
        // PAGE_X + DELTA - 0.5 * WIDTH
        // 100 + 10 - 0.5 * 100 = 60
        expect(parseInt($('.tooltip').css('left'))).toBe(60);
        // PAGE_Y + DELTA - (HEIGHT + 15)
        // 100 + 10 - (100 + 15) = -5
        expect(parseInt($('.tooltip').css('top'))).toBe(-5);
    });
});
