class Main extends Phaser.Scene {

    constructor ()
    {
        super({ key: 'Main', active: true });
    }
    
    preload()
    {
    }

    create ()
    {
        this.scene.sleep();

        this.vDelta = 0;//main screen offset from top, 0 if in landscape mode, 800 in portrait

        this.modeLandscape = true;

        //load settings if any
        this.conf = {};

        this.conf.reelsSpeed = 1;//medium, 0 - slow, 1 - medium, 2 - fast
        this.conf.allSoundMuted = false;
        this.conf.bgrSoundMuted = false;
        this.conf.autoSpinLimit = -1;//unlimited

        this.conf.keyStart = true;
        this.conf.keyAutoStart = true;
        this.conf.keyMaxBet = true;
        this.conf.keyInfo = true;
        this.conf.keyExit = true;
        this.conf.keyBet = true;
        this.conf.keySettings = true;

        if(localStorage)
        {
            if(localStorage.reelsSpeed){this.conf.reelsSpeed = parseInt(localStorage.reelsSpeed);}
            
            if(localStorage.allSoundMuted){this.conf.allSoundMuted = localStorage.allSoundMuted === "true";}
            if(localStorage.bgrSoundMuted){this.conf.bgrSoundMuted = localStorage.bgrSoundMuted === "true";}
            if(localStorage.autoSpinLimit){this.conf.autoSpinLimit = parseInt(localStorage.autoSpinLimit);}

            if(localStorage.keyStart){this.conf.keyStart = localStorage.keyStart === "true";}
            if(localStorage.keyAutoStart){this.conf.keyAutoStart = localStorage.keyAutoStart === "true";}
            if(localStorage.keyMaxBet){this.conf.keyMaxBet = localStorage.keyMaxBet === "true";}
            if(localStorage.keyInfo){this.conf.keyInfo = localStorage.keyInfo === "true";}
            if(localStorage.keyExit){this.conf.keyExit = localStorage.keyExit === "true";}
            if(localStorage.keyBet){this.conf.keyBet = localStorage.keyBet === "true";}
            if(localStorage.keySettings){this.conf.keySettings = localStorage.keySettings === "true";}
        }    

        this.sound.setMute(this.conf.allSoundMuted);

        this.bgrmain = this.add.image(640, 360 + this.vDelta, 'bgrmain');

        this.stoppers = [];
        
        this.stoppers.push(this.add.image(54, 314, 'stopper'));
        this.stoppers.push(this.add.image(288, 314, 'stopper'));
        this.stoppers.push(this.add.image(523, 314, 'stopper'));
        this.stoppers.push(this.add.image(758, 314, 'stopper'));
        this.stoppers.push(this.add.image(993, 314, 'stopper'));
        this.stoppers.push(this.add.image(1228, 314, 'stopper'));

        this.hideStoppers();

        this.images = {};

        this.images["cherry"] = this.add.image(0, 0, "cherry").setVisible(false);
        this.images["lemon"] = this.add.image(0, 0, "lemon").setVisible(false);
        this.images["orange"] = this.add.image(0, 0, "orange").setVisible(false);
        this.images["plum"] = this.add.image(0, 0, "plum").setVisible(false);
        this.images["bell"] = this.add.image(0, 0, "bell").setVisible(false);
        this.images["grape"] = this.add.image(0, 0, "grape").setVisible(false);
        this.images["melon"] = this.add.image(0, 0, "melon").setVisible(false);
        this.images["star"] = this.add.image(0, 0, "star").setVisible(false);
        this.images["seven"] = this.add.image(0, 0, "seven").setVisible(false);
        this.images["break"] = this.add.image(0, 0, "break").setVisible(false);
        this.images["scatter"] = this.add.image(0, 0, "scatter").setVisible(false);
        this.images["mystery"] = this.add.image(0, 0, "mystery").setVisible(false);

        this.gameState = GAME_STATE_NOT_INITIALIZED;
        this.prevGameState = GAME_STATE_NOT_INITIALIZED;

        let startBtnData = {
            'scene': this,
            'key':'startBtn',
            'frameWidth':182,
            'frameHeight':183,
            'x': 1170,
            'y': 431,
            'img': 'holdForAuto',
            'img_x': 1168,
            'img_y':362,
            'horizontalOffset': 0,
            'vDelta': this.vDelta,
            'onClick': this.onStart,
            'onPressed': this.onStartPressed
        }

        this.startBtn = this.scene.add("StartBtn", SceneButtonEx, true, startBtnData);

        let stopBtnData = {
            'scene': this,
            'key':'stopBtn',
            'frameWidth':131,
            'frameHeight':131,
            'x': 1170,
            'y': 431,
            'horizontalOffset': 0,
            'vDelta': this.vDelta,
            'onClick': this.onStop,
            'onPressed': null
        }

        this.stopBtn = this.scene.add("StopBtn", SceneButton, true, stopBtnData);

        let autoStopBtnData = {
            'scene': this,
            'key':'autoStopBtn',
            'counter_key': 'autoCounterBtn',
            'frameWidth':181,
            'frameHeight':156,
            'x': 1170,
            'y': 431,
            'horizontalOffset': 0,
            'vDelta': this.vDelta,
            'onClick': this.onAutoStop,
            'onPressed': null
        }

        this.autoStopBtn = this.scene.add("AutoStopBtn", SceneButtonCounter, true, autoStopBtnData);

        let betBtnData = {
            'scene': this,
            'key':'betBtn',
            'frameWidth':182,
            'frameHeight':183,
            'x': 104,
            'y': 431,
            'img': 'holdForMaxBet',
            'img_x': 104,
            'img_y':362,
            'horizontalOffset': 0,
            'vDelta': this.vDelta,
            'onClick': this.onBet,
            'onPressed': this.onBetPressed
        }

        this.betBtn = this.scene.add("BetBtn", SceneButtonEx, true, betBtnData);

        let infoBtnData = {
            'scene': this,
            'key':'infoBtn',
            'frameWidth':136,
            'frameHeight':136,
            'x': 1170,
            'y': 179,
            'horizontalOffset': 0,
            'vDelta': this.vDelta,
            'onClick': this.onBtnInfo,
            'onPressed': null
        };
        
        this.infoBtn = this.scene.add("InfoBtn", SceneButton, true, infoBtnData);

        let takeJackpotBtnData = {
            'scene': this,
            'key':'takeBtn',
            'frameWidth':182,
            'frameHeight':182,
            'x': 1170,
            'y': 431,
            'horizontalOffset': 0,
            'vDelta': this.vDelta,
            'onClick': this.onJackpotTaken,
            'onPressed': null
        };
        
        this.takeJackpotBtn = this.scene.add("TakeJackpotBtn", SceneButton, true, takeJackpotBtnData);

        let takeCashbackBtnData = {
            'scene': this,
            'key':'takeBtn',
            'frameWidth':182,
            'frameHeight':182,
            'x': 1170,
            'y': 431,
            'horizontalOffset': 0,
            'vDelta': this.vDelta,
            'onClick': this.onCashbackTaken,
            'onPressed': null
        };

        this.takeCashbackBtn = this.scene.add("TakeCashbackBtn", SceneButton, true, takeCashbackBtnData);

        let homeBtnData = {
            'scene': this,
            'key':'homeBtn',
            'frameWidth':182,
            'frameHeight':183,
            'x': 104,
            'y': 179,
            'horizontalOffset': 0,
            'vDelta': this.vDelta,
            'onClick': this.onHome,
            'onPressed': null
        };

        this.homeBtn = this.scene.add("HomeBtn", SceneButton, true, homeBtnData);

        this.homeBtn.setCanWake(homeBtnEnabled(this));
        
        let settingsBtnData = {
            'scene': this,
            'key':'settingsBtn',
            'frameWidth':110,
            'frameHeight':110,
            'x': 104,
            'y': 179,
            'horizontalOffset': 0,
            'vDelta': this.vDelta,
            'onClick': this.onSettings,
            'onPressed': null
        };

        this.settingsBtn = this.scene.add("SettingsBtn", SceneButton, true, settingsBtnData);

        let optionsBtnData = {
            'scene': this,
            'key':'optionsBtn',
            'frameWidth':182,
            'frameHeight':183,
            'x': 1170,
            'y': 179,
            'horizontalOffset': 0,
            'vDelta': this.vDelta,
            'onClick': this.onOptions,
            'onPressed': null
        };

        this.optionsBtn = this.scene.add("OptionsBtn", SceneButton, true, optionsBtnData);

        let settingsBtnSmallData = {
            'scene': this,
            'key':'settingsBtnSmall',
            'frameWidth':180,
            'frameHeight':180,
            'x': 104,
            'y': 179,
            'horizontalOffset': 0,
            'vDelta': this.vDelta,
            'onClick': this.onSettings,
            'onPressed': null
        };

        this.settingsBtnSmall = this.scene.add("SettingsBtnSmall", SceneButton, true, settingsBtnSmallData);

        let rulesBtnData = {
            'scene': this,
            'key':'rulesBtnSmall',
            'frameWidth':180,
            'frameHeight':180,
            'x': 960,
            'y': 650,
            'horizontalOffset': 0,
            'vDelta': this.vDelta,
            'onClick': this.onRules,
            'onPressed': null
        };

        this.rulesBtn = this.scene.add("RulesBtn", SceneButton, true, rulesBtnData);

        this.sndWin = this.sound.add('win');
        this.sndWin.setLoop(true);
        this.sndJackpotWin = this.sound.add('jackpotWin');
        this.sndWinToCredit = this.sound.add('winToCredit');
        this.sndWinToCreditEnd = this.sound.add('winToCreditEnd');
        this.sndStopEarly = this.sound.add("reelstopearly");
                
        this.sndBackground = new CustomSound(this, "spin", true, this.conf.bgrSoundMuted, 1500);
        
        this.bar = this.scene.add("Bar", Bar, true, {scene: this, key: 'bgrbar', vDelta: this.vDelta, logoxl: 694, logoxp: 644, logoy: 668, fontBet: "fontBet", fontUnits: "fontUnits"});
        this.paytable = this.scene.add("Paytable", Paytable, true, {scene: this, vDelta: this.vDelta});
        this.legallimit = this.scene.add("LegalLimit", LegalLimit, true, {scene: this, vDelta: this.vDelta, fontBet: "fontLegalLimitWin"});
        this.settings = this.scene.add("Settings", Settings, true, {scene: this, key: "bgrsettings", x: 640, y: 360});
        this.settingsmobile = this.scene.add("SettingsMobile", SettingsMobile, true, {scene: this, key: "bgrsettingsmobile", x: 640, y: 760});
        this.jackpots = this.scene.add("Jackpots", SceneJackpots, true, {scene: this, fontGrand: "fontJackpotGrand", fontMaxi: "fontJackpotMaxi", fontMini: "fontJackpotMini"});
        this.error = this.scene.add("SceneError", SceneError, true, {'scene': this, vDelta: this.vDelta, x: 640, y: 300, fontText: "totalFont"});

        this.rules = this.scene.add("SceneRules", SceneRules, true, {'scene': this, vDelta: this.vDelta, x: 640, y: 300, imagekey: 'gameinfo'});

        this.totalWin = this.scene.add("TotalWin", TotalWin, true, {'scene': this, vDelta: this.vDelta, x: 640, y: 390, sndWin: this.sndWin, sndWinToCredit: this.sndWinToCredit, sndWinToCreditEnd: this.sndWinToCreditEnd, fontText: "totalwinLetters"});
        this.cashbackWin = this.scene.add("CashBack", CashBack, true, {'scene': this, vDelta: this.vDelta, x: 640, y: 390, sndJackpotWin: this.sndJackpotWin, sndWinToCredit: this.sndWinToCredit, sndWinToCreditEnd: this.sndWinToCreditEnd, fontText: 'totalwinLetters'});
        this.jackpotWin = this.scene.add("JackpotWin", JackpotWin, true, {'scene': this, vDelta: this.vDelta, x: 640, y: 390, sndJackpotWin: this.sndJackpotWin, sndWinToCredit: this.sndWinToCredit, sndWinToCreditEnd: this.sndWinToCreditEnd, fontText: "totalwinLetters"});
        
        this.reelStoppersTime = 2000;
        this.reelStoppersTimer = -1;
        
        this.jackpotPanelTime = 3000;
        this.jackpotPanelTimer = this.jackpotPanelTime;

        this.balancePollTime = 20000;
        this.balancePollTimer = this.balancePollTime;

        this.jackpotPollTime = 20000;
        this.jackpotPollTimer = this.jackpotPollTime;

        this.jackpotWaitTime = 120000;//
        this.jackpotWaitTimer = -1;

        this.cashbackWaitTime = 120000;
        this.cashbackWaitTimer = -1;

        this.btnBlinkTime = 10000;
        this.btnBlinkTimer = this.btnBlinkTime;

        this.btnHintTime = 20000;
        this.btnHintTimer = this.btnHintTime;

        this.sessionExpireTimer = SESSION_TIMEOUT;

        this.balance = 0;
        this.autoPlay = false;
        this.currentGame = null;
        this.autoSpinLimit = this.conf.autoSpinLimit;

        this.errorPending = false;
        this.errorMessage = "";
        this.criticalError = false;

        this.sound.pauseOnBlur = false;//do not stop web audio if game loses focus
        this.input.keyboard.enabled = true;

        this.symbols = ["cherry", "lemon", "orange", "plum", "bell", "grape", "melon", "star", "seven", "break", "scatter", "mystery"];

        if(this.conf.keyStart)
        {
            this.keyStart = this.input.keyboard.addKey('SPACE');
            this.keyStart.on('down', this.onKbdStart, this);
        }
        
        if(this.conf.keyAutoStart)
        {
            this.keyAutoStart = this.input.keyboard.addKey('A');
            this.keyAutoStart.on('down', this.onKbdAutoStart, this);
        }

        if(this.conf.keyMaxBet)
        {
            this.keyMaxBet = this.input.keyboard.addKey('M');
            this.keyMaxBet.on('down', this.onKbdMaxBet, this);
        }

        if(this.conf.keyInfo)
        {
            this.keyInfo = this.input.keyboard.addKey('I');
            this.keyInfo.on('down', this.onKbdPaytable, this);
        }

        if(this.conf.keyExit)
        {
            this.keyExit = this.input.keyboard.addKey('E');
            this.keyExit.on('down', this.onKbdExit, this);
        }

        if(this.conf.keyBet)
        {
            this.keyBet = this.input.keyboard.addKey('B');
            this.keyBet.on('down', this.onKbdBet, this);
        }

        if(this.conf.keySettings)
        {
            this.keySettings = this.input.keyboard.addKey('S');
            this.keySettings.on('down', this.onKbdSettings, this);
        }

        this.keyLayout = this.input.keyboard.addKey('P');
        this.keyLayout.on('down', this.onChangeLayout, this);

        this.server = document.getElementById('Hostname').value;
        this.port = document.getElementById('Port').value;
        this.token = document.getElementById('WalletToken').value;
        this.gameid = document.getElementById('gameId').value;
        this.userid = document.getElementById('userId').value;
        this.casinoid = document.getElementById('casinoId').value;
        this.lobbyUrl = document.getElementById('lobbyUrl').value;

        if( !!document.getElementById('currency') )
        {
            this.external_currency = document.getElementById('currency').value;
        }
        else
        {
            this.external_currency = "";
        }

        this.gameSocket = null;

        if(this.server != "" && this.port != "" && this.token != "" && this.gameid != "" && this.userid != "" && this.casinoid != "")
        {
            this.gameSocket = new GameSocket(this, this.server, this.port, 'r5_break_the_lines.1', this.token, this.userid, this.gameid, this.casinoid, this.external_currency, this.symbols);
        }

        window.addEventListener("orientationchange", this.onOrientationChange.bind(this), false);

        this.firstTapTime = 0;
        this.tapTimer = -1;

        this.input.on('pointerdown', this.onDoubleTap.bind(this));

        this.swipe = this.Gestures.add.swipe();

        this.swipe.on('swipe', this.onSwipe, this);
    }

