import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.InputStreamReader;

public class FileAnalyzer extends Thread
{
    public FileAnalyzer( ThreadGroup tg, String file, char[][] d, BestPath b )
    {
        super( tg, file );
        done = false;
        best = b;
        try
        {
            reader = new BufferedReader( new FileReader( file ) );
        }
        catch( java.io.FileNotFoundException e )
        {
            done=true;
        }
        dataArray = d;
        arrayWidth = dataArray.length;
        arrayHeight = dataArray[0].length;
        visitArray = new int[arrayWidth][arrayHeight];
        for( int i=0; i<arrayWidth; i++)
            for( int j=0;j<arrayHeight; j++)
                visitArray[i][j] = 0;
    }

    public boolean noMoreData()
    {
        return done;
    }

    public void run()
    {
        int currentScore;
        int count = 0;
        try
        {
            toProcess = reader.readLine();
            while( !toProcess.equals( "end" ) )
            {
                setTheDim();
                if( isGood() )
                {
                    currentScore = checksum();
                    if( currentScore > best.score )
                    {
                        best.score = currentScore;
                        best.path = toProcess;
                    }
                }
                toProcess = reader.readLine();
                if( toProcess == null )
                    toProcess = "end";
                count++;
            }
        }
        catch( java.io.IOException e )
        {
            System.out.println( "Analyzer.run() " + e );
        }
    }
    private void resetVisit()
    {
        for( int i=0; i<arrayWidth; i++)
            for( int j=0;j<arrayHeight; j++)
                visitArray[i][j] = 0;
    }

    private void setTheDim()
    {
        //get horizontal
        String horiz = toProcess.substring( 0, 
            toProcess.indexOf( ' ' ) ).trim();
        h = ( new Integer( toProcess.substring( 0, 
           toProcess.indexOf( ' ' ) ).trim() ) ).intValue();
        toProcess = toProcess.substring( toProcess.indexOf( ' ' ) + 1, 
            toProcess.length() );

        //get vertical
        v = ( new Integer( toProcess.substring( 0, 
                           toProcess.indexOf( ' ' ) ) ) ).intValue();
        toProcess = toProcess.substring( toProcess.indexOf( ' ' ) + 1, 
                                         toProcess.length() );

    }

    private int checksum( )
    {
        
        int score = 1;
        char currentMove;
        char previousChar  = ' ';
        char currentChar = ' ';
        int x = 0;
        int y = 0;
        boolean done = false;
        //visit original spot
        resetVisit();
        visitArray[x][y]++;
        
        //move until the end
        while( !done )
        {
            for( int i=0; i<toProcess.length(); i++ )
            {
                previousChar = dataArray[x][y];
                currentMove = toProcess.charAt( i );
                //do the next move
                switch (currentMove )
                {
                    case 'N': 
                        y--;
                        break;
                    case 'S':
                        y++;
                        break;
                    case 'E':
                        x++;
                        break;
                    case 'W':
                        x--;
                        break;
                }
                
                //check for bounds
                if( y < 0 )
                    y = 0;
                if( y >= arrayHeight )
                    y = arrayHeight - 1;
                if( x < 0)
                    x = 0;
                if( x >= arrayWidth )
                    x = arrayWidth - 1;
                if( score < Integer.MIN_VALUE - 1000000 )
                    done = true;
                try
                {
                    currentChar = dataArray[x][y];
                }
                catch( java.lang.ArrayIndexOutOfBoundsException e )
                {
                    System.out.println( "Array Error at " + x + " " + y );
                    System.out.println( "" + e );
                    System.exit( 1 );
                }

                //moving backwards thru alphbet
                if( currentChar < previousChar )
                    score -= 5;

                //number of times that we have visited this cell
                score += 2 - Math.pow( 2, visitArray[x][y] );
                visitArray[x][y]++;
                
                //are we done yet?
                if( x == arrayWidth - 1 && y == arrayHeight - 1)
                    done = true;
                /*
                System.out.println( "Move:"  + visitArray[x][y] );
                System.out.println( "\t" + currentChar + " " + x + " " + y );
                System.out.println( "\t" + score );
                */
            }
        }
        return score - toProcess.length();
    }

    private boolean isGood()
    {
        if( toProcess.length() > arrayWidth * arrayHeight )
            return false;
        if( h >= arrayWidth || v >= arrayHeight )
            return false;
        if( v == 0 && arrayHeight != 1 )
            return false;
        if( h == 0 && arrayWidth != 1 )
            return false;
        if( h == 0 )
        {
            if( v == 0 )
            {
                return false;
            }
            else if( arrayWidth == 1 && (arrayHeight - 1) % v == 0 )
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        else if( v == 0 && arrayHeight == 1 && (arrayWidth - 1) % h == 0 )
        {
            return true;
        }
        else if( (arrayWidth - 1) % h != 0 )
        {
            return false;
        }
        else if( (arrayHeight -1) % v != 0 )
        {
            return false;
        }
        else if( (arrayWidth - 1) % h == 0 && (arrayHeight - 1) % v == 0 )
        {
            return true;
        }
        else
        {
            System.out.println( "isGood Error" + toProcess + " " + h + " " + v );
            return false;
        }
    }

    int h;
    int v;
    int bestScore;
    int arrayWidth;
    int arrayHeight;
    char[][] dataArray;
    int[][] visitArray;
    BufferedReader reader;
    String toProcess;
    BestPath best;
    boolean done;
}
