﻿Type.registerNamespace('InstantGames');

/*
 * Credit Manager operations enumeration
 */
InstantGames.CreditManagerOperations = function() {
    throw Error.NotImpemented();
}

InstantGames.CreditManagerOperations.prototype = {
    AddToBet: 5,
    SetBet: 4,
    TemporaryFixBankroll: 10,
    StartRound: 9,
    EndRound: 1
}

InstantGames.CreditManagerOperations.registerEnum('InstantGames.CreditManagerOperations', true);

/*
 * Play Modes enumeration
 */
InstantGames.PlayModes = function() {
    throw Error.NotImpemented();
}

InstantGames.PlayModes.prototype = {
    ServiceError: -2,
    NotInGame: -1,
    PracticeMode: 0,
    RealMode: 1
}

InstantGames.PlayModes.registerEnum('InstantGames.PlayModes', true);

/*
 * Game wrapper implementation
 */
InstantGames.GameWrapper = function() {
    this._gameName = '';
}

InstantGames.GameWrapper.prototype = {
    // Attach wrapper to game
    attach: function(gameName) {
        this._gameName = gameName;
        if (this._soundVolume == null)
            this._soundVolume = 100;
    },

    // Get instance of game
    get_instance: function() {
        this._gameName = 'flashGame'; // IE patch
        if (this._gameName == '') return null;
        if (window[this._gameName]) {
            return window.document[this._gameName];
        }
        if (document[this._gameName]) {
            return document[this._gameName];
        }
        return null;
    },

    // SetVariable helper
    set_variable: function(name, value) {
        var game = this.get_instance();
        if (game != null) {
            game.SetVariable(name, value);
        }
    },

    // Initialize the game
    initialize: function(initData) {
    //alert(initData);
        this.set_variable('InitializationXML', initData);
    },

    // Set balance in game
    set_balance: function(balance) {
        this.set_variable('Balance', balance.Bankroll);
    },

    // Update Jackpot in game
    set_jackpot: function(jackpotSum) {
        this.set_variable('UpdateJackpotSum', jackpotSum);
    },

    // Set Sound Volume in game
    set_sound: function(soundVolume) {
        this.set_variable('SoundVolume', soundVolume);
        this._soundVolume = soundVolume;
    },

    fix_sound: function() {
        this.set_sound(this._soundVolume);
    },

    // Set Animation Speed in game
    set_animation: function(animationSpeed) {
        this.set_variable('AnimationSpeed', animationSpeed);
    }

}

InstantGames.GameWrapper.registerClass('InstantGames.GameWrapper');

/*
 * Game wrapper implementation
 */
InstantGames.BankrollWrapper = function() {
    this._bankrollName = 'bankroll-value';
    this._bankrollValue = 0;
    this._betAmount = 0;
    this._lastKnownTimestamp = 0;
    this._updater = new InstantGames.Bankroll.StandardUpdater();
}

InstantGames.BankrollWrapper.prototype = {
    // Attach bankroll
    attach: function(bankrollName) {
        this._bankrollName = bankrollName;
    },

    // Get instance of bankroll element
    get_instance: function() {
        return $get(this._bankrollName);
    },

    // Set Bet Amount value to Bankroll
    set_betAmount: function(value) {
        this._betAmount = value;
    },

    // Get current Bet Amount value
    get_betAmount: function() {
        return this._updater.updateAmount(this._betAmount); // We use update strategy here
    },

    // Set Bankroll Value
    set_bankrollValue: function(value) {
        if (value.Timestamp >= this._lastKnownTimestamp) {
            this._bankrollValue = value.Bankroll;
            this.updateTimestamp(value.Timestamp);
        }
        //    alert('Timestamp: ' + value.Timestamp + ', Bankroll: ' + value.Bankroll);
    },

    // Get curent Bankroll Value
    get_bankrollValue: function() {
        return this._updater.updateValue(this._bankrollValue); // We use update strategy here
    },

    // Update bankroll
    update_bankroll: function() {
        var bankroll = this.get_instance();
        if (bankroll != null) {
            var playMode = InstantGames.Manager.get_playMode();
            //alert('play mode: ' + playMode);
            if (playMode == InstantGames.PlayModes.NotInGame || playMode == InstantGames.PlayModes.ServiceError) {
                bankroll.innerHTML = '';
                return;
            }
            var value = this.get_bankrollValue(), amount = this.get_betAmount();
            if (value != "") {
                if ( (parseFloat(value) >= parseFloat(amount)) || playMode == InstantGames.PlayModes.PracticeMode)
                {
                    var b = (parseFloat(value) - parseFloat(amount)) / 100.0;
                    bankroll.innerHTML = (currencyCode + ' ' + b.toFixed(2)).replace(',', '.');
                }
                else
                {
                    var b = parseFloat(value) / 100.0;
                    bankroll.innerHTML = (currencyCode + ' ' + b.toFixed(2)).replace(',', '.');
                }
            } else {
                //bankroll.innerHTML = "";
                if (playMode == InstantGames.PlayModes.PracticeMode)
                    bankroll.innerHTML = (currencyCode + ' 0.00');
                else
                    bankroll.innerHTML = "";
            }
        }
    },

    // Set balance update strategy
    set_updater: function(updater) {
        this._updater = updater;
    },

    // update timestamp
    updateTimestamp: function(lastKnownTimestamp) {
        this._lastKnownTimestamp = lastKnownTimestamp;
    },

    get_Timestamp: function() {
        return this._lastKnownTimestamp;
    }
}

