﻿using UnityEngine;

/// <remarks>
///     Online docs: http://dev.id.net/docs/unity/
///     IDnet sdk version: IDNET-Unity3d_V3.0.9
///     Live IDnet Unity Sample scene: http://apps.id.net/games/idnet_unity_sample_scene
///     Live game with IDnet sdk: Bike Riders:- http://www.y8.com/games/bike_riders
///     Some Api's have callbacks,you just have to write your code inside callbacks(=> lambda expressions).
///     Debug's in Callbacks have been written in api's Eg. /* Callback: Autologin Success , Login Success */
/// </remarks>
/// <summary>
///     This contains working examples for each API function.
///     Each Api function has a detailed XML commenting and instructions for use.
///     Idnet Api uses C# Actions (events) for async Www responses.
///     If you do not pass in a named / anonymous method in the callbacks, Idnet.cs will throw the exception.
///     If you do pass in a callback, make sure you handle the errors.
/// </summary>
public class IdnetSample : MonoBehaviour
{
    private const int BORDER = 10;
    private const int BORDER_X2 = BORDER * 2;
    private const int BOX_WIDTH = 350;

    private const int BOX_WIDTH_SMALL = 400;
    private const int BOX_HEIGHT_SMALL = 90;

    private const float BUTTON_HEIGHT = 19;
    private bool _allowErroneousApiCalls;
    private bool _minimized;

    private void Awake()
    {
        /// Basic Useful Notes:
        // For WebGL/Html5,Set "Enable Exceptions" in Build Settings/Publishing Settings to "Explicitly Thrown Exceptions Only".
        // Side Note: To close any of the opened Idnet GUI windows through code(& not using close button), use Idnet.I.CloseGui();	
        // Important: At any point,in order to check if user logged in to IDnet sdk,use if(Idnet.User.LoggedIn()).
        // Before postscores and leaderboard apis,make sure you create Table name as explained here http://dev.id.net/docs/unity/table-setup

        // Important: Sample App-Id(55961a8be694aa9957000288) is for testing purposes,create your application & Get {app-id} here https://account.y8.com/applications
        Idnet.I.Initialize("55961a8be694aa9957000288", false);

        // Mandatory for all IDnet games.
        AutoLoginGUIWindowCode();
    }


    //****************************************************AUTOLOGIN***************************************************//
    /// <summary>
    ///     Automatically logs user in to IDnet in the game,if user logged on to https://id.net/ website.
    ///     Should be the first api call, just after initializing id.net in your game.
    /// </summary>
    /// <remarks>
    ///     Use Autologin api only in first scene of your game in Start() or Awake(),and only once,just after you initialise the sdk.
    ///     After autologin callback(failed or successful),show the Online Save - Local Save screen as explained here http://dev.id.net/docs/unity/saving/
    ///     In its Callback,you will get user's Nickname,and you could show it in game.
    ///     If autologin is succesfull,Idnet.User.LoggedIn() with return "true".
    /// </remarks>
    private static void AutoLoginGUIWindowCode()
    {
        Idnet.I.AutoLogin((user, autoLoginException) =>
        {
            if (autoLoginException != null)
            {
#if UNITY_EDITOR
                Debug.LogError("Autologin does not work in the Unity Editor,try it browser!");
#else 
                // Callback: Autologin failed,show the OnlineSave-LocalSave setup screen http://dev.id.net/docs/unity/saving/
                Debug.Log("Autologin failed,probably user not logged-in to https://account.y8.com");
#endif
            }
            else
            {
                if (Idnet.User.LoggedIn())
                {
                    // Callback: Autologin Success,you will get user's nickname in callback.
                    // Show the OnlineSave-LocalSave setup screen http://dev.id.net/docs/unity/saving/ with user's name.
                    Debug.Log("Auto login success. " + "Nickname " + Idnet.User.Current.Nickname);
                }
            }
        });
    }


    //*************************************************Login GUI window***********************************************//
    /// <summary>
    ///     Opens IDnet Gui Login window,here user's can enter their email and password to login to IDnet.
    ///     If user already logged in,Login Gui window wont open.
    /// </summary>
    /// <remarks>
    ///     After login is succesfull,you will get user's nickname in callback,and you can show it in game.
    ///     If user already logged in to IDnet sdk,Login Gui window wont open,show user's Nickname instead of Login button
    ///     here.
    ///     Important: At any point,in order to check if user logged in to IDnet,use if(Idnet.User.LoggedIn()).
    /// </remarks>
    private static void LoginGUIWindowCode()
    {
        Idnet.I.Login(loginRegisterException =>
        {
            if (Idnet.User.LoggedIn())
            {
                // Callback: Login Success,you will get user's nickname in callback.
                Debug.Log("User logged in: " + "Nickname " + Idnet.User.Current.Nickname);
            }
        });
    }


    //*************************************************Register GUI window********************************************//
    /// <summary>
    ///     Opens IDnet Gui Register window,here user's can enter their email,nicakname & password.
    ///     If user already logged in,Register Gui window wont open.
    /// </summary>
    /// <remarks>
    ///     Once Registeration is succesfull,IDnet sdk will automatically perform Login operation thereafter.
    ///     If user already logged in to IDnet sdk,Register Gui window wont open,show user's Nickname instead of Register
    ///     button here.
    /// </remarks>
    private static void RegisterGUIWindowCode()
    {
        Idnet.I.Register(loginRegisterException =>
        {
            if (Idnet.User.LoggedIn())
            {
                // Callback: Register & hence Login Success,you will get user's nickname in callback.
                Debug.Log("User logged in: " + "Nickname " + Idnet.User.Current.Nickname);
            }
        });
    }


    //*************************************************User's NickName************************************************//
    /// <summary>
    ///     User's Nickname from IDnet.
    ///     Nickname will only be available after user gets logged-in to IDnet.(by autologin/login/regsiter)
    /// </summary>
    private static void ShowNickname()
    {
        // Call it in Update() or OnGUI or api callbacks.
        if (Idnet.User.LoggedIn())
        {
            Debug.Log("Welcome: " + Idnet.User.Current.Nickname);
        }
        else
        {
            Debug.Log("Not logged-in to idnet");
        }
    }


    //**********************************************Profile GUI window************************************************//
    /// <summary>
    ///     Logged-in user's details Gui window,this api is not used normally.
    ///     This Profile window has Logout button too,that logs out user from IDnet.
    /// </summary>
    private static void ProfileExampleCode()
    {
        if (!Idnet.User.LoggedIn()) return;
        Idnet.I.Profile();
    }


