using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Globalization;
using System.Reflection;
using System.IO;
using System.Configuration;
using System.Threading;

using Betfair.Gamex.API;
using Betfair.Gamex.API.Entities;

using Betfair.Gamex.API.UberClient.Classes;
using Betfair.Gamex.API.UberClient.Controls;
using Betfair.Gamex.API.UberClient.Controls.GameView;

namespace Betfair.Gamex.API.UberClient
{
    public enum MainDisplayMode
    {
        LoggedIn,
        LoggedOut,
        SelectGame,
        UpdateBalance,
        ViewingGame
    };

    public enum RightHandDisplayMode
    {
        About,
        Rules,
        Bets,
        MyBets
    };

    public enum GameType
    {
        NONE,
        TEXAS, 
        OMAHA,
        BLACKJACK,
        BACCARAT,
        HILO 
    };

    public delegate void GetAvailableGames(channelLanding channels);
    public delegate void ClearAvailableGames();
    public delegate void UpdateChannelSnapshot(channelSnapshot snapshot);
    public delegate void UpdateDisplay(MainDisplayMode displayMode);
    public delegate void UpdateStatus(string s);

    /// <summary>
    /// The uber client's bread and butter
    /// </summary>
    public class MainForm : System.Windows.Forms.Form
    {
        #region Form Controls
        private Betfair.Gamex.API.UberClient.Controls.PostBetPanel pnlPostBet;
        private Betfair.Gamex.API.UberClient.Controls.MyBetsPanel pnlMyBets;
        private Betfair.Gamex.API.UberClient.Controls.AboutPanel ctlAbout;
        private System.Windows.Forms.MenuItem menuItemAbout;
        private System.Windows.Forms.MenuItem menuItemGotoBFG;
        private System.Windows.Forms.ToolTip toolTip1;
        private System.Windows.Forms.Button btnMyBets;
        private Button btnViewGames;
        private System.Windows.Forms.MainMenu mainMenu;
        private System.Windows.Forms.MenuItem menuItemFile;
        private System.Windows.Forms.MenuItem menuExit;
        private System.Windows.Forms.MenuItem menuItemHelp;
        private System.Windows.Forms.Button btnRules;
        private System.Windows.Forms.Button btnBets;
        private System.Windows.Forms.Panel pnlLogin;
        private System.Windows.Forms.PictureBox infoPic;
        private System.Windows.Forms.Label lblLoginMessage;
        private System.Windows.Forms.TextBox tbUsername;
        private System.Windows.Forms.Label lblUsername;
        private System.Windows.Forms.TextBox tbPassword;
        private System.Windows.Forms.Label lblPassword;
        private System.Windows.Forms.Button btnLogin;
        private System.Windows.Forms.StatusBar statusBar;
        private System.Windows.Forms.StatusBarPanel statusBarPanelAction;
        private System.Windows.Forms.StatusBarPanel statusBarPanelVerbose;
        private System.Windows.Forms.LinkLabel linkLbCreateAccount;
        private System.ComponentModel.IContainer components;
        private System.Windows.Forms.Panel pnlNavigation;
        private System.Windows.Forms.Button btnLogout;
        private System.Windows.Forms.Label lblSelectGames;
        private System.Windows.Forms.Panel pnlGameSelect;
        private System.Windows.Forms.StatusBarPanel statusBarPanelCurrency;
        private System.Windows.Forms.Button btnAccountStatement;
        private System.Windows.Forms.Button btnBetHistory;
        private System.Windows.Forms.Label lblBalance;
        private System.Windows.Forms.Button btnTransfer;
        private System.Windows.Forms.Panel pnlBetManagerButtons;
        private System.Windows.Forms.PictureBox picBalanceRefresh;
        private System.Windows.Forms.Label lblGamesLoading;
        private System.Windows.Forms.GroupBox gpbLogin;
        private System.Windows.Forms.GroupBox gpbGames;
        private System.Windows.Forms.Label lblCommissionRate;
        private System.Windows.Forms.Panel pnlRules;
        private System.Windows.Forms.Label lblTotalMatched;
        private System.Windows.Forms.Label lblRules;
        private System.Windows.Forms.RichTextBox rtbRules;
        #endregion

        private Thread m_GameUpdateThread;

        private Adapter m_Adapter;
        private bool m_LoggedIn;
        private string m_BaseUrl = string.Format("https://{0}", ConfigurationManager.AppSettings["ServerName"]);
        private accountSnapshot m_AccountSnapshot;

        private GameType m_CurrentlyViewing = GameType.NONE;
        private IGameControl m_ActiveGameControl;
        private long m_CurrentChannelId = -1;