InstantGames.BankrollWrapper.registerClass('InstantGames.BankrollWrapper');

Type.registerNamespace('InstantGames.Bankroll');
/*
 * IUpdater interface definition
 */
InstantGames.Bankroll.IUpdater = function() {
    throw Error.NotImpemented();
}

InstantGames.Bankroll.IUpdater.prototype = {
    // Update strategy
    updateValue: function(balance) {
        throw Error.NotImpemented();
    },

    updateAmount: function(amount) {
        throw Error.NotImpemented();
    }
}

InstantGames.Bankroll.IUpdater.registerInterface('InstantGames.Bankroll.IUpdater');

/*
 * Standard bankroll update strategy implementation
 */
InstantGames.Bankroll.StandardUpdater = function() {
}

InstantGames.Bankroll.StandardUpdater.prototype = {
    // Update strategy
    updateValue: function(balance) {
        return balance;
    },

    updateAmount: function(amount) {
        return amount;
    }
}

InstantGames.Bankroll.StandardUpdater.registerClass('InstantGames.Bankroll.StandardUpdater', null, InstantGames.Bankroll.IUpdater);

/*
 * Temporary fixed bankroll update strategy implementation
 */
InstantGames.Bankroll.TemporaryFix = function(fixedBalance, fixedAmount) {
    this._fixedBalance = fixedBalance;
    this._fixedAmount = fixedAmount;
}

InstantGames.Bankroll.TemporaryFix.prototype = {
    // Update strategy
    updateValue: function(balance) {
        return this._fixedBalance;
    },

    updateAmount: function(amount) {
        return this._fixedAmount;
    }
}

InstantGames.Bankroll.TemporaryFix.registerClass('InstantGames.Bankroll.TemporaryFix', null, InstantGames.Bankroll.IUpdater);

/*
 * ICreditOperation interface definition
 */
InstantGames.Bankroll.ICreditOperation = function() {
    throw Error.NotImpemented();
}

InstantGames.Bankroll.ICreditOperation.prototype = {
    // ICreditOperation command
    execute: function(credit, bet) {
        throw Error.NotImpemented();
    }
}

InstantGames.Bankroll.ICreditOperation.registerInterface('InstantGames.Bankroll.ICreditOperation');

/*
 * AddToBet operation implementation
 */
InstantGames.Bankroll.AddToBet = function() {
}

InstantGames.Bankroll.AddToBet.prototype = {
    // AddToBet implementation
    execute: function(credit, bet) {
        var bankroll = InstantGames.Manager.get_bankroll();
        if (bankroll != null) {
            bankroll.set_betAmount(bet + bankroll.get_betAmount());
            bankroll.update_bankroll();
        }
    }
}

InstantGames.Bankroll.AddToBet.registerClass('InstantGames.Bankroll.AddToBet', null, InstantGames.Bankroll.ICreditOperation);

/*
 * EndRound operation implementation
 */
InstantGames.Bankroll.EndRound = function() {
}

InstantGames.Bankroll.EndRound.prototype = {
    // EndRound implementation
    execute: function(credit, bet) {
        //alert('EndRound');
        InstantGames.Manager.set_inRound(false);
        var bankroll = InstantGames.Manager.get_bankroll();
        if (bankroll != null) {
            bankroll.set_betAmount(0);
            var playMode = InstantGames.Manager.get_playMode();
            if (playMode == InstantGames.PlayModes.RealMode) {
                //InstantGames.Manager.process_Delayed();
                //                if (window['timerId'] != undefined) {
                //                    var prm = Sys.WebForms.PageRequestManager.getInstance();
                //                    prm._doPostBack(window.timerId, document.forms[0].__EVENTARGUMENT.value);
                //                    //__doPostBack(window.timerId, document.forms[0].__EVENTARGUMENT.value);
                //                }
                InstantGames.Manager.executeCommand('EndRound', null);
            }
            else {
                bankroll.set_bankrollValue({ Bankroll: bet, Timestamp: bankroll.get_Timestamp() });
                bankroll.update_bankroll();
                InstantGames.Manager.executeCommand('IAmOnline', null);
            }
        }
    }
}

InstantGames.Bankroll.EndRound.registerClass('InstantGames.Bankroll.EndRound', null, InstantGames.Bankroll.ICreditOperation);

/*
 * SetBet operation implementation
 */
InstantGames.Bankroll.SetBet = function() {
}