    //**************************************************Direct Logout*************************************************//
    /// <summary>
    ///     Logout user from IDnet.
    /// </summary>
    private static void LogoutExampleCode()
    {
        if (!Idnet.User.LoggedIn()) return;
        Idnet.I.Logout();
    }


    //****************************************PostScore to idnet leaderboard******************************************//
    /// <summary>
    ///     This api simply post score to IDnet leaderboards(corresponding to a table).
    ///     IMPORTANT: Firstly you need to create "Table" name(eg. "LEADERBOARD") as explained here http://dev.id.net/docs/unity/table-setup
    ///     To directly go to "table creation" page(make sure you are logged-in to id.net website in browser), 
    ///     pass your {App-id} here https://account.y8.com/applications/{App-id}/playtomic_tables
    ///     If you want to use it with callbacks,check example method PostScoreWithCallbackExampleCode().
    /// </summary>
    /// <remarks>
    ///     Reverse Leaderboards,low to high scores(rarely used): Idnet.I.ReverseLeaderboard=true; just before posting score
    ///     and Leaderboard Gui code.
    ///     "Timer" leaderboards(for racing games) API explained later in this script.
    ///     NOTE: NO NEED for Logged-In user check here, i.e  if (!Idnet.User.LoggedIn ())  return; is not needed before
    ///     posting scores.
    /// </remarks>
    private static void PostScoreExampleCode()
    {
        //Score posted must be an integer.
        var exampleScore = 1000 + Random.Range(0, 1000);
        // "LEADERBOARD" is the Table name you created http://dev.id.net/docs/unity/table-setup
        Idnet.I.PostHighscore(exampleScore, "LEADERBOARD");
    }


    //********************************PostScore with callback(use if you need callback)*******************************//
    /// <summary>
    ///     This api simply post score to IDnet leaderboard and you will receive a callback after post score is successfull.
    ///     IMPORTANT: Create "Table" name (eg. LEADERBOARD) as explained here http://dev.id.net/docs/unity/table-setup
    ///     SubmitHighScore Button(normally present on gameover/level clear menu) already using this callback.
    ///     NOTE: NO NEED for Logged-In user check here, i.e  if (!Idnet.User.LoggedIn ())  return; is not needed before
    ///     posting scores.
    /// </summary>
    private static void PostScoreWithCallbackExampleCode()
    {
        //Score posted must be an integer.
        var exampleScore = 1000 + Random.Range(0, 1000);
        // "LEADERBOARD" is the Table name you created http://dev.id.net/docs/unity/table-setup
        Idnet.I.PostHighscore(exampleScore, "LEADERBOARD", (score, postHighscoreException) =>
        {
            if (postHighscoreException == null)
            {
                // Callback: Post Score succesfull here,you can show leaderboard here.
                Debug.Log("Score posted succesfully");
            }
            else
            {
                Debug.LogError("Posting Score failed " + postHighscoreException);
            }
        });
    }


    //***************************************************Leaderboard**************************************************//
    /// <summary>
    ///     This api simply opens IDnet leaderboard GUI window.
    ///     IMPORTANT: Create "Table" name (eg. LEADERBOARD) as explained here http://dev.id.net/docs/unity/table-setup
    /// </summary>
    /// <remarks>
    ///     Reverse Leaderboards,low to high scores(rarely used): Idnet.I.ReverseLeaderboard=true; just before Leaderboard Gui
    ///     code.
    ///     "Timer" leaderboards(for racing games) API explained later in this script.
    ///     NOTE: NO NEED for Logged-In user check here, i.e  if (!Idnet.User.LoggedIn ())  return; is not needed before
    ///     Leaderboard GUI api.
    /// </remarks>
    private static void LeaderboardExampleCode()
    {
        // "LEADERBOARD" is the Table name you created http://dev.id.net/docs/unity/table-setup
        Idnet.I.Leaderboard("LEADERBOARD");
    }


    //*************************Submit Score and hence open leaderboard window(on callback)****************************//
    /// <summary>
    ///     "Submit Score" Button code,this API post scores and hence open leaderboard window after post score is
    ///     succesfull(Callback).
    ///     For Guest users(user not logged in to IDnet),it will automatically open Login GUI window.
    ///     Used with SubmitScore button present on Gameover/LevelClear.
    ///     IMPORTANT: Create "Table" name (eg. LEADERBOARD) as explained here http://dev.id.net/docs/unity/table-setup
    /// </summary>
    /// <remarks>
    ///     This "Submit Score" button should be present/used on gameover screen(if you are not automatically posting scores on
    ///     gameover using PostScore API).
    ///     For Alterations to this api,create your own Submit score api using PostScore callback
    ///     "PostScoreWithCallbackExampleCode()" or just open Idnet.cs and find SubmitHighScore() method and alter it.
    ///     NOTE: NO NEED for Logged-In user check here, i.e  if (!Idnet.User.LoggedIn ())  return; is not needed before submit
    ///     score api.
    /// </remarks>
    private static void SubmitScoreExampleCode()
    {
        //exampleScore,Score posted must be an integer.
        var exampleScore = 1001 + Random.Range(0, 1000);
        // "LEADERBOARD" is the Table name you created http://dev.id.net/docs/unity/table-setup
        Idnet.I.SubmitHighScore(exampleScore, "LEADERBOARD");
    }


    //**************************************Get User's BestScore from leaderboard*************************************//
    /// <summary>
    ///     Get BestScore of current logged-in user from IDnet leaderboard.
    ///     Dont use this API in Update() or OnGUI() obviously.
    /// </summary>
    private static void GetBestScoreFromLeaderboard()
    {
        // "LEADERBOARD" is the Table name you created http://dev.id.net/docs/unity/table-setup
        Idnet.I.GetBestScore("LEADERBOARD", bestScoreException =>
        {
            if (bestScoreException == null)
            {
                // Callback: Successfully retrieved BestScore of user.
                Debug.Log("Idnet Best Score " + Idnet.User.Current.BestScore);
            }
        });
    }


