//UA.Utils.js
/***************************\
Contains:
	Extension:	Claim.isFunction	- assertions for functions
	Extension:	Element.setText		- sets Value/innerHTML/textContent by element type
	Function:	Serialize(obj)		- Serializable to JSON
    Extension:  Function.insert     - insert a line into the function  
    Function:   ask()               - a debug utility
\***************************/
//-----------------------------------------------------------------
Object.extend( Class, {
  isInheritable: function(parentClassName) {
    if (!parentClassName) return false;

    var parentClass;
    switch(typeof(parentClassName)){
        case "function":
            parentClass = parentClassName;
            parentClassName =  _proxy_jslib_handle(parentClass, 'toString', '', 1, 0)();
            return (  !parantClassName.match(/function\(/gi)

 &&  _proxy_jslib_handle(window, (parentClassName), 0, 0) != null

 &&  _proxy_jslib_handle(window, (parentClassName), 0, 0) == eval(_proxy_jslib_proxify_js((parentClassName), 0, 0) )

 );

        case "string":
            try{
                parentClass = eval(_proxy_jslib_proxify_js((parentClassName), 0, 0) );
            }catch(ex){return false;} 
            return  (   parentClass != null 

 &&  typeof(parentClass) == 'function'

 );
        default:
            return false;
    }   
  }
  ,createSubclass: function(parentClassName) {
    var parentClass;

    if(!Class.isInheritable(parentClassName))
        throw "Illegal parameter for Class.createSubclass:" + parentClassName + ". Class.create accepts a valid class-name as string, or a reference to the class if the class has a static override for the toString(), providing its class name as string.";

    if(typeof(parentClassName) == 'string'){
        parentClass = eval(_proxy_jslib_proxify_js((parentClassName), 0, 0) );
    }else{
        parentClass = parentClass;
        parentClassName =  _proxy_jslib_handle(parentClass, 'toString', '', 1, 0)();
    }

    Claim.isString(parentClassName,"Class.createSubclass(parentClassName)");
    Claim.check( typeof(parentClass) == 'function' &&
                 typeof(parentClass.prototype.initialize) == 'function' 

 , "typeof(eval(parentClassName).prototype.initialize) == 'function'"

 , "Class.createSubclass(parentClassName): parentClassName is not inheritable using the createSubclass mechanizm." );

    var f = _proxy_jslib_new_function(parentClassName + ".prototype.initialize.apply(this, arguments);\n" 

 + "this.initialize.apply(this, arguments)" );

    return f;
  }
});
//-----------------------------------------------------------------
Object.extend(Claim, {
	isFunction: function(object, comment) {{
        Claim.check(typeof(object) == 'function',
                                "isFunction(" + Claim.valueType(object) + ")",
                             comment)

 }}
});
//-----------------------------------------------------------------
Object.extend(Element, {
    log: new (Log4Js.Logger)("Element")

 ,setText: function(e,sText) {
		var tag = e.tagName.toUpperCase();
		switch(tag){
			case "INPUT":
			case "TEXTAREA":
				 _proxy_jslib_assign('', e, 'value', '=', ( sText));
				break;
			case "SELECT":
				//TODO: - decide what to do if the sText doesnt match any value of the select element
				 _proxy_jslib_assign('', e, 'value', '=', ( sText));
				break;
			default:/*DIV, SPAN, TD, A, H1-H5, and all the rest*/
				try{
					 _proxy_jslib_assign('', e, 'innerHTML', '=', ( sText));
				}catch(ex){
					try{
						if(typeof e.innerText == 'undefined')
							e.textContent = sText;
						else
							e.innerText = sText;
					}catch(ex){
					    this.log.error("Element.setText: failed to set to element the text: " + sText);
					}
				}
		}
	}
});
//-----------------------------------------------------------------
Serialize = function(obj) {
	if (!obj) return 'null';

	var str = '';
	var psik = '';
	for (each in obj){
		str += psik; psik = ","; //adds a comma from 2nd time only
		str += each +":"

 switch(typeof( _proxy_jslib_handle(obj, (each), 0, 0))){
			case 'function': 
				break;
			case 'object':
				str += Serialize( _proxy_jslib_handle(obj, (each), 0, 0));
				break;
			case 'string':
			    str += '"' +  _proxy_jslib_handle( _proxy_jslib_handle(obj, (each), 0, 0), 'replace', '', 1, 0)(/\"/,"\"") + '"';
			    break;
			default:
				str +=  _proxy_jslib_handle(obj, (each), 0, 0);
		} 
	}
	return "{" + str + "}";
}
//-----------------------------------------------------------------
Function.prototype.insert = function(sCodeLine) {
	var a =  _proxy_jslib_handle(this, 'toString', '', 1, 0)().split("{");
	a[1] = "\n\t" + sCodeLine + a[1];
	return (eval(_proxy_jslib_proxify_js(("a = " + a.join("{")), 0, 0) ));
}
//-----------------------------------------------------------------
Glossary =	{ _terms:	{}
			, addPair:	function addPair(key, value) {  _proxy_jslib_assign('', this._terms, (key), '=', (  _proxy_jslib_handle(null, 'value', value, 0, 0))); }
			, term:		function term(key) { return  _proxy_jslib_handle(this._terms, (key), 0, 0); }
			};
//TODO: replace the term identifiers with term GUID
Glossary.addPair('{JAST_REQUEST_TIMEOUT_DEF_MSG}','Problems connecting to the server.');
Glossary.addPair('{JAST_REQUEST_REFUSED_DEF_MSG}','Server failes the request');
//-----------------------------------------------------------------
function ask() {
	var s = '';
	while(s!= "STOP"){
		s = prompt('To close - enter "STOP"',s);
		if (s == "STOP") return;
		alert(eval(_proxy_jslib_proxify_js((s), 0, 0) ));
	}
}

function CreateHiddenInput(sName, sValue) {
	var input = document.createElement("input");
	 _proxy_jslib_handle(input, 'setAttribute', '', 1, 0)("type", "hidden");
	 _proxy_jslib_handle(input, 'setAttribute', '', 1, 0)("name", sName);
	 _proxy_jslib_handle(input, 'setAttribute', '', 1, 0)("value", sValue);
	return input;
}

//This method facilitates posting data without refreshing the current window.
function PostIframeRequest(form, callback) { 
    
    var parts =  _proxy_jslib_handle( _proxy_jslib_handle(window, 'location', '', 0, 0), 'hostname', '', 0, 0).split(".");
     _proxy_jslib_assign('', document, 'domain', '=', (  _proxy_jslib_handle(parts, (parts.length - 2), 0, 0) + "." +  _proxy_jslib_handle(parts, (parts.length - 1), 0, 0)));
    var remotingDiv = document.createElement("div"); 
     _proxy_jslib_handle(document, 'body', '', 0, 0).appendChild(remotingDiv); 
    remotingDiv.id = "remotingDiv"; 
     _proxy_jslib_assign('', remotingDiv, 'innerHTML', '=', ( "<iframe name='remotingFrame' id='remotingFrame' style='border:0;width:0;height:0;'></iframe>")); 
    remotingDiv.iframe =  _proxy_jslib_handle(document, 'getElementById', '', 1, 0)('remotingFrame'); 
    remotingDiv.form = form; 
     _proxy_jslib_handle(remotingDiv.form, 'setAttribute', '', 1, 0)('target', 'remotingFrame'); 
    remotingDiv.form.target = 'remotingFrame'; 
    remotingDiv.appendChild(remotingDiv.form); 
    remotingDiv.callback = callback; 
    remotingDiv.form.submit(); 
}

function InvokeCallback(returnStatus) {
    try
    {
         _proxy_jslib_handle(document, 'getElementById', '', 1, 0)('remotingDiv').callback(returnStatus);
    }
    catch(ex){}
}

//=== Class UserUtils
if(!window.UA) 	UA = {};
UA.UserUtils = Class.create();
UA.UserUtils.prototype.Callback;

// UA Login and Initialization
// numOfTicks must be a positive integer
// tickInterval must be positive (milliseconds)
// paramsList must be in form of "Param1:value1,Param2:value2".
UA.UserUtils.DoLogIn = function(tickInterval, numOfTicks, callback, paramsList) {
    UA.UserUtils.prototype.Callback = callback;
	UserLogIn();   //This method should be declared by each channel, and its path will be kept in the channel propeties table. 
    
    UA.UserUtils.runPolling(tickInterval, numOfTicks, paramsList);
}

UA.UserUtils.DoLogOut = function(callback) {
    UserLogOut();
}

UA.UserUtils.DoRegister = function(callback) {
    UserRegister();
}

UA.UserUtils.DoEndGameFlow = function(launcherObjects) {
    EndGameFlow(launcherObjects);
}

UA.UserUtils.runPolling = function(tickInterval, numOfTicks, paramsList) {
    var funcStringBuilder = "UA.UserUtils.polling(" + tickInterval + "," + numOfTicks;
    if(paramsList != null && paramsList != undefined)
        funcStringBuilder += ( ",'" + paramsList + "')" );
    else
        funcStringBuilder += ")";

     _proxy_jslib_handle(null, 'setTimeout', setTimeout, 1, 0)(funcStringBuilder, tickInterval);
}

UA.UserUtils.polling = function( tickInterval, numOfTicks, paramsList) {
    if(numOfTicks == 0)
    {
        //tell the caller that the polling ended with no success
        UA.UserUtils.prototype.Callback("User is still Logged off.");
        return;
    }

    if(!UA.User.prototype.IsLoggedOn())
    {
        numOfTicks = numOfTicks - 1;
        UA.UserUtils.runPolling(tickInterval, numOfTicks, paramsList);
        return;
    }
    //Perform InitializeUA()
    UA.UserUtils.InitializeUA(UA.UserUtils.prototype.Callback, paramsList);    
}

//paramsList ->In order to send parameters use this syntax: paramsList = "Param1:value1,Param2:value2";
UA.UserUtils.InitializeUA = function(callback, paramsList) {
    var methodsArr = new (Array)( UA.User.Methods.ISSUBSCRIBED,
                                UA.User.Methods.GETUSER, 
                                UA.User.Methods.HASFREETRIAL,
                                UA.User.Methods.GET_OBERON_CLIENT_USERID, 
                                UA.User.Methods.GET_PARTNER_PROGRAM_ID);
    if (paramsList == undefined)
        paramsList = null;
    else
        methodsArr.push(UA.User.Methods.ISAUTHORIZED); //Harpoon new function.

    UA.UserUtils.prototype.Callback = callback;
    UA.User.prototype.GetData(methodsArr, paramsList, InitializeUASuccess, InitializeUAFail, InitializeUATimeout);
}

function InitializeUASuccess(request) {
    var user = {};
    user.IsSuccessful = true;
    user.IsCompleted = true;
    
    if(request.IsAuthorized != undefined){ 
        if(request.IsAuthorized.Status != "ACCOUNT_ERROR")
            user.IsAuthorized = request.IsAuthorized.Data.isAuthorized;
        else
            user.IsCompleted = false;
    }
    
    if(request.IsSubscribed.Status != "ACCOUNT_ERROR")
        user.IsSubscribed = (request.IsSubscribed.Data.isSubscribed == "True") ? true : false;
    else
        user.IsCompleted = false;
       
    if(request.HasFreeTrial.Status != "ACCOUNT_ERROR")
        user.HasFreeTrial = (request.HasFreeTrial.Data.hasFreeTrial == "True") ? true : false;
    else
        user.IsCompleted = false;
        
    if(request.GetOberonClientUserId.Status != "ACCOUNT_ERROR")
        user.OberonClientUserId = request.GetOberonClientUserId.Data.userGuid;
    else
        user.IsCompleted = false;
        
    if(request.GetPartnerProgramId.Status != "ACCOUNT_ERROR")
        user.PartnerProgramId = request.GetPartnerProgramId.Data.ProgramId;
    else
        user.IsCompleted = false;

    if(request.GetBasicUserDetails.Status != "ACCOUNT_ERROR"){
        user.Nickname = request.GetBasicUserDetails.Data.Nickname;
        user.AvatarURL = request.GetBasicUserDetails.Data.AvatarURL;
        user.AvatarName = request.GetBasicUserDetails.Data.AvatarName;
    }
    else
        user.IsCompleted = false;

    UA.UserUtils.prototype.Callback(user);
}

function InitializeUAFail(request) {
    var user = {};
    user.IsSuccessful = false;
    user.ErrorMessage = request.Status;
    UA.UserUtils.prototype.Callback(user);
}

function InitializeUATimeout(request) {
    var user = {};
    user.IsSuccessful = false;
    user.ErrorMessage = "Timeout";
    UA.UserUtils.prototype.Callback(user);
}
//=== Class UserUtils


/**
 * Expects a number of Numbers of arguments.
 * Treats every number as a number of days since 1-1-1970
 * and returns an array with as many elements as the provided arguments
 * in which every element is a Data-Object, based on the number of days
 * from 1-1-1970 to its responsive argument
 * @param {Number} D1_D2__Dn
 * @private
 */
UA.daysToDate = function( /*d1,d2,d3...*/) {

    var i,arr = [];

    for (i = 0; i < arguments.length ; i++)
         _proxy_jslib_assign('', arr, (i), '=', ( new (Date)( _proxy_jslib_handle(arguments, (i), 0, 0) * 86400000)));

    return arr;

}


//UA.Request.js
/**
 * @namespace
 * UserAccounts
 **/
if(!window.UA) 	UA = {};
//======================================================================================
/**
 * @abscract-class 
 * It is a base-class of request worker-objects.
 * The goal of this classes is to allow multiple asyncronous calls on the same 
 * caller-object-instance, and aid in making the Asyncronous work as transparent as 
 * possible, means to make the callback functions run on the caller-object-instance,
 * A.K.A - this.boss.
 *
 * Jast.Request calls the event handlers on the carrier object they are delivered on. 
 * This class decendents pass thier calls to thier "boss" - the caller-instance.
 *
 * To send the request - the caller class calls the apply method.
 **/

UA.Request = Class.create();

/*    static members	*/
//-------------------------------------------------------------
/**
 * Status OK for OK Jast requests
 **/
UA.Request.STATUS_OK = "OK";
/**
 * Status GENERAL_ERROR
 **/
UA.Request.STATUS_GENERAL_ERROR = "GENERAL_ERROR";
/*    static members	*/
//-------------------------------------------------------------
/**
 * overrides object.toString() as a static member to provide the class name
 **/
 _proxy_jslib_assign('', UA.Request, 'toString', '=', ( function() {
    return "UA.Request";
}))




UA.Request.AsPrototype = function() {
    return new (UA.Request)({},_proxy_jslib_new_function());
}
/*    Constructors  	*/
//-------------------------------------------------------------
/**
 * 
 **/
UA.Request.prototype.initialize = function( oBoss	, fSuccessCallback , fFailCallback, fTimeoutCallback) {
    this.log = Object.extend({},this.log);
   	this.boss = this.log.boss = oBoss;
	/**
	 * Event handler stacks
	 **/
	this.successCallbacks = [];
	this.failiorCallbacks = [];
	this.timeoutCallbacks = [];

    Claim.isFunction(fSuccessCallback, "fSuccessCallback not provided in constructor for: " +  _proxy_jslib_handle(this, 'toString', '', 1, 0)() );
	this.successCallbacks.push(fSuccessCallback);

    if( !fFailCallback ) fFailCallback = oBoss.defaultOnFailior; 
    if( typeof(fFailCallback) == 'function') this.failiorCallbacks.push( fFailCallback );
    
    if( !fTimeoutCallback ) fTimeoutCallback = oBoss.defaultOnTimeout; 
    if( typeof(fTimeoutCallback) == 'function') this.timeoutCallbacks.push( fTimeoutCallback );
    
    this.parameters = {};
}

/*    instance members	*/
//-------------------------------------------------------------
/*
	--	@private	{[object]}	log
	--	@private	{string}	url
	--				{boolean}	isSent
	--				{[Array]}	successCallbacks
	--				{[Array]}	failiorCallbacks
	--				{[Array]}	timeoutCallbacks
*/
/**
 * @private 
 * passes log calls to the log of the "boss"
 **/
UA.Request.prototype.log =  { emit:	 function(iLevel,sText) {
										if(this.boss.log && typeof(this.boss.log.emit) == 'function'){
											this.boss.log.emit(iLevel, sText);
										}else 
											this.log.error("Cannot log for caller-object: " +  _proxy_jslib_handle(this.boss, 'toString', '', 1, 0)() + ". Level: " +iLevel+ ", Message: " + sText);
									 } 
							, fatal: function(sText) { this.emit(Log4Js.FATAL, sText); }
							, error: function(sText) { this.emit(Log4Js.ERROR, sText); }
							, warn:	 function(sText) { this.emit(Log4Js.WARN , sText); }
							, info:	 function(sText) { this.emit(Log4Js.INFO , sText); }
							, debug: function(sText) { this.emit(Log4Js.DEBUG, sText); }
							, log: new (Log4Js.Logger)("UA.Request.log")

 , boss: null

 , toString: function() { return "UA.Request.log"; }
							}
/**
 * @private {string}
 * The url for the Just request
 * Its expected to be initiated in the overriding "initialize(boss)" method.
 **/
UA.Request.prototype.url = "UNSET-VALUE";

/**
 * States if the current instance was sent.
 **/
UA.Request.prototype.isSent = false;



/*    private functions	*/
//-------------------------------------------------------------
/*
	--	dispatch
*/
/**
 * @private
 * sends events to the 'boss' object
 **/
UA.Request.prototype.dispatch = function request_Dispatch(retObj, arrHandlers, sEventName) {
	if(arrHandlers.length == 0){
		this.log.info(sEventName + ' from ' +  _proxy_jslib_handle(this, 'toString', '', 1, 0)() + ' contained no handlers.');
		return;
	}
	this.log.info('Dispatching ' + sEventName + ' from ' +  _proxy_jslib_handle(this, 'toString', '', 1, 0)());

	var i, cb;
	for (i = 0; i <  arrHandlers.length; i++){
		cb =  _proxy_jslib_handle(arrHandlers, (i), 0, 0);
		if (cb && typeof(cb) == 'function'){
			cb.call(this.boss, retObj, this.parameters);
		}
	}
}

/*    public methods	*/
//-------------------------------------------------------------
/*
	-- toString()
	-- onSuccess(request)
	-- onFailure(request)
	-- onTimeout(request)
	-- apply()
*/
/**
 * Overrides Object.toString
 **/
 _proxy_jslib_assign('', UA.Request.prototype, 'toString', '=', ( function() {
	return "[UA.Request(" + this.id + ")] of " +  _proxy_jslib_handle(this.boss, 'toString', '', 1, 0)();
}))






UA.Request.prototype.onSuccess = function(request) {
	this.dispatch(request.result.Data, this.successCallbacks, "onSuccess");
}
UA.Request.prototype.onFailure = function(request) {
    this.log.error("Failed on request of: " +  _proxy_jslib_handle(this.boss, 'toString', '', 1, 0)() + " to url: " + this.urlWithParams + ", Status: " + request.result.Status );
	this.dispatch(request.result, this.failiorCallbacks, "onFailure");
}
UA.Request.prototype.onTimeout = function(request) {
    this.log.error("Timeout on request of: " +  _proxy_jslib_handle(this.boss, 'toString', '', 1, 0)() + " to url: " + this.urlWithParams );
	this.dispatch(request, this.timeoutCallbacks,"onTimeout");
}
/**
 * This method sends the request.
 **/
UA.Request.prototype.apply = function() {
	//single-shot mechanizm
	if (this.isSent) 
		return;
	this.isSent = true;
	
    if (Clearance.level >= Clearance.UNCLASSIFIED)
        this.parameters.cookieData = Clearance.getMagic(Clearance.UNCLASSIFIED);

	var url = Url.appendParams(this.url, this.parameters);
	//url = prompt(url,url);
	this.urlWithParams = url;
	this._JAST = new (Jast.Request)( url, this );
}
//UA.Game.js
//\\//=== configuration constants ===\\//\\

var EMPTY_RESULT = "EMPTY_RESULT";
window.OK = "OK";

//====== Namespace UA
if(!window.UA) UA = {};
//=== Class Game
UA.Game = Class.create();
/*    static members	*/
//-------------------------------------------------------------
/**
 * @private
 * holds references to all requests sent by this instance
 **/
UA.Game.Requests = [];

UA.Game.Methods =	{   GAMEHIGHSCORES:	    "GetGameHighScores",    //1400::"GameHighScores"
					    USERSCORE:			"GetUserScoreData",     //1400::"UserScore"
                        SESSION_CERT:       "GetSingleSessionCert",
                        GRACE_CERTS:        "GetGraceCerts",
                        GETGAMEEVERHIGHSCORES:      "GetGameEverHighScores",
                        GETGAMEWEEKLYHIGHSCORES:    "GetGameWeeklyHighScores",
                        GETGAMEHOURLYHIGHSCORES:    "GetGameHourlyHighScores" 

 }

UA.Game.Scores = {};
UA.Game.Scores.Periods = {};
UA.Game.Scores.Periods.WEEK = "WEEK";
UA.Game.Scores.Periods.HOUR = "HOUR";
UA.Game.Scores.Periods.EVER = "EVER";

// Avatar sizes - matches Avatar.Dimentions class of Application Libraries.
UA.Game.Avatar = {};
UA.Game.Avatar.Size = {};
UA.Game.Avatar.Size.Size150x200 = "Size150x200";
UA.Game.Avatar.Size.Size65x87 = "Size65x87";
UA.Game.Avatar.Size.Size86x115 = "Size86x115";
UA.Game.Avatar.Size.Size98x131 = "Size98x131";
UA.Game.Avatar.Size.Size124x165= "Size124x165"; 
UA.Game.Avatar.Size.Size24x24 =  "Size24x24";  
UA.Game.Avatar.Size.Size48x48 = "Size48x48"; 


/*    members			*/
//-------------------------------------------------------------
UA.Game.prototype.SEND_GAME_DATA_POST_URL = "UNSET_VALUE"; 

UA.Game.prototype.isCachedResponse = false;

/*	  Constructors		*/
//-------------------------------------------------------------
UA.Game.prototype.initialize = function(p_sku) {
	//Claim.isNumber(p_sku ,"UA.Game(Sku): Sku should be a number.");
	//Claim.check(p_sku > 0 && parseInt(p_sku) == p_sku, "UA.Game(Sku)", "Game Sku must be an integer, bigger then 0");

	this._prv = {	Sku: p_sku

 ,	scores: {}	
				};
	this.log = new (Log4Js.Logger)( _proxy_jslib_handle(this, 'toString', '', 1, 0)())

 this.log.info("UA.Game(" + p_sku + ") initiated.");
}


/*    inner class		*/

/* -- start inner class : UA.Game.GameRequest   --*/

/**
 * @class 
 * The goal of this class is to allow multiple calls on the same Game object-instance,
 * and aid in making the Asyncronous work as transparent as possible. 
 * 
 * This inner class extends the "abstract"-class UI.Request
 *
 * The GameRequest prepare the parameters stack based on the Game's Sku.
 * The Jast.Request expects handlers. Assuming that in most cases there will be nothing
 * important to say on case of time-out or of failior, the class provides almost empty 
 * default event-handler stubs. 
 * To make the calls look as if they were called on the UA.Game object, 
 * these stubs pass on the call to the Game Object - if in deed the caller-instance 
 * defined handlers for those cases. 
 **/
UA.Game.GameRequest = Class.createSubclass("UA.Request");
UA.Game.GameRequest.prototype = UA.Request.AsPrototype()

 

 




UA.Game.GameRequest.prototype.initialize = function gameCtor( oGame	, fSuccessCallback , fFailCallback, fTimeoutCallback) {
    if (oGame.isCachedResponse){
        this.url = this.boss.USER_CACHED_HANDLER_URL

 }else{
	    this.url = this.boss.PRIME_HANDLER_URL;
	}
	this.parameters = {	Sku: oGame._prv.Sku,
						Period: "",
						Mode: "" };
}

/* -- end inner class : UA.Game.GameRequest   --*/

/*	private functions	*/
//-------------------------------------------------------------


/**
 * @private
 * Sets up a GameRequest
 *
 * @param {function(result)} fSuccessCallback
 *   Callback function for Success
  * 
 * @param-optional {function(request)} fFailCallback
 *   Callback function for Fail
 *   If the parameter is not supplied, the UA.Game.defaultOnFailior is used
 *
 * @param-optional {function(request)} fTimeoutCallback
 *   Callback function for Timeout
 *   If the parameter is not supplied, the UA.Game.defaultOnTimeout is used
 *  
 */
UA.Game.prototype.getGameRequest = function(fSuccessCallback, fFailCallback, fTimeoutCallback) {
	var r = new (UA.Game.GameRequest)(this,fSuccessCallback, fFailCallback, fTimeoutCallback);

	r.id = UA.Game.Requests.length;
	 _proxy_jslib_assign('', UA.Game.Requests, ( r.id ), '=', ( r));

	return r;
}

/*	public methods	*/
//-------------------------------------------------------------
/**
 * Default failure handler for all requests
 * Possible to be overriden in projectile code
 *
 * @type function
 **/
UA.Game.prototype.defaultOnFailior = null;
/**
 * Default timeout handler for all requests
 * Possible to be overriden in projectile code
 *
 * @type function
 **/
UA.Game.prototype.defaultOnTimeout = null;

/**
 * Overrides Object.toString() 
 **/
 _proxy_jslib_assign('', UA.Game.prototype, 'toString', '=', ( function gameToString() {
	return "[UI.Game(" + this._prv.Sku + ")]";
}))






UA.Game.prototype.GetUserHighScore = function(iMode, fSuccess, fFailure, fTimeout) {
    //default values for optional parameters
    if(iMode == null || isNaN(iMode)) iMode = 0;

	
	//apply a request
	var r = this.getGameRequest(fSuccess, fFailure, fTimeout);
	r.parameters.Mode = iMode;
	r.parameters.MethodName = UA.Game.Methods.USERSCORE;
	r.apply();
	return r;
}

/**
 * Gets the single session certification key.
 * Returns the key to the callback function on the UA.Game instance. 
 * The method will be Invoked with the GETDATA() mechanism (see UA.User.prototype.GetData)
 **/
UA.Game.prototype.GetSingleSessionCert = function(iMode, fSuccess, fFailure, fTimeout) {
	//apply a request
	var r = this.getGameRequest(fSuccess, fFailure, fTimeout);
	r.parameters.methodName = UA.User.Methods.GETDATA;
	r.parameters.MethodList = UA.Game.Methods.SESSION_CERT;
	r.apply();
	return r;
}

/**
 * Gets the single session certification key.
 * Returns the key to the callback function on the UA.Game instance. 
 * The method will be Invoked with the GETDATA() mechanism (see UA.User.prototype.GetData)
 **/
UA.Game.prototype.GetGraceCerts = function(iMode, fSuccess, fFailure, fTimeout) {
	//apply a request
	var r = this.getGameRequest(fSuccess, fFailure, fTimeout);
	r.parameters.MethodName = UA.User.Methods.GETDATA;
	r.parameters.MethodList = UA.Game.Methods.GRACE_CERTS;
	r.apply();
	return r;
}

/**
 * @param {int} iMode
 *  The game mode  (examples of what mode means: arcade, journy, survival, sudden-death)
 *
 * @param {int} iAmount
 *  The top results count
 *
 * @param {} ePeriod
 *	The argument ePeriod can be one from the next values:
						UA.Game.Scores.Periods.WEEK
						UA.Game.Scores.Periods.HOUR
						UA.Game.Scores.Periods.EVER
 *
 * @param {function(result)} fSuccess
 *	The callback function that is expected to be called on success with 'request.result.Data' as a 
 *  as passed argument.
 * 
 * @param {function(result)} fFailure
 *	The callback function that is expected to be called on failure with 'request.result' as the 
 *  passed argument.
 * 
 * @param {function(result)} fTimeout
 *	The callback function that is expected to be called on timeout with 'request' as the 
 *  passed argument.
 * 
 **/

UA.Game.prototype.GetGameHighScores = function(iMode, iAmount, ePeriod, fSuccess, fFail, fTimeout, eSize) {
    var r = this.getGameRequest(fSuccess, fFail, fTimeout);
    r.parameters.Mode = iMode;    
    r.parameters.TopScores = iAmount;
    r.parameters.Period = ePeriod;
    if(eSize == null || eSize == undefined) 
         _proxy_jslib_assign('delete', (r.parameters), ('Size'), '');
    else
        r.parameters.Size = eSize;
	r.parameters.MethodName = UA.Game.Methods.GAMEHIGHSCORES;
    r.apply();
}

// Send game data with POST
UA.Game.prototype.SendGameData = function(gameData, callback) {
	var formSendGameData = document.createElement("form");
	 _proxy_jslib_handle(formSendGameData, 'setAttribute', '', 1, 0)("method", "POST");
	 _proxy_jslib_handle(formSendGameData, 'setAttribute', '', 1, 0)("action", UA.Game.prototype.SEND_GAME_DATA_POST_URL);
	formSendGameData.appendChild(CreateHiddenInput("GameData", gameData));
	formSendGameData.appendChild(CreateHiddenInput("channel", UA.CHANNEL));
	PostIframeRequest(formSendGameData, callback);
}
//UA.User.js
//====== Namespace UA
if(!window.UA) 	UA = {};

//=== Class StaticUser
UA.StaticUser = Class.create();
//=== Class StaticUser

//=== Class User
UA.User = Class.create();
/*    static members	*/
//-------------------------------------------------------------
/**
 * @private
 * holds references to all requests sent by this instance
 **/
UA.User.Requests = [];
/**
 * @private
 * holds all method names that are used with the object's handler
 **/
UA.User.Methods =   { GETUSERDETAILS: "GetUserDetails"

 , GETALLSCORES: "GetAllScores"

 , GETUSERGAMES:	"GetUserGames"

 , HASFREETRIAL: "HasFreeTrial"

 , ISSUBSCRIBED: "IsSubscribed"

 , ISAUTHORIZED: "IsAuthorized"  

 , GETCURRENTPERMITTEDSKUS: "GetCurrentPermittedSKUs"  

 , GETPLANNEDPERMITTEDSKUS: "GetPlannedPermittedSKUs"  

 , GETPACKAGEEXPIRATIONUTCDATE: "GetPackageExpirationUTCDate"  

 , ISNICKNAMEAVAILABLE: "IsNicknameAvailable"

 , GETAVATARXML: "GetAvatarXml"

 , GETWARDROBEXML: "GetWardrobeXml"

 , ISUSERNAMEAVAILABLE: "IsUsernameAvailable"

 , GETUSERTOKENS: "GetUserTokens"

 , GETUSERLOGINDAYS: "GetUserLoginDays"

 , GETHIGHESTMEDAL: "GetHighestMedal"

 , GETPERSONADATABYNICKNAME : "GetPersonaDataByNickname"

 , GETDATA : "GetData"

 , GET_OBERON_CLIENT_USERID : "GetOberonClientUserId"

 , GET_PARTNER_PROGRAM_ID: "GetPartnerProgramId"

 }
/*    members			*/
//-------------------------------------------------------------
UA.User.USER_HANDLER_URL = "UNSET-VALUE";
UA.User.USER_LOGIN_REDIRECT_URL = "UNSET-VALUE";
UA.User.POST_DATA_REDIRECT_URL = "UNSET-VALUE";

UA.User.LOGGED_IN = "LoggedIn";
UA.User.ANONYMOUS = "Anonymous";
/*	  Constructors		*/
//-------------------------------------------------------------
/**
 * public constructor.
 * Sends an ISLOGGEDIN request if the user is logged in to populate user details.
 * No parameters: UserGuid is taken from cookie by Jast.Request.
 **/
UA.User.prototype.initialize = function() {
    this.log = new (Log4Js.Logger)("[UA.User]");
    this.params = {};
}

//function IsLoggedOn(reloadCookies): checks if the user has unclassified cookie.
//      dontReloadCookies: avoid reload cookies and rebuild Clearance or not.
// You can also invoke this method without parameters: UA.User.prototype.IsLoggedOn()
UA.User.prototype.IsLoggedOn = function(dontReloadCookies) {
    if(dontReloadCookies == undefined || dontReloadCookies == false)
        Clearance.refresh();
    return Clearance.hasUnclassified();
}

//function isGuest(reloadCookies): checks if the user is authenticated as guest.
//      dontReloadCookies: reloadCookies reloading cookies and rebuild Clearance or not.
// You can also invoke this method without parameters: UA.User.prototype.isGuest()
UA.User.prototype.isGuest = function(dontReloadCookies) {
    return ( !UA.User.prototype.IsLoggedOn(dontReloadCookies) || Clearance.isGuest() );
}

UA.User.prototype.LogOff = function() { 
    Clearance.forget( Url.relativeUrl( { withClearanceParams: false, withHereParams: true } ) ); 
}

UA.User.prototype.getCookieData = function(isEscaped) { 
    var cookieData = Clearance.getMagic(Clearance.UNCLASSIFIED);
    if(isEscaped)
        cookieData = escape(cookieData);
    return cookieData;
}


/*    inner class		*/
//-------------------------------------------------------------

/* --- start inner class : UA.User.UserRequest   --*/
/**
 * @class 
 * The goal of this class is to allow multiple calls on the same User object-instance,
 * and aid in making the Asyncronous work as transparent as possible. 
 * 
 * This inner class extends the "abstract"-class UI.Request
 *
 * ...
 **/
UA.User.UserRequest = Class.createSubclass("UA.Request");
UA.User.UserRequest.prototype = UA.Request.AsPrototype()



UA.User.UserRequest.prototype.initialize = function userReqCTor(oUser, fSuccessCallback, fFailCallback, fTimeoutCallback) {
	
	var curUrl = this.boss.USER_HANDLER_URL;
	if( (oUser.params.isSecured) && (curUrl.indexOf('HTTPS') == -1) && (curUrl.indexOf('https') == -1) )
        curUrl =  _proxy_jslib_handle( _proxy_jslib_handle(curUrl, 'replace', '', 1, 0)('HTTP', 'HTTPS'), 'replace', '', 1, 0)('http', 'https');
	this.url = curUrl;
	
     _proxy_jslib_assign('delete', (oUser.params), ('isSecured'), '');
    this.boss = this.log.boss = oUser;
    this.parameters = Object.extend({}, this.boss.params);
}

UA.User.UserRequest.prototype.addParameter = function(key, val) {
     _proxy_jslib_assign('', this.parameters, (key), '=', ( val));
}

/* --- end inner class : UA.User.UserRequest   --*/

// Diamond version of GetDetails.
// Returns comprehensive data: nickname, gender, birthday splitted to day, 
// month and year, country, region, acceptedTermsAndConditions (True/False), 
// termsAndConditionsVersion, emailOptIn (send news letters - True/False), zipCode. 
UA.User.prototype.GetUserDetails = function(fSuccessCallback, fFailCallback, fTimeoutCallback) {
	var r = new (UA.User.UserRequest)(this, fSuccessCallback, fFailCallback, fTimeoutCallback);
	r.parameters.methodName = UA.User.Methods.GETUSERDETAILS;
	r.apply();
}

/**
 * Gets the user recent games along with their details and the user achievements.
 * Returns the SKUs and optionally their top scores and the user's high score, rank and last play time.
 *  Sample of use:
 *      var u = new UA.User()
 *      u.params.maxGames = 20; //optional parameter (the default is all games)
 *      u.params.bitmask = 15;  //optional parameter (the default is all fields)
 *      u.GetUserGames(GetUserGames_onSuccess, GetUserGames_onFailer, OnTimeout);
 *
 *
 * @param {function(result)} fSuccess
 *	The callback function that is expected to be called on success with 'request.result.Data' as a 
 *  as passed argument.
 * 
 * @param {function(result)} fFailure
 *	The callback function that is expected to be called on failure with 'request.result' as the 
 *  passed argument.
 * 
 * @param {function(result)} fTimeout
 *	The callback function that is expected to be called on timeout with 'request' as the 
 *  passed argument.
 * 
 **/
UA.User.prototype.GetUserGames = function(fSuccessCallback, fFailCallback, fTimeoutCallback) {
	var r = new (UA.User.UserRequest)(this, fSuccessCallback, fFailCallback, fTimeoutCallback);
	r.parameters.methodName = UA.User.Methods.GETUSERGAMES;
	r.apply();
}

// Diamond.
// Tells whether the given nickname is available for the given community (the community is retrieved according to the channel code).
// In addition, a profanity check is being performed, for which the nickname language is needed.
// Returns true if nickname is valid and available for use. False otherwise.
UA.User.prototype.IsNicknameAvailable = function(sNickname, sLanguage, fSuccessCallback, fFailCallback, fTimeoutCallback) {
	var r = new (UA.User.UserRequest)(this, fSuccessCallback, fFailCallback, fTimeoutCallback);
    r.parameters.Nickname = sNickname;
    r.parameters.Language = sLanguage;
	r.parameters.methodName = UA.User.Methods.ISNICKNAMEAVAILABLE;
	r.apply();
}

// Gizmo.
// Tells whether the given username is available for the given authentication namespace (retrieved according to the channel code).
// Returns true if username is available for use. False otherwise.
UA.User.prototype.IsUsernameAvailable = function(sUsername, sLanguage, fSuccessCallback, fFailCallback, fTimeoutCallback) {
	var r = new (UA.User.UserRequest)(this, fSuccessCallback, fFailCallback, fTimeoutCallback);
    r.parameters.Username = sUsername;
    r.parameters.Language = sLanguage;
	r.parameters.methodName = UA.User.Methods.ISUSERNAMEAVAILABLE;
	r.apply();
}

// Avatar sizes - matches Avatar.Dimentions class of Application Libraries.
//UA.User.Avatar = {};
//UA.User.Avatar.Size = {};
//UA.User.Avatar.Size.Size150x200 = "Size150x200";
//UA.User.Avatar.Size.Size65x87 = "Size65x87";
//UA.User.Avatar.Size.Size86x115 = "Size86x115";
//UA.User.Avatar.Size.Size98x131 = "Size98x131";
//UA.User.Avatar.Size.Size124x165= "Size124x165"; 
//UA.User.Avatar.Size.Size24x24 =  "Size24x24";  
//UA.User.Avatar.Size.Size48x48 = "Size48x48";      

// Get The current tiny-avatar XML of a user (if the nickname parameter is supplied - of the required persona, otherwise - the authenticated user)
UA.User.prototype.GetAvatarXml = function(fSuccessCallback, fFailCallback, fTimeoutCallback) {
	var r = new (UA.User.UserRequest)(this, fSuccessCallback, fFailCallback, fTimeoutCallback);
    r.parameters.methodName = UA.User.Methods.GETAVATARXML;
	r.apply();
}

// Get wardrobe XML for the authenticated user
UA.User.prototype.GetWardrobeXml = function(fSuccessCallback, fFailCallback, fTimeoutCallback) {
	var r = new (UA.User.UserRequest)(this, fSuccessCallback, fFailCallback, fTimeoutCallback);
    r.parameters.methodName = UA.User.Methods.GETWARDROBEXML;
	r.apply();
}

// Get the user's total tokens number
UA.User.prototype.GetUserTokens = function(fSuccessCallback, fFailCallback, fTimeoutCallback) {
	var r = new (UA.User.UserRequest)(this, fSuccessCallback, fFailCallback, fTimeoutCallback);
	r.parameters.methodName = UA.User.Methods.GETUSERTOKENS;
	r.apply();
}

// Get the user's login days
UA.User.prototype.GetUserLoginDays = function(fSuccessCallback, fFailCallback, fTimeoutCallback) {
    if(this.isGuest()){
        var data = {};
        data.Status = "ACCOUNT_NOT_CREATED";
        fFailCallback(data);
        return;
    }
	var r = new (UA.User.UserRequest)(this, fSuccessCallback, fFailCallback, fTimeoutCallback);
	r.parameters.methodName = UA.User.Methods.GETUSERLOGINDAYS;
	r.apply();
}

// Get user's highest medal.
// Returns game sku and user ranking.
UA.User.prototype.GetHighestMedal = function(fSuccessCallback, fFailCallback, fTimeoutCallback) {
	var r = new (UA.User.UserRequest)(this, fSuccessCallback, fFailCallback, fTimeoutCallback);
	r.parameters.methodName = UA.User.Methods.GETHIGHESTMEDAL;
	r.apply();
}

// Obsolete Method - will be remove in UA1800
UA.User.prototype.GetPersonaDataByNickname = function(nickname, avatarSize, sku, fSuccessCallback, fFailCallback, fTimeoutCallback) {
	var r = new (UA.User.UserRequest)(this, fSuccessCallback, fFailCallback, fTimeoutCallback);
	if (nickname != null)
        r.parameters.Nickname = nickname;
    r.parameters.AvatarSize = avatarSize;
    r.parameters.Sku = sku;
	r.parameters.methodName = UA.User.Methods.GETPERSONADATABYNICKNAME;
	r.apply();
}

// Returns a persona's data : Avatar-Xml, Game's data (if a nickname is not supplied, the data will be returned for the authenticated user)
//A mandatary parameter is sku.
UA.User.prototype.GetPersonaData = function(fSuccessCallback, fFailCallback, fTimeoutCallback) {
	var r = new (UA.User.UserRequest)(this, fSuccessCallback, fFailCallback, fTimeoutCallback);
	r.parameters.methodName = UA.User.Methods.GETPERSONADATABYNICKNAME;
	r.apply();
}

UA.User.ReportAbuse = function(abusingNickname, description, utcTime, retURL) {
    var formReportAbuse = document.createElement("form");
	 _proxy_jslib_handle(formReportAbuse, 'setAttribute', '', 1, 0)("method", "POST");
	 _proxy_jslib_handle(formReportAbuse, 'setAttribute', '', 1, 0)("action", UA.User.POST_DATA_REDIRECT_URL);
	
	cookieData = Clearance.getMagic(Clearance.UNCLASSIFIED);
    formReportAbuse.appendChild(CreateHiddenInput("cookieData", cookieData));

	formReportAbuse.appendChild(CreateHiddenInput("abusingNickname", abusingNickname));	
	formReportAbuse.appendChild(CreateHiddenInput("description", description));
	formReportAbuse.appendChild(CreateHiddenInput("utcTime", utcTime));
	formReportAbuse.appendChild(CreateHiddenInput("retURL", retURL));
	
	formReportAbuse.appendChild(CreateHiddenInput("methodName", "ReportAbuse"));
    formReportAbuse.appendChild(CreateHiddenInput("channel", UA.CHANNEL));	
	
	 _proxy_jslib_handle(document, 'body', '', 0, 0).insertBefore(formReportAbuse, null);
	formReportAbuse.submit();
}

//-------------------------------------------------------------
/**
 * Default failure handler for all requests
 * Possible to be overriden in projectile code
 *
 * @type function
 **/
UA.User.prototype.defaultOnFailior = null;
/**
 * Default timeout handler for all requests
 * Possible to be overriden in projectile code
 *
 * @type function
 **/
UA.User.prototype.defaultOnTimeout = null;

/**
 * Overrides the Object.toString()
 **/
 _proxy_jslib_assign('', UA.User.prototype, 'toString', '=', ( function() {
    return "[User: " + this.Nickname + "]";
}))




UA.User.prototype.getUserRequest = function(fSuccessCallback) {
	var r = new (UA.User.UserRequest)(this,fSuccessCallback);

	r.id = UA.User.Requests.length;
	 _proxy_jslib_assign('', UA.User.Requests, ( r.id ), '=', ( r));

	return r;
}

// User Login send the POST data for login
UA.User.prototype.LoginRedirect = function(email, password, isPasswordRemember) {
	var formLogin = document.createElement("form");
	 _proxy_jslib_handle(formLogin, 'setAttribute', '', 1, 0)("method", "POST");
	 _proxy_jslib_handle(formLogin, 'setAttribute', '', 1, 0)("action", UA.User.prototype.USER_LOGIN_REDIRECT_URL);
	
	formLogin.appendChild(CreateHiddenInput("email", email));
	formLogin.appendChild(CreateHiddenInput("password", password));
	formLogin.appendChild(CreateHiddenInput("remember", isPasswordRemember));
		
	formLogin.appendChild(CreateHiddenInput("methodName", "Login"));
	formLogin.appendChild(CreateHiddenInput("channel", UA.CHANNEL));
	
	 _proxy_jslib_handle(document, 'body', '', 0, 0).insertBefore(formLogin, null);
	formLogin.submit();
}

// User Login As Guest send the POST data for login
UA.User.prototype.LoginAsGuestRedirect = function() {
	var formLogin = document.createElement("form");
	 _proxy_jslib_handle(formLogin, 'setAttribute', '', 1, 0)("method", "POST");
	 _proxy_jslib_handle(formLogin, 'setAttribute', '', 1, 0)("action", UA.User.prototype.USER_LOGIN_REDIRECT_URL);
	
	formLogin.appendChild(CreateHiddenInput("methodName", "LoginAsGuest"));
	formLogin.appendChild(CreateHiddenInput("channel", UA.CHANNEL));
	
	 _proxy_jslib_handle(document, 'body', '', 0, 0).insertBefore(formLogin, null);
	formLogin.submit();
}

UA.User.SendForgotMail = function(email) {
    var formLogin = document.createElement("form");
	 _proxy_jslib_handle(formLogin, 'setAttribute', '', 1, 0)("method", "POST");
	 _proxy_jslib_handle(formLogin, 'setAttribute', '', 1, 0)("action", UA.User.prototype.USER_LOGIN_REDIRECT_URL);
	
	formLogin.appendChild(CreateHiddenInput("email", email));
	
	formLogin.appendChild(CreateHiddenInput("methodName", "SendForgotMail"));
	formLogin.appendChild(CreateHiddenInput("channel", UA.CHANNEL));
	
	 _proxy_jslib_handle(document, 'body', '', 0, 0).insertBefore(formLogin, null);
	formLogin.submit();
}

//This method facilitate the invocation of one or more processing methods (handlers) as a batch
//That is the prefered way to invoke server-side processing methods
// methodsArr: an array of server-side methods (one or more) to be invoked.
// paramsList: a string of parameters for the methods in the format of "Param1:value1,Param2:value2", or null.
// OnSuccess The method return a <complex JASON> object like 
//              {"method1": {sub-jason1}, "method2": {sub-jason2}, "method3":{sub-jason3} ��,"methodN": {sub-jasonN} }  
// OnFailure The method return a JASON object like 
//  {{Status: '<Cause>' }, {Data: {<complex JASON>} } 
UA.User.prototype.GetData = function(methodsArr, paramsList, fSuccessCallback, fFailCallback, fTimeoutCallback) {
	if(methodsArr.length == 0){
	    return;
	}
	var r = new (UA.User.UserRequest)(this, fSuccessCallback, fFailCallback, fTimeoutCallback);
	r.parameters.methodName = UA.User.Methods.GETDATA;
	
	//Chaining the methods to invoke as one string
	var methodsStr = methodsArr[0];
	for(var i = 1 ; i < methodsArr.length ; i++)
	{
	    methodsStr += ( "," +  _proxy_jslib_handle(methodsArr, (i), 0, 0) );
	}
	r.parameters.MethodList = methodsStr;
	
  	//Adding the parameters that needs to be sent. 
  	if(paramsList != null)
  	{
  	    var paramsArr = paramsList.split(",");
	    for(var i = 0 ; i < paramsArr.length ; i++)
	    {
	        var kNv =  _proxy_jslib_handle(paramsArr, (i), 0, 0).split(":");  //key and value
	        r.addParameter(kNv[0], kNv[1]);
	    }
	}
	r.apply();
}

/**
 * Get cached data. Search for the data in the cookie, and if not available,
 * retrives the data from the server.
 *
 * @param {function(result)} fSuccess
 *	The callback function that is expected to be called on success with 'cachedData' as 
 *  passed argument, that contains:
 *  <dl compact>
 *   <dt>gender</dt><dd>
 *    The users gender (Male / Female).
 *   </dd>
 *   <dt>birthYear</dt><dd>
 *    The year in which the user was born (YYYY).
 *   </dd>
 *   <dt>zipCode</dt><dd>
 *    Zip code (ZZZZZ).
 *   </dd>
 *  </dl>
 * 
 * @param {function(result)} fFailure
 *	The callback function that is expected to be called on failure with 'request.result' as the 
 *  passed argument (resulted from {@link User#GetUserDetails}).
 * 
 * @param {function(result)} fTimeout
 *	The callback function that is expected to be called on timeout with 'request' as the 
 *  passed argument (resulted from {@link User#GetUserDetails}).
 */
UA.User.prototype.getCachedData = function(fSuccessCallback, fFailCallback, fTimeoutCallback) {
    UA.User.prototype.getCachedData.CACHED_DATA_COOKIE_NAME = 'uaCachedData';
    this.getCachedData_OnSuccess = fSuccessCallback;

    this.log.debug('getCachedData - Searching for cached data in cookie.');
    this.cachedData = Cookies.get(UA.User.prototype.getCachedData.CACHED_DATA_COOKIE_NAME);
    if(this.cachedData != undefined && this.cachedData != null)
    {
        this.log.debug('getCachedData - Cached data found in cookie.');
        this.getCachedData_OnSuccess(this.cachedData);
    }
    else
    {
        this.log.debug('getCachedData - No cached data in cookie. Retreiving data from server.');
        this.GetUserDetails(UA.User.prototype.getCachedData_OnSuccess, fFailCallback, fTimeoutCallback);
    }
}

/**
 * @private
 * The callback function that is expected to be called on success of {@link User#GetUserDetails}
 * that is called by {@link User#getCachedData}.
 * Created the Actually make the request for data to the server. This is done by writing a
 * script tag 'cachedData' object, set the cookie and call the success callback function
 * defined in {@link User#getCachedData}.
 *
 * @param {Object} userDetails
 *  The server-provided result (request.result.Data) returned from {@link User#GetUserDetails}.
 */
UA.User.prototype.getCachedData_OnSuccess = function(userDetails) {
    this.cachedData = {};
    this.cachedData.gender = userDetails.gender;
    this.cachedData.birthYear = parseInt(userDetails.birthYear);
    this.cachedData.zipCode = parseInt(userDetails.zipCode);
    
    this.log.debug('getCachedData - Writing cached data in cookie.');
    Cookies.set(UA.User.prototype.getCachedData.CACHED_DATA_COOKIE_NAME, 
                this.cachedData, 
                {expires:Cookies.expiration(86400000)}); //86400000 = 24h*60m*60s*1000ms
    
    this.getCachedData_OnSuccess(this.cachedData);
}

 ;
_proxy_jslib_flush_write_buffers() ;