    onSwipe()
    {
        if(this.errorPending)
        {
            return;
        }

        if(this.autoPlay)
        {
            return;
        }

        if(!this.modeLandscape)
        {
            return;
        }

        if(this.settings.scene.isVisible())
        {
            return;
        }

        if(this.rules.scene.isVisible())
        {
            return;
        }
        
        if(this.swipe.down && (this.gameState == GAME_STATE_READY || this.gameState == GAME_STATE_WIN_LINES))
        {
            if(this.startBtn.scene.isSleeping())
            {
                return;
            }

            this.rulesBtn.sleep();
            this.onBtnInfo();
        }
        else if(this.swipe.up && this.gameState == GAME_STATE_PAYTABLE)
        {
            this.paytable.onPaytableClosed();
        }
    }
    
    getTime()
    {
        let d = new Date();
        return d.getTime();
    }

    onDoubleTap(event)//check for double double tap to enter/leave fullscreen
    {
        if(this.sys.game.device.os.desktop)
        {
            return;
        }

        if(!this.sys.game.device.fullscreen.available)
        {
            return;
        }
        
        if (this.firstTapTime == 0)
        {
            this.firstTapTime = this.getTime();
            this.tapTimer = 350;
            return;
        }

        let elapsedTime = this.getTime() - this.firstTapTime;

        if (elapsedTime < 350)
        {
            if((this.modeLandscape && event.downX >= 210 && event.downX < 1058) ||
               (!this.modeLandscape && event.downY >= 0 && event.downY < 1520))
            {
            if(!this.scale.isFullscreen)
            {
                this.scale.startFullscreen();
            }
            else
            {
                this.scale.stopFullscreen();
            }
        }
        }

        this.firstTapTime = 0;
    }
    