    //***********************************SAVE Progress-Data of user to idnet server***********************************//
    /// <summary>
    ///     Save Api post user's progress on IDnet using a 'key' and is retrieved with Get Api using the same 'key'.
    ///     You can post "Strings","Vectors","Int","Arrays","Class" etc(Get Api will need the'type' you used for posting).
    ///     With this api,Players can login from any site and start where they left off with online saves.
    ///     Post user's progress at locations like "Gameover/Level Clear/ShopPurchases/CheckPoints etc".
    ///     Live Game Example: http://www.y8.com/games/bike_riders
    ///     We suggest you to use a "Class" for saving user's progress,as normally we have a lot of user's data to be
    ///     saved/retrieved with a "single key & in a single api call".
    ///     "UserProgressExampleData" Class has been created as a demo for you,just vary the variables & constructor of
    ///     that class as per your needs and use it in Post/Get api.
    ///     Post user's data only in Online Save mode & not Local Save.
    /// </summary>
    /// <remarks>
    ///     Only use this Save API,if user selected Online Save mode,and not Local save.
    ///     Do check OnlineSaveExampleCode & LocalSaveExampleCode() methods,these are the example codes for Online Save and
    ///     Local Save button clicks.
    ///     Online Docs: http://dev.id.net/docs/unity/online-save/
    /// </remarks>
    private static void SaveUserDataExampleCode()
    {
        if (!Idnet.User.LoggedIn()) return;

        //Example 1: Posting a String.
        Idnet.I.Post("MessageOfTheDay", "Hello World");

        //Example 2: Posting Vectors
        Idnet.I.Post("VectorPos", new Vector3(1.2f, 1.2f, 1.2f));

        //Example 2: Posting Arrays
        Idnet.I.Post("ExampleArray", new string[] {"Idnet", "Unity", "Games"});

        // Posting a Class
        // Mostly used type is "Class",as normally,there's a lot of user data to be posted with a 'single key and single api call'.

        //Example 3: Posting Custom class1 "UserProgressExampleData",Create your own class as per your usage,mostly used type for posting user's progress.
        Idnet.I.Post("UserProgress", new UserProgressExampleData(5, 545, 3, 20.5f, "Big Character", true));
    }


    /// <summary>
    ///     Post data and recieve its callback,once the operiation is finished.
    /// </summary>
    private static void SaveUserDataWithCallBackExampleCode()
    {
        // Using Callbacks.
        // Example 1: Post a String.
        Idnet.I.Post<string>("MessageOfTheDay", "Hello World", (data, postDataException) =>
        {
            if (postDataException == null)
            {
                Debug.Log("Data posted succesfully ");
            }
            else
            {
                Debug.LogError("Posting Data failed " + postDataException);
                // "not_saved" as postDataException means you are saving the same "key" twice within a second.
            }
        });


        // Example 2: Posting Arrays
        Idnet.I.Post<int[]>("ExampleArray", new int[] {1, 2, 3}, (data, postDataException) =>
        {
            if (postDataException == null)
            {
                Debug.Log("Data posted succesfully");
            }
            else
            {
                Debug.LogError("Posting Data failed " + postDataException);
                // "not_saved" as postDataException means you are saving the same "key" twice within a second.
            }
        });


        // Example 3: Posting Custom class1 "UserProgressExampleData"
        Idnet.I.Post<UserProgressExampleData>("UserProgress",
            new UserProgressExampleData(5, 545, 3, 20.5f, "Big Character", true), (data, postDataException) =>
            {
                if (postDataException == null)
                {
                    Debug.Log("Data posted succesfully");
                }
                else
                {
                    Debug.LogError("Posting Data failed " + postDataException);
                    // "not_saved" as postDataException means you are saving the same "key" twice within a second.
                }
            });
    }

    //*************************************************GET Saved Progress-Data****************************************//
    /// <summary>
    ///     This Get Api retrieves all saved user's data from IDnet server using the same 'key' and 'type  you used for
    ///     posting.(using Post api like above).
    ///     You can Get "Strings","Vectors","Int","Arrays","Class"(the 'type' should be same you used for posting user's data).
    ///     Get all saved progress using Get api on "Online Save" button click and hence Save retrieved "values"(like
    ///     keyValuePair.Value) in local variables/PlayerPrefs(and hence load level).
    ///     "UserProgressExampleData" Class has been created as a demo for you,just vary the variables & constructor in
    ///     that class as per your needs and use it in Post/Get api.
    /// </summary>
    /// <remarks>
    ///     Live Game Example: http://www.y8.com/games/bike_riders
    ///     Important: Get all the saved data on Online Save button click(this Online Save button should be on start of game
    ///     like in live game example).
    ///     Do check OnlineSaveExampleCode & LocalSaveExampleCode() methods,these are the example codes for Online Save and
    ///     local Save button clicks.
    ///     Online Docs: http://dev.id.net/docs/unity/online-load/
    /// </remarks>
    private static void GetUserDataExampleCode()
    {
        if (!Idnet.User.LoggedIn()) return;

        //Example 1: Get a "String" 
        Idnet.I.Get<string>("MessageOfTheDay", (keyValuePair, getException) =>
        {
            if (getException != null)
            {
                Debug.Log("No Data returned for the key '" + keyValuePair.Key + "'");
                // Callback: Get Data failed,probably no data available with this key on server,debug "getException" for the more details.
                // "Key not found" as a "getException" means server do not contains any data corresponding to this key. 
            }
            else
            {
                Debug.Log("Retrieved '" + keyValuePair.Key + "' with value '" + keyValuePair.Value);
                // Callback: Data retrieved sucessfully,write your code here like saving to Playerprefs/variables,hence load game level.

                /* Example Usage:
				  PlayerPrefs.SetString("Message",keyValuePair.Value);
				  Application.LoadLevel("Idnet Sample Scene"); */
            }
        });


        //Example 2: Get a "Vector"
        Idnet.I.Get<Vector3>("VectorPos", (keyValuePair, getException) =>
        {
            if (getException != null)
            {
                Debug.Log("No Data returned for the key '" + keyValuePair.Key + "'");
                // Callback: Get Data failed,probably no data available with this key on server.
            }
            else
            {
                Debug.Log("Retrieved '" + keyValuePair.Key + "' with value '" + keyValuePair.Value + "'.");
                // Callback: Data retrieved sucessfully,write your code here like saving to Playerprefs/variables,hence load game level.
            }
        });

        //Example 2: Get an "Array"
        Idnet.I.Get<string[]>("ExampleArray", (keyValuePair, getException) =>
        {
            if (getException != null)
            {
                Debug.Log("No Data returned for the key '" + keyValuePair.Key + "'");
                // Callback: Get Data failed,probably no data available with this key on server.
            }
            else
            {
                string ArrayValues = string.Empty;
                //keyValuePair.Value is an array you posted(string[] in this case)
                foreach (var value in keyValuePair.Value)
                {
                    //Debug.Log("Array values "+value);
                    ArrayValues += " | " + value;
                }
                Debug.Log("Retrieved '" + keyValuePair.Key + " with values " + ArrayValues);
            }
        });

        // Example 3: Get a "Class"(Mostly used type)
        // "UserProgressExampleData" created below,create your own class.
        Idnet.I.Get<UserProgressExampleData>("UserProgress", (keyValuePair, getException) =>
        {
            if (getException != null)
            {
                Debug.Log("No Data returned for the key '" + keyValuePair.Key + "'");
                // Callback: Get Data failed,probably no data available with this key on server.
            }
            else
            {
                Debug.Log("Retrieved '" + keyValuePair.Key + "' with value '" + keyValuePair.Value);
                // Callback: Data retrieved sucessfully,write your code here,like saving to Playerprefs/variables & hence load game level.

                /* Example: 
				  PlayerPrefs.SetInt("Life",keyValuePair.Value.Lives);
				  PlayerPrefs.SetInt("TotalCoins",keyValuePair.Value.TotalCoins);
				  Application.LoadLevel("Idnet Sample Scene"); */

#if UNITY_EDITOR
                Debug.Log("Example UserProgress: "
                          + "\t" + keyValuePair.Value.NumOfLevelsUnlocked
                          + "\t" + keyValuePair.Value.TotalCoins
                          + "\t" + keyValuePair.Value.Lives
                          + "\t" + keyValuePair.Value.MaxDistanceTravelled
                          + "\t" + keyValuePair.Value.UnlockedCharacterName
                          + "\t" + keyValuePair.Value.IsTutorialCompleted
                );
#endif
            }
        });
    }


