import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Hashtable;
/**
 *
 * @author user
 */
public class MLoader {
    
    private int quantity;
    private ByteArrayInputStream bais;
    private Hashtable hashtable;
    
    /*
     * Конструктор класса, загружет уровень (level) по пути path
     */
    public MLoader(String path, int level) {
        loadMaps(path);
        quantity = bais.read();
        int size = -1, nLevel = 1;
        while((size = getValue(3)) > 0) {
            if(nLevel == level) {
                getMap();
                break;
            }
            bais.skip(size);
            nLevel++;
        }
        bais = null;
    }
    
    /*
     * Конструктор класса, загружет карту из массива байт
     */
    public MLoader(byte[] data) {
        bais = new ByteArrayInputStream(data);
        data = null;
        getMap();
        bais = null;
    }
    
    /*
     * Возвращает общее количество уровней в игре
     */
    public int quantity() {
        return quantity;
    }
    
    /*
     * Приватная функция, загружет карту из bais'а
     */
    private void getMap() {
        hashtable = new Hashtable();
        bais.skip(getValue(1));
        int[] lWH = {getValue(1), getValue(1)};
        hashtable.put("wh", lWH);
        int[][] tiles = new int[lWH[1]][lWH[0]];
        for(int i=0; i<lWH[1]; i++) {
            for(int j=0; j<lWH[0]; j++) {
                tiles[i][j] = getValue(1);
            }
        }
        lWH = null;
        hashtable.put("tiles", tiles);
        tiles = null;
        int[] lTime = {getValue(1), getValue(1)};
        hashtable.put("time", lTime);
        lTime = null;
        hashtable.put("points", ""+getValue(2));
    }
    
    /*
     * Приватная функция, загружет файл карт по пути path
     */
    private void loadMaps(String path) {
        InputStream is = getClass().getResourceAsStream(path);
        byte[] data = null;
        try {
            data = new byte[is.available()];
            is.read(data);
            is.close();
        } catch (IOException ex) {}
        is = null;
        bais = new ByteArrayInputStream(Encode.encode(data));
        data = null;
    }
    
    /*
     * Возврашает одно из значений карты (например "tiles", "wh", "time" или "points")
     */
    public Object get(String key) {
        return hashtable.get(key);
    }
    
    /*
     * Приватная функция, возвращает int число из массива байт с разрядностью 'd'
     */
    private int getValue(int d) {
        switch(d) {
            case 1:
                return bais.read();
            case 2:
                return bais.read()*256+bais.read();
            case 3:
                return bais.read()*65536+bais.read()*256+bais.read();
        }
        return 0;
    }
    
}