    onOrientationChange(event)
    {
        if(this.gameState == GAME_STATE_NOT_INITIALIZED) 
        {
            return;
        }

        let orientation = 0;

        if(window.hasOwnProperty('orientation'))
        {
            orientation = window.orientation;
        }
        else if(window.screen.orientation.hasOwnProperty('angle'))
        {
            orientation = window.screen.orientation.angle;
        }
        else
        {
            return;
        }
        
        if (orientation == 0 || orientation == 180)
        {
            this.setPortraitLayout();
        }
        else if (orientation == 90 || orientation == -90 || orientation == 270)
        {
            this.setLandscapeLayout();
        }
    }

    setLandscapeLayout()
    {
        this.jackpotPanelTimer = -1;
        this.scale.orientation = Phaser.Scale.LANDSCAPE;
        this.scale.setGameSize(GAME_WIDTH, GAME_LANDSCAPE_HEIGHT);

        this.reelmanager.onOrientationChange(0);
        this.stoppers.forEach(stopper => {stopper.setPosition(stopper.x, stopper.y - this.vDelta); });

        this.vDelta = 0;

        if(this.settingsmobile.scene.isVisible())
        {
            this.onSettings();
        }

        this.jackpots.setCanWake(true);
        this.jackpots.setCanSleep(true);

        this.paytable.onOrientationChange(0, -80);
        this.paytable.scene.setVisible(false);

        this.cashbackWin.onOrientationChange(this.vDelta);
        this.jackpotWin.onOrientationChange(this.vDelta);
        this.error.onOrientationChange(this.vDelta);
        this.bgrmain.setPosition(640, 360 + this.vDelta);
        this.bar.onOrientationChange(this.vDelta);
        this.legallimit.onOrientationChange(this.vDelta);
        
        this.bar.showLogo();
        
        this.rules.onOrientationChange(this.vDelta);

        if(!this.rules.scene.isSleeping())
        {
            this.rules.scene.sleep();
        }
        
        this.totalWin.onOrientationChange(0, -800);

        this.startBtn.setPosition(1170, 431, 1168, 362);
        this.startBtn.setScale(1.0);
        this.startBtn.scene.bringToTop();

        this.autoStopBtn.setPosition(1170, 431);
        this.autoStopBtn.setScale(1.0);
        
        this.stopBtn.setPosition(1170, 431);
        this.stopBtn.setScale(1.0);

        this.betBtn.setPosition(104, 431, 104, 362);
        this.betBtn.setScale(1.0);
        this.betBtn.scene.bringToTop();

        this.homeBtn.setPosition(104, 179);
        this.homeBtn.setScale(1.0);
        this.homeBtn.scene.bringToTop();
        
        this.settingsBtnSmall.sleep();

        this.rulesBtn.setPosition(960, 650);
        this.rulesBtn.sleep();
        
        this.takeJackpotBtn.setPosition(1170, 431);
        this.takeJackpotBtn.setScale(1.0);

        this.takeCashbackBtn.setPosition(1170, 431);
        this.takeCashbackBtn.setScale(1.0);

        this.optionsBtn.setCanWake(true);

        if(this.legallimit.scene.isVisible())
        {
            this.legallimit.scene.bringToTop();
        }

        if(this.gameState == GAME_STATE_WIN_LINES ||
            this.gameState == GAME_STATE_READY)
        {
            if(this.jackpotPanelTimer < 0)
            {
                this.jackpots.scene.bringToTop();
            }
    
            this.optionsBtn.wake();
        }            

        if(this.gameState == GAME_STATE_JACKPOT_WIN)
        {
            this.takeJackpotBtn.scene.bringToTop();
        }

        if(this.gameState == GAME_STATE_CASHBACK_WIN)
        {
            this.takeCashbackBtn.scene.bringToTop();
        }

        if(this.autoPlay)
        {
            this.autoStopBtn.scene.bringToTop();
        }
        
        this.modeLandscape = true;
    }
    