    //**************************************Example "Class" used for Post/Get API*************************************//
    /// <summary>
    ///     Example "Class" for Post/Get data.
    ///     Post/Get,a lot of user's data with a single key using a Class.
    ///     Create your own custom class,as per your own usage.
    ///     Just change/delete variables in class below and in constructor,as per your own user data to be posted.
    /// </summary>
    internal class UserProgressExampleData
    {
        public bool IsTutorialCompleted;
        public int Lives;
        public float MaxDistanceTravelled;
        public int NumOfLevelsUnlocked;
        public int TotalCoins;
        public string UnlockedCharacterName;

        public UserProgressExampleData(int numlevels, int totalcoins, int lives, float maxdistance,
            string charactername,
            bool istutorialcompleted)
        {
            NumOfLevelsUnlocked = numlevels;
            TotalCoins = totalcoins;
            Lives = lives;
            MaxDistanceTravelled = maxdistance;
            UnlockedCharacterName = charactername;
            IsTutorialCompleted = istutorialcompleted;
        }
    }


    //**************************************Example2 "Class" used for Post/Get API*************************************//
    /// <summary>
    ///     Example2 "Class" for Post/Get data.
    /// </summary>
    internal class UserProgressExample2
    {
        public int Coins;
        public string Name;
        public bool Showtutorial;


        public UserProgressExample2(int coins, bool showtutorial, string name)
        {
            Coins = coins;
            Showtutorial = showtutorial;
            Name = name;
        }
    }


    //**********************************************Show Achievements window******************************************//
    /// <summary>
    ///     This Api opens IDnet Achievement GUI window(List all achievements in the game,both locked and unlocked ones)
    ///     Creating achievements on IDnet dashboard: http://dev.id.net/docs/unity/achievements/
    ///     For creating Custom Achievements(Achievements with your own UI),please have a look to
    ///     "CustomAchievementExample.cs".
    /// </summary>
    /// <remarks>
    ///     Pass your {app-id} here 'https://account.y8.com/applications/{app-id}/achievements' ,to directly go to achievement
    ///     page.
    ///     NOTE: NO NEED for Logged-In user check here, i.e  if (!Idnet.User.LoggedIn ())  return; is not needed before
    ///     Achievements Gui Api.
    /// </remarks>
    private void ListAchievementsExampleCode()
    {
        Idnet.I.ListAchievements();
    }


    //************************************************Unlock Achievements*********************************************//
    /// <summary>
    ///     This Api unlock achievements,using Achievement "Name" and "Unlock Key".
    ///     Achievements "Name" and "Unlock Key" are obtained when you create achievements on IDnet dashboard.
    /// </summary>
    /// <remarks>
    ///     Online Docs: http://dev.id.net/docs/unity/achievements-unlock/
    ///     NOTE: NO NEED for Logged-In user check here, i.e  if (!Idnet.User.LoggedIn ())  return; is not needed before Unlock
    ///     Achievements Api.
    /// </remarks>
    private void UnlockAchievementExampleCode()
    {
        Idnet.AchievementUnlocker au;
        //achievement to be unlocked.
        au = new Idnet.AchievementUnlocker("Unity Test Achievement 1", "150e06bccaaa9d8422d9");
        // "Unity Test Achievement 1" is the "Name" of achievement that you create at "https://account.y8.com/applications/{app-id}/achievements" (Pass your app-id here.)
        // "4b51803aac54decb4d7b" is the "Unlock Key" you get here "https://account.y8.com/applications/{app-id}/achievements" (Pass your app-id here)

        Idnet.I.UnlockAchievement(au);
    }


    //*******************************************Unlock Achievements with callbacks*****************************************//
    /// <summary>
    ///     This Api unlock achievements,and you will get a callback after achievement is successfully unlocked.
    ///     Achievements "Name" and "Unlock Key" are obtained when you create achievements on IDnet dashboard.
    /// </summary>
    private void UnlockAchievementCallbackExampleCode()
    {
        Idnet.AchievementUnlocker au;
        //achievement to be unlocked.
        au = new Idnet.AchievementUnlocker("Unity Test Achievement 1", "150e06bccaaa9d8422d9");
        // "Unity Test Achievement 1" is the "Name" of achievement that you create at "https://account.y8.com/applications/{app-id}/achievements" (Pass your app-id here.)
        // "4b51803aac54decb4d7b" is the "Unlock Key" you get here "https://account.y8.com/applications/{app-id}/achievements" (Pass your app-id here)

        Idnet.I.UnlockAchievement(au, unlockAchievementsException =>
        {
            if (unlockAchievementsException == null)
            {
                // Callback: Achievement Unlocked sucessfully.
                Debug.Log("Achievement unlocked sucessfully: " + "\n" + au.Name + "\n" + au.Key);
            }
            else
            {
                // Callback: Achievement unlocking failed.
                Debug.LogError("Unlock Achievements Failed: " + unlockAchievementsException);
            }
        });
    }


