package paulscode.sound;

import net.lax1dude.eaglercraft.EaglerAdapter;

/**
 * The CommandThread class is designed to move all command processing into a
 * single thread to be run in the background and avoid conflicts between
 * threads.  Commands are processed in the order that they were queued.  The
 * arguements for each command are stored in a
 * {@link paulscode.sound.CommandObject CommandObject}.  The Command Queue is
 * located in the {@link paulscode.sound.SoundSystem SoundSystem} class.
 * Calling kill() stops the thread, and this should be immediatly followed
 * by a call to interrupt() to wake up the thread so it may end.  This class
 * also checks for temporary sources that are finished playing, and removes
 * them.
 *
 * NOTE: The command thread is created automatically by the sound system, so it
 * is unlikely that the user would ever need to use this class.
 *<br><br>
 *<b><i>    SoundSystem License:</b></i><br><b><br>
 *    You are free to use this library for any purpose, commercial or otherwise.
 *    You may modify this library or source code, and distribute it any way you
 *    like, provided the following conditions are met:
 *<br>
 *    1) You may not falsely claim to be the author of this library or any
 *    unmodified portion of it.
 *<br>
 *    2) You may not copyright this library or a modified version of it and then
 *    sue me for copyright infringement.
 *<br>
 *    3) If you modify the source code, you must clearly document the changes
 *    made before redistributing the modified source code, so other users know
 *    it is not the original code.
 *<br>
 *    4) You are not required to give me credit for this library in any derived
 *    work, but if you do, you must also mention my website:
 *    http://www.paulscode.com
 *<br>
 *    5) I the author will not be responsible for any damages (physical,
 *    financial, or otherwise) caused by the use if this library or any part
 *    of it.
 *<br>
 *    6) I the author do not guarantee, warrant, or make any representations,
 *    either expressed or implied, regarding the use of this library or any
 *    part of it.
 * <br><br>
 *    Author: Paul Lamb
 * <br>
 *    http://www.paulscode.com
 * </b>
 */
public class CommandThread extends SimpleThread
{
/**
 * Processes status messages, warnings, and error messages.
 */
    protected SoundSystemLogger logger;
    
/**
 * Handle to the Sound System.  This is where the Command Queue is located.
 */
    private SoundSystem soundSystem;
    
/**
 * Name of this class.
 */
    protected String className = "CommandThread";
    
/**
 * Constructor:  Takes a handle to the SoundSystem object as a parameter.
 * @param s Handle to the SoundSystem.
*/
    public CommandThread( SoundSystem s )
    {
        // grab a handle to the message logger:
        logger = SoundSystemConfig.getLogger();
        
        soundSystem = s;
    }
    
/**
 * Shuts the thread down and removes references to all instantiated objects.  
 * NOTE: Method alive() will return false when cleanup() has finished.
 */
    @Override
    protected void cleanup()
    {
        kill();
        
        logger = null;
        soundSystem = null;
        
        super.cleanup();  // Important!
    }
    
/**
 * The main loop for processing commands.  The Command Thread starts out 
 * asleep, and it sleeps again after it finishes processing commands, so it 
 * must be interrupted when commands are queued for processing.
 */
    @Override
    public void run()
    {
        long previousTime = EaglerAdapter.steadyTimeMillis();
        long currentTime = previousTime;
        
        if( soundSystem == null )
        {
            errorMessage( "SoundSystem was null in method run().", 0 );
            cleanup();
            return;
        }
        
        // Start out asleep:
        snooze( 3600000 );
        
        while( !dying() )
        {
            // Perform user-specific source management:
            soundSystem.ManageSources();

            // Process all queued commands:
            soundSystem.CommandQueue( null );
            
            // Remove temporary sources every ten seconds:
            currentTime = EaglerAdapter.steadyTimeMillis();
            if( (!dying()) && ((currentTime - previousTime) > 10000) )
            {
                previousTime = currentTime;
                soundSystem.removeTemporarySources();
            }
            
            // Wait for more commands:
            if( !dying() )
                snooze( 3600000 );
        }
        
        cleanup();   // Important!
    }
    
/**
 * Prints a message.
 * @param message Message to print.
 */
    protected void message( String message, int indent )
    {
        logger.message( message, indent );
    }
    
/**
 * Prints an important message.
 * @param message Message to print.
 */
    protected void importantMessage( String message, int indent )
    {
        logger.importantMessage( message, indent );
    }
    
/**
 * Prints the specified message if error is true.
 * @param error True or False.
 * @param message Message to print if error is true.
 * @return True if error is true.
 */
    protected boolean errorCheck( boolean error, String message )
    {
        return logger.errorCheck( error, className, message, 0 );
    }
    
/**
 * Prints an error message.
 * @param message Message to print.
 */
    protected void errorMessage( String message, int indent )
    {
        logger.errorMessage( className, message, indent );
    }
}
