// Path: core/src/de/golfgl/gdxgamesvcs/achievement/IFetchAchievementsResponseListener.java
// public interface IFetchAchievementsResponseListener {
// 
//     /**
//      * Response with achievement list
//      *
//      * @param achievements null if achievements couldn't be fetched.
//      */
//     void onFetchAchievementsResponse(Array<IAchievement> achievements);
// 
// }
// 
// Path: core/src/de/golfgl/gdxgamesvcs/gamestate/IFetchGameStatesListResponseListener.java
// public interface IFetchGameStatesListResponseListener {
//     /**
//      * Called when game state list was loaded
//      *
//      * @param gameStates null if game states couldn't be fetched.
//      */
//     void onFetchGameStatesListResponse(Array<String> gameStates);
// }
// 
// Path: core/src/de/golfgl/gdxgamesvcs/gamestate/ILoadGameStateResponseListener.java
// public interface ILoadGameStateResponseListener {
//     /**
//      * Returns a game state that was saved in Cloud services
//      *
//      * @param gameState null if loading failed
//      */
//     public void gsGameStateLoaded(byte[] gameState);
// }
// 
// Path: core/src/de/golfgl/gdxgamesvcs/gamestate/ISaveGameStateResponseListener.java
// public interface ISaveGameStateResponseListener {
// 
//     /**
//      * Result of save game request
//      *
//      * @param success   true if game state was sucessfully saved
//      * @param errorCode null if succesful
//      */
//     void onGameStateSaved(boolean success, String errorCode);
// }
// 
// Path: core/src/de/golfgl/gdxgamesvcs/leaderboard/IFetchLeaderBoardEntriesResponseListener.java
// public interface IFetchLeaderBoardEntriesResponseListener {
//     /**
//      * Called when leaderBoard entries are received.
//      *
//      * @param leaderBoard null if leaderBoard couldn't be fetched.
//      */
//     void onLeaderBoardResponse(Array<ILeaderBoardEntry> leaderBoard);
// }


import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Net;
import com.badlogic.gdx.utils.JsonValue;
import com.badlogic.gdx.utils.JsonWriter;
import com.badlogic.gdx.utils.Timer;
import java.util.HashMap;
import de.golfgl.gdxgamesvcs.achievement.IFetchAchievementsResponseListener;
import de.golfgl.gdxgamesvcs.gamestate.IFetchGameStatesListResponseListener;
import de.golfgl.gdxgamesvcs.gamestate.ILoadGameStateResponseListener;
import de.golfgl.gdxgamesvcs.gamestate.ISaveGameStateResponseListener;
import de.golfgl.gdxgamesvcs.leaderboard.IFetchLeaderBoardEntriesResponseListener;
    private native void nativeIncAchievement(String achievementId, int incNum) /*-{
        $wnd.gapi.client.request({
              path: 'games/v1/achievements/' + achievementId + '/increment',
              params: {stepsToIncrement: incNum},
              method: 'POST',
              callback: function(response) {
                //response.newlyUnlocked could be checked to toast
              }
        });
    }-*/;

    @Override
    public void saveGameState(final String fileId, final byte[] gameState, long progressValue, final ISaveGameStateResponseListener success) {
        if (!enableDrive)
            throw new UnsupportedOperationException();

        if (!isSessionActive()) {
            if (success != null)
                success.onGameStateSaved(false, "NOT_CONNECTED");
            return;
        }

        findDriveFileId(fileId, new IDoWithDriveFileId() {
            @Override
            public void doWithDriveFileId(String driveFileId) {
                saveFileToDrive(fileId, driveFileId, gameState, success);
            }
        });
    }

// Path: core/src/de/golfgl/gdxgamesvcs/achievement/IFetchAchievementsResponseListener.java
// public interface IFetchAchievementsResponseListener {
// 
//     /**
//      * Response with achievement list
//      *
//      * @param achievements null if achievements couldn't be fetched.
//      */
//     void onFetchAchievementsResponse(Array<IAchievement> achievements);
// 
// }
// 
// Path: core/src/de/golfgl/gdxgamesvcs/gamestate/IFetchGameStatesListResponseListener.java
// public interface IFetchGameStatesListResponseListener {
//     /**
//      * Called when game state list was loaded
//      *
//      * @param gameStates null if game states couldn't be fetched.
//      */
//     void onFetchGameStatesListResponse(Array<String> gameStates);
// }
// 
// Path: core/src/de/golfgl/gdxgamesvcs/gamestate/ILoadGameStateResponseListener.java
// public interface ILoadGameStateResponseListener {
//     /**
//      * Returns a game state that was saved in Cloud services
//      *
//      * @param gameState null if loading failed
//      */
//     public void gsGameStateLoaded(byte[] gameState);
// }
// 
// Path: core/src/de/golfgl/gdxgamesvcs/gamestate/ISaveGameStateResponseListener.java
// public interface ISaveGameStateResponseListener {
// 
//     /**
//      * Result of save game request
//      *
//      * @param success   true if game state was sucessfully saved
//      * @param errorCode null if succesful
//      */
//     void onGameStateSaved(boolean success, String errorCode);
// }
// 
// Path: core/src/de/golfgl/gdxgamesvcs/leaderboard/IFetchLeaderBoardEntriesResponseListener.java
// public interface IFetchLeaderBoardEntriesResponseListener {
//     /**
//      * Called when leaderBoard entries are received.
//      *
//      * @param leaderBoard null if leaderBoard couldn't be fetched.
//      */
//     void onLeaderBoardResponse(Array<ILeaderBoardEntry> leaderBoard);
// }


// Path: html-gpgs/src/de/golfgl/gdxgamesvcs/GpgsClient.java
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Net;
import com.badlogic.gdx.utils.JsonValue;
import com.badlogic.gdx.utils.JsonWriter;
import com.badlogic.gdx.utils.Timer;
import java.util.HashMap;
import de.golfgl.gdxgamesvcs.achievement.IFetchAchievementsResponseListener;
import de.golfgl.gdxgamesvcs.gamestate.IFetchGameStatesListResponseListener;
import de.golfgl.gdxgamesvcs.gamestate.ILoadGameStateResponseListener;
import de.golfgl.gdxgamesvcs.gamestate.ISaveGameStateResponseListener;
import de.golfgl.gdxgamesvcs.leaderboard.IFetchLeaderBoardEntriesResponseListener;

    private native void nativeIncAchievement(String achievementId, int incNum) /*-{
        $wnd.gapi.client.request({
              path: 'games/v1/achievements/' + achievementId + '/increment',
              params: {stepsToIncrement: incNum},
              method: 'POST',
              callback: function(response) {
                //response.newlyUnlocked could be checked to toast
              }
        });
    }-*/;

    @Override
    public void saveGameState(final String fileId, final byte[] gameState, long progressValue, final ISaveGameStateResponseListener success) {
        if (!enableDrive)
            throw new UnsupportedOperationException();

        if (!isSessionActive()) {
            if (success != null)
                success.onGameStateSaved(false, "NOT_CONNECTED");
            return;
        }

        findDriveFileId(fileId, new IDoWithDriveFileId() {
            @Override
            public void doWithDriveFileId(String driveFileId) {
                saveFileToDrive(fileId, driveFileId, gameState, success);
            }
        });
    }

    protected void saveFileToDrive(String fileName, String driveFileId, byte[] gameState, final ISaveGameStateResponseListener success) {