InstantGames.Bankroll.SetBet.prototype = {
    // AddToBet implementation
    execute: function(credit, bet) {
        var bankroll = InstantGames.Manager.get_bankroll();
        if (bankroll != null) {
            bankroll.set_betAmount(bet);
            bankroll.update_bankroll();
        }
    }
}

InstantGames.Bankroll.SetBet.registerClass('InstantGames.Bankroll.SetBet', null, InstantGames.Bankroll.ICreditOperation);

/*
 * StartRound operation implementation
 */
InstantGames.Bankroll.StartRound = function() {
}

InstantGames.Bankroll.StartRound.prototype = {
    // StartRound implementation
    execute: function(credit, bet) {
        InstantGames.Manager.set_inRound(true);
        var game = InstantGames.Manager.get_game();
        game.fix_sound();
        var bankroll = InstantGames.Manager.get_bankroll();
        if (bankroll != null) {
            bankroll.set_betAmount(0);
            bankroll.set_updater(new InstantGames.Bankroll.StandardUpdater());
            if (InstantGames.Manager.get_playMode() == InstantGames.PlayModes.RealMode) {
                //                var inRound = InstantGames.Manager.get_inRound();
                //                if (!inRound) {
                InstantGames.Manager.executeCommand('StartRound', null);
                //                }
            }
            else {
                bankroll.set_bankrollValue({ Bankroll: bet, Timestamp: bankroll.get_Timestamp() });
                bankroll.update_bankroll();
                InstantGames.Manager.executeCommand('IAmOnline', null);
            }
        }
    }
}

InstantGames.Bankroll.StartRound.registerClass('InstantGames.Bankroll.StartRound', null, InstantGames.Bankroll.ICreditOperation);

/*
 * TemporaryFixBankroll operation implementation
 */
InstantGames.Bankroll.TemporaryFixBankroll = function() {
}

InstantGames.Bankroll.TemporaryFixBankroll.prototype = {
    // TemporaryFixBankroll implementation
    execute: function(credit, bet) {
        var bankroll = InstantGames.Manager.get_bankroll();
        if (bankroll != null) {
            //bankroll.set_bankrollValue({ Bankroll: bet, Timestamp: bankroll.get_Timestamp() });
            bankroll.set_updater(new InstantGames.Bankroll.TemporaryFix(bankroll.get_bankrollValue(), bankroll.get_betAmount()));
            //bankroll.update_bankroll();
            //alert("TemporaryFixBankroll");
        }
    }
}

InstantGames.Bankroll.TemporaryFixBankroll.registerClass('InstantGames.Bankroll.TemporaryFixBankroll', null, InstantGames.Bankroll.ICreditOperation);

Type.registerNamespace('InstantGames.Commands');
/*
 * ICommand interface definition
 */
InstantGames.Commands.ICommand = function() {
    throw Error.NotImpemented();
}

InstantGames.Commands.ICommand.prototype = {
    // Command execution
    execute: function(context, args) {
        throw Error.NotImpemented();
    }
}

InstantGames.Commands.ICommand.registerInterface('InstantGames.Commands.ICommand');

/*
 * ReadyForInitData command implementation
 */
InstantGames.Commands.ReadyForInitData = function() {
}

InstantGames.Commands.ReadyForInitData.prototype = {
    // ICommand implementation
    execute: function(context, args) {
        var playMode = InstantGames.Manager.get_playMode();
        GameService.GetInitializationData(playMode, gameId, this.succeededCallback,
            this.failedCallback, context);
    },

    succeededCallback: function(result, context, methodName) {
        var game = InstantGames.Manager.get_game();
        game.initialize(result);
    },

    failedCallback: function(error, context, methodName) {
        InstantGames.Manager.addError();
    }
}

InstantGames.Commands.ReadyForInitData.registerClass('InstantGames.Commands.ReadyForInitData', null, InstantGames.Commands.ICommand);

/*
 * GameReady command implementation
 */
InstantGames.Commands.GameReady = function() {
}

InstantGames.Commands.GameReady.prototype = {
    // GameReady implementation
    execute: function(context, args) {
        var playMode = InstantGames.Manager.get_playMode();
        GameService.GetBalance(playMode, this.succeededCallback, this.failedCallback, context);
    },

    succeededCallback: function(result, context, methodName) {
        //InstantGames.Manager.addError();
        var game = InstantGames.Manager.get_game();
        game.set_balance(result);
        var bankroll = InstantGames.Manager.get_bankroll();
        if (bankroll != null) {
            //alert("sb3 " + result.Bankroll);
            bankroll.set_bankrollValue(result);
            bankroll.update_bankroll();
        }
    },

    failedCallback: function(error, context, methodName) {
        InstantGames.Manager.addError();
    }
}

InstantGames.Commands.GameReady.registerClass('InstantGames.Commands.GameReady', null, InstantGames.Commands.ICommand);

/*
 * UpdateBankroll command implementation
 */
InstantGames.Commands.UpdateBankroll = function() {
}

