(function () {
'use strict';
describe('VideoVolumeControl', function () {
    var state, oldOTBD, volumeControl;

    beforeEach(function () {
        oldOTBD = window.onTouchBasedDevice;
        window.onTouchBasedDevice = jasmine.createSpy('onTouchBasedDevice')
            .andReturn(null);
    });

    afterEach(function () {
        $('source').remove();
        window.onTouchBasedDevice = oldOTBD;
        state.storage.clear();
        state.videoPlayer.destroy();
    });

    it('Volume level has correct value even if cookie is broken', function () {
        $.cookie.andReturn('broken_cookie');
        state = jasmine.initializePlayer();
        volumeControl = state.videoVolumeControl;
        expect(volumeControl.volume).toEqual(100);
    });

    describe('constructor', function () {
        beforeEach(function () {
            spyOn($.fn, 'slider').andCallThrough();
            $.cookie.andReturn('75');
            state = jasmine.initializePlayer();
            volumeControl = state.videoVolumeControl;
        });

        it('initialize volume to 75%', function () {
            expect(volumeControl.volume).toEqual(75);
        });

        it('render the volume control', function () {
            expect($('.volume')).toExist();
        });

        it('create the slider', function () {
            expect($.fn.slider.calls[2].args).toEqual([{
                orientation: 'vertical',
                range: 'min',
                min: 0,
                max: 100,
                slide: jasmine.any(Function)
            }]);
            expect($.fn.slider).toHaveBeenCalledWith(
                'value', volumeControl.volume
            );
        });

        it('add ARIA attributes to live region', function () {
            var liveRegion = $('.video-live-region');

            expect(liveRegion).toHaveAttrs({
                'role': 'status',
                'aria-live': 'polite',
                'aria-atomic': 'false'
            });
        });

        it('add ARIA attributes to volume control', function () {
            var button = $('.volume > a');

            expect(button).toHaveAttrs({
                'role': 'button',
                'title': 'Volume',
                'aria-disabled': 'false'
            });
        });

        it('bind the volume control', function () {
            var button = $('.volume > a');

            expect(button).toHandle('keydown');
            expect(button).toHandle('mousedown');
            expect($('.volume')).not.toHaveClass('is-opened');

            $('.volume').mouseenter();
            expect($('.volume')).toHaveClass('is-opened');

            $('.volume').mouseleave();
            expect($('.volume')).not.toHaveClass('is-opened');
        });
    });

    describe('setVolume', function () {
        beforeEach(function () {
            state = jasmine.initializePlayer();
            volumeControl = state.videoVolumeControl;

            this.addMatchers({
                assertLiveRegionState: function (volume, expectation) {
                    var region = $('.video-live-region');

                    var getExpectedText = function (text) {
                        return text + ' Volume.';
                    };

                    this.actual.setVolume(volume, true, true);
                    return region.text() === getExpectedText(expectation);
                }
            });
        });

        it('update is not called, if new volume equals current', function () {
            volumeControl.volume = 60;
            spyOn(volumeControl, 'updateSliderView');
            volumeControl.setVolume(60, false, true);
            expect(volumeControl.updateSliderView).not.toHaveBeenCalled();
        });

        it('volume is changed on sliding', function () {
            volumeControl.onSlideHandler(null, {value: 99});
            expect(volumeControl.volume).toBe(99);
        });

        describe('when the new volume is more than 0', function () {
            beforeEach(function () {
                volumeControl.setVolume(60, false, true);
            });

            it('set the player volume', function () {
                expect(volumeControl.volume).toEqual(60);
            });

            it('remove muted class', function () {
                expect($('.volume')).not.toHaveClass('is-muted');
            });
        });

        describe('when the new volume is more than 0, but was 0', function () {
             it('remove muted class', function () {
                volumeControl.setVolume(0, false, true);
                expect($('.volume')).toHaveClass('is-muted');
                state.el.trigger('volumechange', [20]);
                expect($('.volume')).not.toHaveClass('is-muted');
            });
        });

        describe('when the new volume is 0', function () {
            beforeEach(function () {
                volumeControl.setVolume(0, false, true);
            });

            it('set the player volume', function () {
                expect(volumeControl.volume).toEqual(0);
            });

            it('add muted class', function () {
                expect($('.volume')).toHaveClass('is-muted');
            });
        });

        it('when the new volume is Muted', function () {
            expect(volumeControl).assertLiveRegionState(0, 'Muted');
        });

        it('when the new volume is in ]0,20]', function () {
            expect(volumeControl).assertLiveRegionState(10, 'Very low');
        });

        it('when the new volume is in ]20,40]', function () {
            expect(volumeControl).assertLiveRegionState(30, 'Low');
        });

        it('when the new volume is in ]40,60]', function () {
            expect(volumeControl).assertLiveRegionState(50, 'Average');
        });

        it('when the new volume is in ]60,80]', function () {
            expect(volumeControl).assertLiveRegionState(70, 'Loud');
        });

        it('when the new volume is in ]80,100[', function () {
            expect(volumeControl).assertLiveRegionState(90, 'Very loud');
        });

        it('when the new volume is Maximum', function () {
            expect(volumeControl).assertLiveRegionState(100, 'Maximum');
        });
    });

    describe('increaseVolume', function () {
        beforeEach(function () {
            state = jasmine.initializePlayer();
            volumeControl = state.videoVolumeControl;
        });

        it('volume is increased correctly', function () {
            volumeControl.volume = 60;
            state.el.trigger(jQuery.Event("keydown", {
                keyCode: $.ui.keyCode.UP
            }));
            expect(volumeControl.volume).toEqual(80);
        });

        it('volume level is not changed if it is already max', function () {
            volumeControl.volume = 100;
            volumeControl.increaseVolume();
            expect(volumeControl.volume).toEqual(100);
        });
    });

    describe('decreaseVolume', function () {
        beforeEach(function () {
            state = jasmine.initializePlayer();
            volumeControl = state.videoVolumeControl;
        });

        it('volume is decreased correctly', function () {
            volumeControl.volume = 60;
            state.el.trigger(jQuery.Event("keydown", {
                keyCode: $.ui.keyCode.DOWN
            }));
            expect(volumeControl.volume).toEqual(40);
        });

        it('volume level is not changed if it is already min', function () {
            volumeControl.volume = 0;
            volumeControl.decreaseVolume();
            expect(volumeControl.volume).toEqual(0);
        });
    });

    describe('toggleMute', function () {
        beforeEach(function () {
            state = jasmine.initializePlayer();
            volumeControl = state.videoVolumeControl;
        });

        describe('when the current volume is more than 0', function () {
            beforeEach(function () {
                volumeControl.volume = 60;
                volumeControl.button.trigger('mousedown');
            });

            it('save the previous volume', function () {
                expect(volumeControl.storedVolume).toEqual(60);
            });

            it('set the player volume', function () {
                expect(volumeControl.volume).toEqual(0);
            });
        });

        describe('when the current volume is 0', function () {
            beforeEach(function () {
                volumeControl.volume = 0;
                volumeControl.storedVolume = 60;
                volumeControl.button.trigger('mousedown');
            });

            it('set the player volume to previous volume', function () {
                expect(volumeControl.volume).toEqual(60);
            });
        });
    });

    describe('keyDownHandler', function () {
        beforeEach(function () {
            state = jasmine.initializePlayer();
            volumeControl = state.videoVolumeControl;
        });

        var assertVolumeIsNotChanged = function (eventObject) {
            volumeControl.volume = 60;
            state.el.trigger(jQuery.Event("keydown", eventObject));
            expect(volumeControl.volume).toEqual(60);
        };

        it('nothing happens if ALT+keyUp are pushed down', function () {
            assertVolumeIsNotChanged({
                keyCode: $.ui.keyCode.UP,
                altKey: true
            });
        });

        it('nothing happens if SHIFT+keyUp are pushed down', function () {
            assertVolumeIsNotChanged({
                keyCode: $.ui.keyCode.UP,
                shiftKey: true
            });
        });

        it('nothing happens if SHIFT+keyDown are pushed down', function () {
            assertVolumeIsNotChanged({
                keyCode: $.ui.keyCode.DOWN,
                shiftKey: true
            });
        });
    });

    describe('keyDownButtonHandler', function () {
        beforeEach(function () {
            state = jasmine.initializePlayer();
            volumeControl = state.videoVolumeControl;
        });

        it('nothing happens if ALT+ENTER are pushed down', function () {
            var isMuted = volumeControl.getMuteStatus();
            $('.volume > a').trigger(jQuery.Event("keydown", {
                keyCode: $.ui.keyCode.ENTER,
                altKey: true
            }));
            expect(volumeControl.getMuteStatus()).toEqual(isMuted);
        });
    });
});
}).call(this);