        /// <summary>
        /// Constructor
        /// </summary>
        public MainForm()
        {
            InitializeComponent();
            this.Size = new Size(648, 472);
        }

        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
            this.mainMenu = new System.Windows.Forms.MainMenu(this.components);
            this.menuItemFile = new System.Windows.Forms.MenuItem();
            this.menuExit = new System.Windows.Forms.MenuItem();
            this.menuItemHelp = new System.Windows.Forms.MenuItem();
            this.menuItemAbout = new System.Windows.Forms.MenuItem();
            this.menuItemGotoBFG = new System.Windows.Forms.MenuItem();
            this.btnRules = new System.Windows.Forms.Button();
            this.btnBets = new System.Windows.Forms.Button();
            this.pnlRules = new System.Windows.Forms.Panel();
            this.lblCommissionRate = new System.Windows.Forms.Label();
            this.lblTotalMatched = new System.Windows.Forms.Label();
            this.lblRules = new System.Windows.Forms.Label();
            this.rtbRules = new System.Windows.Forms.RichTextBox();
            this.pnlLogin = new System.Windows.Forms.Panel();
            this.gpbLogin = new System.Windows.Forms.GroupBox();
            this.linkLbCreateAccount = new System.Windows.Forms.LinkLabel();
            this.tbPassword = new System.Windows.Forms.TextBox();
            this.lblPassword = new System.Windows.Forms.Label();
            this.btnLogin = new System.Windows.Forms.Button();
            this.lblUsername = new System.Windows.Forms.Label();
            this.tbUsername = new System.Windows.Forms.TextBox();
            this.infoPic = new System.Windows.Forms.PictureBox();
            this.lblLoginMessage = new System.Windows.Forms.Label();
            this.statusBar = new System.Windows.Forms.StatusBar();
            this.statusBarPanelAction = new System.Windows.Forms.StatusBarPanel();
            this.statusBarPanelVerbose = new System.Windows.Forms.StatusBarPanel();
            this.statusBarPanelCurrency = new System.Windows.Forms.StatusBarPanel();
            this.pnlNavigation = new System.Windows.Forms.Panel();
            this.btnViewGames = new System.Windows.Forms.Button();
            this.btnTransfer = new System.Windows.Forms.Button();
            this.lblBalance = new System.Windows.Forms.Label();
            this.btnBetHistory = new System.Windows.Forms.Button();
            this.btnAccountStatement = new System.Windows.Forms.Button();
            this.btnLogout = new System.Windows.Forms.Button();
            this.picBalanceRefresh = new System.Windows.Forms.PictureBox();
            this.pnlGameSelect = new System.Windows.Forms.Panel();
            this.gpbGames = new System.Windows.Forms.GroupBox();
            this.lblGamesLoading = new System.Windows.Forms.Label();
            this.lblSelectGames = new System.Windows.Forms.Label();
            this.pnlBetManagerButtons = new System.Windows.Forms.Panel();
            this.btnMyBets = new System.Windows.Forms.Button();
            this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
            this.pnlMyBets = new Betfair.Gamex.API.UberClient.Controls.MyBetsPanel();
            this.pnlPostBet = new Betfair.Gamex.API.UberClient.Controls.PostBetPanel();
            this.ctlAbout = new Betfair.Gamex.API.UberClient.Controls.AboutPanel();
            this.pnlRules.SuspendLayout();
            this.pnlLogin.SuspendLayout();
            this.gpbLogin.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.infoPic)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.statusBarPanelAction)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.statusBarPanelVerbose)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.statusBarPanelCurrency)).BeginInit();
            this.pnlNavigation.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.picBalanceRefresh)).BeginInit();
            this.pnlGameSelect.SuspendLayout();
            this.gpbGames.SuspendLayout();
            this.pnlBetManagerButtons.SuspendLayout();
            this.SuspendLayout();
            // 
            // mainMenu
            // 
            this.mainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menuItemFile,
            this.menuItemHelp});
            // 
            // menuItemFile
            // 
            this.menuItemFile.Index = 0;
            this.menuItemFile.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menuExit});
            this.menuItemFile.Text = "&File";
            // 
            // menuExit
            // 
            this.menuExit.Index = 0;
            this.menuExit.Text = "E&xit";
            this.menuExit.Click += new System.EventHandler(this.menuExit_Click);
            // 
            // menuItemHelp
            // 
            this.menuItemHelp.Index = 1;
            this.menuItemHelp.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menuItemAbout,
            this.menuItemGotoBFG});
            this.menuItemHelp.Text = "&Help";
            // 
            // menuItemAbout
            // 
            this.menuItemAbout.Index = 0;
            this.menuItemAbout.Text = "&About";
            this.menuItemAbout.Click += new System.EventHandler(this.menuAbout_Click);
            // 
            // menuItemGotoBFG
            // 
            this.menuItemGotoBFG.Index = 1;
            this.menuItemGotoBFG.Text = "&Go to Betfair Games...";
            this.menuItemGotoBFG.Click += new System.EventHandler(this.menuItemGotoBFG_Click);
            // 
            // btnRules
            // 
            this.btnRules.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("btnRules.BackgroundImage")));
            this.btnRules.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
            this.btnRules.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.btnRules.Image = ((System.Drawing.Image)(resources.GetObject("btnRules.Image")));
            this.btnRules.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
            this.btnRules.Location = new System.Drawing.Point(157, 3);
            this.btnRules.Name = "btnRules";
            this.btnRules.Size = new System.Drawing.Size(56, 24);
            this.btnRules.TabIndex = 0;
            this.btnRules.Text = "Rules";
            this.btnRules.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
            this.toolTip1.SetToolTip(this.btnRules, "Shows rules for this game");
            this.btnRules.Click += new System.EventHandler(this.btnRules_Click);
            // 
            // btnBets
            // 
            this.btnBets.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("btnBets.BackgroundImage")));
            this.btnBets.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
            this.btnBets.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.btnBets.Image = ((System.Drawing.Image)(resources.GetObject("btnBets.Image")));
            this.btnBets.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
            this.btnBets.Location = new System.Drawing.Point(4, 3);
            this.btnBets.Name = "btnBets";
            this.btnBets.Size = new System.Drawing.Size(77, 24);
            this.btnBets.TabIndex = 1;
            this.btnBets.Text = "Place Bets";
            this.btnBets.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
            this.toolTip1.SetToolTip(this.btnBets, "Shows bets that are unplaced or unmatched on this game");
            this.btnBets.Click += new System.EventHandler(this.btnBets_Click);
            // 
            // pnlRules
            // 
            this.pnlRules.BackColor = System.Drawing.Color.Transparent;
            this.pnlRules.Controls.Add(this.lblCommissionRate);
            this.pnlRules.Controls.Add(this.lblTotalMatched);
            this.pnlRules.Controls.Add(this.lblRules);
            this.pnlRules.Controls.Add(this.rtbRules);
            this.pnlRules.ForeColor = System.Drawing.Color.Black;
            this.pnlRules.Location = new System.Drawing.Point(424, 41);
            this.pnlRules.Name = "pnlRules";
            this.pnlRules.Size = new System.Drawing.Size(217, 351);
            this.pnlRules.TabIndex = 4;
            this.pnlRules.Visible = false;
            // 
            // lblCommissionRate
            // 
            this.lblCommissionRate.Location = new System.Drawing.Point(0, 23);
            this.lblCommissionRate.Name = "lblCommissionRate";
            this.lblCommissionRate.Size = new System.Drawing.Size(197, 16);
            this.lblCommissionRate.TabIndex = 3;
            this.lblCommissionRate.Text = "Market commission: Unknown";
            // 
            // lblTotalMatched
            // 
            this.lblTotalMatched.Location = new System.Drawing.Point(0, 7);
            this.lblTotalMatched.Name = "lblTotalMatched";
            this.lblTotalMatched.Size = new System.Drawing.Size(191, 13);
            this.lblTotalMatched.TabIndex = 2;
            this.lblTotalMatched.Text = "Total amount matched: Unknown";
            // 
            // lblRules
            // 
            this.lblRules.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.lblRules.Location = new System.Drawing.Point(0, 39);
            this.lblRules.Name = "lblRules";
            this.lblRules.Size = new System.Drawing.Size(149, 16);
            this.lblRules.TabIndex = 1;
            this.lblRules.Text = "Game Rules:";
            // 
            // rtbRules
            // 
            this.rtbRules.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(215)))), ((int)(((byte)(236)))));
            this.rtbRules.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.rtbRules.Dock = System.Windows.Forms.DockStyle.Bottom;
            this.rtbRules.Location = new System.Drawing.Point(0, 59);
            this.rtbRules.Name = "rtbRules";
            this.rtbRules.ReadOnly = true;
            this.rtbRules.Size = new System.Drawing.Size(217, 292);
            this.rtbRules.TabIndex = 0;
            this.rtbRules.Text = "Loading...";
            // 
            // pnlLogin
            // 
            this.pnlLogin.BackColor = System.Drawing.Color.White;
            this.pnlLogin.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pnlLogin.BackgroundImage")));
            this.pnlLogin.Controls.Add(this.gpbLogin);
            this.pnlLogin.Location = new System.Drawing.Point(12, 124);
            this.pnlLogin.Name = "pnlLogin";
            this.pnlLogin.Size = new System.Drawing.Size(396, 200);
            this.pnlLogin.TabIndex = 5;
            // 
            // gpbLogin
            // 
            this.gpbLogin.BackColor = System.Drawing.Color.Transparent;
            this.gpbLogin.Controls.Add(this.linkLbCreateAccount);
            this.gpbLogin.Controls.Add(this.tbPassword);
            this.gpbLogin.Controls.Add(this.lblPassword);
            this.gpbLogin.Controls.Add(this.btnLogin);
            this.gpbLogin.Controls.Add(this.lblUsername);
            this.gpbLogin.Controls.Add(this.tbUsername);
            this.gpbLogin.Controls.Add(this.infoPic);
            this.gpbLogin.Controls.Add(this.lblLoginMessage);
            this.gpbLogin.Location = new System.Drawing.Point(10, 5);
            this.gpbLogin.Name = "gpbLogin";
            this.gpbLogin.Size = new System.Drawing.Size(376, 184);
            this.gpbLogin.TabIndex = 8;
            this.gpbLogin.TabStop = false;
            // 
            // linkLbCreateAccount
            // 
            this.linkLbCreateAccount.BackColor = System.Drawing.Color.Transparent;
            this.linkLbCreateAccount.Location = new System.Drawing.Point(127, 142);
            this.linkLbCreateAccount.Name = "linkLbCreateAccount";
            this.linkLbCreateAccount.Size = new System.Drawing.Size(122, 16);
            this.linkLbCreateAccount.TabIndex = 7;
            this.linkLbCreateAccount.TabStop = true;
            this.linkLbCreateAccount.Text = "Need a Betfair account?";
            this.linkLbCreateAccount.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLbCreateAccount_LinkClicked);
            // 
            // tbPassword
            // 
            this.tbPassword.Location = new System.Drawing.Point(128, 112);
            this.tbPassword.Name = "tbPassword";
            this.tbPassword.PasswordChar = '*';
            this.tbPassword.Size = new System.Drawing.Size(178, 21);
            this.tbPassword.TabIndex = 4;
            this.tbPassword.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.tbPassword_KeyPress);
            // 
            // lblPassword
            // 
            this.lblPassword.BackColor = System.Drawing.Color.Transparent;
            this.lblPassword.Font = new System.Drawing.Font("Tahoma", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.lblPassword.ForeColor = System.Drawing.Color.Black;
            this.lblPassword.Location = new System.Drawing.Point(56, 113);
            this.lblPassword.Name = "lblPassword";
            this.lblPassword.Size = new System.Drawing.Size(69, 24);
            this.lblPassword.TabIndex = 5;
            this.lblPassword.Text = "Password:";
            // 
            // btnLogin
            // 
            this.btnLogin.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("btnLogin.BackgroundImage")));
            this.btnLogin.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
            this.btnLogin.ForeColor = System.Drawing.Color.White;
            this.btnLogin.Image = ((System.Drawing.Image)(resources.GetObject("btnLogin.Image")));
            this.btnLogin.ImageAlign = System.Drawing.ContentAlignment.MiddleRight;
            this.btnLogin.Location = new System.Drawing.Point(250, 137);
            this.btnLogin.Name = "btnLogin";
            this.btnLogin.Size = new System.Drawing.Size(56, 24);
            this.btnLogin.TabIndex = 6;
            this.btnLogin.Text = "Login";
            this.btnLogin.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
            this.btnLogin.Click += new System.EventHandler(this.Login_Click);
            // 
            // lblUsername
            // 
            this.lblUsername.BackColor = System.Drawing.Color.Transparent;
            this.lblUsername.Font = new System.Drawing.Font("Tahoma", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.lblUsername.ForeColor = System.Drawing.Color.Black;
            this.lblUsername.Location = new System.Drawing.Point(56, 81);
            this.lblUsername.Name = "lblUsername";
            this.lblUsername.Size = new System.Drawing.Size(72, 23);
            this.lblUsername.TabIndex = 3;
            this.lblUsername.Text = "Username:";
            // 
            // tbUsername
            // 
            this.tbUsername.Location = new System.Drawing.Point(128, 80);
            this.tbUsername.Name = "tbUsername";
            this.tbUsername.Size = new System.Drawing.Size(178, 21);
            this.tbUsername.TabIndex = 2;
            this.tbUsername.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.tbUsername_KeyPress);
            // 
            // infoPic
            // 
            this.infoPic.BackColor = System.Drawing.Color.Transparent;
            this.infoPic.Image = ((System.Drawing.Image)(resources.GetObject("infoPic.Image")));
            this.infoPic.Location = new System.Drawing.Point(8, 16);
            this.infoPic.Name = "infoPic";
            this.infoPic.Size = new System.Drawing.Size(48, 50);
            this.infoPic.TabIndex = 1;
            this.infoPic.TabStop = false;
            // 
            // lblLoginMessage
            // 
            this.lblLoginMessage.BackColor = System.Drawing.Color.Transparent;
            this.lblLoginMessage.Font = new System.Drawing.Font("Tahoma", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.lblLoginMessage.ForeColor = System.Drawing.Color.Black;
            this.lblLoginMessage.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
            this.lblLoginMessage.Location = new System.Drawing.Point(64, 16);
            this.lblLoginMessage.Name = "lblLoginMessage";
            this.lblLoginMessage.Size = new System.Drawing.Size(296, 48);
            this.lblLoginMessage.TabIndex = 0;
            this.lblLoginMessage.Text = "Please login with your Betfair username and password to begin";
            this.lblLoginMessage.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
            // 
            // statusBar
            // 
            this.statusBar.Location = new System.Drawing.Point(0, 325);
            this.statusBar.Name = "statusBar";
            this.statusBar.Panels.AddRange(new System.Windows.Forms.StatusBarPanel[] {
            this.statusBarPanelAction,
            this.statusBarPanelVerbose,
            this.statusBarPanelCurrency});
            this.statusBar.ShowPanels = true;
            this.statusBar.Size = new System.Drawing.Size(642, 22);
            this.statusBar.SizingGrip = false;
            this.statusBar.TabIndex = 6;
            // 
            // statusBarPanelAction
            // 
            this.statusBarPanelAction.Name = "statusBarPanelAction";
            this.statusBarPanelAction.Text = "Idle";
            this.statusBarPanelAction.Width = 200;
            // 
            // statusBarPanelVerbose
            // 
            this.statusBarPanelVerbose.Name = "statusBarPanelVerbose";
            this.statusBarPanelVerbose.Text = "Please login";
            this.statusBarPanelVerbose.Width = 250;
            // 
            // statusBarPanelCurrency
            // 
            this.statusBarPanelCurrency.Name = "statusBarPanelCurrency";
            this.statusBarPanelCurrency.Width = 193;
            // 
            // pnlNavigation
            // 
            this.pnlNavigation.BackColor = System.Drawing.Color.Transparent;
            this.pnlNavigation.Controls.Add(this.btnViewGames);
            this.pnlNavigation.Controls.Add(this.btnTransfer);
            this.pnlNavigation.Controls.Add(this.lblBalance);
            this.pnlNavigation.Controls.Add(this.btnBetHistory);
            this.pnlNavigation.Controls.Add(this.btnAccountStatement);
            this.pnlNavigation.Controls.Add(this.btnLogout);
            this.pnlNavigation.Controls.Add(this.picBalanceRefresh);
            this.pnlNavigation.Enabled = false;
            this.pnlNavigation.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.pnlNavigation.ForeColor = System.Drawing.Color.White;
            this.pnlNavigation.Location = new System.Drawing.Point(6, 5);
            this.pnlNavigation.Name = "pnlNavigation";
            this.pnlNavigation.Size = new System.Drawing.Size(634, 32);
            this.pnlNavigation.TabIndex = 7;
            // 
            // btnViewGames
            // 
            this.btnViewGames.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("btnViewGames.BackgroundImage")));
            this.btnViewGames.Cursor = System.Windows.Forms.Cursors.Hand;
            this.btnViewGames.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
            this.btnViewGames.Font = new System.Drawing.Font("Tahoma", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.btnViewGames.Image = ((System.Drawing.Image)(resources.GetObject("btnViewGames.Image")));
            this.btnViewGames.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
            this.btnViewGames.Location = new System.Drawing.Point(293, 4);
            this.btnViewGames.Name = "btnViewGames";
            this.btnViewGames.Size = new System.Drawing.Size(88, 22);
            this.btnViewGames.TabIndex = 6;
            this.btnViewGames.Text = "View Games";
            this.btnViewGames.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
            this.btnViewGames.Click += new System.EventHandler(this.btnViewGames_Click);
            // 
            // btnTransfer
            // 
            this.btnTransfer.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("btnTransfer.BackgroundImage")));
            this.btnTransfer.Cursor = System.Windows.Forms.Cursors.Hand;
            this.btnTransfer.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
            this.btnTransfer.Font = new System.Drawing.Font("Tahoma", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.btnTransfer.Image = ((System.Drawing.Image)(resources.GetObject("btnTransfer.Image")));
            this.btnTransfer.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
            this.btnTransfer.Location = new System.Drawing.Point(227, 4);
            this.btnTransfer.Name = "btnTransfer";
            this.btnTransfer.Size = new System.Drawing.Size(65, 22);
            this.btnTransfer.TabIndex = 0;
            this.btnTransfer.Text = "Transfer";
            this.btnTransfer.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
            this.btnTransfer.Click += new System.EventHandler(this.btnTransfer_Click);
            // 
            // lblBalance
            // 
            this.lblBalance.Font = new System.Drawing.Font("Tahoma", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.lblBalance.ForeColor = System.Drawing.Color.White;
            this.lblBalance.Location = new System.Drawing.Point(25, 10);
            this.lblBalance.Name = "lblBalance";
            this.lblBalance.Size = new System.Drawing.Size(116, 16);
            this.lblBalance.TabIndex = 0;
            this.lblBalance.Text = "Balance: Unknown";
            // 
            // btnBetHistory
            // 
            this.btnBetHistory.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("btnBetHistory.BackgroundImage")));
            this.btnBetHistory.Cursor = System.Windows.Forms.Cursors.Hand;
            this.btnBetHistory.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
            this.btnBetHistory.Font = new System.Drawing.Font("Tahoma", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.btnBetHistory.Image = ((System.Drawing.Image)(resources.GetObject("btnBetHistory.Image")));
            this.btnBetHistory.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
            this.btnBetHistory.Location = new System.Drawing.Point(493, 4);
            this.btnBetHistory.Name = "btnBetHistory";
            this.btnBetHistory.Size = new System.Drawing.Size(77, 22);
            this.btnBetHistory.TabIndex = 2;
            this.btnBetHistory.Text = "Bet History";
            this.btnBetHistory.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
            this.btnBetHistory.Click += new System.EventHandler(this.btnBetHistory_Click);
            // 
            // btnAccountStatement
            // 
            this.btnAccountStatement.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("btnAccountStatement.BackgroundImage")));
            this.btnAccountStatement.Cursor = System.Windows.Forms.Cursors.Hand;
            this.btnAccountStatement.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
            this.btnAccountStatement.Font = new System.Drawing.Font("Tahoma", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.btnAccountStatement.Image = ((System.Drawing.Image)(resources.GetObject("btnAccountStatement.Image")));
            this.btnAccountStatement.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
            this.btnAccountStatement.Location = new System.Drawing.Point(382, 4);
            this.btnAccountStatement.Name = "btnAccountStatement";
            this.btnAccountStatement.Size = new System.Drawing.Size(110, 22);
            this.btnAccountStatement.TabIndex = 1;
            this.btnAccountStatement.Text = "Account Statement";
            this.btnAccountStatement.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
            this.btnAccountStatement.Click += new System.EventHandler(this.btnAccountStatement_Click);
            // 
            // btnLogout
            // 
            this.btnLogout.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("btnLogout.BackgroundImage")));
            this.btnLogout.Cursor = System.Windows.Forms.Cursors.Hand;
            this.btnLogout.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
            this.btnLogout.Font = new System.Drawing.Font("Tahoma", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.btnLogout.Image = ((System.Drawing.Image)(resources.GetObject("btnLogout.Image")));
            this.btnLogout.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
            this.btnLogout.Location = new System.Drawing.Point(571, 4);
            this.btnLogout.Name = "btnLogout";
            this.btnLogout.Size = new System.Drawing.Size(58, 22);
            this.btnLogout.TabIndex = 3;
            this.btnLogout.Text = "Logout";
            this.btnLogout.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
            this.btnLogout.Click += new System.EventHandler(this.btnLogout_Click);
            // 
            // picBalanceRefresh
            // 
            this.picBalanceRefresh.AccessibleDescription = "";
            this.picBalanceRefresh.Cursor = System.Windows.Forms.Cursors.Hand;
            this.picBalanceRefresh.Image = ((System.Drawing.Image)(resources.GetObject("picBalanceRefresh.Image")));
            this.picBalanceRefresh.Location = new System.Drawing.Point(8, 7);
            this.picBalanceRefresh.Name = "picBalanceRefresh";
            this.picBalanceRefresh.Size = new System.Drawing.Size(17, 16);
            this.picBalanceRefresh.TabIndex = 5;
            this.picBalanceRefresh.TabStop = false;
            this.toolTip1.SetToolTip(this.picBalanceRefresh, "Refresh");
            this.picBalanceRefresh.Click += new System.EventHandler(this.BalanceRefresh_Click);
            // 
            // pnlGameSelect
            // 
            this.pnlGameSelect.BackColor = System.Drawing.Color.Transparent;
            this.pnlGameSelect.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pnlGameSelect.BackgroundImage")));
            this.pnlGameSelect.Controls.Add(this.gpbGames);
            this.pnlGameSelect.Location = new System.Drawing.Point(46, 80);
            this.pnlGameSelect.Name = "pnlGameSelect";
            this.pnlGameSelect.Size = new System.Drawing.Size(320, 288);
            this.pnlGameSelect.TabIndex = 8;
            this.pnlGameSelect.Visible = false;
            // 
            // gpbGames
            // 
            this.gpbGames.Controls.Add(this.lblGamesLoading);
            this.gpbGames.Controls.Add(this.lblSelectGames);
            this.gpbGames.Location = new System.Drawing.Point(18, 8);
            this.gpbGames.Name = "gpbGames";
            this.gpbGames.Size = new System.Drawing.Size(285, 264);
            this.gpbGames.TabIndex = 3;
            this.gpbGames.TabStop = false;
            // 
            // lblGamesLoading
            // 
            this.lblGamesLoading.ForeColor = System.Drawing.Color.Black;
            this.lblGamesLoading.Location = new System.Drawing.Point(40, 48);
            this.lblGamesLoading.Name = "lblGamesLoading";
            this.lblGamesLoading.Size = new System.Drawing.Size(112, 16);
            this.lblGamesLoading.TabIndex = 2;
            this.lblGamesLoading.Text = "Loading games...";
            // 
            // lblSelectGames
            // 
            this.lblSelectGames.Font = new System.Drawing.Font("Tahoma", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.lblSelectGames.ForeColor = System.Drawing.Color.Black;
            this.lblSelectGames.Location = new System.Drawing.Point(24, 24);
            this.lblSelectGames.Name = "lblSelectGames";
            this.lblSelectGames.Size = new System.Drawing.Size(208, 23);
            this.lblSelectGames.TabIndex = 1;
            this.lblSelectGames.Text = "Please select a game:";
            // 
            // pnlBetManagerButtons
            // 
            this.pnlBetManagerButtons.BackColor = System.Drawing.Color.Transparent;
            this.pnlBetManagerButtons.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.pnlBetManagerButtons.Controls.Add(this.btnMyBets);
            this.pnlBetManagerButtons.Controls.Add(this.btnRules);
            this.pnlBetManagerButtons.Controls.Add(this.btnBets);
            this.pnlBetManagerButtons.Enabled = false;
            this.pnlBetManagerButtons.Location = new System.Drawing.Point(424, 394);
            this.pnlBetManagerButtons.Name = "pnlBetManagerButtons";
            this.pnlBetManagerButtons.Size = new System.Drawing.Size(218, 32);
            this.pnlBetManagerButtons.TabIndex = 9;
            // 
            // btnMyBets
            // 
            this.btnMyBets.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("btnMyBets.BackgroundImage")));
            this.btnMyBets.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
            this.btnMyBets.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.btnMyBets.Image = ((System.Drawing.Image)(resources.GetObject("btnMyBets.Image")));
            this.btnMyBets.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
            this.btnMyBets.Location = new System.Drawing.Point(83, 3);
            this.btnMyBets.Name = "btnMyBets";
            this.btnMyBets.Size = new System.Drawing.Size(72, 24);
            this.btnMyBets.TabIndex = 2;
            this.btnMyBets.Text = "Matched";
            this.btnMyBets.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
            this.toolTip1.SetToolTip(this.btnMyBets, "Shows all matched bets on this game");
            this.btnMyBets.Click += new System.EventHandler(this.btnMyBets_Click);
            // 
            // pnlMyBets
            // 
            this.pnlMyBets.Adapter = null;
            this.pnlMyBets.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(215)))), ((int)(((byte)(236)))));
            this.pnlMyBets.Bets = null;
            this.pnlMyBets.Location = new System.Drawing.Point(424, 41);
            this.pnlMyBets.Name = "pnlMyBets";
            this.pnlMyBets.Size = new System.Drawing.Size(217, 351);
            this.pnlMyBets.TabIndex = 12;
            // 
            // pnlPostBet
            // 
            this.pnlPostBet.Adapter = null;
            this.pnlPostBet.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(215)))), ((int)(((byte)(236)))));
            this.pnlPostBet.CurrentChannelID = ((long)(0));
            this.pnlPostBet.Location = new System.Drawing.Point(424, 41);
            this.pnlPostBet.Name = "pnlPostBet";
            this.pnlPostBet.Size = new System.Drawing.Size(217, 351);
            this.pnlPostBet.TabIndex = 11;
            this.pnlPostBet.Visible = false;
            // 
            // ctlAbout
            // 
            this.ctlAbout.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(215)))), ((int)(((byte)(236)))));
            this.ctlAbout.Location = new System.Drawing.Point(424, 48);
            this.ctlAbout.Name = "ctlAbout";
            this.ctlAbout.Size = new System.Drawing.Size(207, 240);
            this.ctlAbout.TabIndex = 10;
            // 
            // MainForm
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 14);
            this.BackColor = System.Drawing.Color.White;
            this.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("$this.BackgroundImage")));
            this.ClientSize = new System.Drawing.Size(642, 347);
            this.Controls.Add(this.pnlMyBets);
            this.Controls.Add(this.pnlLogin);
            this.Controls.Add(this.pnlPostBet);
            this.Controls.Add(this.ctlAbout);
            this.Controls.Add(this.pnlGameSelect);
            this.Controls.Add(this.pnlNavigation);
            this.Controls.Add(this.pnlBetManagerButtons);
            this.Controls.Add(this.statusBar);
            this.Controls.Add(this.pnlRules);
            this.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.ForeColor = System.Drawing.Color.White;
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.MaximizeBox = false;
            this.Menu = this.mainMenu;
            this.Name = "MainForm";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "ÜberClient";
            this.pnlRules.ResumeLayout(false);
            this.pnlLogin.ResumeLayout(false);
            this.gpbLogin.ResumeLayout(false);
            this.gpbLogin.PerformLayout();
            ((System.ComponentModel.ISupportInitialize)(this.infoPic)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.statusBarPanelAction)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.statusBarPanelVerbose)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.statusBarPanelCurrency)).EndInit();
            this.pnlNavigation.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)(this.picBalanceRefresh)).EndInit();
            this.pnlGameSelect.ResumeLayout(false);
            this.gpbGames.ResumeLayout(false);
            this.pnlBetManagerButtons.ResumeLayout(false);
            this.ResumeLayout(false);

        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }

            base.Dispose(disposing);
        }
        #endregion

        #region Public Properties
        public Adapter Api
        {
            get { return m_Adapter; }
        }

        public accountSnapshot Account
        {
            get { return m_AccountSnapshot; }
        }
        #endregion

        #region Login Process
        /// <summary>
        /// Login button clicked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Login_Click(object sender, System.EventArgs e)
        {
            if (tbUsername.Text.Length > 0 && tbPassword.Text.Length > 0)
            {
                _SetStatusAction("Logging in...");

                // create adapter
                m_Adapter = new Adapter(m_BaseUrl, "UberClient", tbUsername.Text, tbPassword.Text);

                // fire off async login process
                m_Adapter.BeginGetAccountSnapshot(new AsyncCallback(_AsyncLoginProcess), null);
                pnlPostBet.Adapter = m_Adapter;
            }
            else
            {
                MessageBox.Show("Please enter both a username and password", "Login", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        /// <summary>
        /// Called when the account snapshot async finishes
        /// </summary>
        /// <param name="asyncResult"></param>
        private void _AsyncLoginProcess(IAsyncResult asyncResult)
        {
            try
            {
                // get the response
                AsyncRequestState requestState = (AsyncRequestState)asyncResult.AsyncState;
                AsyncResponseState responseState = m_Adapter.EndGetAccountSnapshot(asyncResult);
                m_AccountSnapshot = (accountSnapshot)responseState.ReturnObject;

                m_LoggedIn = true;

                // set delegate to update display
                Invoke(new UpdateDisplay(_SetDisplay), new object[] { MainDisplayMode.LoggedIn });

                // then load available games
                _LoadAvailableGames();
            }
            catch (Exception)
            {
                MessageBox.Show("Either your username or password is incorrect.\n\nPlease ensure you do not have caps lock on.", "Error logging in", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                _SafeSetStatusAction("Idle");
            }
        }

        /// <summary>
        /// Load channel landing
        /// </summary>
        private void _LoadAvailableGames()
        {
            _SafeSetStatusAction("Loading available games...");

            Invoke(new ClearAvailableGames(_ClearAvailableGames));
            m_Adapter.BeginGetChannelLanding(new AsyncCallback(_AsyncLoadAvailableGames), null);
        }

        /// <summary>
        /// Called when the channel landing async finishes
        /// </summary>
        /// <param name="asyncResult"></param>
        private void _AsyncLoadAvailableGames(IAsyncResult asyncResult)
        {
            try
            {
                // get response
                AsyncRequestState requestState = (AsyncRequestState)asyncResult.AsyncState;
                AsyncResponseState responseState = m_Adapter.EndGetChannelLanding(asyncResult);
                channelLanding channels = (channelLanding)responseState.ReturnObject;

                //set delegate to display available games
                Invoke(new GetAvailableGames(_DisplayAvailableGames), new object[] { channels });
            }
            catch (Exception ex)
            {
                _ProcessGeneralException(ex);
            }
            finally
            {
                _SafeSetStatusAction("Idle");
            }
        }

        /// <summary>
        /// Clear current available games list
        /// </summary>
        private void _ClearAvailableGames()
        {
            // remove label links
            for (int i = 0; i < gpbGames.Controls.Count; i++)
            {
                if (gpbGames.Controls[i].GetType() == typeof(LinkLabel))
                {
                    gpbGames.Controls.Remove(gpbGames.Controls[i]);
                    i = 0;
                }
            }

            lblGamesLoading.Show();
        }

        /// <summary>
        /// Display all available games
        /// </summary>
        /// <param name="channels"></param>
        private void _DisplayAvailableGames(channelLanding channels)
        {
            _SetDisplay(MainDisplayMode.SelectGame);
            lblGamesLoading.Hide();

            int gameCount = 0;
            //create new label links
            for (int i = 0; i < channels.channel.Length; i++)
            {
                if (Util.ArrayIndexOf(channels.channel[i].gameType, new string[] { "POKER", "BLACKJACK", "BACCARAT", "HILO", "OMAHA_POKER" }, true) > -1)
                {
                    LinkLabel ll = new LinkLabel();
                    ll.Text = channels.channel[i].name;
                    ll.Links.Add(0, ll.Text.Length, String.Format("{0}|{1}", channels.channel[i].id, channels.channel[i].gameType));
                    ll.Top = 48 + (i * 17);
                    ll.Left = 40;
                    ll.Width = 225;
                    ll.Height = 16;
                    ll.LinkClicked += new LinkLabelLinkClickedEventHandler(GameLink_Clicked);
                    gpbGames.Controls.Add(ll);
                    gameCount++;
                }
            }

            if (gameCount == 0)
            {
                MessageBox.Show("No games are currently available.\n\nPlease try again later.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                pnlGameSelect.Hide();
            }
        }

        /// <summary>
        /// Load account details for user
        /// </summary>
        private void _LoadAccountDetails()
        {
            _SetStatusAction("Loading account details...");
            m_Adapter.BeginGetAccountSnapshot(new AsyncCallback(_AsyncLoadAccountDetails), null);
        }

        /// <summary>
        /// Called when the account snapshot async finishes
        /// </summary>
        /// <param name="asyncResult"></param>
        private void _AsyncLoadAccountDetails(IAsyncResult asyncResult)
        {
            try
            {
                // get response
                AsyncRequestState requestState = (AsyncRequestState)asyncResult.AsyncState;
                AsyncResponseState responseState = m_Adapter.EndGetAccountSnapshot(asyncResult);
                m_AccountSnapshot = (accountSnapshot)responseState.ReturnObject;

                // set delegate to update balance
                Invoke(new UpdateDisplay(_SetDisplay), new object[] { MainDisplayMode.LoggedIn });
            }
            catch (Exception ex)
            {
                _ProcessGeneralException(ex);
            }
            finally
            {
                _SafeSetStatusAction("Idle");
            }
        }
        #endregion

        #region Display Related Methods
        /// <summary>
        /// Update status bar with current action
        /// </summary>
        /// <param name="status"></param>
        public void _SafeSetStatusAction(string status)
        {
            Invoke(new UpdateStatus(_SetStatusAction), new object[] { status });
        }

        private void _SetStatusAction(string status)
        {
            statusBarPanelAction.Text = status;
        }

        private void _SetDisplay(MainDisplayMode displayMode)
        {
            switch (displayMode)
            {
                case MainDisplayMode.LoggedIn:
                    pnlLogin.Hide();
                    pnlNavigation.Enabled = true;
                    statusBarPanelCurrency.Text = String.Format("Currency: {0}", m_AccountSnapshot.currency);
                    statusBarPanelVerbose.Text = String.Format("Logged in as: {0}", tbUsername.Text);
                    _SetDisplay(MainDisplayMode.UpdateBalance);
                    break;
                case MainDisplayMode.LoggedOut:
                    pnlLogin.Show();
                    pnlGameSelect.Hide();
                    pnlNavigation.Enabled = false;
                    statusBarPanelCurrency.Text = string.Empty;
                    statusBarPanelVerbose.Text = "Please login";
                    tbPassword.Text = string.Empty;
                    pnlBetManagerButtons.Enabled = false;
                    _SetRightHandDisplay(RightHandDisplayMode.About);
                    break;
                case MainDisplayMode.SelectGame:
                    pnlPostBet.Clear();
                    pnlGameSelect.Show();
                    pnlBetManagerButtons.Enabled = false;
                    break;
                case MainDisplayMode.UpdateBalance:
                    lblBalance.Text = String.Format("Balance: {0}", Util.FormatMoney(m_AccountSnapshot.availableToBetBalance));
                    break;
                case MainDisplayMode.ViewingGame:
                    _SetRightHandDisplay(RightHandDisplayMode.Rules);
                    pnlGameSelect.Hide();
                    pnlBetManagerButtons.Enabled = true;
                    break;
            }
        }

        private void _SetRightHandDisplay(RightHandDisplayMode displayMode)
        {
            switch (displayMode)
            {
                case RightHandDisplayMode.About:
                    ctlAbout.Show();
                    pnlRules.Hide();
                    pnlPostBet.Hide();
                    pnlMyBets.Hide();
                    break;
                case RightHandDisplayMode.Rules:
                    ctlAbout.Hide();
                    pnlRules.Show();
                    pnlPostBet.Hide();
                    pnlMyBets.Hide();
                    break;
                case RightHandDisplayMode.Bets:
                    ctlAbout.Hide();
                    pnlRules.Hide();
                    pnlPostBet.Show();
                    pnlMyBets.Hide();
                    break;
                case RightHandDisplayMode.MyBets:
                    ctlAbout.Hide();
                    pnlRules.Hide();
                    pnlPostBet.Hide();
                    pnlMyBets.Show();
                    break;
            }
        }

        private void _ShowGame(long channelID, string gameName)
        {
            GameType gameType = GameType.NONE;
            switch (gameName)
            {
                case "BLACKJACK":
                    gameType = GameType.BLACKJACK;
                    break;
                case "POKER":
                    gameType = GameType.TEXAS;
                    break;
                case "OMAHA_POKER":
                    gameType = GameType.OMAHA;
                    break;
                case "BACCARAT":
                    gameType = GameType.BACCARAT;
                    break;
                case "HILO":
                    gameType = GameType.HILO;
                    break;
            }

            if (gameType != GameType.NONE)
            {
                // hide active game
                if (m_CurrentlyViewing != GameType.NONE)
                {
                    this.Controls.Remove((UserControl)m_ActiveGameControl);
                    UserControl uc = (UserControl)m_ActiveGameControl;
                    uc.Dispose();
                }

                // init new control
                switch (gameType)
                {
                    case GameType.BLACKJACK:
                        m_ActiveGameControl = new BlackjackView(this);
                        break;
                    case GameType.TEXAS:
                        m_ActiveGameControl = new TexasHoldemView(this);
                        break;
                    case GameType.OMAHA:
                        m_ActiveGameControl = new OmahaView(this);
                        break;
                    case GameType.BACCARAT:
                        m_ActiveGameControl = new BaccaratView(this);
                        break;
                    case GameType.HILO:
                        m_ActiveGameControl = new HiLoView(this);
                        break;
                }

                m_ActiveGameControl.ShowBetPlacement += new ShowBetPlaceHandler(LoadBetsPanel);
                m_ActiveGameControl.ClearBets += new ClearBetsHandler(ActiveGameControl_ClearBets);
                this.Controls.Add((UserControl)m_ActiveGameControl);

                m_CurrentlyViewing = gameType;
                m_CurrentChannelId = channelID;

                _SetDisplay(MainDisplayMode.ViewingGame);
                _LoadGameRules(gameType);

                // load current unmatched bets on this channel if any
                pnlPostBet.CurrentChannelID = channelID;
                pnlPostBet.Initialise();
            }

            // kill current update thread
            if (m_GameUpdateThread != null)
            {
                m_GameUpdateThread.Abort();
                m_GameUpdateThread = null;
            }

            // begin background thread to update games
            GameUpdateThread threadParams = new GameUpdateThread(m_Adapter, channelID, this);
            m_GameUpdateThread = new Thread(new ThreadStart(threadParams.Run));
            m_GameUpdateThread.IsBackground = true;
            m_GameUpdateThread.Name = "GameUpdateThread";
            m_GameUpdateThread.Start();
        }

        // display game rules data
        private void _LoadGameRules(GameType gameType)
        {
            Stream s = null;
            Assembly a = Assembly.Load("Betfair.Gamex.API.UberClient");
            switch (gameType)
            {
                case GameType.TEXAS:
                    s = a.GetManifestResourceStream("Betfair.Gamex.API.UberClient.Resources.Files.pokerRules.txt");
                    break;
                case GameType.OMAHA:
                    s = a.GetManifestResourceStream("Betfair.Gamex.API.UberClient.Resources.Files.omahaRules.txt");
                    break;
                case GameType.BLACKJACK:
                    s = a.GetManifestResourceStream("Betfair.Gamex.API.UberClient.Resources.Files.blackjackRules.txt");
                    break;
                case GameType.BACCARAT:
                    s = a.GetManifestResourceStream("Betfair.Gamex.API.UberClient.Resources.Files.bacarratRules.txt");
                    break;
                case GameType.HILO:
                    s = a.GetManifestResourceStream("Betfair.Gamex.API.UberClient.Resources.Files.hiLoRules.txt");
                    break;
            }

            if (s != null)
            {
                using (StreamReader sr = new StreamReader(s))
                {
                    rtbRules.Text = sr.ReadToEnd();
                }
            }
        }

        /// <summary>
        /// Called from background update thread
        /// </summary>
        /// <param name="snapshot"></param>
        public void UpdateGameData(channelSnapshot snapshot)
        {
            try
            {
                _SafeSetStatusAction("Refreshing game data...");
                BeginInvoke(new UpdateChannelSnapshot(_UpdateChannelData), new object[] { snapshot });
            }
            catch (ThreadAbortException)
            {
                // do nothing for these
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error: " + ex.Message + "\n\n" + ex.StackTrace);
            }
            finally
            {
                _SafeSetStatusAction("Idle");
            }
        }

        /// <summary>
        /// Update current game movie
        /// </summary>
        /// <param name="snapshot"></param>
        private void _UpdateChannelData(channelSnapshot snapshot)
        {
            m_ActiveGameControl.CurrentChannelSnapshot = snapshot;
            pnlPostBet.CurrentChannelID = snapshot.channel.id;

            //update amount matched
            lblTotalMatched.Text = String.Format("Total amount matched: {0}", Util.FormatMoney(_CalculateAmountMatched(snapshot)));

            //update commission rate on this market...
            lblCommissionRate.Text = String.Format("Market commission: {0:0.00}%", snapshot.channel.game.markets.market[0].commissionRate);
        }

        /// <summary>
        /// Calculate amount matched on current channel (all markets)
        /// </summary>
        /// <param name="snapshot"></param>
        /// <returns></returns>
        private double _CalculateAmountMatched(channelSnapshot snapshot)
        {
            double total = 0;
            for (int n = 0; n < snapshot.channel.game.markets.market.Length; n++)
            {
                marketSnapshot ms = snapshot.channel.game.markets.market[n];
                if (ms.selections.selection != null)
                {
                    for (int i = 0; i < ms.selections.selection.Length; i++)
                    {
                        total += ms.selections.selection[i].amountMatched;
                    }
                }
            }

            return total;
        }

        public void LoadBetsPanel(Bet bet)
        {
            _SetRightHandDisplay(RightHandDisplayMode.Bets);
            if (bet != null)
            {
                pnlPostBet.AddBet(bet);
            }
        }
        #endregion

        #region Events
        private void linkLbCreateAccount_LinkClicked(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e)
        {
            _GoToUrl("http://www.betfairgames.com");
        }

        private void menuExit_Click(object sender, System.EventArgs e)
        {
            Application.Exit();
        }

        private void menuItemGotoBFG_Click(object sender, System.EventArgs e)
        {
            _GoToUrl("http://www.betfairgames.com");
        }

        private void tbUsername_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
        {
            if (Convert.ToInt32(e.KeyChar) == 13)
            {
                Login_Click(this, null);
            }
        }

        private void tbPassword_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
        {
            if (Convert.ToInt32(e.KeyChar) == 13)
            {
                Login_Click(this, null);
            }
        }

        private void btnTransfer_Click(object sender, System.EventArgs e)
        {
            FundsTransfer fft = new FundsTransfer(m_Adapter, this);
            fft.ShowDialog();
        }

        private void btnViewGames_Click(object sender, System.EventArgs e)
        {
            if (m_LoggedIn)
            {
                _SetDisplay(MainDisplayMode.SelectGame);
                _LoadAvailableGames();
            }
        }

        private void btnAccountStatement_Click(object sender, System.EventArgs e)
        {
            AccountStatement accStatement = new AccountStatement(m_Adapter);
            accStatement.ShowDialog();
        }

        private void btnBetHistory_Click(object sender, System.EventArgs e)
        {
            BetHistory betHistory = new BetHistory(m_Adapter);
            betHistory.ShowDialog();
        }

        private void GameLink_Clicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            //what game type?
            string[] gameInfo = e.Link.LinkData.ToString().Split('|');
            if (gameInfo.Length == 2)
            {
                _ShowGame(long.Parse(gameInfo[0]), gameInfo[1]);
            }
        }

        private void menuItemAvailableGames_Click(object sender, System.EventArgs e)
        {
            if (m_LoggedIn)
            {
                _SetDisplay(MainDisplayMode.SelectGame);
                _LoadAvailableGames();
            }
        }

        private void btnLogout_Click(object sender, System.EventArgs e)
        {
            m_AccountSnapshot = null;
            m_LoggedIn = false;
            _SetDisplay(MainDisplayMode.LoggedOut);
        }

        public void BalanceRefresh_Click(object sender, System.EventArgs e)
        {
            _LoadAccountDetails();
        }

        private void btnMyBets_Click(object sender, System.EventArgs e)
        {
            // get the current matched bets
            pnlMyBets.Bets = m_Adapter.GetBetSnapshot(BetSnapshotBetStatus.MATCHED, Convert.ToInt32(m_CurrentChannelId), BetSnapshotOrderBy.placedDate);
            _SetRightHandDisplay(RightHandDisplayMode.MyBets);
        }

        private void btnBets_Click(object sender, System.EventArgs e)
        {
            LoadBetsPanel(null);
        }

        private void menuAbout_Click(object sender, System.EventArgs e)
        {
            _SetRightHandDisplay(RightHandDisplayMode.About);
        }

        private void btnRules_Click(object sender, System.EventArgs e)
        {
            _SetRightHandDisplay(RightHandDisplayMode.Rules);
        }

        /// <summary>
        /// Clears all the bets currently displayed.  This will typically
        /// happen when the market is no longer active
        /// </summary>
        private void ActiveGameControl_ClearBets()
        {
            pnlPostBet.Clear();
        }

        /// <summary>
        /// Display a message box for any exceptions which have went unhandled
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
        {
            string message = string.Format("An error has occurred: {0}{1}", Environment.NewLine, e.Exception.ToString());
            MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
        #endregion

        #region helpers
        private void _GoToUrl(string url)
        {
            using (System.Diagnostics.Process p = new System.Diagnostics.Process())
            {
                p.StartInfo.FileName = url;
                p.Start();
            }
        }

        private void _ProcessGeneralException(Exception ex)
        {
            MessageBox.Show("An error occurred:\n\n" + ex.Message + "\n\n" + ex.StackTrace);
        }
        #endregion
    }
}