    //*******************************************Delete/Reset user's progress*****************************************//
    /// <summary>
    ///     Used to Reset progress of user.
    /// </summary>
    private static void DeleteUserDataExampleCode()
    {
        if (!Idnet.User.LoggedIn()) return;
        Idnet.I.DeleteKey("MessageOfTheDay");
    }


    //****************************************"Online Save" Button Click Code*****************************************//
    /// <summary>
    ///     Live Game Visualisation: http://www.y8.com/games/bike_riders
    ///     Games should have 2 modes: "Online Save" and "Local Save",these buttons should be on the first screen of the game.
    ///     **Online-Save Concept**
    ///     ==> If user is Not logged-in to IDnet(i.e Idnet.User.LoggedIn()==false),and clicks on Online Save button,open IDnet
    ///     Login Gui window and after login is successfull "Get" all data from server using Get api(Login API callback) and
    ///     save to unity variables/playerprefs.
    ///     ==> If user already logged in to idnet using autologin or whatever means(i.e Idnet.User.LoggedIn()==true),just
    ///     "Get" all saved data using "Get" api.
    ///     **Local Save Concept**
    ///     Just load the game level normally,no need to Use "Get" api.
    /// </summary>
    private void OnlineSaveExampleCode()
    {
        // Let IDnet know your current game mode.
        Idnet.I.CurrentMode = Idnet.GameMode.OnlineSave;

        if (!Idnet.User.LoggedIn())
        {
            //If user not logged-in,open Login window and hence retrieve all saved data using Get API,if login is successfull.
            Idnet.I.LoginRegister(loginRegisterException =>
            {
                if (Idnet.User.LoggedIn())
                {
                    // User succesfully logged-in here.
                    Debug.Log("User logged in: " + "Nickname " + Idnet.User.Current.Nickname);
                    //Get all saved from server and hence load the level,as done in OnlineSaveGetDataExample();
                    OnlineSaveGetDataExample();
                }
            });
        }
        else
        {
            // User already logged-in,using cached-login(PlayerPrefs) or autologin,so Get all saved from server and hence load the level,as done in OnlineSaveGetDataExample().
            OnlineSaveGetDataExample();
        }
    }


    //****************************************"Local Save" button Example Code****************************************//
    /// <summary>
    ///     **Local Save Concept**
    ///     Just load the game level normally,no need to Use "Get" api.
    /// </summary>
    private void LocalSaveExampleCode()
    {
        //Set Current Selected Mode of user.
        Idnet.I.CurrentMode = Idnet.GameMode.LocalSave;
        // Play the game normally,just load the gameplay level here.
    }


    //*************************************"Online Save" Get-Data Example Code****************************************//
    /// <summary>
    ///     Online Save Get-Data Example Code.
    /// </summary>
    private void OnlineSaveGetDataExample()
    {
        Idnet.I.Get<UserProgressExampleData>("UserProgress", (keyValuePair, getException) =>
        {
            if (getException != null)
            {
                Debug.Log("Get failed for '" + keyValuePair.Key + "'" +
                          "probably no data available on server with this key");
                // Callback: Get Data Failed(probably no data available on server with this key),load the next gameplay level here(No values to be saved in playerprefs).
                // Examples Usage:
                // Application.LoadLevel("Idnet Sample Scene"); //Load your game level here
            }
            else
            {
                Debug.Log("Retrieved '" + keyValuePair.Key + "' with value '" + keyValuePair.Value);
                // Callback: Data retrieved sucessfully,write your code here like saving to unity variables/playerprefs,hence load game level too.

                //Examples Usage below: Store "retrieved values" to unity variables/playerprefs,and use it in game.
                PlayerPrefs.SetInt("Current_Level", keyValuePair.Value.NumOfLevelsUnlocked);
                PlayerPrefs.SetInt("TotalCoins", keyValuePair.Value.TotalCoins);
                PlayerPrefs.SetInt("Life", keyValuePair.Value.Lives);
                PlayerPrefs.SetFloat("MaxDistanceTravelled", keyValuePair.Value.MaxDistanceTravelled);
                PlayerPrefs.SetString("UnlockedCharacterName", keyValuePair.Value.UnlockedCharacterName);
                PlayerPrefs.SetString("IsTutorialCompleted", keyValuePair.Value.IsTutorialCompleted.ToString());
                // Application.LoadLevel("Idnet Sample Scene"); //Load your game level here

#if UNITY_EDITOR
                Debug.Log("Example UserProgress: "
                          + "\n" + keyValuePair.Value.NumOfLevelsUnlocked
                          + "\n" + keyValuePair.Value.TotalCoins
                          + "\n" + keyValuePair.Value.Lives
                          + "\n" + keyValuePair.Value.MaxDistanceTravelled
                          + "\n" + keyValuePair.Value.UnlockedCharacterName
                          + "\n" + keyValuePair.Value.IsTutorialCompleted
                );
#endif
            }
        });
    }


    //************************************"Multiple Leaderboards" per game Info***********************************//
    /// <remarks>
    ///     If your game have more than 1 leaderboards(games with more than 1 levels,and each level has its own
    ///     leaderboard),follow steps below.
    ///     Firstly you need to create "leaderboard names" called tables,for each leaderboard of your game on "Applications
    ///     page" of id.net.
    ///     To directly go to "Create tables/leaderboard names" page,pass your {app-id} here:
    ///     https://account.y8.com/applications/{app-id}/playtomic_tables# and create leaderboard/table names there.
    ///     Example of passing {app-id}: https://account.y8.com/applications/55961a8be694aa9957000288/playtomic_tables#
    ///     Example of "Leaderboard/table names": "Level1 Leaderboard","Level2 Leaderboard","Highway Leaderboard","Mountain
    ///     Level","Level 1" etc.
    ///     You will need these "table/leaderboard names",to PostScore to a particular level leaderboard and hence opening
    ///     corresponding leaderboard window.
    ///     Online Docs: Create "Table" name (eg. Leaderboard) as explained here http://dev.id.net/docs/unity/table-setup
    /// </remarks>
    /// <summary>
    ///     Post Score to "Level 1" Leaderboard.
    ///     Make sure you have created table/leaderboard name "Level 1" on applications page
    ///     https://account.y8.com/applications/{app-id}/playtomic_tables#
    ///     NOTE: NO NEED for Logged-In user check here, i.e  if (!Idnet.User.LoggedIn ())  return; is not needed before
    ///     posting scores.
    /// </summary>
    private void PostScoreLevel1ExampleCode()
    {
        //Score posted must be an integer.
        var exampleScore = 1000 + Random.Range(0, 1000);
        //Make sure you have created table/leaderboard name "Level 1" on applications page https://account.y8.com/applications/{app-id}/playtomic_tables#
        Idnet.I.PostHighscore(exampleScore, "Level 1");
    }

