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

    var KEY = $.ui.keyCode,

    keyPressEvent = function(key) {
        return $.Event('keydown', { keyCode: key });
    };

    beforeEach(function () {
        oldOTBD = window.onTouchBasedDevice;
        window.onTouchBasedDevice = jasmine.createSpy('onTouchBasedDevice')
            .and.returnValue(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.and.returnValue('broken_cookie');
        state = jasmine.initializePlayer();
        volumeControl = state.videoVolumeControl;
        expect(volumeControl.volume).toEqual(100);
    });

    describe('constructor', function () {
        beforeEach(function () {
            spyOn($.fn, 'slider').and.callThrough();
            $.cookie.and.returnValue('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.argsFor(2)).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({
                'aria-live': 'polite'
            });
        });

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

            expect(button).toHaveAttrs({
                'aria-disabled': 'false'
            });
        });

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

            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;

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

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

                            actual.setVolume(volume, true, true);
                            return {
                                pass: 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 () {
            var button = $('.volume .control');
            volumeControl.volume = 60;

            // adjust the volume
            button.focus();
            button.trigger(keyPressEvent(KEY.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 () {
            var button = $('.volume .control');
            volumeControl.volume = 60;

            // adjust the volume
            button.focus();
            button.trigger(keyPressEvent(KEY.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: KEY.UP,
                altKey: true
            });
        });

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

        it('nothing happens if SHIFT+keyDown are pushed down', function () {
            assertVolumeIsNotChanged({
                keyCode: KEY.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 .control').trigger(jQuery.Event("keydown", {
                keyCode: KEY.ENTER,
                altKey: true
            }));
            expect(volumeControl.getMuteStatus()).toEqual(isMuted);
        });
    });
});
}).call(this);
