/Users/petercappello/NetBeansProjects/56-2014/56-2014-5-Gala/src/Assembler.java
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import javax.swing.JTextArea;

/**
 * The GALA assembler.
 * @author Peter Cappello
 */
public class Assembler extends TextFileReader
{
    private static final String ignoreLineRegex = "(#.*|\\s*)"; 
    
    private final List<Instruction> program = new ArrayList<>();
    private int lineNum;
    private boolean isValid = true;
    private int numInvalidStatements;
    private JTextArea output;
    private JTextArea console;
    
    boolean assemble( JTextArea output, JTextArea console ) throws IOException
    {    
        this.output = output;
        this.console = console;
        Instruction.resetClass();
        process();
        return Instruction.areAllIdentifiersDefined( console ) ? isValid : false;
    }
        
    int getNumInvalidStatements() { return numInvalidStatements; }
    
    List<Instruction> getProgram() { return program; }
    
    int[][] toArray()
    {
        int[][] instructionArray = new int[ program.size() ][];
        for ( int i = 0; i < program.size(); i++ )
        {
            instructionArray[ i ] = program.get( i ).toArray();
        }
        return instructionArray;
    }
    
    @Override
    public void processLine( String line )
    {
        output.append( String.format( "%3d %s%n", ++lineNum, line ) );
        
        // Prepare line for processing: remove comment & trim
        line = line.replaceFirst("#.*", "").trim();
        if ( line.matches( ignoreLineRegex ) )
        {
            return; // ignore lines w/o an instruction
        }       
        
        Instruction instruction = new Instruction( line, lineNum );
        if ( ! instruction.isValid() )
        {
            console.append( lineNum + ": ");
            console.append( instruction.getErrorMessage() );
            console.append( "\n" );
            isValid = false;
            numInvalidStatements++;
        }
        if ( instruction.isMachineInstruction() )
        {
            program.add( instruction );
        }
    }
    
    /**
     * Used to test regular expressions.
     * @param args unused
     */
    public static void main( String[] args )
    {
        System.out.println("identifierRegex: '# whatever' " + Pattern.matches( ignoreLineRegex, "# whatever" ) );
        System.out.println("identifierRegex: '    ' " + Pattern.matches( ignoreLineRegex, "    " ) );
    }
}