// Path: app/src/main/java/com/protolambda/blocktopograph/WorldActivityInterface.java
// public interface WorldActivityInterface {
// 
// 
//     World getWorld();
// 
//     Dimension getDimension();
// 
//     MapType getMapType();
// 
//     boolean getShowGrid();
// 
//     void onFatalDBError(WorldData.WorldDBException worldDB);
// 
//     void addMarker(AbstractMarker marker);
// 
//     void logFirebaseEvent(WorldActivity.CustomFirebaseEvent firebaseEvent);
// 
//     void logFirebaseEvent(WorldActivity.CustomFirebaseEvent firebaseEvent, Bundle eventContent);
// 
//     void showActionBar();
// 
//     void hideActionBar();
// 
//     EditableNBT getEditablePlayer() throws Exception;
// 
//     void changeMapType(MapType mapType, Dimension dimension);
// 
//     void openChunkNBTEditor(final int chunkX, final int chunkZ, final NBTChunkData nbtChunkData, final ViewGroup viewGroup);
// }
// 
// Path: app/src/main/java/com/protolambda/blocktopograph/chunk/ChunkManager.java
// public class ChunkManager {
// 
//     @SuppressLint("UseSparseArrays")
//     private Map<Long, Chunk> chunks = new HashMap<>();
// 
//     private WorldData worldData;
// 
//     public final Dimension dimension;
// 
//     public ChunkManager(WorldData worldData, Dimension dimension){
//         this.worldData = worldData;
//         this.dimension = dimension;
//     }
// 
// 
//     public static long xzToKey(int x, int z){
//         return (((long) x) << 32) | (((long) z) & 0xFFFFFFFFL);
//     }
// 
//     public Chunk getChunk(int cX, int cZ) {
//         long key = xzToKey(cX, cZ);
//         Chunk chunk = chunks.get(key);
//         if(chunk == null) {
//             chunk = new Chunk(worldData, cX, cZ, dimension);
//             this.chunks.put(key, chunk);
//         }
//         return chunk;
//     }
// 
//     public void disposeAll(){
//         this.chunks.clear();
//     }
// 
// 
// 
// 
// }
// 
// Path: app/src/main/java/com/protolambda/blocktopograph/map/renderer/MapType.java
// public enum MapType implements DetailLevelManager.LevelType {
// 
//     //shows that a chunk was present, but couldn't be renderer
//     ERROR(new ChessPatternRenderer(0xFF2B0000, 0xFF580000)),
// 
//     //simple xor pattern renderer
//     DEBUG(new DebugRenderer()),
// 
//     //simple chess pattern renderer
//     CHESS(new ChessPatternRenderer(0xFF2B2B2B, 0xFF585858)),
// 
//     //just the surface of the world, with shading for height diff
//     OVERWORLD_SATELLITE(new SatelliteRenderer()),
// 
//     //cave mapping
//     OVERWORLD_CAVE(new CaveRenderer()),
// 
//     OVERWORLD_SLIME_CHUNK(new SlimeChunkRenderer()),
// 
//     //render skylight value of highest block
//     OVERWORLD_HEIGHTMAP(new HeightmapRenderer()),
// 
//     //render biome id as biome-unique color
//     OVERWORLD_BIOME(new BiomeRenderer()),
// 
//     //render the voliage colors
//     OVERWORLD_GRASS(new GrassRenderer()),
// 
//     //render only the valuable blocks to mine (diamonds, emeralds, gold, etc.)
//     OVERWORLD_XRAY(new XRayRenderer()),
// 
//     //block-light renderer: from light-sources like torches etc.
//     OVERWORLD_BLOCK_LIGHT(new BlockLightRenderer()),
// 
//     NETHER(new NetherRenderer()),
// 
//     NETHER_XRAY(new XRayRenderer()),
// 
//     NETHER_BLOCK_LIGHT(new BlockLightRenderer()),
// 
//     END_SATELLITE(new SatelliteRenderer()),
// 
//     END_HEIGHTMAP(new HeightmapRenderer()),
// 
//     END_BLOCK_LIGHT(new BlockLightRenderer());
// 
//     //REDSTONE //TODO redstone circuit mapping
//     //TRAFFIC //TODO traffic mapping (land = green, water = blue, gravel/stone/etc. = gray, rails = yellow)
// 
// 
//     public final MapRenderer renderer;
// 
//     MapType(MapRenderer renderer){
//         this.renderer = renderer;
//     }
// 
// }


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import com.protolambda.blocktopograph.WorldActivityInterface;
import com.protolambda.blocktopograph.chunk.ChunkManager;
import com.protolambda.blocktopograph.map.renderer.MapType;
import com.qozix.tileview.graphics.BitmapProvider;
import com.qozix.tileview.tiles.Tile;
package com.protolambda.blocktopograph.map;




public class MCTileProvider implements BitmapProvider {


    public static final int TILESIZE = 256,


    //TODO the maximum world size is way bigger than the worldsize that this app can handle (due to render glitches & rounding errors)
    //HALF_WORLDSIZE has to be a power of 2! (It must be perfectly divisible by TILESIZE, which is a power of two)
    HALF_WORLDSIZE = 1 << 20;

    public static int worldSizeInBlocks = 2 * HALF_WORLDSIZE,
    viewSizeW = worldSizeInBlocks * TILESIZE / Dimension.OVERWORLD.chunkW,
    viewSizeL = worldSizeInBlocks * TILESIZE / Dimension.OVERWORLD.chunkL;

