/*
========================
idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::AdjustField
========================
*/
void idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::AdjustField( const int fieldIndex, const int adjustAmount ) {
    switch ( fieldIndex ) {
    case SYSTEM_FIELD_FRAMERATE: {
        //Carl: Oculus Rift DK1 can be hacked to use refresh rates from 60Hz to 83Hz (71Hz max undistorted). CV1 will probably support 90Hz.
        //Carl: Doom 3 BFG also originally supported 120Hz. So list everything from 60 to 83, with 90 and 120 last.
        static const int numValues = 26;
        static const int values[numValues] = { 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 90, 120 };
        com_engineHz.SetInteger( AdjustOption( com_engineHz.GetInteger(), values, numValues, adjustAmount ) );
        break;
    }
    case SYSTEM_FIELD_VSYNC: {
        static const int numValues = 3;
        static const int values[numValues] = { 0, 1, 2 };
        r_swapInterval.SetInteger( AdjustOption( r_swapInterval.GetInteger(), values, numValues, adjustAmount ) );
        break;
    }
    case SYSTEM_FIELD_ANTIALIASING: {
        static const int numValues = 5;
        static const int values[numValues] = { 0, 2, 4, 8, 16 };
        r_multiSamples.SetInteger( AdjustOption( r_multiSamples.GetInteger(), values, numValues, adjustAmount ) );
        break;
    }
    case SYSTEM_FIELD_MOTIONBLUR: {
        static const int numValues = 5;
        static const int values[numValues] = { 0, 2, 3, 4, 5 };
        r_motionBlur.SetInteger( AdjustOption( r_motionBlur.GetInteger(), values, numValues, adjustAmount ) );
        break;
    }
    case SYSTEM_FIELD_LODBIAS: {
        const float percent = LinearAdjust( r_lodBias.GetFloat(), -1.0f, 1.0f, 0.0f, 100.0f );
        const float adjusted = percent + (float)adjustAmount * 5.0f;
        const float clamped = idMath::ClampFloat( 0.0f, 100.0f, adjusted );
        r_lodBias.SetFloat( LinearAdjust( clamped, 0.0f, 100.0f, -1.0f, 1.0f ) );
        break;
    }
    case SYSTEM_FIELD_BRIGHTNESS: {
        const float percent = LinearAdjust( r_lightScale.GetFloat(), 2.0f, 4.0f, 0.0f, 100.0f );
        const float adjusted = percent + (float)adjustAmount;
        const float clamped = idMath::ClampFloat( 0.0f, 100.0f, adjusted );
        r_lightScale.SetFloat( LinearAdjust( clamped, 0.0f, 100.0f, 2.0f, 4.0f ) );
        break;
    }
    case SYSTEM_FIELD_VOLUME: {
        const float percent = 100.0f * Square( 1.0f - ( s_volume_dB.GetFloat() / DB_SILENCE ) );
        const float adjusted = percent + (float)adjustAmount;
        const float clamped = idMath::ClampFloat( 0.0f, 100.0f, adjusted );
        s_volume_dB.SetFloat( DB_SILENCE - ( idMath::Sqrt( clamped / 100.0f ) * DB_SILENCE ) );
        break;
    }
    }
    cvarSystem->ClearModifiedFlags( CVAR_ARCHIVE );
}
/*
========================
idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::GetField
========================
*/
idSWFScriptVar idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::GetField( const int fieldIndex ) const {
    switch ( fieldIndex ) {
    case SYSTEM_FIELD_FULLSCREEN: {
        const int fullscreen = r_fullscreen.GetInteger();
        const int vidmode = r_vidMode.GetInteger();
        if ( fullscreen == 0 ) {
            return "#str_swf_disabled";
        }
        if ( fullscreen < 0 || vidmode < 0 || vidmode >= modeList.Num() ) {
            return "???";
        }
        if ( modeList[vidmode].displayHz == 60 ) {
            return va( "%4i x %4i", modeList[vidmode].width, modeList[vidmode].height );
        } else {
            return va( "%4i x %4i @ %dhz", modeList[vidmode].width, modeList[vidmode].height, modeList[vidmode].displayHz );
        }
    }
    case SYSTEM_FIELD_FRAMERATE:
        return va( "%d FPS", com_engineHz.GetInteger() );
    case SYSTEM_FIELD_VSYNC:
        if ( r_swapInterval.GetInteger() == 1 ) {
            return "#str_swf_smart";
        } else if ( r_swapInterval.GetInteger() == 2 ) {
            return "#str_swf_enabled";
        } else {
            return "#str_swf_disabled";
        }
    case SYSTEM_FIELD_ANTIALIASING:
        if ( r_multiSamples.GetInteger() == 0 ) {
            return "#str_swf_disabled";
        }
        return va( "%dx", r_multiSamples.GetInteger() );
    case SYSTEM_FIELD_MOTIONBLUR:
        if ( r_motionBlur.GetInteger() == 0 ) {
            return "#str_swf_disabled";
        }
        return va( "%dx", idMath::IPow( 2, r_motionBlur.GetInteger() ) );
    case SYSTEM_FIELD_LODBIAS:
        return LinearAdjust( r_lodBias.GetFloat(), -1.0f, 1.0f, 0.0f, 100.0f );
    case SYSTEM_FIELD_BRIGHTNESS:
        return LinearAdjust( r_lightScale.GetFloat(), 2.0f, 4.0f, 0.0f, 100.0f );
    case SYSTEM_FIELD_VOLUME: {
        return 100.0f * Square( 1.0f - ( s_volume_dB.GetFloat() / DB_SILENCE ) );
    }
    }
    return false;
}
/*
========================
idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::AdjustField
========================
*/
void idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::AdjustField( const int fieldIndex, const int adjustAmount )
{
	switch( fieldIndex )
	{
		case SYSTEM_FIELD_FRAMERATE:
		{
			static const int numValues = 2;
			static const int values[numValues] = { 60, 120 };
			com_engineHz.SetInteger( AdjustOption( com_engineHz.GetInteger(), values, numValues, adjustAmount ) );
			break;
		}
		case SYSTEM_FIELD_VSYNC:
		{
			static const int numValues = 3;
			static const int values[numValues] = { 0, 1, 2 };
			r_swapInterval.SetInteger( AdjustOption( r_swapInterval.GetInteger(), values, numValues, adjustAmount ) );
			break;
		}
		case SYSTEM_FIELD_ANTIALIASING:
		{
			// RB: disabled 16x MSAA
			static const int numValues = 4;
			static const int values[numValues] = { 0, 2, 4, 8 };
			// RB end
			r_multiSamples.SetInteger( AdjustOption( r_multiSamples.GetInteger(), values, numValues, adjustAmount ) );
			break;
		}
		case SYSTEM_FIELD_MOTIONBLUR:
		{
			static const int numValues = 5;
			static const int values[numValues] = { 0, 2, 3, 4, 5 };
			r_motionBlur.SetInteger( AdjustOption( r_motionBlur.GetInteger(), values, numValues, adjustAmount ) );
			break;
		}
		// RB begin
		case SYSTEM_FIELD_SHADOWMAPPING:
		{
			static const int numValues = 2;
			static const int values[numValues] = { 0, 1 };
			r_useShadowMapping.SetInteger( AdjustOption( r_useShadowMapping.GetInteger(), values, numValues, adjustAmount ) );
			break;
		}
		/*case SYSTEM_FIELD_LODBIAS:
		{
			const float percent = LinearAdjust( r_lodBias.GetFloat(), -1.0f, 1.0f, 0.0f, 100.0f );
			const float adjusted = percent + ( float )adjustAmount * 5.0f;
			const float clamped = idMath::ClampFloat( 0.0f, 100.0f, adjusted );
			r_lodBias.SetFloat( LinearAdjust( clamped, 0.0f, 100.0f, -1.0f, 1.0f ) );
			break;
		}*/
		// RB end
		case SYSTEM_FIELD_BRIGHTNESS:
		{
			const float percent = LinearAdjust( r_lightScale.GetFloat(), 2.0f, 4.0f, 0.0f, 100.0f );
			const float adjusted = percent + ( float )adjustAmount;
			const float clamped = idMath::ClampFloat( 0.0f, 100.0f, adjusted );
			r_lightScale.SetFloat( LinearAdjust( clamped, 0.0f, 100.0f, 2.0f, 4.0f ) );
			break;
		}
		case SYSTEM_FIELD_VOLUME:
		{
			const float percent = 100.0f * Square( 1.0f - ( s_volume_dB.GetFloat() / DB_SILENCE ) );
			const float adjusted = percent + ( float )adjustAmount;
			const float clamped = idMath::ClampFloat( 0.0f, 100.0f, adjusted );
			s_volume_dB.SetFloat( DB_SILENCE - ( idMath::Sqrt( clamped / 100.0f ) * DB_SILENCE ) );
			break;
		}
	}
	cvarSystem->ClearModifiedFlags( CVAR_ARCHIVE );
}
/*
========================
idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::GetField
========================
*/
idSWFScriptVar idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::GetField( const int fieldIndex ) const
{
	switch( fieldIndex )
	{
		case SYSTEM_FIELD_FULLSCREEN:
		{
			const int fullscreen = r_fullscreen.GetInteger();
			const int vidmode = r_vidMode.GetInteger();
			if( fullscreen == 0 )
			{
				return "#str_swf_disabled";
			}
			if( fullscreen < 0 || vidmode < 0 || vidmode >= modeList.Num() )
			{
				return "???";
			}
			if( modeList[vidmode].displayHz == 60 )
			{
				return va( "%4i x %4i", modeList[vidmode].width, modeList[vidmode].height );
			}
			else
			{
				return va( "%4i x %4i @ %dhz", modeList[vidmode].width, modeList[vidmode].height, modeList[vidmode].displayHz );
			}
		}
		case SYSTEM_FIELD_FRAMERATE:
			return va( "%d FPS", com_engineHz.GetInteger() );
		case SYSTEM_FIELD_VSYNC:
			if( r_swapInterval.GetInteger() == 1 )
			{
				return "#str_swf_smart";
			}
			else if( r_swapInterval.GetInteger() == 2 )
			{
				return "#str_swf_enabled";
			}
			else
			{
				return "#str_swf_disabled";
			}
		case SYSTEM_FIELD_ANTIALIASING:
		{
			if( r_antiAliasing.GetInteger() == 0 )
			{
				return "#str_swf_disabled";
			}
			
			static const int numValues = 5;
			static const char* values[numValues] =
			{
				"None",
				"SMAA 1X",
				"MSAA 2X",
				"MSAA 4X",
				"MSAA 8X"
			};
			
			compile_time_assert( numValues == ( ANTI_ALIASING_MSAA_8X + 1 ) );
			
			return values[ r_antiAliasing.GetInteger() ];
		}
		case SYSTEM_FIELD_MOTIONBLUR:
			if( r_motionBlur.GetInteger() == 0 )
			{
				return "#str_swf_disabled";
			}
			return va( "%dx", idMath::IPow( 2, r_motionBlur.GetInteger() ) );
		// RB begin
		case SYSTEM_FIELD_SHADOWMAPPING:
			if( r_useShadowMapping.GetInteger() == 1 )
			{
				return "#str_swf_enabled";
			}
			else
			{
				return "#str_swf_disabled";
			}
		//case SYSTEM_FIELD_LODBIAS:
		//	return LinearAdjust( r_lodBias.GetFloat(), -1.0f, 1.0f, 0.0f, 100.0f );
		// RB end
		case SYSTEM_FIELD_BRIGHTNESS:
			return LinearAdjust( r_exposure.GetFloat(), 0.0f, 1.0f, 0.0f, 100.0f );
		case SYSTEM_FIELD_VOLUME:
		{
			return 100.0f * Square( 1.0f - ( s_volume_dB.GetFloat() / DB_SILENCE ) );
		}
	}
	return false;
}