/**
* Copyright (C) 2009-2014 Cars and Tracks Development Project (CTDP).
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package net.ctdp.rfdynhud.widgets.standard.statusflags;
import java.io.IOException;
import net.ctdp.rfdynhud.gamedata.LiveGameData;
import net.ctdp.rfdynhud.gamedata.SessionType;
import net.ctdp.rfdynhud.gamedata.StatusFlag;
import net.ctdp.rfdynhud.properties.BooleanProperty;
import net.ctdp.rfdynhud.properties.FloatProperty;
import net.ctdp.rfdynhud.properties.ImagePropertyWithTexture;
import net.ctdp.rfdynhud.properties.PropertiesContainer;
import net.ctdp.rfdynhud.properties.PropertyLoader;
import net.ctdp.rfdynhud.render.DrawnStringFactory;
import net.ctdp.rfdynhud.render.TextureImage2D;
import net.ctdp.rfdynhud.util.PropertyWriter;
import net.ctdp.rfdynhud.util.SubTextureCollector;
import net.ctdp.rfdynhud.valuemanagers.Clock;
import net.ctdp.rfdynhud.values.EnumValue;
import net.ctdp.rfdynhud.widgets.base.widget.Widget;
import net.ctdp.rfdynhud.widgets.standard._util.StandardWidgetSet;
/**
* The {@link StatusFlagsWidget} displays status flags when ever they're thrown.
*
* @author Marvin Froehlich (CTDP)
*/
public class StatusFlagsWidget extends Widget
{
private final BooleanProperty showGreenAfterBlue = new BooleanProperty( "showGreenAfterBlue", false );
private final FloatProperty showGreenTime = new FloatProperty( "showGreenTime", 5f, -1f, Float.MAX_VALUE );
private final ImagePropertyWithTexture imageGreen = new ImagePropertyWithTexture( "imageGreen", null, "standard/flag_green.png", false, false );
private final ImagePropertyWithTexture imageYellow = new ImagePropertyWithTexture( "imageYellow", null, "standard/flag_yellow.png", false, false );
private final ImagePropertyWithTexture imageBlue = new ImagePropertyWithTexture( "imageBlue", null, "standard/flag_blue.png", false, false );
private final ImagePropertyWithTexture imageRed = new ImagePropertyWithTexture( "imageRed", null, "standard/flag_red.png", false, false );
private final ImagePropertyWithTexture imageRedYellow = new ImagePropertyWithTexture( "imageRedYellow", null, "standard/flag_red_yellow_striped.png", false, false );
private final ImagePropertyWithTexture imageWhite = new ImagePropertyWithTexture( "imageWhite", null, "standard/flag_white.png", false, false );
private final ImagePropertyWithTexture imageBlack = new ImagePropertyWithTexture( "imageBlack", null, "standard/flag_black.png", false, false );
private final ImagePropertyWithTexture imageChequered = new ImagePropertyWithTexture( "imageChequered", null, "standard/flag_chequered.png", false, false );
private final EnumValue<StatusFlag> flagValue = new EnumValue<StatusFlag>();
private float sessionTimeForGreenFlag = -1f;
private boolean greenFlagShown = false;
public StatusFlagsWidget()
{
super( StandardWidgetSet.INSTANCE, StandardWidgetSet.WIDGET_PACKAGE, 6.0f, 5.333f );
getBorderProperty().setBorder( null );
getBackgroundProperty().setColorValue( "#00000000" );
setPadding( 0 );
}
/**
* {@inheritDoc}
*/
@Override
public void saveProperties( PropertyWriter writer ) throws IOException
{
super.saveProperties( writer );
writer.writeProperty( showGreenAfterBlue, "Whether to show the green flag after the blue flag disappeared" );
writer.writeProperty( showGreenTime, "Number of seconds to display the green flag after thrown (-1 for forever)" );
writer.writeProperty( imageGreen, "" );
writer.writeProperty( imageYellow, "" );
writer.writeProperty( imageBlue, "" );
writer.writeProperty( imageRed, "" );
writer.writeProperty( imageRedYellow, "" );
writer.writeProperty( imageWhite, "" );
writer.writeProperty( imageBlack, "" );
writer.writeProperty( imageChequered, "" );
}
/**
* {@inheritDoc}
*/
@Override
public void loadProperty( PropertyLoader loader, LiveGameData gameData )
{
super.loadProperty( loader, gameData );
if ( loader.loadProperty( showGreenAfterBlue ) );
else if ( loader.loadProperty( showGreenTime ) );
else if ( loader.loadProperty( imageGreen ) );
else if ( loader.loadProperty( imageYellow ) );
else if ( loader.loadProperty( imageBlue ) );
else if ( loader.loadProperty( imageRed ) );
else if ( loader.loadProperty( imageRedYellow ) );
else if ( loader.loadProperty( imageWhite ) );
else if ( loader.loadProperty( imageBlack ) );
else if ( loader.loadProperty( imageChequered ) );
}
@Override
protected boolean hasText()
{
return ( false );
}
/**
* {@inheritDoc}
*/
@Override
public void getProperties( PropertiesContainer propsCont, boolean forceAll )
{
super.getProperties( propsCont, forceAll );
propsCont.addGroup( "Misc" );
propsCont.addProperty( showGreenAfterBlue );
propsCont.addProperty( showGreenTime );
propsCont.addGroup( "Flag images" );
propsCont.addProperty( imageGreen );
propsCont.addProperty( imageYellow );
propsCont.addProperty( imageBlue );
propsCont.addProperty( imageRed );
propsCont.addProperty( imageRedYellow );
propsCont.addProperty( imageWhite );
propsCont.addProperty( imageBlack );
propsCont.addProperty( imageChequered );
}
@Override
protected void initSubTextures( LiveGameData gameData, boolean isEditorMode, int widgetInnerWidth, int widgetInnerHeight, SubTextureCollector collector )
{
/*
imageGreen.updateSize( widgetInnerWidth, widgetInnerHeight, isEditorMode );
imageYellow.updateSize( widgetInnerWidth, widgetInnerHeight, isEditorMode );
imageBlue.updateSize( widgetInnerWidth, widgetInnerHeight, isEditorMode );
imageRed.updateSize( widgetInnerWidth, widgetInnerHeight, isEditorMode );
imageRedYellow.updateSize( widgetInnerWidth, widgetInnerHeight, isEditorMode );
imageWhite.updateSize( widgetInnerWidth, widgetInnerHeight, isEditorMode );
imageBlack.updateSize( widgetInnerWidth, widgetInnerHeight, isEditorMode );
imageChequered.updateSize( widgetInnerWidth, widgetInnerHeight, isEditorMode );
*/
}
/**
* {@inheritDoc}
*/
@Override
protected void initialize( LiveGameData gameData, boolean isEditorMode, DrawnStringFactory dsf, TextureImage2D texture, int width, int height )
{
}
private static StatusFlag getFlag( LiveGameData gameData, boolean isEditorMode )
{
StatusFlag flag = gameData.getScoringInfo().getViewedVehicleScoringInfo().getStatusFlag();
if ( isEditorMode )
flag = StatusFlag.CHEQUERED;
else if ( flag == null )
flag = StatusFlag.GREEN;
return ( flag );
}
private void updateSessionTimeForGreenFlag( LiveGameData gameData, StatusFlag flag, boolean wasBlue, boolean isEditorMode )
{
if ( flag == null )
flag = getFlag( gameData, isEditorMode );
if ( flag == StatusFlag.GREEN )
{
if ( wasBlue && !showGreenAfterBlue.getBooleanValue() )
sessionTimeForGreenFlag = -Float.MAX_VALUE;
else if ( showGreenTime.getFloatValue() < 0f )
sessionTimeForGreenFlag = Float.MAX_VALUE;
else
sessionTimeForGreenFlag = gameData.getScoringInfo().getSessionTime() + showGreenTime.getFloatValue();
}
else
{
sessionTimeForGreenFlag = -Float.MAX_VALUE;
}
}
@Override
public void onSessionStarted( SessionType sessionType, LiveGameData gameData, boolean isEditorMode )
{
super.onSessionStarted( sessionType, gameData, isEditorMode );
updateSessionTimeForGreenFlag( gameData, null, false, isEditorMode );
}
@Override
public void onCockpitEntered( LiveGameData gameData, boolean isEditorMode )
{
super.onCockpitEntered( gameData, isEditorMode );
flagValue.reset( true );
updateSessionTimeForGreenFlag( gameData, null, false, isEditorMode );
}
@Override
public void onCockpitExited( LiveGameData gameData, boolean isEditorMode )
{
super.onCockpitExited( gameData, isEditorMode );
updateSessionTimeForGreenFlag( gameData, null, false, isEditorMode );
}
@Override
protected void drawWidget( Clock clock, boolean needsCompleteRedraw, LiveGameData gameData, boolean isEditorMode, TextureImage2D texture, int offsetX, int offsetY, int width, int height )
{
StatusFlag flag = getFlag( gameData, isEditorMode );
if ( flagValue.update( flag ) || needsCompleteRedraw )
{
clearBackgroundRegion( texture, offsetX, offsetY, 0, 0, width, height, true, null );
ImagePropertyWithTexture image = null;
switch ( flag )
{
case GREEN:
image = imageGreen;
break;
case YELLOW:
image = imageYellow;
break;
case BLUE:
image = imageBlue;
break;
case RED:
image = imageRed;
break;
case RED_YELLOW_STRIPED:
image = imageRedYellow;
break;
case WHITE:
image = imageWhite;
break;
case BLACK:
image = imageBlack;
break;
case CHEQUERED:
image = imageChequered;
break;
}
if ( ( flag == StatusFlag.GREEN ) && flagValue.hasChanged( false ) )
updateSessionTimeForGreenFlag( gameData, flag, ( flagValue.getOldValue() == StatusFlag.BLUE ), isEditorMode );
if ( ( flag != StatusFlag.GREEN ) || ( gameData.getScoringInfo().getSessionTime() <= sessionTimeForGreenFlag ) )
{
if ( image != null )
{
image.updateSize( getInnerSize().getEffectiveWidth(), getInnerSize().getEffectiveHeight(), isEditorMode );
texture.drawImage( image.getTexture(), offsetX, offsetY, true, null );
if ( flag == StatusFlag.GREEN )
greenFlagShown = true;
}
}
flagValue.setUnchanged();
}
else if ( ( flag == StatusFlag.GREEN ) && ( gameData.getScoringInfo().getSessionTime() > sessionTimeForGreenFlag ) )
{
if ( greenFlagShown )
clearBackgroundRegion( texture, offsetX, offsetY, 0, 0, width, height, true, null );
greenFlagShown = false;
}
}
}