    setPortraitLayout()
    {
        this.scale.orientation = Phaser.Scale.PORTRAIT;
        this.scale.setGameSize(GAME_WIDTH, GAME_PORTRAIT_HEIGHT);

        this.vDelta = 800;

        if(this.gameState == GAME_STATE_PAYTABLE)
        {
            this.onPaytableClosed();
        }

        if(this.settings.scene.isVisible())
        {
            this.onSettings();
        }

        if(this.rules.scene.isVisible())
        {
            this.onRules();
        }

        if(this.jackpots.scene.isSleeping())
        {
            this.jackpots.wake();
        }

        if(this.paytable.scene.isSleeping())
        {
            this.paytable.scene.wake();
        }

        this.paytable.scene.setVisible(true);
        this.paytable.scene.bringToTop();
        this.paytable.onOrientationChange(80, 80);

        this.jackpots.setCanWake(false);
        this.jackpots.setCanSleep(false);
        this.jackpots.scene.bringToTop();

        this.cashbackWin.onOrientationChange(this.vDelta);
        this.jackpotWin.onOrientationChange(this.vDelta);
        this.error.onOrientationChange(this.vDelta);
        
        this.optionsBtn.sleep();

        this.startBtn.setPosition(620, 1751, 618, 1619);
        this.startBtn.setScale(2.0);

        this.autoStopBtn.setPosition(620, 1751);
        this.autoStopBtn.setScale(2.0);

        this.stopBtn.setPosition(620, 1751);
        this.stopBtn.setScale(2.8);

        this.betBtn.setPosition(1104, 1751, 1101, 1632);
        this.betBtn.setScale(1.7);

        this.homeBtn.setPosition(154, 1739);
        this.homeBtn.setScale(2);

        if((this.gameState == GAME_STATE_SHOW_REELS ||
            this.gameState == GAME_STATE_READY ||
            this.gameState == GAME_STATE_WIN_LINES) &&
            !this.homeBtn.scene.isVisible())
        {
            this.homeBtn.wake();
        }
 
        this.settingsBtnSmall.setPosition(90, 2085);
        this.rulesBtn.setPosition(1180, 2085);

        if(this.gameState == GAME_STATE_SHOW_REELS ||
           this.gameState == GAME_STATE_READY ||
           this.gameState == GAME_STATE_WIN_LINES)
        {
            this.settingsBtnSmall.wake();
            this.rulesBtn.wake();
        }
 
        this.takeJackpotBtn.setPosition(620, 1751);
        this.takeJackpotBtn.setScale(2.0);

        this.takeCashbackBtn.setPosition(620, 1751);
        this.takeCashbackBtn.setScale(2.0);

        this.optionsBtn.setCanWake(false);
        this.optionsBtn.sleep();

        this.totalWin.onOrientationChange(800, 800);

        this.bgrmain.setPosition(640, 360 + this.vDelta);
        this.stoppers.forEach(stopper => {stopper.setPosition(stopper.x, stopper.y + this.vDelta); });
        this.bar.onOrientationChange(this.vDelta);
        this.legallimit.onOrientationChange(this.vDelta);
        
        this.rules.onOrientationChange(this.vDelta);
        
        this.reelmanager.onOrientationChange(this.vDelta);
        
        this.scene.wake();
        this.scene.bringToTop();
        this.bar.scene.wake();
        this.bar.scene.bringToTop();
        this.bar.showLogo();

        if(this.gameState == GAME_STATE_JACKPOT_WIN)
        {
            this.jackpotWin.scene.bringToTop();
        }

        if(this.gameState == GAME_STATE_CASHBACK_WIN)
        {
            this.cashbackWin.scene.bringToTop();
        }

        if(this.gameState != GAME_STATE_READY &&
           this.gameState != GAME_STATE_WIN_LINES)
        {
            this.paytable.clearWins();
        }

        this.totalWin.scene.bringToTop();

        if(this.legallimit.scene.isVisible())
        {
            this.legallimit.scene.bringToTop();
        }

        if(!this.error.scene.isSleeping())
        {
            this.error.scene.bringToTop();
        }

        this.modeLandscape = false;
    }

    update (time, delta) 
    {
        if (this.hasOwnProperty('reelmanager'))
        {
            this.reelmanager.update(time, delta);
        }

        if (this.gameState == GAME_STATE_NOT_INITIALIZED)
        {
            return;
        }

        this.updateOnDoubleTap(delta);
        this.updateSessionTimeout(delta);
        this.updateReelBorders(delta);
        this.updateJackpotPanel(delta);
        this.updateBalance(delta);
        this.updateJackpots(delta);
        this.updateJackpotWait(delta);
        this.updateCashbackWait(delta);
        this.updateBtnBlink(delta);
        this.updateBtnHint(delta);
    }

    updateOnDoubleTap(delta)
    {
        if(this.tapTimer >= 0)
        {
            this.tapTimer -= delta;
            if(this.tapTimer < 0)
            {
                this.firstTapTime = 0;
            }
        }
    }

    updateSessionTimeout(delta)
    {
        if ((this.gameState == GAME_STATE_READY ||
              this.gameState == GAME_STATE_WIN_LINES) && !this.autoPlay)
        {
            if(this.sessionExpireTimer >= 0)
            {
                this.sessionExpireTimer -= delta;

                if(this.sessionExpireTimer < 0)
                {
                    this.gameSocket.disconnect();
                    this.gameState = GAME_STATE_NOT_INITIALIZED;
                }
            }
        }
    }

    updateReelBorders(delta)
    {
        if(this.reelStoppersTimer >= 0)
        {
            this.reelStoppersTimer -= delta;

            if(this.reelStoppersTimer < 0)
            {
                this.hideStoppers();
            }
        }
    }

    updateBalance(delta)
    {
        if ((this.gameState == GAME_STATE_READY ||
              this.gameState == GAME_STATE_WIN_LINES) && !this.autoPlay)
        {
            if(this.balancePollTimer >= 0)
            {
                this.balancePollTimer -= delta;
    
                if(this.balancePollTimer < 0)
                {
                    this.gameSocket.queryBalance();
                    this.balancePollTimer = this.balancePollTime;
                }
            }

            if(!this.errorPending)
            {
                if(this.balance < this.gameSocket.getBet())
                {
                    if(this.error.scene.isSleeping())
                    {
                        this.error.setBlinkingMessage("NOT ENOUGH CREDIT");
                    }
                    else if(!this.error.scene.isVisible())
                    {
                        this.error.scene.setVisible(true);
                        this.error.scene.bringToTop();
                    }
                }
                else if(this.error.scene.isVisible())
                {
                    this.error.clearMessage();
                }
            }                
        }
    }

    updateJackpots(delta)
    {
        if (this.gameState == GAME_STATE_NOT_INITIALIZED)
        {
            return;
        }

        if(this.jackpotPollTimer >= 0)
        {
            this.jackpotPollTimer -= delta;

            if(this.jackpotPollTimer < 0)
            {
                this.gameSocket.queryJackpots();
                this.jackpotPollTimer = this.jackpotPollTime;
            }
        }
    }

    updateJackpotPanel(delta)
    {
        if (this.gameState == GAME_STATE_SPIN ||
            this.gameState == GAME_STATE_SERVER_RESPONSE_PENDING ||
            this.gameState == GAME_STATE_TOTAL_WIN ||
            this.gameState == GAME_STATE_JACKPOT_WIN ||
            this.gameState == GAME_STATE_CASHBACK_WIN || 
            this.gameState == GAME_STATE_PAYTABLE ||
            this.reelmanager.state == RM_STATE_SHAKE ||
            this.autoPlay)
        {
            return;
        }

        if(this.jackpotPanelTimer >= 0)
        {
            this.jackpotPanelTimer -= delta;

            if(this.jackpotPanelTimer < 0)
            {
                this.jackpots.wake();
                if(this.rules.scene.isVisible())
                {
                    this.rules.scene.bringToTop();
                }
            }
        }
    }
    
    updateJackpotWait(delta)
    {
        if (this.gameState != GAME_STATE_JACKPOT_WIN )
        {
            return;
        }

        if(this.jackpotWaitTimer >= 0)
        {
            this.jackpotWaitTimer -= delta;

            if(this.jackpotWaitTimer < 0)
            {
                this.onJackpotTaken();
            }
        }
    }

    updateCashbackWait(delta)
    {
        if (this.gameState != GAME_STATE_CASHBACK_WIN )
        {
            return;
        }

        if(this.cashbackWaitTimer >= 0)
        {
            this.cashbackWaitTimer -= delta;

            if(this.cashbackWaitTimer < 0)
            {
                this.onCashbackTaken();
            }
        }
    }

    updateBtnBlink(delta)
    {
        if(( this.gameState == GAME_STATE_READY ||
             this.gameState == GAME_STATE_WIN_LINES ) && !this.autoPlay)
        {
            if(this.btnBlinkTimer >= 0)
            {
                this.btnBlinkTimer -= delta;
                if(this.btnBlinkTimer < 0)
                {
                    this.btnBlinkTimer = this.btnBlinkTime;
                    this.startBtn.setFrame('OVER');
                    this.betBtn.setFrame('OVER');
                    this.optionsBtn.setFrame('OVER');
                }
            }
        }
    }

    updateBtnHint(delta)
    {
        if(( this.gameState == GAME_STATE_READY ||
             this.gameState == GAME_STATE_WIN_LINES ) && !this.autoPlay)
        {
            if(this.btnHintTimer >= 0)
            {
                this.btnHintTimer -= delta;
                if(this.btnHintTimer < 0)
                {
                    this.btnHintTimer = this.btnHintTime;
                    this.startBtn.showHint();
                    this.betBtn.showHint();
                }
            }
        }
    }
    