    //***************************************Post Score to "Level 2" leaderboard**************************************//
    /// <summary>
    ///     Post Score to "Level 2" Leaderboard.
    ///     NOTE: NO NEED for Logged-In user check here, i.e  if (!Idnet.User.LoggedIn ())  return; is not needed before
    ///     posting scores.
    /// </summary>
    private void PostScoreLevel2ExampleCode()
    {
        //Score posted must be an integer.
        var exampleScore = 1000 + Random.Range(0, 1000);
        //Make sure you have created table/leaderboard name "Level 2" on applications page https://account.y8.com/applications/{app-id}/playtomic_tables#
        Idnet.I.PostHighscore(exampleScore, "Level 2");
    }


    //************************SubmitScore to "Level 1" and hence open "Level 1" leaderboard***************************//
    /// <summary>
    ///     "Submit Score" Button code,this API post scores to "Level 1" Leaderboard and hence open corresponding leaderboard
    ///     window after post score is succesfull(Callback).
    ///     For Guest users(user not logged in to IDnet),it will automatically open Login GUI window.
    /// </summary>
    /// <remarks>
    ///     This "Submit Score" button should be present/used on gameover screen(if you are not automatically posting scores on
    ///     gameover using PostScore API).
    ///     For Alterations to this api,create your own Submit score api using PostScore callback
    ///     "PostScoreWithCallbackExampleCode()" or just open Idnet.cs and find SubmitHighScore() method and alter it.
    ///     Make sure you have created table/leaderboard name "Level 1" on applications page
    ///     https://account.y8.com/applications/{app-id}/playtomic_tables# before using it.
    ///     NOTE: NO NEED for Logged-In user check here, i.e  if (!Idnet.User.LoggedIn ())  return; is not needed before submit
    ///     score api.
    /// </remarks>
    private static void SubmitScoreLevel1ExampleCode()
    {
        //exampleScore,Score posted must be an integer.
        var exampleScore = 1001 + Random.Range(0, 1000);

        //Make sure you have created table/leaderboard name "Level 1" on applications page https://account.y8.com/applications/{app-id}/playtomic_tables#
        Idnet.I.SubmitHighScore(exampleScore, "Level 1");
    }


    //************************SubmitScore to "Level 2" and hence open "Level 2" leaderboard***************************//
    /// <summary>
    ///     "Submit Score" Button code,this API post scores to "Level 2" Leaderboard and hence open corresponding leaderboard
    ///     window after post score is succesfull(Callback).
    ///     For Guest users(user not logged in to IDnet),it will automatically open Login GUI window.
    /// </summary>
    private static void SubmitScoreLevel2ExampleCode()
    {
        //exampleScore,Score posted must be an integer.
        var exampleScore = 1001 + Random.Range(0, 1000);

        //Make sure you have created table/leaderboard name "Level 2" on applications page https://account.y8.com/applications/{app-id}/playtomic_tables#
        Idnet.I.SubmitHighScore(exampleScore, "Level 2");
    }


    //********************************************"Level 1" Leaderboard window****************************************//
    /// <summary>
    ///     Open table "Level 1" 'Leaderboard' window.
    ///     Make sure you have created table/leaderboard name "Level 1" on applications page
    ///     https://account.y8.com/applications/{app-id}/playtomic_tables#
    ///     NOTE: NO NEED for Logged-In user check here, i.e  if (!Idnet.User.LoggedIn ())  return; is not needed before
    ///     Leaderboard GUI api.
    /// </summary>
    private static void LeaderboardLevel1ExampleCode()
    {
        //Make sure you have created table/leaderboard name "Level 1" on applications page https://account.y8.com/applications/{app-id}/playtomic_tables#
        Idnet.I.Leaderboard("Level 1");
    }

    //********************************************"Level 2" Leaderboard window****************************************//
    /// <summary>
    ///     Open table "Level 2" 'Leaderboard' window.
    ///     Make sure you have created table/leaderboard name "Level 2" on applications page
    ///     https://account.y8.com/applications/{app-id}/playtomic_tables#
    ///     NOTE: NO NEED for Logged-In user check here, i.e  if (!Idnet.User.LoggedIn ())  return; is not needed before
    ///     Leaderboard GUI api.
    /// </summary>
    private static void LeaderboardLevel2ExampleCode()
    {
        //Make sure you have created table/leaderboard name "Level 2" on applications page https://account.y8.com/applications/{app-id}/playtomic_tables#
        Idnet.I.Leaderboard("Level 2");
    }


    //**********************************Get User's BestScore from "Level 1" leaderboard*******************************//
    /// <summary>
    ///     Get BestScore of current logged-in user from "Level 1" leaderboard.
    ///     Dont use this API in Update() or OnGUI() obviously.
    /// </summary>
    private static void GetBestScoreFromLevel1Leaderboard()
    {
        //Make sure you have created table/leaderboard name "Level 1" on applications page https://account.y8.com/applications/{app-id}/playtomic_tables#
        Idnet.I.GetBestScore("Level 1", bestScoreException =>
        {
            if (bestScoreException == null)
            {
                // Callback: Successfully retrieved BestScore of user.
                Debug.Log("Idnet Best Score " + Idnet.User.Current.BestScore);
            }
        });
    }