InstantGames.Commands.UpdateBankroll.prototype = {
    // ICommand implementation
    execute: function(context, args) {
        var playMode = InstantGames.Manager.get_playMode();
        GameService.GetBalance(playMode, this.succeededCallback,
            this.failedCallback, context);
    },

    succeededCallback: function(result, context, methodName) {
        var bankroll = InstantGames.Manager.get_bankroll();
        if (bankroll != null) {
            bankroll.set_bankrollValue(result);
            bankroll.update_bankroll();
        }
    },

    failedCallback: function(error, context, methodName) {
        var message = error.get_message();
        if (message == "LogoutError") {
            KillMePlenty();
        } else {
            InstantGames.Manager.addError();
        }
    }
}

InstantGames.Commands.UpdateBankroll.registerClass('InstantGames.Commands.UpdateBankroll', null, InstantGames.Commands.ICommand);

/*
 * StartRound command implementation
 */
InstantGames.Commands.StartRound = function() {
}

InstantGames.Commands.StartRound.prototype = {
    // ICommand implementation
    execute: function(context, args) {
        var inFrameClosing = InstantGames.Manager.get_inFrameClosing();
        if (!inFrameClosing) {
            var playMode = InstantGames.Manager.get_playMode();
            GameService.StartRound(playMode, this.succeededCallback,
            this.failedCallback, context);
        }
    },

    succeededCallback: function(result, context, methodName) {
        var bankroll = InstantGames.Manager.get_bankroll();
        if (bankroll != null) {
            //alert("sb5 " + result.Bankroll);
            bankroll.set_bankrollValue(result);
            bankroll.update_bankroll();
        }
    },

    failedCallback: function(error, context, methodName) {
    var message = error.get_message();
    if (message == "LogoutError") {
        KillMePlenty();
    } else {
        InstantGames.Manager.addError();
    }
}
}

InstantGames.Commands.StartRound.registerClass('InstantGames.Commands.StartRound', null, InstantGames.Commands.ICommand);

/*
 * EndRound command implementation
 */
InstantGames.Commands.EndRound = function() {
}

InstantGames.Commands.EndRound.prototype = {
    // ICommand implementation
    execute: function(context, args) {
        var playMode = InstantGames.Manager.get_playMode();
        GameService.EndRound(playMode, this.succeededCallback,
            this.failedCallback, context);
    },

    succeededCallback: function(result, context, methodName) {
        var bankroll = InstantGames.Manager.get_bankroll();
        if (bankroll != null) {
            bankroll.set_bankrollValue(result);
            bankroll.update_bankroll();
        }
    },

    failedCallback: function(error, context, methodName) {
        var message = error.get_message();
        if (message == "LogoutError") {
            KillMePlenty();
        } else {
            InstantGames.Manager.addError();
        }
    }
}

InstantGames.Commands.EndRound.registerClass('InstantGames.Commands.EndRound', null, InstantGames.Commands.ICommand);

/*
 * CreditManagerUpdate command implementation
 */
InstantGames.Commands.CreditManagerUpdate = function() {
    this._operations = new Array();
    this._operations[InstantGames.CreditManagerOperations.AddToBet] = InstantGames.Bankroll.AddToBet;
    this._operations[InstantGames.CreditManagerOperations.SetBet] = InstantGames.Bankroll.SetBet;
    this._operations[InstantGames.CreditManagerOperations.TemporaryFixBankroll] = InstantGames.Bankroll.TemporaryFixBankroll;
    this._operations[InstantGames.CreditManagerOperations.StartRound] = InstantGames.Bankroll.StartRound;
    this._operations[InstantGames.CreditManagerOperations.EndRound] = InstantGames.Bankroll.EndRound;
}

InstantGames.Commands.CreditManagerUpdate.prototype = {
    // CreditManagerUpdate implementation
    execute: function(context, args) {
        var operation = this.build_operation(args.operation);
        if (operation != null) {
            operation.execute(args.credit, args.bet);
        }
    },

    build_operation: function(opcode) {
        var proto = this._operations[opcode];
        if (proto != null) {
            return new proto();
        }
        return null;
    }
}

InstantGames.Commands.CreditManagerUpdate.registerClass('InstantGames.Commands.CreditManagerUpdate', null, InstantGames.Commands.ICommand);

/*
 * CreditManagerUpdate command implementation
 */
InstantGames.Commands.JackpotUpdateReqest = function() {
}

InstantGames.Commands.JackpotUpdateReqest.prototype = {
    // ReadyForInitData implementation
    execute: function(context, args) {
        // TODO: Command execution
    }
}

InstantGames.Commands.JackpotUpdateReqest.registerClass('InstantGames.Commands.JackpotUpdateReqest', null, InstantGames.Commands.ICommand);

/*
 * ExitToLobby command implementation
 */
InstantGames.Commands.ExitToLobby = function() {
}

InstantGames.Commands.ExitToLobby.prototype = {
    // ExitToLobby implementation
    execute: function(context, args) {
        InstantGames.Manager.backToLobby();
    }
}