    onStart()
    {
        if(this.balance < this.gameSocket.getBet())
        {
            this.startBtn.sleep();
            return;
        }

        if(this.rules.scene.isVisible())
        {
            this.rules.scene.sleep();
        }

        if(this.modeLandscape)
        {
            this.rulesBtn.scene.sleep();
        }

        if(!this.settings.scene.isSleeping())
        {
            this.settings.scene.sleep();
        }

        if(!this.settingsmobile.scene.isSleeping())
        {
            this.settingsmobile.scene.sleep();
        }

        this.paytable.clearWins();

        this.jackpotPanelTimer = -1;
        this.balance -= this.gameSocket.getBet();
        this.bar.reset();
        this.bar.updateBalance(this.balance);
        
        this.jackpots.sleep();

        if(this.currentGame != null && this.currentGame.legal_limit_applyed && this.legallimit.scene.isSleeping())
        {
            this.legallimit.show(this.getTotalWin());
            this.totalWin.scene.sleep();
        }
        else 
        {
            if(this.gameState == GAME_STATE_TOTAL_WIN)
            {
                this.totalWin.scene.wake();
                this.totalWin.scene.bringToTop();
            }
            
            this.totalWin.forceSleep(this.getTotalWin());
        }
        
        this.hideStoppers();

        this.reelmanager.onStart();

        if(!this.modeLandscape)
        {
            this.settingsBtnSmall.sleep();
            this.rulesBtn.sleep();
        }

        this.homeBtn.sleep();
        this.infoBtn.sleep();
        this.settingsBtn.sleep();
        this.optionsBtn.sleep();
        this.betBtn.sleep();
        this.betBtn.reset();
        this.startBtn.sleep();
        this.startBtn.reset();

        this.gameState = GAME_STATE_SERVER_RESPONSE_PENDING;

        this.gameSocket.spin();
    }
    
    onStartPressed()
    {
        this.autoPlay = true;
        this.autoSpinLimit = this.conf.autoSpinLimit;

        this.startBtn.onPressedComplete();
        this.autoStopBtn.wake();
        
        if(this.autoSpinLimit > 0)
        {
            this.autoStopBtn.startCountdown();
            this.autoStopBtn.setCounter(this.autoSpinLimit);
        }            
        
        this.onStart();
    }
    
    onKbdStart(event)
    {
        if(this.gameState == GAME_STATE_PAYTABLE)
        {
            this.paytable.onPaytableClosed();

            this.onStart();
            return;
        }

        if(this.gameState == GAME_STATE_READY ||
           this.gameState == GAME_STATE_WIN_LINES ||
           this.gameState == GAME_STATE_TOTAL_WIN)
        {
            if(this.startBtn.scene.isSleeping() || !this.startBtn.scene.isVisible())
            {
                return;
            }
    
            this.onStart();
            return;
        }

        if(this.gameState == GAME_STATE_SPIN && this.stopBtn.scene.isVisible())
        {
            this.onStop();
            return;
        }

        if(this.gameState == GAME_STATE_JACKPOT_WIN && this.takeJackpotBtn.scene.isVisible())
        {
            this.onJackpotTaken();
            return;
        }

        if(this.gameState == GAME_STATE_CASHBACK_WIN && this.takeCashbackBtn.scene.isVisible())
        {
            this.onCashbackTaken();
            return;
        }
    }

    onKbdAutoStart(event)
    {
        if(this.autoPlay)
        {
            this.onAutoStop();
            this.sound.play("click");
            
            return;
        }

        if(this.startBtn.scene.isSleeping() || !this.startBtn.scene.isVisible())
        {
            return;
        }

        this.sound.play("click");
        
        if(this.autoStopBtn.scene.isVisible())
        {
            this.onAutoStop();
            return;
        }            

        if(this.gameState != GAME_STATE_READY &&
           this.gameState != GAME_STATE_WIN_LINES &&
           this.gameState != GAME_STATE_TOTAL_WIN)
         {
            this.autoPlay = true;
            this.stopBtn.sleep();
            this.autoStopBtn.wake();
            return;
        }
 
        if(this.balance >= this.gameSocket.getBet())
        {
            this.autoPlay = true;
            this.autoSpinLimit = this.conf.autoSpinLimit;
            
            this.autoStopBtn.wake();

            if(this.autoSpinLimit > 0)
            {
                this.autoStopBtn.startCountdown();
                this.autoStopBtn.setCounter(this.autoSpinLimit);
            }            
            
            this.onStart();
        }
    }

    startAutoPlay()
    {
        if(this.autoSpinLimit > 0)
        {
            --this.autoSpinLimit;
            this.autoStopBtn.setCounter(this.autoSpinLimit)
        }

        if(this.balance < this.gameSocket.getBet() || this.autoSpinLimit == 0)
        {
            this.autoPlay = false;
            this.autoStopBtn.sleep();

            this.btnBlinkTimer = this.btnBlinkTime;
            this.btnHintTimer = this.btnHintTime;
    
            this.optionsBtn.wake();
            this.betBtn.wake();
            this.homeBtn.wake();

            if(!this.modeLandscape)
            {
                this.settingsBtnSmall.wake();
                this.rulesBtn.wake();
            }

            if(this.balance < this.gameSocket.getBet())
            {
                this.startBtn.sleep();
            }
            else
            {
                this.startBtn.wake();
            }                
            return;
        }
        else
        {
            this.balance -= this.gameSocket.getBet();
            this.bar.updateBalance(this.balance);
        }
       
        this.hideStoppers();

        this.jackpots.sleep();

        if(this.currentGame.legal_limit_applyed && this.legallimit.scene.isSleeping())
        {
            this.legallimit.show(this.gameSocket.getTotalWin());
            this.totalWin.scene.sleep();
        }
        else 
        {
            this.totalWin.forceSleep(this.getTotalWin());
        }

        this.paytable.clearWins();

        this.reelmanager.onStart();

        this.gameState = GAME_STATE_SERVER_RESPONSE_PENDING;

        this.gameSocket.spin();
    }

    onAutoStop()
    {
        this.autoPlay = false;
        this.autoStopBtn.sleep();
        
        if(this.gameState == GAME_STATE_SPIN)
        {
            if(this.reelmanager.canShowStopBtn())
            {
                this.stopBtn.wake();
            }
        }
        else if( this.gameState == GAME_STATE_REELS_STOPPING)
        {
            this.stopBtn.sleep();
        }
        else if(this.gameState == GAME_STATE_TOTAL_WIN)
        {
            if(this.gameSocket.getBalance() >= this.gameSocket.getBet())
            {
                this.startBtn.wake();
            }
        }
    }

    onBet()
    {
        this.gameSocket.onBetChange();
        
        if(this.balance < this.gameSocket.getBet())
        {
            this.startBtn.sleep();
        }
        else if(this.startBtn.scene.isSleeping())
        {
            this.startBtn.wake();
        }
        
        this.paytable.updatePaytable();
        this.bar.updateBet();
    }

    onBetPressed()
    {
        this.gameSocket.onBetChangeEx();

        if(this.balance < this.gameSocket.getBet())
        {
            this.startBtn.sleep();
        }
        else if(this.startBtn.scene.isSleeping())
        {
            this.startBtn.wake();
        }

        this.paytable.updatePaytable();
        this.bar.updateBet();

        if(this.gameSocket.getBet() == this.gameSocket.getMaxBet())
        {
            this.betBtn.onPressedComplete();
            this.onStart();
        }            
    }