    //*************************************"TIMER Leaderboards(mm:ss:ms)"*********************************************//
    /// <remarks>
    ///     In case of Timer games like racing games,we must have Timer leaderboards in format min:sec:millisec (lower the
    ///     time,better it is).
    ///     API for posting "time" to IDnet leaderboard is same as normal score-posting API,but just write
    ///     "Idnet.I.TimerLeaderboard=true;" before using it.
    ///     Idnet.I.TimerLeaderboard=true; will make sure that Leaderboards will accept time(milliseconds) in leaderboard and
    ///     Leaderboard window will show "time" automatically in format mm:ss:ms.
    ///     Make sure you send "Milliseconds" while posting time to leaderboard.
    ///     Idnet.I.TimerLeaderboard=true; means "timer" leaderboards and "Idnet.I.TimerLeaderboard=false"(Default) means
    ///     normal "score" leaderboards.
    /// </remarks>
    /// <summary>
    ///     Post Time(it must be in milliseconds) to "Race Level 1" Leaderboard.
    ///     NOTE: NO NEED for Logged-In user check here, i.e  if (!Idnet.User.LoggedIn ())  return; is not needed before Post
    ///     Score api.
    /// </summary>
    private void PostTimeLevel1ExampleCode()
    {
        //Let idnet know that its a timer leaderboard.
        Idnet.I.TimerLeaderboard = true;

        //Time posted must be an "Milliseconds",here "127676698" is a milliseconds time.
        var exampleTime = 127676698;
        //Make sure you have created table/leaderboard name "Race Level 1" on applications page https://account.y8.com/applications/{app-id}/playtomic_tables#
        Idnet.I.PostHighscore(exampleTime, "Race Level 1");
    }


    //********************************************Leaderboard "Timer" window******************************************//
    /// <summary>
    ///     Open "Race Level 1" Timer Leaderboard.
    ///     NOTE: NO NEED for Logged-In user check here, i.e  if (!Idnet.User.LoggedIn ())  return; is not needed before
    ///     Leaderboard GUI api.
    /// </summary>
    private void TimerLeaderboardLevel1ExampleCode()
    {
        //Let idnet know that its a timer leaderboard.
        Idnet.I.TimerLeaderboard = true;

        //Make sure you have created table/leaderboard name "Race Level 1" on applications page https://account.y8.com/applications/{app-id}/playtomic_tables#
        Idnet.I.Leaderboard("Race Level 1");
    }


    //**********************Submit Time(ms) to "Race Level 1"  and hence open Level 1 Leaderboard window*******************//
    /// <summary>
    ///     Submit Time to "Race Level 1" Leaderbard window and hence open Leaderboard window after post score is successfull.
    /// </summary>
    private void SubmitTimeLevel1ExampleCode()
    {
        //Let idnet know that its a timer leaderboard.
        Idnet.I.TimerLeaderboard = true;

        var exampleTime = 127676698;
        //Make sure you have created table/leaderboard name "Race Level 1" on applications page https://account.y8.com/applications/{app-id}/playtomic_tables#
        Idnet.I.SubmitHighScore(exampleTime, "Race Level 1");
    }


    //**************************************************Protection Api************************************************//
    private static void BlacklistedWebsitesExampleCode()
    {
        Idnet.I.Protection(protectionException =>
        {
            if (protectionException == null)
            {
                if (Idnet.I.IsBlacklisted)
                {
                    // Callback: Blacklisted website, open blacklisted game scene here.
                    Debug.Log("Website is blacklisted,disable the game here");
                }
            }
        });
    }

    //*************************************************Sponser API****************************************************//
    private static void SponserWebsitesExampleCode()
    {
        Idnet.I.Protection(protectionException =>
        {
            if (protectionException == null)
            {
                if (Idnet.I.IsSponsor)
                {
                    // Callback: Game is Running on Y8's network,this api can also be used for sitelock/branding.
                    Debug.Log("Game is Running on Y8's network.");
                }
            }
        });
    }


    //********************************************END OF CODE EXAMPLES:***********************************************//