InstantGames.Commands.ExitToLobby.registerClass('InstantGames.Commands.ExitToLobby', null, InstantGames.Commands.ICommand);

/*
 * NavigationButtonsState command implementation
 */
InstantGames.Commands.NavigationButtonsState = function() {
}

InstantGames.Commands.NavigationButtonsState.prototype = {
    // NavigationButtonsState implementation
    execute: function(context, args) {
        InstantGames.Manager.set_buttons(args);
    }
}

InstantGames.Commands.NavigationButtonsState.registerClass('InstantGames.Commands.NavigationButtonsState', null, InstantGames.Commands.ICommand);

/*
 * AddToFavorite command implementation
 */
InstantGames.Commands.AddToFavorite = function() {
}

InstantGames.Commands.AddToFavorite.prototype = {
    // ICommand implementation
    execute: function(context, args) {
        GameService.AddToFavorite(args, this.succeededCallback, this.failedCallback, context);
    },

    succeededCallback: function(result, context, methodName) {
        AddFavCompleted();
    },

    failedCallback: function(error, context, methodName) {
        var errorMessage = error.get_message();
        //alert(errorMessage);
    }
}

InstantGames.Commands.AddToFavorite.registerClass('InstantGames.Commands.AddToFavorite', null, InstantGames.Commands.ICommand);

/*
 * CheckInFavorite command implementation
 */
InstantGames.Commands.CheckInFavorite = function() {
}

InstantGames.Commands.CheckInFavorite.prototype = {
    // ICommand implementation
    execute: function(context, args) {
        GameService.CheckInFavorite(args, this.succeededCallback, this.failedCallback, context);
    },

    succeededCallback: function(result, context, methodName) {
        if (result == true) {
            GameAlredyInFav();
        } else {
            AddFavStart(context);
        }
    },

    failedCallback: function(error, context, methodName) {
        var errorMessage = error.get_message();
        //alert(errorMessage);
    }
}

InstantGames.Commands.CheckInFavorite.registerClass('InstantGames.Commands.CheckInFavorite', null, InstantGames.Commands.ICommand);

/*
 * RemoveFromFavorite command implementation
 */
InstantGames.Commands.RemoveFromFavorite = function() {
}

InstantGames.Commands.RemoveFromFavorite.prototype = {
    // ICommand implementation
    execute: function(context, args) {
        GameService.RemoveFromFavorite(args, this.succeededCallback, this.failedCallback, context);
    },

    succeededCallback: function(result, context, methodName) {
        window.location = '/Default.aspx?CategoryId=Favorites';
    },

    failedCallback: function(error, context, methodName) {
        var errorMessage = error.get_message();
        //alert(errorMessage);
    }
}

InstantGames.Commands.RemoveFromFavorite.registerClass('InstantGames.Commands.RemoveFromFavorite', null, InstantGames.Commands.ICommand);

/*
 * StartPlayMode command implementation
 */
InstantGames.Commands.StartPlayMode = function() {
}

InstantGames.Commands.StartPlayMode.prototype = {
    // ICommand implementation
    execute: function(context, args) {
        //alert('StartPlayMode: ' + args);
        GameService.StartPlayMode(this.succeededCallback, this.failedCallback, context);
    },

    succeededCallback: function(result, context, methodName) {
        StartPlayModeComplete(result);
    },

    failedCallback: function(error, context, methodName) {
        ShowServiceError();
    }
}

InstantGames.Commands.StartPlayMode.registerClass('InstantGames.Commands.StartPlayMode', null, InstantGames.Commands.ICommand);

/*
 * SwitchPlayMode command implementation
 */
InstantGames.Commands.SwitchPlayMode = function() {
}

InstantGames.Commands.SwitchPlayMode.prototype = {
    // ICommand implementation
    execute: function(context, args) {
        //alert('SwitchPlayMode: ' + args);
        GameService.SwitchPlayMode(this.succeededCallback, this.failedCallback, context);
    },

    succeededCallback: function(result, context, methodName) {
        SwitchPlayModeComplete(result);
    },

    failedCallback: function(error, context, methodName) {
        ShowServiceError();
    }
}

InstantGames.Commands.SwitchPlayMode.registerClass('InstantGames.Commands.SwitchPlayMode', null, InstantGames.Commands.ICommand);

/*
 * GoingToFish command implementation
 */
InstantGames.Commands.GoingToFish = function() {
}

InstantGames.Commands.GoingToFish.prototype = {
    // ICommand implementation
    execute: function(context, args) {
        GameService.GoingToFish(this.succeededCallback, this.failedCallback, context);
        InstantGames.Manager.wait_for(200);
    },

    succeededCallback: function(result, context, methodName) {
    },

    failedCallback: function(error, context, methodName) {
    }
}

InstantGames.Commands.GoingToFish.registerClass('InstantGames.Commands.GoingToFish', null, InstantGames.Commands.ICommand);