    public final WorldActivityInterface worldProvider;

// Path: app/src/main/java/com/protolambda/blocktopograph/WorldActivityInterface.java
// public interface WorldActivityInterface {
// 
// 
//     World getWorld();
// 
//     Dimension getDimension();
// 
//     MapType getMapType();
// 
//     boolean getShowGrid();
// 
//     void onFatalDBError(WorldData.WorldDBException worldDB);
// 
//     void addMarker(AbstractMarker marker);
// 
//     void logFirebaseEvent(WorldActivity.CustomFirebaseEvent firebaseEvent);
// 
//     void logFirebaseEvent(WorldActivity.CustomFirebaseEvent firebaseEvent, Bundle eventContent);
// 
//     void showActionBar();
// 
//     void hideActionBar();
// 
//     EditableNBT getEditablePlayer() throws Exception;
// 
//     void changeMapType(MapType mapType, Dimension dimension);
// 
//     void openChunkNBTEditor(final int chunkX, final int chunkZ, final NBTChunkData nbtChunkData, final ViewGroup viewGroup);
// }
// 
// Path: app/src/main/java/com/protolambda/blocktopograph/chunk/ChunkManager.java
// public class ChunkManager {
// 
//     @SuppressLint("UseSparseArrays")
//     private Map<Long, Chunk> chunks = new HashMap<>();
// 
//     private WorldData worldData;
// 
//     public final Dimension dimension;
// 
//     public ChunkManager(WorldData worldData, Dimension dimension){
//         this.worldData = worldData;
//         this.dimension = dimension;
//     }
// 
// 
//     public static long xzToKey(int x, int z){
//         return (((long) x) << 32) | (((long) z) & 0xFFFFFFFFL);
//     }
// 
//     public Chunk getChunk(int cX, int cZ) {
//         long key = xzToKey(cX, cZ);
//         Chunk chunk = chunks.get(key);
//         if(chunk == null) {
//             chunk = new Chunk(worldData, cX, cZ, dimension);
//             this.chunks.put(key, chunk);
//         }
//         return chunk;
//     }
// 
//     public void disposeAll(){
//         this.chunks.clear();
//     }
// 
// 
// 
// 
// }
// 
// Path: app/src/main/java/com/protolambda/blocktopograph/map/renderer/MapType.java
// public enum MapType implements DetailLevelManager.LevelType {
// 
//     //shows that a chunk was present, but couldn't be renderer
//     ERROR(new ChessPatternRenderer(0xFF2B0000, 0xFF580000)),
// 
//     //simple xor pattern renderer
//     DEBUG(new DebugRenderer()),
// 
//     //simple chess pattern renderer
//     CHESS(new ChessPatternRenderer(0xFF2B2B2B, 0xFF585858)),
// 
//     //just the surface of the world, with shading for height diff
//     OVERWORLD_SATELLITE(new SatelliteRenderer()),
// 
//     //cave mapping
//     OVERWORLD_CAVE(new CaveRenderer()),
// 
//     OVERWORLD_SLIME_CHUNK(new SlimeChunkRenderer()),
// 
//     //render skylight value of highest block
//     OVERWORLD_HEIGHTMAP(new HeightmapRenderer()),
// 
//     //render biome id as biome-unique color
//     OVERWORLD_BIOME(new BiomeRenderer()),
// 
//     //render the voliage colors
//     OVERWORLD_GRASS(new GrassRenderer()),
// 
//     //render only the valuable blocks to mine (diamonds, emeralds, gold, etc.)
//     OVERWORLD_XRAY(new XRayRenderer()),
// 
//     //block-light renderer: from light-sources like torches etc.
//     OVERWORLD_BLOCK_LIGHT(new BlockLightRenderer()),
// 
//     NETHER(new NetherRenderer()),
// 
//     NETHER_XRAY(new XRayRenderer()),
// 
//     NETHER_BLOCK_LIGHT(new BlockLightRenderer()),
// 
//     END_SATELLITE(new SatelliteRenderer()),
// 
//     END_HEIGHTMAP(new HeightmapRenderer()),
// 
//     END_BLOCK_LIGHT(new BlockLightRenderer());
// 
//     //REDSTONE //TODO redstone circuit mapping
//     //TRAFFIC //TODO traffic mapping (land = green, water = blue, gravel/stone/etc. = gray, rails = yellow)
// 
// 
//     public final MapRenderer renderer;
// 
//     MapType(MapRenderer renderer){
//         this.renderer = renderer;
//     }
// 
// }


// Path: app/src/main/java/com/protolambda/blocktopograph/map/MCTileProvider.java
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import com.protolambda.blocktopograph.WorldActivityInterface;
import com.protolambda.blocktopograph.chunk.ChunkManager;
import com.protolambda.blocktopograph.map.renderer.MapType;
import com.qozix.tileview.graphics.BitmapProvider;
import com.qozix.tileview.tiles.Tile;

package com.protolambda.blocktopograph.map;




public class MCTileProvider implements BitmapProvider {


    public static final int TILESIZE = 256,


    //TODO the maximum world size is way bigger than the worldsize that this app can handle (due to render glitches & rounding errors)
    //HALF_WORLDSIZE has to be a power of 2! (It must be perfectly divisible by TILESIZE, which is a power of two)
    HALF_WORLDSIZE = 1 << 20;

    public static int worldSizeInBlocks = 2 * HALF_WORLDSIZE,
    viewSizeW = worldSizeInBlocks * TILESIZE / Dimension.OVERWORLD.chunkW,
    viewSizeL = worldSizeInBlocks * TILESIZE / Dimension.OVERWORLD.chunkL;

    public final WorldActivityInterface worldProvider;

    public MCTileProvider(WorldActivityInterface worldProvider){