package com.mygdx.game.data;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

import com.mygdx.game.Constants;
import com.mygdx.game.GameTile;
import com.mygdx.game.R;

import static android.provider.BaseColumns._ID;

public class GameDAO extends SQLiteOpenHelper {
    private static final String DATABASE_NAME = "njoy.db";
    private static final int DATABASE_VERSION = 3;

    // Create table statements

    /**
     * The table containing the definitions of each available game tile type.
     */
    private static final String CREATE_TABLE_GAME_TILES = "CREATE TABLE " + GameTileData.TABLE_NAME + " ("
            + _ID + " INTEGER PRIMARY KEY, "
            + GameTileData.NAME + " STRING,"
            + GameTileData.TYPE + " INTEGER DEFAULT 0,"
            + GameTileData.DRAWABLE + " INTEGER DEFAULT 0,"
            + GameTileData.VISIBLE + " INTEGER DEFAULT 1"
            + ");";

    /**
     * The table containing the definitions of each level.
     */
    private static final String CREATE_TABLE_GAME_LEVEL_TILES = "CREATE TABLE " + GameLevelTileData.TABLE_NAME + " ("
            + _ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
            + GameLevelTileData.LEVEL + " INTEGER DEFAULT 0,"
            + GameLevelTileData.PLAYER_START_TILE_X + " INTEGER DEFAULT 0,"
            + GameLevelTileData.PLAYER_START_TILE_Y + " INTEGER DEFAULT 0,"
            + GameLevelTileData.TILE_DATA + " TEXT NOT NULL"
            + ");";

    // Populate table statements

    /**
     * Populates the game tile definition table. Each row contains:
     * - A unique ID, specified instead of generated by AUTOINCREMENT so tile definitions
     * are easier to reference when populating the level data table
     * - The tile name.
     * - The tile type ID.
     * - The tile drawable resource ID.
     * - The tile visibility option (1 = visible, 0 = invisible.)
     */
    private static final String[] POPULATE_TABLE_GAME_TILES = {
            "INSERT INTO " + GameTileData.TABLE_NAME + " VALUES "
                    + "(1,\"Empty\"," + GameTile.Type.EMPTY.getId() + "," + R.drawable.empty + ",0);",

            "INSERT INTO " + GameTileData.TABLE_NAME + " VALUES "
                    + "(2,\"Grass 01\"," + GameTile.Type.EMPTY.getId() + "," + R.drawable.grass + ",1);",

            "INSERT INTO " + GameTileData.TABLE_NAME + " VALUES "
                    + "(3,\"Dirt 01\"," + GameTile.Type.EMPTY.getId() + "," + R.drawable.dirt + ",1);"
    };

    /**
     * Populates the level data definition table. Each row contains:
     * - An automatically generated unique ID.
     * - The level ID.
     * - The player start tile X (horizontal) location.
     * - The player start tile Y (vertical) location.
     * - The level tile data.
     * Level tile data consists of rows of comma-delimited game tile IDs.
     * The tile IDs used correspond to the unique IDs found in the game
     * tile definition table.
     * <p/>
     * The position of each game tile ID corresponds to the position the
     * tile will be drawn in the game.
     */

    private static final String[] POPULATE_TABLE_GAME_LEVEL_1_TILES = {
            "INSERT INTO " + GameLevelTileData.TABLE_NAME + " VALUES "
                    + "(null,1,7,3,\""
                    // 1  2  3  4  5  6  7  8  9  10 11 12 13 14 15
        /* 1  */ + "03,03,03,03,03,03,03,03,03,03,03,03,03,03,03" + GameLevelTileData.TILE_DATA_LINE_BREAK
        /* 2  */ + "03,02,02,02,02,02,02,02,02,02,02,02,02,02,03" + GameLevelTileData.TILE_DATA_LINE_BREAK
        /* 3  */ + "03,02,02,02,02,02,02,02,02,02,02,02,02,02,03" + GameLevelTileData.TILE_DATA_LINE_BREAK
		/* 4  */ + "03,02,02,02,02,02,02,02,02,03,03,03,03,03,03" + GameLevelTileData.TILE_DATA_LINE_BREAK
		/* 5  */ + "03,02,02,02,02,02,02,02,02,03,02,02,02,02,03" + GameLevelTileData.TILE_DATA_LINE_BREAK
		/* 6  */ + "03,03,03,03,03,02,02,02,02,03,02,02,02,02,03" + GameLevelTileData.TILE_DATA_LINE_BREAK
		/* 7  */ + "03,02,02,02,03,02,02,02,02,03,03,02,02,02,03" + GameLevelTileData.TILE_DATA_LINE_BREAK
		/* 8  */ + "03,02,02,02,03,02,02,02,02,02,03,02,02,02,03" + GameLevelTileData.TILE_DATA_LINE_BREAK
		/* 9  */ + "03,02,02,02,03,02,02,02,02,02,03,02,02,02,03" + GameLevelTileData.TILE_DATA_LINE_BREAK
		/* 10 */ + "03,02,02,02,03,02,02,02,02,02,03,02,02,02,03" + GameLevelTileData.TILE_DATA_LINE_BREAK
		/* 11 */ + "03,02,02,03,03,02,02,02,02,03,03,02,02,02,03" + GameLevelTileData.TILE_DATA_LINE_BREAK
		/* 12 */ + "03,02,02,03,02,02,02,02,02,03,02,02,02,02,03" + GameLevelTileData.TILE_DATA_LINE_BREAK
		/* 13 */ + "03,02,02,03,02,02,02,02,02,03,02,02,02,02,03" + GameLevelTileData.TILE_DATA_LINE_BREAK
		/* 14 */ + "03,02,02,03,03,03,03,03,03,03,02,02,02,02,03" + GameLevelTileData.TILE_DATA_LINE_BREAK
		/* 15 */ + "03,02,02,02,02,02,02,02,02,02,02,02,02,02,03" + GameLevelTileData.TILE_DATA_LINE_BREAK
		/* 16 */ + "03,02,02,02,02,02,02,02,02,02,02,02,02,02,03" + GameLevelTileData.TILE_DATA_LINE_BREAK
		/* 17 */ + "03,03,03,03,03,03,03,03,03,03,03,03,03,03,03" + GameLevelTileData.TILE_DATA_LINE_BREAK
                    + "\");"
    };

    public GameDAO(Context ctx) {
        super(ctx, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // Create game tables

        Log.d(Constants.N_JOY, "Creating DB tables");

        db.execSQL(CREATE_TABLE_GAME_TILES);
        db.execSQL(CREATE_TABLE_GAME_LEVEL_TILES);

        // Populate game tables

        Log.d(Constants.N_JOY, "Populating DB tables");

        for (String query : POPULATE_TABLE_GAME_TILES) {
            db.execSQL(query);
        }

        for (String query : POPULATE_TABLE_GAME_LEVEL_1_TILES) {
            db.execSQL(query);
        }
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + GameTileData.TABLE_NAME);
        db.execSQL("DROP TABLE IF EXISTS " + GameLevelTileData.TABLE_NAME);

        onCreate(db);
    }

}