/*
 * IAmOnline command implementation
 */
InstantGames.Commands.IAmOnline = function() {
}

InstantGames.Commands.IAmOnline.prototype = {
    // ICommand implementation
    execute: function(context, args) {
        GameService.IAmOnline(this.succeededCallback, this.failedCallback, context);
    },

    succeededCallback: function(result, context, methodName) {
    },

    failedCallback: function(error, context, methodName) {
    }
}

InstantGames.Commands.IAmOnline.registerClass('InstantGames.Commands.IAmOnline', null, InstantGames.Commands.ICommand);

/*
* Game manager implementation
*/
InstantGames.GameManager = function() {
    // Manager initiaization
    this._gameWrapper = new InstantGames.GameWrapper();
    this._bankrollWrapper = new InstantGames.BankrollWrapper();
    this._playMode = InstantGames.PlayModes.NotInGame;
    this._container = 'header';
    this._linkEnabled = true;
    this._errorCounter = 0;
    this._inRound = false;
    this._inDecision = false;
    this._inFrameClosing = false;
    this._delayed = new Array();
}

InstantGames.GameManager.prototype = {
    // Attach manager to game
    attach_game: function(gameName) {
        this._gameWrapper.attach(gameName);
    },

    // Returns wrapper for a game
    get_game: function() {
        return this._gameWrapper;
    },

    // Attach bankroll
    attach_bankroll: function(bankrollName) {
        this._bankrollWrapper.attach(bankrollName);
    },

    //Returns wrapper for bankroll
    get_bankroll: function() {
        return this._bankrollWrapper;
    },

    // Execution of FSCommand method
    executeCommand: function(command, args, context) {
        //alert('command started: ' + command + ", args: " + args);
        //var context = { args: args };
        var cmd = new this.commands[command]();
        cmd.execute(context, args);
    },

    // Back to Lobby
    backToLobby: function() {
        window.close();
    },

    is_linkEnabled: function() {
        return this._linkEnabled;
    },

    attach_container: function(container) {
        this._container = container;
        var c = this.get_container();
        if (c != null) {
            $A(c.getElementsByTagName('a')).each(
                function(child) {
                    if (child.onclick != 'unassigned') {
                        var old_onclick = child.onclick;
                        child.onclick = function() {
                            if (InstantGames.Manager.is_linkEnabled()) {
                                return old_onclick();
                            }
                            return false;
                        };
                    }
                }
            );
        }
    },

    get_container: function() {
        if (this._container != '') {
            return $(this._container);
        }
        return null;
    },

    // Set state for navigation buttons
    set_buttons: function(state) {
        switch (state) {
            case 0:
                this.disable_navigation();
                break;
            case 1:
                this.enable_navigation();
                break;
        }
    },

    disable_navigation: function() {
        var container = this.get_container();
        if (container != null) {
            new Effect.Appear(container, { duration: 0.2, from: 1.0, to: 0.6 });
            $A(container.getElementsByTagName('input')).each(
                function(child) {
                    child.setAttribute('disabled', 'disabled');
                }
            );
            $A(container.getElementsByTagName('select')).each(
                function(child) {
                    child.setAttribute('disabled', 'disabled');
                }
            );
            this._linkEnabled = false;
        }
    },

    enable_navigation: function() {
        var container = this.get_container();
        if (container != null) {
            new Effect.Appear(container, { duration: 0.2, from: 0.6, to: 1 });
            $A(container.getElementsByTagName('input')).each(
                function(child) {
                    child.removeAttribute('disabled');
                }
            );
            $A(container.getElementsByTagName('select')).each(
                function(child) {
                    child.removeAttribute('disabled');
                }
            );
            this._linkEnabled = true;
        }
    },

    // Get current Play Mode
    get_playMode: function() {
        return this._playMode;
    },

    // Set new play mode
    set_playMode: function(playMode) {
        //alert(playMode);
        var oldMode = this.get_playMode();
        if (playMode != oldMode) {
            this._playMode = playMode;
        }
    },

    // Supported commands
    commands: {
        ReadyForInitData: InstantGames.Commands.ReadyForInitData,
        GameReady: InstantGames.Commands.GameReady,
        UpdateBankroll: InstantGames.Commands.UpdateBankroll,
        CreditManagerUpdate: InstantGames.Commands.CreditManagerUpdate,
        JackpotUpdateReqest: InstantGames.Commands.JackpotUpdateReqest,
        ExitToLobby: InstantGames.Commands.ExitToLobby,
        NavigationButtonsState: InstantGames.Commands.NavigationButtonsState,
        AddToFavorite: InstantGames.Commands.AddToFavorite,
        RemoveFromFavorite: InstantGames.Commands.RemoveFromFavorite,
        CheckInFavorite: InstantGames.Commands.CheckInFavorite,
        StartPlayMode: InstantGames.Commands.StartPlayMode,
        SwitchPlayMode: InstantGames.Commands.SwitchPlayMode,
        StartRound: InstantGames.Commands.StartRound,
        EndRound: InstantGames.Commands.EndRound,
        GoingToFish: InstantGames.Commands.GoingToFish,
        IAmOnline: InstantGames.Commands.IAmOnline
    },

    // Error handling: increment error counter
    addError: function() {
        //alert('Error captured');
        this._errorCounter++;
        if (this._errorCounter == 3) {
            var oldPlayMode = InstantGames.Manager.get_playMode();
            var bankroll = InstantGames.Manager.get_bankroll();
            if (bankroll != null) {
                InstantGames.Manager.set_playMode(InstantGames.PlayModes.ServiceError)
                bankroll.update_bankroll();
            }
            //this.clearErrors();
            if (window.serviceError != undefined) {
                window.serviceError = true;
            }
            if (oldPlayMode == InstantGames.PlayModes.RealMode) { // Go to Select Mode
                ShowRequiredRedirect();
                //window.location.href = window.location.href;
            } else {
                ShowServiceError();
            }
        }
    },

    // Error handling: clear error state
    clearErrors: function() {
        //alert('Errors cleared!');
        this._errorCounter = 0;
        if (window.serviceError != undefined) {
            window.serviceError = false;
        }
    },

    // Check in round
    get_inRound: function() {
        //        if (Prototype.Browser.IE && parseInt(navigator.userAgent.substring(navigator.userAgent.indexOf("MSIE") + 5)) == 6) {
        //            return false;
        //        }
        return this._inRound;
    },

    set_inRound: function(inRound) {
        this._inRound = inRound;
        //        if (inRound) {
        //            Sys.WebForms.PageRequestManager.getInstance().abortPostBack();
        //        }
    },

    // Check in player decision
    get_inDecision: function() {
        return this._inDecision;
    },

    set_inDecision: function(inDecision) {
        this._inDecision = inDecision;
        //        if (inDecision) {
        //            Sys.WebForms.PageRequestManager.getInstance().abortPostBack();
        //        }
    },

    wait_for: function(millis) {
        var date = new Date();
        var curDate = null;

        do { curDate = new Date(); }
        while (curDate - date < 200);
    },

    get_inFrameClosing: function() {
        return this._inFrameClosing;
    },

    set_inFrameClosing: function(inFrameClosing) {
        this._inFrameClosing = inFrameClosing;
        //        if (inFrameClosing) {
        //            Sys.WebForms.PageRequestManager.getInstance().abortPostBack();
        //        }
    },

    // Delayed postback handling
    add_Delayed: function(id, args) {
        //if (InstantGames.Manager._delayed.length == 0) {
        this._delayed.push({ id: id, args: args });
        //}
    },

    process_Delayed: function() {
        if (InstantGames.Manager._delayed.length > 0) {
            var inRound = InstantGames.Manager.get_inRound();
            var inDecision = InstantGames.Manager.get_inDecision();
            var inFrameClosing = InstantGames.Manager.get_inFrameClosing();
            var prm = Sys.WebForms.PageRequestManager.getInstance();

            if (inRound || inDecision || inFrameClosing || prm.get_isInAsyncPostBack()) {
                return;
            }

            var delayed = InstantGames.Manager._delayed.shift();
            __doPostBack(delayed.id, delayed.args);
        }
    }
}

