package org.vostan.banvor.game;

import static org.vostan.banvor.App.TAG;

import android.util.Log;

import org.vostan.banvor.model.Puzzle;

import java.io.IOException;
import java.io.InputStream;

public class PuzzleBinLoader {

    /*
     * Load puzzle from the puzzle.bin.
     */
    public static Puzzle loadNthPuzzle(InputStream is, int i )
    {try{
        //
        //	Read amount of puzzles.
        //
        int count = read_i32(is);
        if ( i >= count )
            return null;
        //
        //	Read the offset.
        //
        is.skip( i*4 );
        int offset = read_i32(is);
        //
        //	Jump to the offset and read the puzzle.
        //
        is.skip( offset - 4 - (i+1)*4);
        Puzzle p = loadPuzzle(is);
        //
        //	Finally return the puzzle and we are done.
        //
        return p;
    }
    catch ( java.lang.Exception e )
    {
        //Log.d(TAG, "Exception: " + e.getMessage() );
        e.printStackTrace();
        return null;
    }}
    //
    //	Retrive amount of puzzles.
    //
    public static int getCount(InputStream is)
    {try{
        int count = read_i32(is);
        return count;
    }
    catch ( java.lang.Exception e )
    {
        //Log.d(TAG, "Exception: " + e.getMessage() );
        e.printStackTrace();
        return 0;
    }}

    private static Puzzle loadPuzzle( InputStream is )
    { try{
        int cols = is.read();
        int rows = is.read();

        int [] board = new int[cols*rows];
        byte [] b = new byte [cols*rows];
        is.read( b, 0, cols*rows);
        for( int i = 0; i < b.length; ++i )
        {
            switch( b[i] )
            {
                case 0:
                    board[i] = Puzzle.FLOOR;
                    break;
                case 1:
                    board[i] = Puzzle.WALL;
                    break;
                case 2:
                    board[i] = Puzzle.BOX;
                    break;
                case 3:
                    board[i] = Puzzle.GOAL;
                    break;
                case 4:
                    board[i] = Puzzle.BINGO;
                    break;
                case 5:
                    board[i] = Puzzle.WORKER;
                    break;
                default:
            }
        }
        return new Puzzle(cols, rows, board);
    }
    catch ( Exception e )
    {
        Log.d( TAG, "load()", e);
        return null;
    }}

    //
    //	Helper function to read little endian 32bit integer.
    //
    private static int read_i32( InputStream is ) throws IOException
    {
        int i = is.read();
        i |= is.read() << 8;
        i |= is.read() << 16;
        i |= is.read() << 24;
        return i;
    }
}