    onKbdBet()
    {
        if((this.betBtn.scene.isSleeping() || !this.betBtn.scene.isVisible()) && this.gameState != GAME_STATE_PAYTABLE)
        {
            return;
        }

        if(this.autoPlay)
        {
            return;
        }

        if(this.gameState == GAME_STATE_READY ||
            this.gameState == GAME_STATE_WIN_LINES ||
            this.gameState == GAME_STATE_TOTAL_WIN ||
            this.gameState == GAME_STATE_PAYTABLE)
        {
            this.gameSocket.onBetChange();
            
            if(this.gameState != GAME_STATE_PAYTABLE)
            {
                if(this.balance < this.gameSocket.getBet())
                {
                    this.startBtn.sleep();
                }
                else if(this.startBtn.scene.isSleeping())
                {
                    this.startBtn.wake();
                }
            }

            this.paytable.updatePaytable();
            this.bar.updateBet();

            this.sound.play("click");
        }            
    }
    
    onKbdMaxBet(event)
    {
        if(this.betBtn.scene.isSleeping() || !this.betBtn.scene.isVisible())
        {
            return;
        }

        if(this.autoPlay)
        {
            return;
        }

        if(this.gameState == GAME_STATE_READY ||
            this.gameState == GAME_STATE_WIN_LINES ||
            this.gameState == GAME_STATE_TOTAL_WIN)
        {
 
            this.gameSocket.setMaxBet();

            this.paytable.updatePaytable();
            this.bar.updateBet();

            this.sound.play("click");

            if(this.balance < this.gameSocket.getBet())
            {
                this.startBtn.sleep();
                return;
            }
            else if(this.startBtn.scene.isSleeping())
            {
                this.startBtn.wake();
            }

            this.onStart();
         }            
    }

    onBtnInfo()
    {
        if(!this.swipe.isSwiped && (this.infoBtn.scene.isSleeping() || !this.infoBtn.scene.isVisible()))
        {
            return;
        }

        this.onInfo();
    }

    onInfo()
    {
        if(!this.rules.scene.isSleeping())
        {
            this.rules.scene.sleep();
        }

        if(!this.settings.scene.isSleeping())
        {
            this.settings.scene.sleep();
        }

        this.scene.setVisible(false);

        if(this.getTotalWin() > 0)
        {
            this.totalWin.scene.sleep();
        }

        this.prevGameState = this.gameState;
        this.gameState = GAME_STATE_PAYTABLE;

        this.rulesBtn.sleep();
        this.startBtn.sleep();
        this.betBtn.sleep();
        this.infoBtn.sleep();
        this.homeBtn.sleep();
        this.jackpots.sleep();
        this.paytable.open();
        
        this.bar.scene.bringToTop();
        this.bar.onPaytableOpen();
        this.paytable.showBackButton();
    }
    
    onPaytableClosed()
    {
        if(!this.modeLandscape)
        {
            return;
        }

        this.gameState = this.prevGameState;

        this.btnBlinkTimer = this.btnBlinkTime;
        this.btnHintTimer = this.btnHintTime;

        this.scene.setVisible(true);

        if(this.getTotalWin() > 0)
        {
            this.totalWin.scene.wake();
        }

        if(this.balance < this.gameSocket.getBet())
        {
            this.startBtn.sleep();
        }      
        else
        {
            this.startBtn.wake();
        }

        this.settingsBtn.sleep();
        this.rulesBtn.sleep();
        this.betBtn.wake();
        this.optionsBtn.wake();
        this.homeBtn.wake();
        this.jackpots.wake();
        this.bar.onPaytableClosed();
        this.bar.scene.bringToTop();
    }

    onKbdPaytable()
    {
        if(this.autoPlay)
        {
            return;
        }
        
        if(!this.modeLandscape)
        {
            return;
        }
        
        this.sound.play("click");

        if(this.gameState == GAME_STATE_READY ||
           this.gameState == GAME_STATE_WIN_LINES) 
        {
            this.onInfo();
        }
        else if(this.gameState == GAME_STATE_PAYTABLE)
        {
            this.paytable.onPaytableClosed();
        }
    }

    onKbdExit()
    {
        if( this.gameState == GAME_STATE_SHOW_REELS ||
            this.gameState == GAME_STATE_READY ||
            this.gameState == GAME_STATE_WIN_LINES)
         {
            this.onHome();
         }
    }

    onKbdSettings()
    {
        if(this.gameState == GAME_STATE_READY ||
            this.gameState == GAME_STATE_WIN_LINES) 
        {
            if(this.modeLandscape && this.settings.scene.isSleeping())
            {
                this.onOptions();
            }

            this.onSettings();

            this.sound.play("click");
        }            
    }

    onChangeLayout()
    {
        if(this.modeLandscape)
        {
            this.setPortraitLayout();
        }
        else
        {
            this.setLandscapeLayout();
        }
    }

	onHome()
    {
        let lobbyEnabled = !!+this.cache.json.get('config').lobbyEnabled;
        
        if(lobbyEnabled != null && !lobbyEnabled)//game lobby is disabled, go to casino id url instead
        {
            if(this.lobbyUrl != null && this.lobbyUrl != "")//if casino provided dynamic home url, use it
            {
                parent.location.href = this.lobbyUrl;
                return;
            }
            
            let homeUrl = "";

            let config = this.cache.json.get('config').casinoUrls;

            if(config != null)
            {
                for(let i = 0; i < config.length; ++i)
                {
                    if(parseInt(config[i].casinoId) === parseInt(this.casinoid))
                    {
                        homeUrl = config[i].url;
                        break;
                    }
                }
            }
            
            if(homeUrl != "")
            {
                parent.location.href = homeUrl;
            }
            
            return;
        }

        this.lobby = this.scene.add("Lobby", SceneLobby, true, {scene: this, gameSocket: this.gameSocket, Hostname: this.server, Port: this.port, WalletToken: this.token, gameId: this.gameid, userId: this.userid, casinoId: this.casinoid, lobbyUrl: this.lobbyUrl, modeLandscape: this.modeLandscape});

        this.startBtn.scene.remove();
        this.stopBtn.scene.remove();
        this.autoStopBtn.scene.remove();
        this.betBtn.scene.remove();
        this.infoBtn.scene.remove();
        this.optionsBtn.scene.remove();
        this.takeJackpotBtn.scene.remove();
        this.takeCashbackBtn.scene.remove();
        this.settingsBtn.scene.remove();
        this.settingsBtnSmall.scene.remove();
        this.rulesBtn.scene.remove();

        this.bar.scene.remove();

        this.paytable.scene.remove();
        this.settings.scene.remove();
        this.rules.scene.remove();
        this.settingsmobile.scene.remove();
        this.jackpots.scene.remove();
        this.error.scene.remove();

        this.totalWin.scene.remove();
        this.cashbackWin.scene.remove();
        this.jackpotWin.scene.remove();

        this.sound.stopAll();
        
        window.removeEventListener("orientationchange", this.onOrientationChange);

        this.scene.remove();
    }

    onRules()
    {
        if(!this.settings.scene.isSleeping())
        {
            this.settings.scene.sleep();
        }

        if(!this.settingsmobile.scene.isSleeping())
        {
            this.settingsmobile.scene.sleep();
        }

        if(this.rules.scene.isSleeping())
        {
            this.rules.scene.wake();
            this.rules.scene.bringToTop();
        }
        else
        {
            this.rules.scene.sleep();
        }            
    }

    onOptions()
    {
        this.optionsBtn.sleep();
        this.homeBtn.sleep();
        this.infoBtn.wake();
        this.settingsBtn.wake();
        this.rulesBtn.wake()
    }