InstantGames.Manager = new InstantGames.GameManager();
InstantGames.GameManager.registerClass('InstantGames.GameManager');

// Global handler for errors.
function InstantGamesErrorHandler(sender, args) {
    var error = args.get_error();
    if (error != undefined) {
        var response = args.get_response();
        if (response.get_responseAvailable()) {
            var statusCode = response.get_statusCode();
            if (statusCode == '200') { // Server side error
                args.set_errorHandled(true);
                if (error.message.indexOf('InstantGames.Services.Util.LogoutError') > 0) { // special handling.
                    KillMePlenty();
                    return;
                }
                if (error.message.indexOf('InstantGames.Services.Util.TimeoutError') > 0) { // special handling.
                    KillMePlenty();
                    return;
                }
                InstantGames.Manager.addError();
            } else { // Transport level error
                // TODO
            }
        } else {
            args.set_errorHandled(true);
            InstantGames.Manager.addError();
        }
        return;
    }
    InstantGames.Manager.clearErrors();
}

// Bankroll initialization handler
function InstantGamesInitBankrollHandler(sender, args) {
    var inRound = InstantGames.Manager.get_inRound();
    var inDecision = InstantGames.Manager.get_inDecision();
    var inFrameClosing = InstantGames.Manager.get_inFrameClosing();
    var prm = Sys.WebForms.PageRequestManager.getInstance();
    if (inRound || inDecision || inFrameClosing || prm.get_isInAsyncPostBack()) {
        args.set_cancel(true);
        InstantGames.Manager.add_Delayed(args.get_postBackElement().id, document.forms[0].__EVENTARGUMENT.value);
        //alert('Bankroll cancelled: inRound=' + inRound + ', inDecision=' + inDecision + ', inFrameClosing=' + inFrameClosing);
    }
}

