package se.nicklasgavelin.sphero.macro;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import se.nicklasgavelin.sphero.macro.command.Emit;
import se.nicklasgavelin.util.ByteArrayBuffer;
/**
* Still experimental
*
* @author Orbotix
* @author Nicklas Gavelin, nicklas.gavelin@gmail.com, LuleƄ University of
* Technology
*/
public class MacroObject
{
private Collection<MacroCommand> commands;
private MacroObjectMode mode = MacroObjectMode.Normal;
private static final int MAX_MACRO_LENGTH = 256,
MAX_TOTAL_COMMAND_LENGTH = 240; // x | (248);
public MacroObject()
{
this.commands = new ArrayList<MacroCommand>();
}
public MacroObject( Collection<MacroCommand> _commands )
{
this.commands.addAll( _commands );
}
/**
* Returns the currently stored commands
*
* @return The currently stored commands
*/
public Collection<MacroCommand> getCommands()
{
return this.commands;
}
/**
* Add a command to send
*
* @param command The command to add
*/
public void addCommand( MacroCommand command )
{
this.commands.add( command );
}
/**
* Generate the data for all the commands,
* the maximum size of the macro is 256 and a Roll stop command will be
* appended
* if the size of the concatenated commands exceed 248 bytes
*
* @return The macro commands as a byte array
*/
public byte[] generateMacroData()
{
// Create a buffer
ByteArrayBuffer data = new ByteArrayBuffer( MAX_MACRO_LENGTH );
int currentLength = 0;
// Go through all our commands that we got
for( Iterator<MacroCommand> i = this.commands.iterator(); i.hasNext(); )
{
// Fetch the next command
MacroCommand command = i.next();
// Check if we still got space left
if( command.getLength() + currentLength > MAX_TOTAL_COMMAND_LENGTH )
{
// TODO: Will this really work??? The command will not be added if the
// byte array is full
// Roll stop = new Roll( Double.valueOf( 0.0D ), Integer.valueOf( 0 ),
// Integer.valueOf( 0 ) );
// data.append( stop.getByteRepresentation(), 0, stop.getLength() );
break;
}
// Append the command to our buffer
data.append( command.getByteRepresentation() );
// Update the current length
currentLength += command.getLength();
}
// Append a end command for the macro
data.append( new Emit( 1 ).getByteRepresentation() );
data.append( MacroCommand.MACRO_COMMAND.MAC_END.getValue() );
// Return the created macro data
return data.toByteArray();
}
/**
* Returns the macro mode set for this macro object
*
* @return The current macro mode
*/
public MacroObjectMode getMode()
{
return this.mode;
}
/**
* Set the macro mode for this macro object
*
* @param _mode The new macro mode
*/
public void setMode( MacroObjectMode _mode )
{
this.mode = _mode;
}
/**
* The available macro modes for the MacroObject class
*/
public static enum MacroObjectMode
{
Normal, CachedStreaming;
}
}