    //GUI for Sample scene
    private void OnGUI()
    {
        var dynamicRect = new Rect(BORDER, BORDER, BOX_WIDTH, Screen.height - BORDER_X2);

        // Minimize IdnetSample.
        if (Idnet.I.IsShowingGui() || _minimized)
        {
            dynamicRect.height = BOX_HEIGHT_SMALL;
            dynamicRect.width = BOX_WIDTH_SMALL;
        }


        // Title.
        GUI.Box(dynamicRect, "IDNET");

        // Area.
        GUILayout.BeginArea(new Rect(dynamicRect.x + BORDER, dynamicRect.y + BORDER, dynamicRect.width - BORDER_X2,
            dynamicRect.height - BORDER_X2));

        GUILayout.Space(BORDER_X2);

        // Debug info.
        GUILayout.BeginHorizontal();

        GUILayout.BeginVertical();
        GUI.color = Color.white;
        var smallText = new GUIStyle
        {
            fontSize = 9,
            wordWrap = true,
            normal = {textColor = Color.white}
        };
        GUILayout.Label((Idnet.User.LoggedIn() ? "LOGGED IN" : "CACHED (PlayerPrefs)") + " User Properties", smallText);
        GUILayout.Label("Nickname:" + Idnet.User.Current.Nickname, smallText);
        GUILayout.Label("Email:" + Idnet.User.Current.Email, smallText);
        GUILayout.Label("Session Token:" + Idnet.User.Current.SessionToken, smallText);
        GUILayout.Label("Pid:" + Idnet.User.Current.Pid, smallText);
        GUILayout.EndVertical();

        GUILayout.FlexibleSpace();

        if (!Idnet.I.IsShowingGui())
        {
            if (GUILayout.Button(_minimized ? "Maximize" : "Minimize"))
            {
                _minimized = !_minimized;
            }
        }

        GUILayout.EndHorizontal();

        // Minimize?
        if (Idnet.I.IsShowingGui())
        {
            // Do nothing.
        }
        else if (_minimized)
        {
            GUILayout.Label(" Minimized.");
        }
        else
        {
            // Content.

            _allowErroneousApiCalls = GUILayout.Toggle(_allowErroneousApiCalls, "Allow erroneous Api calls");

            GUILayout.FlexibleSpace();

            // Two columns.
            GUILayout.BeginHorizontal();
            GUILayout.BeginVertical();

            //GUILayout.FlexibleSpace();
            GUI.color = Color.cyan;
            GUI.enabled = _allowErroneousApiCalls;
#if !UNITY_EDITOR
			GUI.enabled = true;
#endif
            GUILayout.Label("Users (Authentication)");

            if (GUILayout.Button("AutoLogin", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                AutoLoginGUIWindowCode();
            }

            GUI.enabled = _allowErroneousApiCalls || !Idnet.User.LoggedIn();
            if (GUILayout.Button("Login", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                LoginGUIWindowCode();
            }

            GUI.enabled = _allowErroneousApiCalls || !Idnet.User.LoggedIn();
            if (GUILayout.Button("Register", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                RegisterGUIWindowCode();
            }

            GUI.enabled = _allowErroneousApiCalls || !GUI.enabled;
            if (GUILayout.Button("Logout", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                LogoutExampleCode();
            }

            if (GUILayout.Button("User Profile", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                ProfileExampleCode();
            }

            GUILayout.FlexibleSpace();
            GUI.color = Color.green;
            GUI.enabled = true;
            GUILayout.Label("Users (Leaderboards / Highscores)");

            GUI.enabled = _allowErroneousApiCalls || Idnet.User.LoggedIn();

            if (GUILayout.Button("Post Score to IDNET's Leaderboard", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                PostScoreWithCallbackExampleCode();
            }

            GUI.enabled = true;

            if (GUILayout.Button("Show IDNET'S Leaderboard", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                LeaderboardExampleCode();
            }

            if (GUILayout.Button("Submit Score Button", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                SubmitScoreExampleCode();
            }

            GUILayout.FlexibleSpace();
            GUI.color = Color.yellow;
            GUI.enabled = true;
            GUILayout.Label("User (Data)");

            GUI.enabled = _allowErroneousApiCalls || Idnet.User.LoggedIn();

            if (GUILayout.Button("Save Data to IDNET'S Server", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                SaveUserDataWithCallBackExampleCode();
            }

            if (GUILayout.Button("Get Data from IDNET's Server", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                GetUserDataExampleCode();
            }

            if (GUILayout.Button("Delete data from IDNET's Server", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                DeleteUserDataExampleCode();
            }

            GUILayout.FlexibleSpace();
            GUI.color = Color.red;
            GUI.enabled = _allowErroneousApiCalls || Idnet.User.LoggedIn();
            GUILayout.Label("User (Achievements)");

            GUI.enabled = true;
            if (GUILayout.Button("Show IDNET User Achievements", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                ListAchievementsExampleCode();
            }

            GUI.enabled = _allowErroneousApiCalls || Idnet.User.LoggedIn();
            if (GUILayout.Button("Unlock Random IDNET User Achievement", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                UnlockAchievementCallbackExampleCode();
            }

            GUILayout.FlexibleSpace();
            GUI.enabled = true;
            GUI.color = Color.magenta;
            GUILayout.Label("Example: Online Save-Local Save ");
            string onlineSaveText;
            if (!Idnet.User.LoggedIn())
            {
                onlineSaveText = "Online Save. Not logged-in";
            }
            else
            {
                onlineSaveText = "Online Save. Welcome: " + Idnet.User.Current.Nickname;
            }
            if (GUILayout.Button(onlineSaveText, GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                OnlineSaveExampleCode();
            }


            if (GUILayout.Button("Local Save", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                LocalSaveExampleCode();
            }


            GUILayout.FlexibleSpace();
            GUILayout.EndVertical();
            GUILayout.EndHorizontal();


            GUILayout.EndArea();
            var dynamicRect2 = new Rect(BORDER + dynamicRect.width + BORDER / 2, BORDER, BOX_WIDTH,
                Screen.height - BORDER_X2);

            GUI.Box(dynamicRect2, "Multiple Leaderboards");
            GUILayout.BeginArea(new Rect(dynamicRect.x + BORDER + dynamicRect.width, dynamicRect.y + BORDER,
                dynamicRect.width - BORDER_X2,
                dynamicRect.height - BORDER_X2));


            GUILayout.Space(BORDER_X2);
            // Debug info.
            GUILayout.BeginHorizontal();

            GUILayout.BeginVertical();

            GUI.color = Color.yellow;
            GUI.enabled = _allowErroneousApiCalls || Idnet.User.LoggedIn();

            GUILayout.Label("Level 1 Table/Leaderboard");
            if (GUILayout.Button("Post Score to Level 1", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                PostScoreLevel1ExampleCode();
            }
            GUI.enabled = true;

            if (GUILayout.Button("Level 1 Leaderboard", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                LeaderboardLevel1ExampleCode();
            }

            if (GUILayout.Button("Submit Score to Level 1", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                SubmitScoreLevel1ExampleCode();
            }


            GUILayout.Space(BORDER_X2 / 2);
            GUI.color = Color.blue;
            GUI.enabled = _allowErroneousApiCalls || Idnet.User.LoggedIn();

            GUILayout.Label("Level 2 Table/Leaderboard");
            if (GUILayout.Button("Post Score to Level 2", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                PostScoreLevel2ExampleCode();
            }
            GUI.enabled = true;

            if (GUILayout.Button("Level 2 Leaderboard", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                LeaderboardLevel2ExampleCode();
            }

            if (GUILayout.Button("Submit Score to Level 2", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                SubmitScoreLevel2ExampleCode();
            }

            GUILayout.Space(BORDER_X2);
            GUI.color = Color.red;
            GUI.enabled = _allowErroneousApiCalls || Idnet.User.LoggedIn();


            GUILayout.Label("Timer Leaderboards(mm:ss:ms)");
            if (GUILayout.Button("Post Time to Race Level 1", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                PostTimeLevel1ExampleCode();
            }
            GUI.enabled = true;

            if (GUILayout.Button("Race Level 1 Timer Leaderboard", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                TimerLeaderboardLevel1ExampleCode();
            }

            if (GUILayout.Button("Submit Time to Race Level 1", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
                SubmitTimeLevel1ExampleCode();
            }

			GUILayout.Label("GameBreak");
			if (GUILayout.Button("GameBreak", GUILayout.MaxHeight(BUTTON_HEIGHT)))
            {
				Idnet.I.GameBreak();
            }

            GUILayout.Label("Browser Only: Y8's network: " + Idnet.I.IsSponsor);
            GUILayout.Label("Browser Only: isLogoClickable: " + !Idnet.I.IsSponsor);
            //hide more games button on y8 network
            GUILayout.Label("Browser Only: Hide MoreGames: " + Idnet.I.IsSponsor);

            GUILayout.FlexibleSpace();
            GUILayout.EndVertical();
            GUILayout.EndHorizontal();
        }
        GUILayout.EndArea();
    }
}