    onSettings()
    {
        if(!this.rules.scene.isSleeping())
        {
            this.rules.scene.sleep();
        }

        if(this.modeLandscape)
        {
            let settings = null;

            if(this.sys.game.device.os.desktop)
            {
                settings = this.settings;
            }
            else
            {
                settings = this.settingsmobile;
                settings.setScale(1.0)
            }

            if(settings.scene.isSleeping())
            {
                settings.wake();
                this.optionsBtn.sleep();
                this.rulesBtn.scene.sleep();

                if(this.getTotalWin() > 0)
                {
                    this.totalWin.scene.sleep();
                }
            }
            else
            {
                this.settingsBtn.sleep();
                settings.scene.sleep();

                if(this.balance < this.gameSocket.getBet())
                {
                    this.startBtn.sleep();
                }      
                else
                {
                    this.startBtn.wake();
                }

                this.infoBtn.sleep();
                this.optionsBtn.wake();
                this.homeBtn.wake();

                if(this.getTotalWin() > 0)
                {
                    this.totalWin.scene.wake();
                }
            }            
        }
        else
        {
            if(this.settingsmobile.scene.isSleeping())
            {
                this.settingsmobile.setScale(2.0);
                this.settingsmobile.wake();
            }
            else
            {
                this.settingsmobile.scene.sleep();

                if(this.balance < this.gameSocket.getBet())
                {
                    this.startBtn.sleep();
                }      
                else
                {
                    this.startBtn.wake();
                }

                this.betBtn.wake();
                this.homeBtn.wake();

                if(!this.modeLandscape)
                {
                    this.settingsBtnSmall.wake();
                    this.rulesBtn.wake();
                }
            }            
        }
    }

    onStop()
    {
        this.stopBtn.sleep();
        this.reelmanager.stopReels();
    }

    onBalance()
    {
        this.balance = this.gameSocket.getBalance();
        this.bar.updateBalance(this.balance);
    }
    
    onBalanceChange(newBalance, oldBalance)
    {
        if(this.gameState == GAME_STATE_READY ||
            this.gameState == GAME_STATE_WIN_LINES) 
        {
            this.balance = newBalance;

            if(this.balance >= this.gameSocket.getBet() && this.startBtn.scene.isSleeping() )
            {
                this.startBtn.wake();
            }
            else if(this.balance < this.gameSocket.getBet() && !this.startBtn.scene.isSleeping() )
            {
                this.startBtn.sleep();
            }
        }
        else
        {
            this.balance = newBalance - (oldBalance - this.balance);
        }

        this.bar.updateBalance(this.balance);
        this.sound.play("credit");
    }

    onJackpotWait()
    {
        this.takeJackpotBtn.wake();
        this.jackpotWaitTimer = this.jackpotWaitTime;
    }

    onJackpotTaken()
    {
        this.jackpotWaitTimer = -1;
        this.takeJackpotBtn.sleep();
        this.jackpotWin.onJackpotTaken();
    }

    onJackpotCompleted()
    {
        this.gameState = this.prevGameState;
        this.gameSocket.clearJackpotWin();
        
        if(this.gameState == GAME_STATE_TOTAL_WIN)
        {
            if(this.gameSocket.getCashbackWin() == 0 && this.gameSocket.getBalance() >= this.gameSocket.getBet() && !this.autoPlay)
            {
                this.startBtn.wake();
            }

            this.reelmanager.playTotalWin();
            this.sndWin.play();
        }
        else if(this.gameState == GAME_STATE_READY)
        {
            if(this.gameSocket.getCashbackWin() > 0)
            {
                this.prevGameState = GAME_STATE_READY;
                this.gameState = GAME_STATE_CASHBACK_WIN;
                this.cashbackWin.start();
            }
            else
            {
                this.gameState = GAME_STATE_READY;

                if(this.errorPending)
                {
                    this.showError(this.errorMessage);
                    return;
                }
    
                this.btnBlinkTimer = this.btnBlinkTime;
                this.btnHintTimer = this.btnHintTime;
        
                if(!this.modeLandscape)
                {
                    this.settingsBtnSmall.wake();
                    this.rulesBtn.wake();
                }
        
                this.homeBtn.wake();
                this.optionsBtn.wake();
                this.betBtn.wake();

                if(this.gameSocket.getBalance() >= this.gameSocket.getBet())
                {
                    this.startBtn.wake();
                }                    
            }            
        }            
    }

    onCashbackWait()
    {
        this.autoStopBtn.scene.sleep();
        this.autoPlay = false;
        this.takeCashbackBtn.wake();
        this.cashbackWaitTimer = this.cashbackWaitTime;
    }

    onCashbackTaken()
    {
        this.cashbackWaitTimer = -1;
        this.takeCashbackBtn.sleep();
        this.cashbackWin.onCashbackTaken();
    }

    onCashbackCompleted()
    {
        this.gameState = this.prevGameState;
                
        if(this.errorPending)
        {
            this.showError(this.errorMessage);
            return;
        }

        this.btnBlinkTimer = this.btnBlinkTime;
        this.btnHintTimer = this.btnHintTime;
    
        if(!this.modeLandscape)
        {
            this.settingsBtnSmall.wake();
            this.rulesBtn.wake();
        }

        this.homeBtn.wake();
        this.optionsBtn.wake();
        this.betBtn.wake();
        
        if(this.gameSocket.getBalance() >= this.gameSocket.getBet())
        {
            this.startBtn.wake();
        }

        if(this.gameState == GAME_STATE_WIN_LINES)
        {
            this.reelmanager.onWin();
        }
    }

    hideStoppers()
    {
        this.stoppers.forEach(stopper => {stopper.setVisible(false);});
        this.reelStoppersTimer = -1;
    }

    onSocketOpen()
    {
        this.gameSocket.send_command(0x2700);
    }
    
    start(startScene)
    {
        this.startScene = startScene;
        
        if(this.gameSocket != null)
        {
        this.gameSocket.connect();
    }
        else
        {
            this.showError("INVALID START PARAMETERS");
        }
    }

    onEnterFullscreen()
    {
//        console.log("orientation: " + this.scale.orientation);
    }

    onGameSessionReady()
    {
        this.gameSessionReady = true;
//disable jackpots panel if no jackpots are available
        let jp = this.gameSocket.getJackpots();

        let w = 0;

        for(let i = 0; i < jp.length; ++i)
        {
            w += jp[i];
        }

        if(w == 0)
        {
            this.jackpots.disableJackpots();
        }

        if(this.startScene.connectingSprite != null && this.startScene.connectingSprite.visible)//we've been waiting for connection to Game server so hide connection animation and start game
        {
            this.startScene.connectingSprite.setVisible(false);
            this.startScene.connectingSprite.stop();
            this.startScene.waitConnectionTimer = -1;
            this.startSceneCompleted();
        }
    }

    startSceneCompleted()
    {
        if (!this.hasOwnProperty('gameSessionReady'))
        {
            this.startScene.waitForConnection();
   
            return;
        }

        this.gameState = GAME_STATE_SHOW_REELS;
        
        this.paytable.getPaytable();
        this.bar.setUnits();

        let rmconf = 
        {
            scene: this,
            symbols: this.symbols,
            lines: this.gameSocket.getLines(),
            reels: this.gameSocket.getReels(),
            reels_speed: this.conf.reelsSpeed,
            vDelta: this.vDelta
        }

        this.reelmanager = new ReelManager(rmconf);
//        this.reelmanager.setVisible(false);

        if(this.scale.orientation == 'portrait-primary' || this.scale.orientation == 'portrait-secondary')
        {
            this.setPortraitLayout();
        }
        
        this.scene.wake();
        this.scene.bringToTop();
        this.bar.scene.wake();
        this.bar.scene.bringToTop();
        this.bar.showLogo();

        this.tweens.add({

            targets: this.startScene.intro,
            volume: 0,

            ease: 'Linear',
            duration: 1500,
            onCompleteScope: this,
            onComplete: function() 
            {
                this.tweens.killTweensOf(this.startScene.intro);
                this.startScene.scene.remove();
            },
        });
    }

    onShowReelsCompleted()
    {
        if(this.criticalError)
        {
            this.error.scene.bringToTop();
            return;
        }

        this.gameState = GAME_STATE_READY;

        if(this.balance >= this.gameSocket.getBet())
        {
            this.startBtn.wake();
        }

        this.betBtn.wake();
        this.optionsBtn.wake();
        this.homeBtn.wake();
    }

