void ScoreLoopThread::RequestUserCompletionCallback(void *userData, SC_Error_t completionStatus) {
	/* Get the application from userData argument */
	AppData_t *app = (AppData_t *) userData;

	/* Check completion status */
	if (completionStatus != SC_OK) {
		SC_UserController_Release(app->userController); /* Cleanup Controller */
		HandleError(app, completionStatus);
		return;
	}
	qDebug() << "Done requesting User";

	/* Get the session from the client. */
	SC_Session_h session = SC_Client_GetSession(app->client);

	/* Get the session user from the session. */
	SC_User_h user = SC_Session_GetUser(session);

	/* Write out some user data */
	SC_String_h login = SC_User_GetLogin(user);
	qDebug() << "  User's login:"******"<unknown>");
	SC_String_h email = SC_User_GetEmail(user);
	qDebug() << " User's email: " << (email ? SC_String_GetData(email) : "<unknown>");

	/* We don't need the UserController anymore, so release it */
	SC_UserController_Release(app->userController);

	/* send this to the app so we can save it for future requests */
	emit(instance()->ScoreLoopUserReady(app));

	/* normal signal for emitting the username */
	emit(instance()->RequestUserCompleted(login ? SC_String_GetData(login) : "<unknown>"));
}
void OnlineService::downloadSaveGame(const char *filename)
{
	//printf("online download %s\n", filename); fflush(stdout);
	const size_t pathsize = 255;
	char originalfilepath[pathsize];
	snprintf(originalfilepath, pathsize, "%s%s", get_save_filename_prefix(), filename);
	char encodedfilepath[pathsize];
	snprintf(encodedfilepath, pathsize, "%s%s.txt", get_save_filename_prefix(), filename);

	SC_Context_h user_context = SC_User_GetContext(scoreloop_user);

	SC_String_h save_data;

	//printf("getting user context entry %s... ", filename); fflush(stdout);
	SC_Error_t getContextResult = SC_Context_Get(user_context, filename, &save_data);

	if (getContextResult == SC_OK)
	{
		//printf("done\n"); fflush(stdout);

		//printf("writing %s... ", encodedfilepath); fflush(stdout);
		bFILE *file = open_file(encodedfilepath, "w");
		if(!file->open_failure())
		{
			//printf("done\n"); fflush(stdout);
			const char *data = SC_String_GetData(save_data);
			file->write(data, strlen(data));
		}
		else
		{
			//printf("failed\n"); fflush(stdout);
		}
		delete file;
		file = 0;

		//printf("decoding %s to %s... ", encodedfilepath, originalfilepath); fflush(stdout);
		int result = ascii85_decode(encodedfilepath, originalfilepath);
		//if (result == 0)
		//	printf("done\n");
		//else
		//	printf("failed\n");
		//fflush(stdout);
	}
	else if (getContextResult == SC_NOT_FOUND)
	{
		//printf("not found\n"); fflush(stdout);
	}
	else
	{
		//printf("failed\n"); fflush(stdout);
	}
}
void CScores::OnRequestSuccess()
{
	m_listview->Clear();
	SC_ScoreList_h scores = SC_ScoresController_GetScores(m_scoresController);
	unsigned int count = SC_ScoreList_GetScoresCount(scores);
	int index;
	char buf[128];
	for (unsigned int i = 0; i < count; i++)
	{
		/* Get the i-th score */
		SC_Score_h score = SC_ScoreList_GetScore(scores, i);
		
		/* Get login of the score's user */
		SC_User_h user = SC_Score_GetUser(score);
		const char* login = SC_String_GetData(SC_User_GetLogin(user));
		sprintf(buf, "%d. %s", (int)SC_Score_GetRank(score), login);
		index = m_listview->AddItem(NULL, buf);
		m_listview->SetItemCaptionRighti(index, (int)SC_Score_GetResult(score));
		//Get OS type from Minor Result
		int OSindex = (int)SC_Score_GetMinorResult(score);
		if (OSindex < 0 && OSindex > 22)
			OSindex = 0;
		m_listview->SetItemSubtext(index, g_OScaptions[OSindex]);
	}
	if (m_curuserrank > 0)
	{
		if (m_curuserrank <= SC_PAGE_SCORES_COUNT && m_curuserrank < (int)m_listview->get_itemscount() + 1)
		{
			CGUIListItem *li = m_listview->get_item(m_curuserrank - 1);
			li->fontcolor = 0xff0000ff;
			m_listview->MoveItemToCenter(m_curuserrank - 1);
			FinishWait();
		}
		else
		{
			// Loading user score if rank > SC_PAGE_SCORES_COUNT
			// See OnRequestSuccessUser()
			SC_UserController_RequestUserDetail(m_userController);
			StartWait("Loading current user details");
		}
	}
	else
	{
		FinishWait();
	}	
	
}
void ScoreLoopThread::LoadAchievementsCompletionCallback(void *userData, SC_Error_t completionStatus) {
	/* Get the application from userData argument */
	AppData_t *app = (AppData_t *) userData;

	/* Check completion status */
	if (completionStatus != SC_OK) {
		SC_LocalAchievementsController_Release(app->achievementsController); /* Cleanup Controller */
		HandleError(app, completionStatus);
		return;
	}

	/* Just log the achievements here for demonstration purposes */
	SC_AchievementList_h achievementList = SC_LocalAchievementsController_GetAchievements(app->achievementsController);
	if (achievementList == NULL) {
		SC_LocalAchievementsController_Release(app->achievementsController); /* Cleanup Controller */
		HandleError(app, SC_NOT_FOUND);
		return;
	}
	qDebug() << "Done loading Achievements";

	unsigned int i, numAchievements = SC_AchievementList_GetCount(achievementList);
	for (i = 0; i < numAchievements; ++i) {
		SC_Achievement_h achievement = SC_AchievementList_GetAt(achievementList, i);
		SC_Award_h award = SC_Achievement_GetAward(achievement);
		qDebug() << "Achieved Award: " << SC_String_GetData(SC_Award_GetIdentifier(award));
	}

	/* Cleanup Controller */
	SC_LocalAchievementsController_Release(app->achievementsController);

	/* Create a Challenge here for demonstration purposes only */
	/*
	SC_Money_h money = GetStake(app);
	if (money) {
		CreateChallenge(app, money, GetScoreResult(app), 0);
	} else {
		// No balance, so skip this step and continue with next step for demonstration only
		LoadChallenges(app);
	}
	*/
}
void CScores::OnRequestSuccessUser()
{
	FinishWait();
	SC_User_h user = SC_UserController_GetUser(m_userController);
	SC_String_h login = SC_User_GetLogin(user);
	if (login)
	{
		char buf[128];
		const char* login = SC_String_GetData(SC_User_GetLogin(user));
		sprintf(buf, "%d. %s", m_curuserrank, login);
		int index = m_listview->AddItem(NULL, buf);
		m_listview->SetItemCaptionRighti(index, m_curuserscore);
		//Get OS type from Minor Result
		int OSindex = m_curuserminorresult;
		if (OSindex < 0 && OSindex > 22)
			OSindex = 0;
		m_listview->SetItemSubtext(index, g_OScaptions[OSindex]);
		CGUIListItem *li = m_listview->get_item(index);
		li->fontcolor = 0xff0000ff;
		m_listview->MoveItemToCenter(index);
	}

}
void ScoreLoopThread::LoadLeaderboardCompletionCallback(void *userData, SC_Error_t completionStatus) {
	/* Get the application from userData argument */
	AppData_t *app = (AppData_t *) userData;

	/* Check completion status */
	if (completionStatus != SC_OK) {
		SC_ScoresController_Release(app->scoresController); /* Cleanup Controller */
		HandleError(app, completionStatus);
		return;
	}

	/* Just log the scores here for demonstration purposes */
	SC_ScoreList_h scoreList = SC_ScoresController_GetScores(app->scoresController);
	if (scoreList == NULL) {
		SC_ScoresController_Release(app->scoresController); /* Cleanup Controller */
		HandleError(app, SC_NOT_FOUND);
		return;
	}
	qDebug() << "Done loading Leaderboard";

	/* Get the score formatter here - remember that you need to add a
	 * scoreloop/SLScoreFormatter.strings file to your asset files in order to retrieve a formatter.
	 */
	SC_ScoreFormatter_h scoreFormatter = SC_Client_GetScoreFormatter(app->client);
	if (!scoreFormatter) {
		SC_ScoresController_Release(app->scoresController); /* Cleanup Controller */
		HandleError(app, SC_NOT_FOUND);
		return;
	}

	QVariantList leaderboardData;

	unsigned int i, numScores = SC_ScoreList_GetCount(scoreList);
	for (i = 0; i < numScores; ++i) {
		SC_Score_h score = SC_ScoreList_GetAt(scoreList, i);
		SC_User_h user = SC_Score_GetUser(score);
		SC_String_h login = user ? SC_User_GetLogin(user) : NULL;
		SC_String_h formattedScore;

		/* Format the score - we take ownership of string */
		int rc = SC_ScoreFormatter_FormatScore(scoreFormatter, score, SC_SCORE_FORMAT_DEFAULT, &formattedScore);
		if (rc != SC_OK) {
			HandleError(app, rc);
			return;
		}
		qDebug() << "  Rank: " << SC_Score_GetRank(score) << ", Result: " << SC_String_GetData(formattedScore) << ", User: "******"<unknown>");

		QVariantMap scoreData;
		scoreData["rank"] = SC_Score_GetRank(score);
		scoreData["formattedScore"] = SC_String_GetData(formattedScore);
		scoreData["username"] = login ? SC_String_GetData(login) : "<unknown>";

		leaderboardData.append(scoreData);

		/* Release the string */
		SC_String_Release(formattedScore);
	}

	emit(instance()->LoadLeaderboardCompleted(leaderboardData));

	/* Cleanup Controller */
	SC_ScoresController_Release(app->scoresController);

	/* Set an Award as achieved here just for demonstration purposes */
	//AchieveAward(app, SCORELOOP_AN_AWARD_ID);
}
FREObject getScores(FREContext ctx, void* functionData, uint32_t argc, FREObject argv[])
{
	SC_ScoreList_h score_list;
	SC_Score_h aScore;
    FREObject returnObject;
    int i,j;
    unsigned int contextArrayLength = 0;
	FREGetArrayLength(argv[0],&contextArrayLength);

	score_list = SC_ScoresController_GetScores(scores_controller);
	// arrayArgs has the Array arguments.
#if defined(BB10)
	unsigned int scoreListSize = SC_ScoreList_GetCount(score_list);
#else
	unsigned int scoreListSize = SC_ScoreList_GetScoresCount(score_list);
#endif

    FREObject* arrayArgs = (FREObject*)malloc(sizeof(FREObject)*scoreListSize);

	for(i = 0 ; i < scoreListSize ; i++)
	{
#if defined(BB10)
		aScore = SC_ScoreList_GetAt(score_list,i);
#else
		aScore = SC_ScoreList_GetScore(score_list,i);
#endif
	    FREObject* argV=(FREObject*)malloc(sizeof(FREObject)*6);
	    FRENewObjectFromInt32(SC_Score_GetMode(aScore), &argV[0]);
	    FRENewObjectFromInt32(SC_Score_GetLevel(aScore), &argV[1]);
	    FRENewObjectFromDouble(SC_Score_GetResult(aScore), &argV[2]);
	    FRENewObjectFromDouble(SC_Score_GetMinorResult(aScore), &argV[3]);

	    // Create the 5th argument(User)
	    SC_User_h aUser = SC_Score_GetUser(aScore);
	    SC_String_h scLogin = SC_User_GetLogin(aUser);
	    SC_String_h scEmail = SC_User_GetEmail(aUser);
	    const char * login = "";
	    const char * email = "";
	    if(scLogin != NULL)
	    	login= SC_String_GetData(scLogin);
	    if(scEmail != NULL)
	    	email = SC_String_GetData(scEmail);
	    FREObject* userArgV=(FREObject*)malloc(sizeof(FREObject)*2);
	    FRENewObjectFromUTF8(strlen(login)+1,(const uint8_t*)login, &userArgV[0]);
	    FRENewObjectFromUTF8(strlen(email)+1,(const uint8_t*)email, &userArgV[1]);
	    fprintf(stderr, "username: %s\n", login);

	    FRENewObject((const uint8_t*)"com.wallwizz.scoreloop.User",2,userArgV,&argV[4],NULL);

	    // Create the 6th argument(Context)
	    FREObject* contextArray = (FREObject*)malloc(sizeof(FREObject)*contextArrayLength);
	    for(j = 0; j < contextArrayLength; j++)
	    {
		    FREObject context;
			FREObject freContextKey;
			const char * aKey = "test";
			SC_String_h scValue = NULL;
			const char* aValue = NULL;
			unsigned int length;
			FREGetArrayElementAt(argv[0], j, &freContextKey);

			if(FREGetObjectAsUTF8(freContextKey,&length,(const uint8_t**)&aKey) != FRE_OK)
				fprintf(stderr, "FREGetArrayElementAt Error\n");

		    fprintf(stderr, "retrieved aKey: %s\n", aKey);
			SC_Context_h aContext = SC_Score_GetContext(aScore);
			SC_Context_Get(aContext, aKey, &scValue);
		    if(scValue != NULL)
		    {
		    	aValue= SC_String_GetData(scValue);
		    }else{
			    fprintf(stderr, "scValue NULL\n");
			    aValue = "not found";
		    }
		    fprintf(stderr, "retrieved aValue: %s\n", aValue);

		    FREObject* contextArgv=(FREObject*)malloc(sizeof(FREObject)*2);
		    FRENewObjectFromUTF8(strlen(aKey)+1,(const uint8_t*)aKey, &contextArgv[0]);
		    FRENewObjectFromUTF8(strlen(aValue)+1,(const uint8_t*)aValue, &contextArgv[1]);
		    FRENewObject((const uint8_t*)"com.wallwizz.scoreloop.Context",2,contextArgv,&contextArray[j],NULL);
		    free(contextArgv);
	    }
	    FRENewObject((const uint8_t*)"Array",contextArrayLength,contextArray,&argV[5],NULL);

	    FRENewObject((const uint8_t*)"com.wallwizz.scoreloop.Score",6,argV,&arrayArgs[i],NULL);
	    free(contextArray);
	}
    FRENewObject((const uint8_t*)"Array",scoreListSize,arrayArgs,&returnObject,NULL);
    free(arrayArgs);
    return returnObject;
}