﻿function Permissions( userPermissionsList, userRolesList, permFuncs, defaultAccessRights, mainObj )
{
	this.AccessRightsView = 0x01;
	this.AccessRightsAdd = 0x04;
	this.AccessRightsEdit = 0x10;
	this.AccessRightsDelete = 0x40;
	this.AccessRightsAdvancedView = 0x02;
	this.AccessRightsAdvancedAdd = 0x08;
	this.AccessRightsAdvancedEdit = 0x20;
	this.AccessRightsAdvancedDelete = 0x80;
	this.AccessRightsSystemView = 0x03;
	this.AccessRightsSystemAdd = 0x0C;
	this.AccessRightsSystemEdit = 0x30;
	this.AccessRightsSystemDelete = 0xC0;
	this.AccessRightsSeasonOverride = 0x100;
	this.AccessRightsImportExport = 0x200;
	this.AccessRightsConfirm = 0x400;
	this.AccessRightsReject = 0x800;
	this.AccessRightsUse = 0x1000;

	this.AccessRightsHasJuniors = 0x2000;
	this.SARights = 0x1FFF;
	this.EditAccessRights = this.AccessRightsAdd | this.AccessRightsEdit | this.AccessRightsDelete | this.AccessRightsAdvancedEdit | this.AccessRightsAdvancedDelete | this.AccessRightsSystemEdit | this.AccessRightsImportExport;
	this.Int64Conversion = "0123456789ABCDEFGHIJLKMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz{|";
	
	this.IntToInt64 = function( num )
	{
		var code = [];
		var num1 = Math.floor(num / 64);
		var num2 = num % 64;
		code.push( this.Int64Conversion.charAt([num1]) );
		code.push( this.Int64Conversion.charAt([num2]) );
		return code.join("");
	}

	this.ParseBase64 = function( code )
	{
		var num = code - 48;
		if( num > 9 )
			num -= 7;
		if( num > 35 )
			num -= 6;
		return num;
	}

	this.ParseInt64 = function( code )
	{
		var num1 = this.ParseBase64( code.charCodeAt(0) );
		var num2 = this.ParseBase64( code.charCodeAt(1) );
		return num2 + (64*num1);
	}

	this.DecodeOldAccessString = function( accessRights )
	{
		var accessCodes = {};
		if( accessRights != null )
		{
			var codeList, permissionID, permObj;
			var list = accessRights.split(",");
			if( list != null )
			{
				var inx = 0;
				for( permissionID in this.userPermissionsList )
				{
					permObj = this.userPermissionsList[permissionID];
					code = list[inx++];
					codeList = [];
					if( code.length >= 2 )
						codeList.push( this.ParseInt64( code.substr(0,2) ) );
					if( code.length >= 4 )
						codeList.push( this.ParseInt64( code.substr(2,2) ) );
					if( code.length >= 6 )
						codeList.push( this.ParseInt64( code.substr(4,2) ) );
					accessCodes[permissionID] = codeList;
				}
			}
			else
				{description:throw "Invalid User Permissions, Please inform the System Administrator"};
		}
		return accessCodes;
	}
	
	this.DecodeAccessString = function( accessRights )
	{
		if( typeof(accessRights) == "string" && accessRights.indexOf(",") != -1 )
			return this.DecodeOldAccessString( accessRights );
		var accessCodes = {};
		if( accessRights != null )
		{
			var inx = 0;
			var permObj, permissionID, codeList;
			while( inx < accessRights.length )
			{
				codeList = [];
				permissionID = this.ParseInt64( accessRights.substr(inx,2) );
				if( permissionID == 0 )
				{
					inx -= 2;
					permissionID = this.ParseInt64( accessRights.substr(inx,2) );
				}
				inx += 2;
				if( permissionID < this.AccessRightsHasJuniors )
				{
					if( inx+2 > accessRights.length )
						throw "Error parsing Access Rights string";
					codeList.push( this.ParseInt64( accessRights.substr(inx,2) ) );
					inx += 2;
				}
				else
				{
					if( inx+6 > accessRights.length )
						throw "Error parsing Access Rights string";
					codeList.push( this.ParseInt64( accessRights.substr(inx,2) ) );
					codeList.push( this.ParseInt64( accessRights.substr(inx+2,2) ) );
					codeList.push( this.ParseInt64( accessRights.substr(inx+4,2) ) );
					inx += 6;
					permissionID = permissionID - this.AccessRightsHasJuniors;
				}
				accessCodes[permissionID] = codeList;
			}
		}
		return accessCodes;
	}

	this.ConvertAccessStringToJson = function( accessRights )
	{
		var accessCodes;
		if( typeof(accessRights) == "string" )
		{
			accessCodes = this.DecodeAccessString( accessRights );
		}
		else
		{
			accessCodes = accessRights;
		}
		var js, codeList, codes = [];
		for( var permissionID in accessCodes )
		{
			codeList = accessCodes[permissionID];
			if( codeList.join == null )
			{
				js = [permissionID,":["];
				js.push( codeList.AdultPermissions );
				if( codeList.JuniorPermissions != null )
				{
					js.push( "," );
					js.push( codeList.JuniorPermissions );
				}
				if( codeList.SchoolPermissions != null )
				{
					js.push( "," );
					js.push( codeList.SchoolPermissions );
				}
				js.push( "]" );
				codes.push( js.join("") );
			}
			else
				codes.push( permissionID+":["+codeList.join(",")+"]" );
		}
		return "{"+codes.join(",")+"}";
	}
	
	this.DecodeRawAccessCodes = function( rawAccessCodes )
	{
		var codeList, i, row;
		var accessCodes = {};
		for( i=0; i<rawAccessCodes.length; i++ )
		{
			row = rawAccessCodes[i];
			if( row.PermissionID != null )
			{
				codeList = [row.AdultPermissions];
				if( row.JuniorPermissions != null || row.SchoolPermissions != null )
				{
					codeList.push( row.JuniorPermissions == null ? 0 : row.JuniorPermissions );
					codeList.push( row.SchoolPermissions == null ? 0 : row.SchoolPermissions );
				}
				accessCodes[row.PermissionID] = codeList;
			}
		}
		if( codes.length == 0 )
			return null;
		return accessCodes;
	}
	
	this.ConvertAccessCodesToJson = function( rawAccessCodes )
	{
		var codeList, i, row, permissionID;
		var codes = [];
		for( var key in rawAccessCodes )
		{
			row = rawAccessCodes[key];
			permissionID = null;
			if( rawAccessCodes.length == null )
				permissionID = key;
			else
				permissionID = row.PermissionID;
			if( permissionID != null )
			{
				if( row.length == null )
				{
					codeList = [row.AdultPermissions];
					if( row.JuniorPermissions != null || row.SchoolPermissions != null )
					{
						codeList.push( row.JuniorPermissions == null ? 0 : row.JuniorPermissions );
						codeList.push( row.SchoolPermissions == null ? 0 : row.SchoolPermissions );
					}
					codes.push( permissionID+":["+codeList.join(",")+"]" );
				}
				else
				{
					codes.push( permissionID+":["+row.join(",")+"]" );
				}
			}
		}
		if( codes.length == 0 )
			return "null";
		return "{"+codes.join(",")+"}";
	}

	this.BuildAccessString = function( accessCodes )
	{
		var i, code, permCode, permObj;
		var accessRights = [];
		for( var permissionID in accessCodes )
		{
			permObj = accessCodes[permissionID];
			permissionID = parseInt(permissionID,10);
			if( permObj.length > 1 )
				permissionID += this.AccessRightsHasJuniors;
			accessRights.push( this.IntToInt64( permissionID ) );
			for( i=0; i<permObj.length; i++ )
				accessRights.push( this.IntToInt64( permObj[i] ) );
		}
		return accessRights.join("");
	}

	this.BuildSysAdminAccessRights = function()
	{
		var permObj;
		var accessCodes = {};
		for( permissionID in this.userPermissionsList )
		{
			permObj = this.userPermissionsList[permissionID];
			var enabledList = permObj.websites[website];
			if( enabledList != null )
			{
				if( enabledList.juniorsEnabled || enabledList.schoolsEnabled )
				{
					accessCodes[permissionID] = [this.SARights,this.SARights,this.SARights];
				}
				else
				{
					accessCodes[permissionID] = [this.SARights];
				}
			}
			else
			{
				accessCodes[permissionID] = [0];
			}
		}
		return accessCodes;
	}
	
	this.LogicalOrAccessRights = function( rights1, rights2 )
	{
		if( rights1 == null )
			return rights2;
		if( rights2 == null )
			return rights1;
		var permObj, a1, a2, c1, c2, i, codes, count;
		var accessCodes = [];
		for( permID in this.userPermissionsList )
		{
			permObj = this.userPermissionsList[permID];
			a1 = rights1[permID];
			a2 = rights2[permID];
			if( a1 == null )
			{
				if( a2 != null )
					accessCodes[permID] = a2;
			}
			else
			{
				if( a2 != null )
				{
					var enabledList = permObj.websites[website];
					if( enabledList != null )
					{
						codes = [];
						count = 1;
						if( enabledList.juniorsEnabled || enabledList.schoolsEnabled )
							count = 3;
						for( i=0; i<count; i++ )
						{
							if( i < a1.length )
							{
								if( i < a2.length )
									codes.push( a1[i] | a2[i] );
								else
									codes.push( a1[i] );
							}
							else
							{
								if( i < a2.length )
									codes.push( a2[i] );
								else
									codes.push( 0 );
							}
						}
						accessCodes[permID] = codes;
					}
				}
				else
					accessCodes[permID] = a1;
			}
		}
		return accessCodes;
	}
	
	// Methods

	this.SetLogonState = function( data )
	{
		if( data.isLoggedOn )
		{
			this.userRolesInfo = data.UserRolesInfo;
			this.userPlayerID = data.PlayerID;
			this.canLockLogins = data.CanLockLogins;
			this.canChangePassword = data.CanChangePassword
			this.isSysAdmin = data.SysAdmin;
			this.userID = data.UserID;
			this.username = data.Username;
		}
		else
		{
			this.userRolesInfo = {0:{}};
			this.userPlayerID = 0;
			this.canLockLogins = false;
			this.canChangePassword = false;
			this.isSysAdmin = false;
			this.userID = 0;
			this.username = "";
		}
		if( this.serverInstance )
		{
			Session("URI") = this.userRolesInfo;
			Session("PID") = this.userPlayerID;
			Session("LL") = this.canLockLogins;
			Session("CP") = this.canChangePassword;
			Session("SA") = this.isSysAdmin;
			Session("UID") = this.userID;
			Session("UN") = this.username;
		}
	}
	
	this.GetDefaultAccessRights = function()
	{
		return this.defaultAccessRights;
	}

	this.BuildTeamAccessListJson = function()
	{
		if( dbCmdObj != null && this.serverInstance )
		{
			var htm = [];
			if( this.teamAccessList == null )
				htm.push( 'var teamAccessList = null;\n' );
			else
			{
				htm.push( 'var teamAccessList = {' );
				var jsList = [];
				for( var teamID in this.teamAccessList )
				{
					jsList.push( teamID+':true' );
				}
				htm.push( jsList.join(",") );
				htm.push( '};' );
			}
			return htm.join("");
		}
		throw {description:"BuildTeamAccessListJson method not available for client code"};
	}

	this.GetUserRoleList = function()
	{
		if( this.serverInstance )
		{
			this.userRoles = [];
			var userRoles = Session("URI");
			if( userRoles != null )
			{
				for( var ur in userRoles )
				{
					this.userRoles.push( ur );
				}
			}
		}
		return this.userRoles;
	}

	this.GetUserRolesInfo = function()
	{
		if( this.serverInstance )
		{
			this.userRolesInfo = Session("URI");
			if( this.userRolesInfo == null )
			{
				this.userRolesInfo = {0:{}};
			}
		}
		return this.userRolesInfo;
	}

	this.GetUserID = function()
	{
		if( this.serverInstance )
		{
			this.userID = 0;
			var ID = Session("UID");
			if( ID != null && ID != "" )
			{
				var num = parseInt(ID,10);
				if( !isNaN(num) )
					this.userID = num;
			}
		}
		else
		{
			if( this.userID == null )
				this.userID = 0;
		}
		return this.userID;
	}

	this.GetUserPlayerID = function()
	{
		if( this.serverInstance )
		{
			var playerID = 0;
			var ID = Session("PID");
			if( ID != null && ID != "" )
			{
				var num = parseInt(ID,10);
				if( !isNaN(num) )
					this.userPlayerID = num;
			}
		}
		return this.userPlayerID;
	}
	
	this.IsLoggedIn = function()
	{
		return this.GetUserID() != 0;
	}
	
	this.IsSystemAdministrator = function()
	{
		if( this.serverInstance )
			this.isSysAdmin = Session("SA");
		return this.isSysAdmin;
	}
	
	this.CanChangePassword = function()
	{
		if( this.serverInstance )
			this.canChangePassword = Session("CP");
		return this.canChangePassword;
	}
	
	this.CanLockLogins = function()
	{
		if( this.serverInstance )
			this.canLockLogins = Session("LL");
		return this.canLockLogins;
	}

	this.GetAccessRightsForUserRole = function( userRoleID, sysAdmin, overrideWebsite )
	{
		if( sysAdmin )
			return this.BuildSysAdminAccessRights();
		var rights;
		var userRoleObj = this.userRolesList[userRoleID];
		if( userRoleObj != null )
		{
			if( overrideWebsite == null )
			{
				if( userRoleObj.websiteID == website )
					rights = this.LogicalOrAccessRights( userRoleObj.accessRights, this.GetDefaultAccessRights() );
				else
					rights = {};				
			}
			else
			{
				if( userRoleObj.websiteID == overrideWebsite )
					rights = this.LogicalOrAccessRights( userRoleObj.accessRights, this.GetDefaultAccessRights() );
				else
					rights = {};				
			}
		}
		else
		{
			rights = this.GetDefaultAccessRights();
			if( rights == null )
				rights = {};
		}
		return rights;
	}

	this.GetAccessRights = function( userRoleID, overrideWebsite )
	{
		return this.GetAccessRightsForUserRole( userRoleID, this.IsSystemAdministrator(), overrideWebsite );
	}

	this.GetSchoolListByPermission = function( permissionID, permFlags, params )
	{
		if( params == null )
			params = {};
		var schoolList = {};
		var roleInfoObj, accessRights;
		var userRolesInfo = this.GetUserRolesInfo();
		for( var userRoleID in userRolesInfo )
		{
			roleInfoObj = userRolesInfo[userRoleID];
			accessRights = this.GetAccessRights( userRoleID, params.overrideWebsite );
			if( this.CheckAccessList( accessRights, permissionID, permFlags, params ) )
			{
				if( roleInfoObj.SchoolList == null )
					return null;
				for( var i=0; i<roleInfoObj.SchoolList.length; i++ )
				{
					schoolList[roleInfoObj.SchoolList[i]] = true;
				}
			}
		}
		return schoolList;
	}

	this.GetLeagueListByPermission = function( permissionID, permFlags, params )
	{
		if( params == null )
			params = {};
		var leagueList = {};
		var roleInfoObj, accessRights;
		var userRolesInfo = this.GetUserRolesInfo();
		for( var userRoleID in userRolesInfo )
		{
			roleInfoObj = userRolesInfo[userRoleID];
			accessRights = this.GetAccessRights( userRoleID, params.overrideWebsite );
			if( this.CheckAccessList( accessRights, permissionID, permFlags, params ) )
			{
				if( roleInfoObj.LeagueList == null )
					return null;
				for( var i=0; i<roleInfoObj.LeagueList.length; i++ )
				{
					leagueList[roleInfoObj.LeagueList[i]] = true;
				}
			}
		}
		return leagueList;
	}

	this.GetClubListByPermission = function( permissionID, permFlags, params )
	{
		if( params == null )
			params = {};
		var clubList = {};
		var roleInfoObj, accessRights;
		var userRolesInfo = this.GetUserRolesInfo();
		for( var userRoleID in userRolesInfo )
		{
			roleInfoObj = userRolesInfo[userRoleID];
			accessRights = this.GetAccessRights( userRoleID, params.overrideWebsite );
			if( this.CheckAccessList( accessRights, permissionID, permFlags, params ) )
			{
				if( roleInfoObj.ClubList == null )
					return null;
				for( var i=0; i<roleInfoObj.ClubList.length; i++ )
				{
					clubList[roleInfoObj.ClubList[i]] = true;
				}
			}
		}
		return clubList;
	}

	this.GetTeamListByPermission = function( permissionID, permFlags, params )
	{
		if( params == null )
			params = {};
		var teamList = {};
		var roleInfoObj, accessRights, i;
		var userRolesInfo = this.GetUserRolesInfo();
		for( var userRoleID in userRolesInfo )
		{
			roleInfoObj = userRolesInfo[userRoleID];
			accessRights = this.GetAccessRights( userRoleID, params.overrideWebsite );
			if( this.CheckAccessList( accessRights, permissionID, permFlags, params ) )
			{
				if( params.juniors )
				{
					if( roleInfoObj.JuniorTeamList == null )
						return null;
					else
					{
						for( i=0; i<roleInfoObj.JuniorTeamList.length; i++ )
							teamList[roleInfoObj.JuniorTeamList[i]] = true;
					}
				}
				else
				{
					if( params.schools )
					{
						if( roleInfoObj.SchoolTeamList == null )
							return null;
						else
						{
							for( i=0; i<roleInfoObj.SchoolTeamList.length; i++ )
								teamList[roleInfoObj.SchoolTeamList[i]] = true;
						}
					}
					else
					{
						if( roleInfoObj.AdultTeamList == null )
							return null;
						else
						{
							for( i=0; i<roleInfoObj.AdultTeamList.length; i++ )
								teamList[roleInfoObj.AdultTeamList[i]] = true;
						}
					}
				}
			}
		}
		return teamList;
	}

	this.GetRawTeamList = function( userRoleID, juniors, schools )
	{
		var userRolesInfo = this.GetUserRolesInfo();
		if( userRolesInfo[userRoleID] != null )
		{
			if( juniors )
				return userRolesInfo[userRoleID].JuniorTeamList;
			else
			{
				if( schools )
					return userRolesInfo[userRoleID].SchoolTeamList;
			}
			return userRolesInfo[userRoleID].AdultTeamList;
		}
		return [];
	}

	this.GetRelatedClubList = function( userRoleID )
	{
		var userRolesInfo = this.GetUserRolesInfo();
		var clubList = [];
		if( userRolesInfo[userRoleID] != null )
		{
			clubList = userRolesInfo[userRoleID].ClubList;
		}

		var arr = null;
		if( clubList != null )
		{
			arr = {};
			for( var i=0; i<clubList.length; i++ )
				arr[clubList[i]] = true;
		}
		return arr;
	}

	this.GetRelatedSchoolList = function( userRoleID )
	{
		var userRolesInfo = this.GetUserRolesInfo();
		var schoolList = [];
		if( userRolesInfo[userRoleID] != null )
		{
			schoolList = userRolesInfo[userRoleID].SchoolList;
		}

		var arr = null;
		if( schoolList != null )
		{
			arr = {};
			for( var i=0; i<schoolList.length; i++ )
				arr[schoolList[i]] = true;
		}
		return arr;
	}

	this.GetLeagueList = function( userRoleID )
	{
		var userRolesInfo = this.GetUserRolesInfo();
		var leagueList = [];
		if( userRolesInfo[userRoleID] != null )
		{
			leagueList = userRolesInfo[userRoleID].LeagueList;
		}

		var arr = null;
		if( leagueList != null )
		{
			arr = {};
			for( var i=0; i<leagueList.length; i++ )
				arr[leagueList[i]] = true;
		}
		return arr;
	}

	this.GetRelatedTeamList = function( userRoleID, juniors, schools )
	{
		var arr = null;
		var teamList = this.GetRawTeamList( userRoleID, juniors, schools );
		if( teamList != null )
		{
			arr = {};
			for( var i=0; i<teamList.length; i++ )
				arr[teamList[i]] = true;
		}
		return arr;
	}

	this.HasClubAccess = function( userRoleID, clubIDList )
	{
		var clubList = this.GetRelatedClubList( userRoleID );
		var hasAccess = true;
		if( clubList != null && clubIDList != null )
		{
			if( typeof(clubIDList) == "number" )
				clubIDList = [clubIDList];
			if( clubIDList.length > 0 )
			{
				hasAccess = false;
				for( var i=0; i<clubIDList.length; i++ )
				{
					if( clubList[clubIDList[i]] == true )
					{
						hasAccess = true;
						break;
					}
				}
			}
		}
		return hasAccess;
	}

	this.HasTeamAccess = function( userRoleID, teamIDList, juniors, schools )
	{
		var teamList = this.GetRelatedTeamList( userRoleID, juniors, schools );
		var hasAccess = true;
		if( teamList != null && teamIDList != null )
		{
			if( typeof(teamIDList) == "number" )
				teamIDList = [teamIDList];
			if( teamIDList.length > 0 )
			{
				hasAccess = false;
				for( var i=0; i<teamIDList.length; i++ )
				{
					if( teamList[teamIDList[i]] == true )
					{
						hasAccess = true;
						break;
					}
				}
			}
		}
		return hasAccess;
	}

	this.HasSchoolAccess = function( userRoleID, schoolIDList )
	{
		var schoolList = this.GetRelatedSchoolList( userRoleID );
		var hasAccess = true;
		if( schoolList != null && schoolIDList != null )
		{
			if( typeof(schoolIDList) == "number" )
				schoolIDList = [schoolIDList];
			if( schoolIDList.length > 0 )
			{
				hasAccess = false;
				for( var i=0; i<schoolIDList.length; i++ )
				{
					if( schoolList[schoolIDList[i]] == true )
					{
						hasAccess = true;
						break;
					}
				}
			}
		}
		return hasAccess;
	}

	this.HasLeagueAccess = function( userRoleID, leagueIDList )
	{
		var leagueList = this.GetLeagueList( userRoleID );
		var hasAccess = true;
		if( leagueList != null && leagueIDList != null )
		{
			if( typeof(leagueIDList) == "number" )
				leagueIDList = [leagueIDList];
			if( leagueIDList.length > 0 )
			{
				hasAccess = false;
				for( var i=0; i<leagueIDList.length; i++ )
				{
					if( leagueList[leagueIDList[i]] == true )
					{
						hasAccess = true;
						break;
					}
				}
			}
		}
		return hasAccess;
	}
	
	this.IsPreviousSeason = function( overrideSeason )
	{
		if( this.serverInstance || overrideSeason != null )
		{
			if( overrideSeason == null )
			{
				if( season > 1 )
					return true;
				return season == 0 && LatestSeason != NextSeason;
			}
			else
			{
				if( overrideSeason > 1 )
					return true;
				return overrideSeason == 0 && LatestSeason != NextSeason;
			}
		}
		if( mainObj.getCurrentSeason() > 1 )
			return true;
		return mainObj.getCurrentSeason() == 0 && mainObj.getLatestSeason() != mainObj.getNextSeason();
	}

	this.CheckAccessList = function( access, permissionID, permFlagList, params )
	{
		var viewAccess = permFlagList&this.AccessRightsSystemView;
		var addAccess = permFlagList&this.AccessRightsSystemAdd;
		var editAccess = permFlagList&this.AccessRightsSystemEdit;
		var deleteAccess = permFlagList&this.AccessRightsSystemDelete;

		if( viewAccess != 0 )
		{
			if( this.CheckAccess( access, permissionID, viewAccess, this.AccessRightsSystemView, params ) )
				return true;
		}

		if( addAccess != 0 )
		{
			if( this.CheckAccess( access, permissionID, addAccess, this.AccessRightsSystemAdd, params ) )
				return true;
		}

		if( editAccess != 0 )
		{
			if( this.CheckAccess( access, permissionID, editAccess, this.AccessRightsSystemEdit, params ) )
				return true;
		}

		if( deleteAccess != 0 )
		{
			if( this.CheckAccess( access, permissionID, deleteAccess, this.AccessRightsSystemDelete, params ) )
				return true;
		}
		if( (permFlagList&this.AccessRightsUse) != 0 )
		{
			if( this.CheckAccess( access, permissionID, this.AccessRightsUse, this.AccessRightsUse, params ) )
				return true;
		}
		if( (permFlagList&this.AccessRightsImportExport) != 0 )
		{
			if( this.CheckAccess( access, permissionID, this.AccessRightsImportExport, this.AccessRightsImportExport, params ) )
				return true;
		}
		if( (permFlagList&this.AccessRightsConfirm) != 0 )
		{
			if( this.CheckAccess( access, permissionID, this.AccessRightsConfirm, this.AccessRightsConfirm, params ) )
				return true;
		}
		if( (permFlagList&this.AccessRightsReject) != 0 )
		{
			if( this.CheckAccess( access, permissionID, this.AccessRightsReject, this.AccessRightsReject, params ) )
				return true;
		}
		return false;
	}
	
	this.CheckAccess = function( access, permissionID, accessRight, mask, params )
	{
		var obj = access[permissionID];
		if( obj == null )
			return false;
		var hasAccess = false;
		if( params.juniors )
			hasAccess = obj.length > 1 && (obj[1]&mask) >= accessRight;
		if( !hasAccess && params.schools )
			hasAccess = obj.length > 2 && (obj[2]&mask) >= accessRight;
		if( !hasAccess && !params.juniors && !params.schools )
			hasAccess = obj.length > 0 && (obj[0]&mask) >= accessRight;
		return hasAccess;
	}
	
	this.CheckAnyAccessForPermission = function( permissionID, permFlagList, params )
	{
		var viewAccess = permFlagList&this.AccessRightsSystemView;
		if( viewAccess != 0 )
		{
			if( this.CheckPermissions( permissionID, viewAccess, this.AccessRightsSystemView, params ) )
				return true;
		}

		var addAccess = permFlagList&this.AccessRightsSystemAdd;
		if( addAccess != 0 )
		{
			if( this.CheckPermissions( permissionID, addAccess, this.AccessRightsSystemAdd, params ) )
				return true;
		}

		var editAccess = permFlagList&this.AccessRightsSystemEdit;
		if( editAccess != 0 )
		{
			if( this.CheckPermissions( permissionID, editAccess, this.AccessRightsSystemEdit, params ) )
				return true;
		}

		var deleteAccess = permFlagList&this.AccessRightsSystemDelete;
		if( deleteAccess != 0 )
		{
			if( this.CheckPermissions( permissionID, deleteAccess, this.AccessRightsSystemDelete, params ) )
				return true;
		}

		if( (permFlagList&this.AccessRightsUse) != 0 )
		{
			if( this.CheckPermissions( permissionID, this.AccessRightsUse, this.AccessRightsUse, params ) )
				return true;
		}
		if( (permFlagList&this.AccessRightsImportExport) != 0 )
		{
			if( this.CheckPermissions( permissionID, this.AccessRightsImportExport, this.AccessRightsImportExport, params ) )
				return true;
		}
		if( (permFlagList&this.AccessRightsConfirm) != 0 )
		{
			if( this.CheckPermissions( permissionID, this.AccessRightsConfirm, this.AccessRightsConfirm, params ) )
				return true;
		}
		if( (permFlagList&this.AccessRightsReject) != 0 )
		{
			if( this.CheckPermissions( permissionID, this.AccessRightsReject, this.AccessRightsReject, params ) )
				return true;
		}
		return false;
	}
	
	this.CheckPermissions = function( permissionID, rights, mask, params )
	{
		if( params == null )
			params = {};
		var flag = false;
		var roleObj, access, permObj, overrideSeason, isPrevSeason, isEditPerm, clubList, teamList, schoolList, leagueList;
		var rolesList = params.overrideAccessRights == null ? this.GetUserRolesInfo() : params.overrideAccessRights;
		for( var userRoleID in rolesList )
		{
			roleObj = rolesList[userRoleID];
			flag = true;
			if( roleObj.access == null )
				access = this.GetAccessRights( userRoleID, params.overrideWebsite );
			else
				access = roleObj.access;
			permObj = this.userPermissionsList[permissionID];
			overrideSeason = this.CheckAccess( access, permissionID, this.AccessRightsSeasonOverride, this.AccessRightsSeasonOverride, params );

			isPrevSeason = this.IsPreviousSeason( params.overrideSeason );
			isEditPerm = (rights & this.EditAccessRights) != 0;
			if( permObj.hasSeasons )
			{
				if( isPrevSeason && isEditPerm && !overrideSeason )
					flag = false;
			}
			if( flag )
			{
				hasAccess = this.CheckAccess( access, permissionID, rights, mask, params );
				if( !hasAccess )
					flag = false;
			}
			if( flag )
			{
				schoolList = this.GetRelatedSchoolList( userRoleID );
				leagueList = this.GetLeagueList( userRoleID );
				clubList = this.GetRelatedClubList( userRoleID );
				teamList = this.GetRelatedTeamList( userRoleID, params.juniors, params.schools );
				if( teamList != null && params.teamIDList != null )
				{
					flag = this.HasTeamAccess( userRoleID, params.teamIDList, params.juniors, params.schools );
				}
				else
				{
					if( clubList != null && params.clubIDList != null )
					{
						flag = this.HasClubAccess( userRoleID, params.clubIDList );
						if( flag && leagueList != null && params.leagueIDList != null )
						{
							flag = this.HasLeagueAccess( userRoleID, params.leagueIDList );
						}
					}
					else
					{
						if( schoolList != null && params.schoolIDList != null )
						{
							flag = this.HasSchoolAccess( userRoleID, params.schoolIDList );
							if( flag && leagueList != null && params.leagueIDList != null )
							{
								flag = this.HasLeagueAccess( userRoleID, params.leagueIDList );
							}
						}
						else
						{
							if( leagueList != null && params.leagueIDList != null )
							{
								flag = this.HasLeagueAccess( userRoleID, params.leagueIDList );
							}
						}
					}
				}
			}
			if( flag && this.lockDbWritesFlag && params.overrideAccessRights == null && mask != this.AccessRightsSystemView )
			{
				flag = this.CanLockLogins();
			}
			if( flag )
				break;
		}
		return flag;
	}

	this.CheckAnyAccess = function( compareTo, accessRequired, permObj, permissionID )
	{
		var reqdObj = accessRequired[permissionID];
		if( reqdObj == null )
			return false;
		var rights, isEditPerm, isPrevSeason = this.IsPreviousSeason();
		var compareObj = compareTo[permissionID];
		if( compareObj == null )
			compareObj = [0,0,0];
		var overrideSeason = this.CheckAccess( compareTo, permissionID, this.AccessRightsSeasonOverride, this.AccessRightsSeasonOverride, {} );
		for( var i=0; i<reqdObj.length; i++ )
		{
			if( i < compareObj.length )
			{
				if( (compareObj[i]&reqdObj[i]) != 0 )
				{
					rights = reqdObj[i];
					if( permObj.hasSeasons )
					{
						isEditPerm = (rights & this.EditAccessRights) == rights;
						if( !isPrevSeason || !isEditPerm || overrideSeason )
							return true;
					}
					else
						return true;
				}
			}
		}
		return false;
	}

	this.CheckAnyPermissions = function( accessRequired, compareTo )
	{
		var permObj, permReqd, userPerm;
		if( accessRequired == null )
			return true;

		var rolesList;
		if( compareTo == null )
		{
			rolesList = this.GetUserRolesInfo();
		}
		else
		{
			rolesList = {0:true};
		}
		for( var userRoleID in rolesList )
		{
			var access;
			if( compareTo == null )
				access = this.GetAccessRights( userRoleID );
			else
				access = compareTo;
			if( access == null || objectLength(access) == 0 )
				return false;
			for( var permissionID in this.userPermissionsList )
			{
				permObj = this.userPermissionsList[permissionID];
				if( permObj.websites[website] != null )
				{
					if( this.CheckAnyAccess( access, accessRequired, permObj, permissionID ) )
						return true;
				}
			}
		}
		return false;
	}

	this.CheckAllAccess = function( compareTo, accessRequired, permissionID )
	{
		var reqdObj = accessRequired[permissionID];
		if( reqdObj == null )
			return true;
		var overrideSeason = this.CheckAccess( compareTo, permissionID, this.AccessRightsSeasonOverride, this.AccessRightsSeasonOverride, {} );
		var rights, isEditPerm, sPrevSeason = this.IsPreviousSeason();
		var compareObj = compareTo[permissionID];
		if( compareObj == null )
			compareObj = [0,0,0];
		var isPrevSeason = this.IsPreviousSeason();
		for( var i=0; i<reqdObj.length; i++ )
		{
			rights = reqdObj[i];
			if( i < compareObj.length )
			{
				if( (compareObj[i]&rights) != rights )
					return false;
				//if( permObj.hasSeasons )
				//{
				//	isEditPerm = (rights & this.EditAccessRights) != 0;
				//	if( isPrevSeason && isEditPerm && !overrideSeason )
				//		return false;
				//}
			}
			else
			{
				if( rights != 0 )
					return false;
			}
		}
		return true;
	}

	this.CheckAllPermissions = function( accessRequired, compareTo )
	{
		var permObj, permReqd, userPerm;
		if( accessRequired == null )
			return true;
		var reqdAccess;
		var flag = true;
		var rolesList;
		if( compareTo == null )
		{
			rolesList = this.GetUserRolesInfo();
		}
		else
		{
			rolesList = compareTo;
		}
		for( var reqdRoleID in accessRequired )
		{
			reqdAccess = this.GetAccessRights( reqdRoleID );
			for( var userRoleID in rolesList )
			{
				access = this.GetAccessRights( userRoleID );
				if( reqdAccess != null && reqdAccess != "" )
				{
					for( var permissionID in this.userPermissionsList )
					{
						if( !this.CheckAllAccess( access, reqdAccess, permissionID ) )
						{
							flag = false;
							break;
						}
					}
				}
			}
		}
		return true;
	}

	this.GetBestViewPermission = function( permissionID, params )
	{
		if( params == null )
			params = {};
		var rolesList = params.overrideAccessRights == null ? this.GetUserRolesInfo() : params.overrideAccessRights;
		var roleObj, accessRights, viewPerm, bestPerm = 0;
		for( var userRoleID in rolesList )
		{
			roleObj = rolesList[userRoleID];
			if( roleObj.access == null )
				accessRights = params.overrideAccessRights == null ? this.GetAccessRights( userRoleID, params.overrideWebsite ) : params.overrideAccessRights[userRoleID];
			else
				accessRights = roleObj.access;
			if( this.CheckAccess( accessRights, permissionID, this.AccessRightsSystemView, this.AccessRightsSystemView, params ) )
			{
				if( this.AccessRightsSystemView > bestPerm )
					bestPerm = this.AccessRightsSystemView;
			}
			else
			{
				if( this.CheckAccess( accessRights, permissionID, this.AccessRightsAdvancedView, this.AccessRightsSystemView, params ) )
				{
					if( this.AccessRightsAdvancedView > bestPerm )
						bestPerm = this.AccessRightsAdvancedView;
				}
				else
				{
					viewPerm = this.CheckAccess( accessRights, permissionID, this.AccessRightsView, this.AccessRightsSystemView, params ) ? this.AccessRightsView : 0;
					if( viewPerm > bestPerm )
						bestPerm = viewPerm;
				}
			}
		}
		return bestPerm;
	}

	this.GetBestEditPermission = function( permissionID, params )
	{
		if( params == null )
			params = {};
		var rolesList = params.overrideAccessRights == null ? this.GetUserRolesInfo() : params.overrideAccessRights;
		var roleObj, accessRights, viewPerm, bestPerm = 0;
		for( var userRoleID in rolesList )
		{
			roleObj = rolesList[userRoleID];
			if( roleObj.access == null )
				accessRights = params.overrideAccessRights == null ? this.GetAccessRights( userRoleID, params.overrideWebsite ) : params.overrideAccessRights[userRoleID];
			else
				accessRights = roleObj.access;
			if( this.CheckAccess( accessRights, permissionID, this.AccessRightsSystemEdit, this.AccessRightsSystemEdit, params ) )
			{
				if( this.AccessRightsSystemEdit > bestPerm )
					bestPerm = this.AccessRightsSystemEdit;
			}
			else
			{
				if( this.CheckAccess( accessRights, permissionID, this.AccessRightsAdvancedEdit, this.AccessRightsSystemEdit, params ) )
				{
					if( this.AccessRightsAdvancedEdit > bestPerm )
						bestPerm = this.AccessRightsAdvancedEdit;
				}
				else
				{
					viewPerm = this.CheckAccess( accessRights, permissionID, this.AccessRightsEdit, this.AccessRightsSystemEdit, params ) ? this.AccessRightsEdit : 0;
					if( viewPerm > bestPerm )
						bestPerm = viewPerm;
				}
			}
		}
		return bestPerm;
	}

	this.GetBestAddPermission = function( permissionID, params )
	{
		if( params == null )
			params = {};
		var rolesList = params.overrideAccessRights == null ? this.GetUserRolesInfo() : params.overrideAccessRights;
		var roleObj, accessRights, viewPerm, bestPerm = 0;
		for( var userRoleID in rolesList )
		{
			roleObj = rolesList[userRoleID];
			if( roleObj.access == null )
				accessRights = params.overrideAccessRights == null ? this.GetAccessRights( userRoleID, params.overrideWebsite ) : params.overrideAccessRights[userRoleID];
			else
				accessRights = roleObj.access;
			if( this.CheckAccess( accessRights, permissionID, this.AccessRightsSystemAdd, this.AccessRightsSystemAdd, params ) )
			{
				if( this.AccessRightsSystemAdd > bestPerm )
					bestPerm = this.AccessRightsSystemAdd;
			}
			else
			{
				if( this.CheckAccess( accessRights, permissionID, this.AccessRightsAdvancedAdd, this.AccessRightsSystemAdd, params ) )
				{
					if( this.AccessRightsAdvancedAdd > bestPerm )
						bestPerm = this.AccessRightsAdvancedAdd;
				}
				else
				{
					viewPerm = this.CheckAccess( accessRights, permissionID, this.AccessRightsAdd, this.AccessRightsSystemAdd, params ) ? this.AccessRightsAdd : 0;
					if( viewPerm > bestPerm )
						bestPerm = viewPerm;
				}
			}
		}
		return bestPerm;
	}

	this.GetBestDeletePermission = function( permissionID, params )
	{
		if( params == null )
			params = {};
		var rolesList = params.overrideAccessRights == null ? this.GetUserRolesInfo() : params.overrideAccessRights;
		var roleObj, accessRights, viewPerm, bestPerm = 0;
		for( var userRoleID in rolesList )
		{
			roleObj = rolesList[userRoleID];
			if( roleObj.access == null )
				accessRights = params.overrideAccessRights == null ? this.GetAccessRights( userRoleID, params.overrideWebsite ) : params.overrideAccessRights[userRoleID];
			else
				accessRights = roleObj.access;
			if( this.CheckAccess( accessRights, permissionID, this.AccessRightsSystemDelete, this.AccessRightsSystemDelete, params ) )
			{
				if( this.AccessRightsSystemDelete > bestPerm )
					bestPerm = this.AccessRightsSystemDelete;
			}
			else
			{
				if( this.CheckAccess( accessRights, permissionID, this.AccessRightsAdvancedDelete, this.AccessRightsSystemDelete, params ) )
				{
					if( this.AccessRightsAdvancedDelete > bestPerm )
						bestPerm = this.AccessRightsAdvancedDelete;
				}
				else
				{
					viewPerm = this.CheckAccess( accessRights, permissionID, this.AccessRightsDelete, this.AccessRightsSystemDelete, params ) ? this.AccessRightsDelete : 0;
					if( viewPerm > bestPerm )
						bestPerm = viewPerm;
				}
			}
		}
		return bestPerm;
	}
	
	this.IsEnabled = function( permissionID, juniorFlag, schoolFlag )
	{
		permObj = this.userPermissionsList[permissionID];
		var flag = false;
		if( permObj != null )
		{
			var obj = permObj.websites[website];
			if( obj != null )
			{
				if( juniorFlag == true )
				{
					flag = obj.juniorsEnabled;
				}
				else
				{
					if( schoolFlag == true )
						flag = obj.schoolsEnabled;
					else
						flag = obj.adultsEnabled || (!obj.adultsEnabled && !obj.juniorsEnabled && !obj.schoolsEnabled);
				}
			}
		}
		return flag;
	}

	this.RenderAppVars = function()
	{
		if( this.serverInstance )
		{
			var json = getApplicationVar("UserRoles");
			if( json == null )
				this.userRolesList = {};
			else
			{
				if( json == null || json == "" )
					this.userRolesList = {};
				else
					eval( "this.userRolesList = "+json+";" );
			}
			json = getSystemProperty("DefaultAccessRights");
			if( json == null  )
				this.defaultAccessRights = {};
			else
				this.defaultAccessRights = json;
		}
	}

	if( permFuncs == null )
	{
		this.serverInstance = true;
		var userPermsJson = getApplicationVar("UserPerms");
		try
		{
			eval( 'this.userPermissionsList = ' + userPermsJson + ';' );
		}
		catch(e)
		{
			this.userPermissionsList = {};
		}
		var js, permObj;
		var js = [];
		this.fnCount;
		var index = 0;
		this.userRoles = "";
		this.accessRights = null;
		this.isSysAdmin = false;
		this.canLockLogins = false;
		this.canChangePassword = false;
		this.userRolesInfo = {};
		this.userPlayerID = 0;
		this.userID = 0;
		this.username = "";
		this.RenderAppVars();
	}
	else
	{
		this.mainObj = mainObj;
		this.serverInstance = false;
		eval( 'this.userPermissionsList = ' + userPermissionsList + ';' );
		eval( 'this.userRolesList = '+userRolesList+';' );
		eval( 'this.defaultAccessRights = '+defaultAccessRights+';' );
	}
	this.Can = new CanClass( this );
	var js = [];
	for( permissionID in this.userPermissionsList )
	{
		permObj = this.userPermissionsList[permissionID];
		js.push( "this." );
		js.push( permObj.name );
		js.push( " = " );
		js.push( permissionID );
		js.push( ";" );
	}
	eval( js.join("") );

	this.GetUserRoles = function() { return this.userRolesList; };
	this.GetUserPermissionsList = function() { return this.userPermissionsList; };
}