setInterval('InstantGames.Manager.process_Delayed();', 100);

// Bankroll timestamp routine
function UpdateBankrollTimestamp(sender, args) {
    var bankroll = InstantGames.Manager.get_bankroll();
    if (bankroll != null) {
        var bet = bankroll.get_betAmount();
        var inRound = InstantGames.Manager.get_inRound();
        if (bet != 0 || inRound) {
            bankroll.update_bankroll();
        } else {
            var bankrollContainer = $('bankroll-value');
            if (bankrollContainer != null) {
                $A(bankrollContainer.getElementsByTagName('span')).each(
                        function(child) {
                            child.removeAttribute('style');
                        }
                    );
            }
            var containerTimestamp = $get('LastKnownTimestamp'),
                containerValue = $get('LastKnownBankroll');
                bankrollTimestamp = 0,
                bankrollValue = 0.0;

                if (containerTimestamp != null) {
                    bankrollTimestamp = parseInt(containerTimestamp.value);
                    //alert('lastKnownTimestamp: ' + lastKnownTimestamp);
                    //bankroll.updateTimestamp(lastKnownTimestamp);
                }
                if (containerValue != null) {
                    bankrollValue = parseFloat(containerValue.value);
                    //alert('lastKnownTimestamp: ' + lastKnownTimestamp);
                    //bankroll.updateTimestamp(lastKnownTimestamp);
                }
                //alert("sb7 " + bankrollValue);
                bankroll.set_bankrollValue({ Bankroll: bankrollValue, Timestamp: bankrollTimestamp });
            }
    }
}

Sys.WebForms.PageRequestManager.getInstance().add_endRequest(InstantGamesErrorHandler);
Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(InstantGamesInitBankrollHandler);
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(UpdateBankrollTimestamp);

/*
 * Cashier manager implementation
 */
InstantGames.CashierManager = function() {
    // Manager initiaization
    this._cashierName = 'cashier-form';
    this._cashierWindow = 'CashierWindow';
    this._cashierForm = null;
    this._props = ['UserInfo', 'GMTGap', 'SessionType', 'MachineID', 'HardwareID', 'LangID', 'ClientVersion', 'PlatformID', 'SessionSourceID', 'BrandID', 'CID', 'GameCategory', 'EncryptionType'];
    this._props1 = ['UserInfo', 'GMTGap', 'SessionType', 'MachineID', 'HardwareID', 'LangID', 'ClientVersion', 'PlatformID', 'SessionSourceID', 'BrandID', 'CID', 'GameCategory', 'EncryptionType', 'TargetPackageNavigationView', 'SourceSubBrand', 'SourceProductPackage'];
}

InstantGames.CashierManager.prototype = {
    // Start cashier
	proceed: function (isUO) {
		if (isUO)
			GameService.GetCashierData(this.succeededCallback1, this.failedCallback);
		else
			GameService.GetCashierData(this.succeededCallback, this.failedCallback);
    },

    createCashierForm: function(x) {
        var cashierForm = document.createElement('form');
        cashierForm.id = this._cashierName;
        cashierForm.method = 'post';
        //cashierForm.target = this._cashierWindow;
		if (x==1)
			$A(InstantGames.Cashier._props).each(function(e) {
				var input = document.createElement('input');
				input.type = 'hidden';
				input.name = e;
				cashierForm.appendChild(input);
			});
		else
			$A(InstantGames.Cashier._props1).each(function (e) {
				var input = document.createElement('input');
				input.type = 'hidden';
				input.name = e;
				cashierForm.appendChild(input);
			});
        document.body.appendChild(cashierForm);
        return cashierForm;
    },

    succeededCallback: function(result, context, methodName) {
        var cashierForm = $get('cashier-form');
        if (cashierForm == undefined) {
            cashierForm = InstantGames.Cashier.createCashierForm(1);
        }
        $A(cashierForm.getElementsByTagName('input')).each(function(e) {
            var val = result[e.name];
            e.value = val == undefined ? '' : val;
        });
        cashierForm.action = result.ActionUrl;
        //var cashierWin = window.open('', this._cashierWindow, '');
        cashierForm.submit();
       },

	succeededCallback1: function (result, context, methodName) {
	var cashierForm = $get('cashier-form');
	if (cashierForm == undefined) {
       	cashierForm = InstantGames.Cashier.createCashierForm(2);
	}
	$A(cashierForm.getElementsByTagName('input')).each(function (e) {
       	var val = result[e.name];
       	e.value = val == undefined ? '' : val;
	});
	cashierForm.action = result.ActionUrl;
	//var cashierWin = window.open('', this._cashierWindow, '');
	cashierForm.submit();
	},

    failedCallback: function(error, context, methodName) {
        window.close(); //ShowServiceError();
    }

}

InstantGames.Cashier = new InstantGames.CashierManager();
InstantGames.CashierManager.registerClass('InstantGames.CashierManager');
