/**
 * @singleton ABTest
 */
ABTest = {};     

/**
 * days for expiry of user-group mark cookie
 * @type Number
 */
ABTest.cookieExpiryDays = 21;

/**
 * collection. key - the original pcode, value - object{abCodes:Array, exe}
 * @type Object
 */
ABTest.tested = {};

ABTest.tested.all = [];

/**
 * collection. key - the ab pcode, value - object{reportName, exe}
 * @type Object 
 */
ABTest.abGames = {};


/**
 * Adds a game to the tested-games array
 *
 * @param {Number} gameCode 
 *           The product code of the original game
 * @param {String} exeFile
 *           The name of the installer file of the original tested game
 */
ABTest.addTestedGame = function(gameCode, sReportName, exeFile)
{
	return this.tested.all[this.tested.all.length] = this.tested[gameCode] = {abCodes: [], abGames: [], exe: exeFile , code: gameCode, addABGame: this.prv_addABGame, reportName: sReportName.replace("'","’") };
}
/**
 * Implementation of a function that adds a AB-Test game for a tested game instance
 *
 * TRICKY: Executed on the tested-game scope, and not on the ABTest scope!
 *
 * @param {Number} abCode
 *           The product code of the ab-game of the tested game
 * @param {String} abReportName
 *           The report name name of the ab-game tested game
 * @param {String} abExeFile
 *           The name of the installer file of the ab-game tested game
 * 
 */
ABTest.prv_addABGame = function(abCode, abReportName, abExeFile, abReportName)
{
	this.abCodes[ this.abCodes.length ] = abCode;
	ABTest.abGames[abCode] = 
		this.abGames[ this.abGames.length ] = 
			{reportName: abReportName.replace("'","’") , exe: abExeFile, code: abCode };
	return this;
}

/**
 * selects a group for the user and writes it in a cookie
 * @param {Number} pCode 
 *           The product code of the tested game
 * @private
 * @returns the user group digit as a string
 * @type String
 */
ABTest.getUserRandomGroup = function(pCode) 
{
    var currentDateMillis = (new Date()).getTime(); 
    var sGroupIndex = String(currentDateMillis % this.tested[pCode].abCodes.length ); 
    var sUTCExpiry = ( new Date(currentDateMillis + this.cookieExpiryDays * 24 * 60 * 60 * 1000) ).toUTCString();
    document.cookie = 'ABTest_' + pCode + '=' + sGroupIndex + '; expires=' + sUTCExpiry + '; domain=' + location.host.substr(location.host.indexOf("."))
    Cookies.rawByName['ABTest_' + pCode] = sGroupIndex;
    return sGroupIndex;
}

/**
 * gets the user group, or selects one for him and writes it in a cookie
 * @param {Number} pCode 
 *           The product code of the tested game
 * @returns the user group digit as a string
 * @type String
 */
ABTest.getUserGroup = function(pCode)
{
    return Cookies.rawByName['ABTest_' + pCode] || this.getUserRandomGroup(pCode);
}

/**
 * wrap for logDownload to preserve 'this' scope and the 'event' object(FF/IE)
 *
 * TRICKY: executed from the A.onclick event scope, and not from ABTest scope!
 *
 * @param {Number} pCode 
 *           The product code of the original game
 * @param {String} omnitureChannel 
 *           The omniture suit of the channel
 * @param {String} gameReportName 
 *           The report-name of the original game
 * @private
 */
ABTest.omnitureLogDownload = function(gameCode, omnitureChannel, gameReportName)
{
	var oDwnld = {code: gameCode, channel: omnitureChannel, reportName: gameReportName};

    var myEvent = window.event;
    //mozilla based - extract the 'event' argument 
    if(!myEvent)
    {
        var f = ABTest.omnitureLogDownload.caller;
        if (f && f.arguments &&  f.arguments.length)
             myEvent = f.arguments[0];
    }

    ABTest.controlDownload(oDwnld, myEvent);

    ABTest._omnitureLogDownload(oDwnld.code, oDwnld.channel, oDwnld.reportName);
}

/**
 * when a download is of a tested game - changes the properties of the 
 * passed download-request object and the .href of the <A> DOM-element.
 *
 * @param {Object} oDwnld
 *       expected to be : {code: <Number>,channel: <String>,reportName: <String>}    
 * @param {Event} event
 *			 The event object (FF or IE event)
 * @private
 */
ABTest.controlDownload = function(oDwnld, event)
{
    var testedGame = this.tested[ oDwnld.code ];
    if(testedGame)
    {
        var abCode = testedGame.abCodes[ this.getUserGroup( oDwnld.code ) ];

		var a = Event.findElement(event,"A");
        a.href = a.href.replace( new RegExp(testedGame.exe, "gi") , this.abGames[ abCode ].exe.toLowerCase() );
        
        oDwnld.reportName = this.abGames[ abCode ].reportName;
        oDwnld.code = abCode;
    }
}

/**
 * takes over the page: if its gamepage - redirects, 
 * otherwise - replaces omnitureLogDownload
 */
ABTest.takeOver = function()
{
    var gameCode = Url.here.params.code;

	/* any page that run under a tested-game context should run its AB-Game context */
	if( this.tested[gameCode] )
        return location.replace( location.href.replace( gameCode , this.tested[ gameCode ].abCodes[ this.getUserGroup( gameCode ) ] ) );
	/* if the page already runs in an AB-Game context - leave it as is */
	else if ( this.abGames[gameCode] )
		return;
	/* any other case - must capture the 'omnitureLogDownload' function */
	else if (window.omnitureLogDownload == undefined) 
		return setTimeout('ABTest.takeOver();',20);

    this._omnitureLogDownload = window.omnitureLogDownload;
    window.omnitureLogDownload = this.omnitureLogDownload;
}
//---- call the Take Over function
ABTest.takeOver();