function GetMask( permFlags )
{
	switch( permFlags )
	{
		case permsClass.AccessRightsView:
		case permsClass.AccessRightsAdvancedView:
		case permsClass.AccessRightsSystemView:
			return permsClass.AccessRightsSystemView;

		case permsClass.AccessRightsAdd:
		case permsClass.AccessRightsAdvancedAdd:
		case permsClass.AccessRightsSystemAdd:
			return permsClass.AccessRightsSystemAdd;

		case permsClass.AccessRightsEdit:
		case permsClass.AccessRightsAdvancedEdit:
		case permsClass.AccessRightsSystemEdit:
			return permsClass.AccessRightsSystemEdit;

		case permsClass.AccessRightsDelete:
		case permsClass.AccessRightsAdvancedDelete:
		case permsClass.AccessRightsSystemDelete:
			return permsClass.AccessRightsSystemDelete;

		default:
			return permFlags;
	}
}

function CanClass( permsClass )
{
	var verbs =
	{
		"View":				[permsClass.AccessRightsView,			permsClass.AccessRightsSystemView],
		"AdvancedView":		[permsClass.AccessRightsAdvancedView,	permsClass.AccessRightsSystemView],
		"SystemView":		[permsClass.AccessRightsSystemView,		permsClass.AccessRightsSystemView],

		"Add":				[permsClass.AccessRightsAdd,			permsClass.AccessRightsSystemAdd],
		"AdvancedAdd":		[permsClass.AccessRightsAdvancedAdd,	permsClass.AccessRightsSystemAdd],
		"SystemAdd":		[permsClass.AccessRightsSystemAdd,		permsClass.AccessRightsSystemAdd],

		"Edit":				[permsClass.AccessRightsEdit,			permsClass.AccessRightsSystemEdit],
		"AdvancedEdit":		[permsClass.AccessRightsAdvancedEdit,	permsClass.AccessRightsSystemEdit],
		"SystemEdit":		[permsClass.AccessRightsSystemEdit,		permsClass.AccessRightsSystemEdit],

		"Delete":			[permsClass.AccessRightsDelete,			permsClass.AccessRightsSystemDelete],
		"AdvancedDelete":	[permsClass.AccessRightsAdvancedDelete,	permsClass.AccessRightsSystemDelete],
		"SystemDelete":		[permsClass.AccessRightsSystemDelete,	permsClass.AccessRightsSystemDelete],

		"Use":				[permsClass.AccessRightsUse,			permsClass.AccessRightsUse],
		"Import":			[permsClass.AccessRightsImportExport,	permsClass.AccessRightsImportExport],
		"Confirm":			[permsClass.AccessRightsConfirm,		permsClass.AccessRightsConfirm],
		"Reject":			[permsClass.AccessRightsReject,			permsClass.AccessRightsReject]
	};
	this.permsClass = permsClass;
	var fnJs, params;
	for( var verb in verbs )
	{
		params = verbs[verb];
		fnJs = ["this."];
		fnJs.push( verb );
		fnJs.push( " = function( permissionID, params ) { return this.permsClass.CheckPermissions( permissionID, " );
		fnJs.push( params.join(", ") );
		fnJs.push( ", params ); }" );
		eval( fnJs.join("") );
	}
}