    onSpinReceived()
    {
        this.gameState = GAME_STATE_SPIN;
        
        this.sessionExpireTimer = SESSION_TIMEOUT;

        this.currentGame = this.gameSocket.getGame();

        this.balance = this.gameSocket.getBalanceBeforeWin();
        this.bar.updateBalance(this.balance);
        this.legallimit.enable();

        this.reelmanager.playGame(this.currentGame.spin_result);

        if(!this.autoPlay)
        {
            this.stopBtn.wake();
        }            
    }

    getTotalWin()
    {
        if(this.currentGame != null)
        {
            return this.gameSocket.getTotalWin();
        }
        else
        {
            return 0;
        }            
    }

    onReelStopped(reelId)
    {
        switch(reelId)
        {
            case 0:{
                        this.gameState = GAME_STATE_REELS_STOPPING;
                        
                        this.stoppers[0].setVisible(true);
                        this.stoppers[1].setVisible(true);

                        if(this.totalWin.scene.isActive())
                        {
                            this.totalWin.forceClose();
                        }
                    };break;
            case 1:{this.stoppers[2].setVisible(true);};break;
            case 2:{this.stoppers[3].setVisible(true);};break;
            case 3:{this.stoppers[4].setVisible(true);};break;
            case 4:{
                    this.stoppers[5].setVisible(true);

                    this.reelStoppersTimer = this.reelStoppersTime;
                    this.jackpotPanelTimer = this.jackpotPanelTime;

                    this.totalWin.reset();

                };break;
            default:break;     
        }
    }

    onReelEarlyStopped()
    {
        this.gameState = GAME_STATE_REELS_STOPPING;

        if(this.totalWin.scene.isActive())
        {
            this.totalWin.forceClose();
        }
        
        this.totalWin.reset();

        this.stoppers[0].setVisible(true);
        this.stoppers[1].setVisible(true);
        this.stoppers[2].setVisible(true);
        this.stoppers[3].setVisible(true);
        this.stoppers[4].setVisible(true);
        this.stoppers[5].setVisible(true);

        this.reelStoppersTimer = this.reelStoppersTime;
        this.jackpotPanelTimer = this.jackpotPanelTime;
    }

    onShowStartButton()
    {
        if(this.autoPlay)
        {
            return;
        }

        if(this.gameSocket.getBalance() >= this.gameSocket.getBet())
        {
            this.startBtn.wake();
        }
        else
        {
            this.startBtn.sleep();
        }
    }
    
    onHideStopBtn()
    {
        if(this.stopBtn.scene.isVisible) 
        {
            this.stopBtn.scene.sleep();
        };
    }

    onReelsReady()
    {
        if(this.gameSocket.getJackpotWin() > 0)
        {
            this.prevGameState = GAME_STATE_READY;
            this.gameState = GAME_STATE_JACKPOT_WIN;
            this.autoPlay = false;
            
            this.autoStopBtn.sleep();
            this.jackpotWin.start();
        }
        else if(this.gameSocket.getCashbackWin() > 0)
        {
            this.prevGameState = GAME_STATE_READY;
            this.gameState = GAME_STATE_CASHBACK_WIN;
            this.cashbackWin.start();
        }
        else
        {
            this.gameState = GAME_STATE_READY;

            if(this.errorPending)
            {
                this.showError(this.errorMessage);
                return;
            }
            
            if(this.autoPlay)
            {
                setTimeout(this.startAutoPlay.bind(this), 150);
                return;
            }

            this.btnBlinkTimer = this.btnBlinkTime;
            this.btnHintTimer = this.btnHintTime;
    
            if(!this.modeLandscape)
            {
                this.settingsBtnSmall.wake();
                this.rulesBtn.wake();
            }

            this.optionsBtn.wake();
            this.betBtn.wake();
            this.homeBtn.wake();

            this.onShowStartButton();
        }
    }

    onTotalWin()
    {
        if(this.gameSocket.getJackpotWin() > 0)
        {
            this.prevGameState = GAME_STATE_TOTAL_WIN;
            this.gameState = GAME_STATE_JACKPOT_WIN;
            this.autoPlay = false;

            this.autoStopBtn.sleep();
            this.jackpotWin.start();
        }
        else
        {
            this.hideStoppers();
            
            this.gameState = GAME_STATE_TOTAL_WIN;

            if(this.gameSocket.getCashbackWin() == 0 && this.gameSocket.getBalance() >= this.gameSocket.getBet() && !this.autoPlay)
            {
                this.startBtn.wake();
            }

            this.reelmanager.playTotalWin();
        }
    }

    onShowTotalWinCounter()
    {
        this.totalWin.setCounterSpeed(this.getTotalWin());
        this.totalWin.scene.wake();
        this.totalWin.scene.bringToTop();
    }

    onWin()
    {
        if(this.gameSocket.getCashbackWin() > 0)
        {
            this.prevGameState = GAME_STATE_WIN_LINES;
            this.gameState = GAME_STATE_CASHBACK_WIN;
            this.cashbackWin.reset();
            this.cashbackWin.scene.wake();
            this.cashbackWin.scene.bringToTop();
        }
        else
        {
            this.gameState = GAME_STATE_WIN_LINES;

            if(this.errorPending)
            {
                this.showError(this.errorMessage);
                return;
            }

            if(this.autoPlay)
            {
                this.gameState = GAME_STATE_READY;
                this.startAutoPlay();
                return;
            }
            
            if(!this.modeLandscape)
            {
                this.settingsBtnSmall.wake();
                this.rulesBtn.wake();
            }
    
            this.homeBtn.wake();
            this.optionsBtn.wake();
            this.betBtn.wake();

            if(this.gameSocket.getBalance() >= this.gameSocket.getBet() && !this.autoPlay)
            {
                this.startBtn.wake();
            }

            if(this.currentGame.legal_limit_applyed && this.legallimit.scene.isSleeping())
            {
                this.legallimit.show(this.getTotalWin());
            }

            this.reelmanager.onWin();
        }            
    }

    onError(message)
    {
        if(this.errorPending)
        {
            return;
        }

        if( this.gameState == GAME_STATE_SPIN ||
            this.gameState == GAME_STATE_REELS_STOPPING ||
            this.gameState == GAME_STATE_JACKPOT_WIN ||
            this.gameState == GAME_STATE_TOTAL_WIN ||
            this.gameState == GAME_STATE_CASHBACK_WIN)
        {
            this.errorPending = true;
            this.errorMessage = message;
            
            return;
        }
        else
        {
            this.showError(message);
        }
    }

    showError(message)
    {
        this.errorPending = true;//do not show next errors if any
        this.criticalError = true;

        if(this.startScene.connectingSprite != null && this.startScene.connectingSprite.visible)//we've been waiting for connection to Game server so hide connection animation and show error message
        {
            this.startScene.connectingSprite.setVisible(false);
            this.startScene.connectingSprite.stop();
            this.startScene.waitConnectionTimer = -1;
        }
        
        if(this.gameState == GAME_STATE_PAYTABLE)
        {
            this.onPaytableClosed();
        }

        this.error.setMessage(message);

        this.startBtn.scene.sleep();
        this.stopBtn.scene.sleep();
        this.autoStopBtn.scene.sleep();
        this.betBtn.scene.sleep();
        this.infoBtn.scene.sleep();
        this.optionsBtn.scene.sleep();
        this.takeJackpotBtn.scene.sleep();
        this.takeCashbackBtn.scene.sleep();
        this.homeBtn.scene.sleep();
        this.settingsBtnSmall.scene.sleep();
        this.rulesBtn.scene.sleep();

        this.settings.scene.sleep();
        this.settingsmobile.scene.sleep();

        this.autoPlay = false;

        this.sound.stopAll();

        if(this.modeLandscape)
        {
            this.paytable.scene.sleep();
        }

		this.gameState = GAME_STATE_NOT_INITIALIZED;
    }
//additional functions
    setAutoSpinLimit(v)
    {
        this.conf.autoSpinLimit = v;
    }
}

