package ocgcore;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.annotation.WorkerThread;
import android.util.Log;
import android.util.SparseArray;

import java.io.File;
import java.io.FilenameFilter;

import cn.garymb.ygomobile.AppsSettings;
import cn.garymb.ygomobile.utils.IOUtils;
import ocgcore.data.Card;


public class CardManager {
    private String dbDir, exDbPath;
    private final SparseArray<Card> cardDataHashMap = new SparseArray<>();

    public CardManager(String dbDir, String exPath) {
        this.dbDir = dbDir;
        this.exDbPath = exPath;
    }

    public Card getCard(int code) {
        return cardDataHashMap.get(Integer.valueOf(code));
    }

    public int getCount() {
        return cardDataHashMap.size();
    }

    public SparseArray<Card> getAllCards() {
        return cardDataHashMap;
    }

    @WorkerThread
    public void loadCards() {
        cardDataHashMap.clear();
        int count = readAllCards(AppsSettings.get().getDataBaseFile(), cardDataHashMap);
        Log.i("Irrlicht", "load defualt cdb:" + count);
        if (AppsSettings.get().isReadExpansions()) {
            File dir = new File(exDbPath);
            if (dir.exists()) {
                File[] files = dir.listFiles(new FilenameFilter() {
                    @Override
                    public boolean accept(File dir, String name) {
                        File file = new File(dir, name);
                        return file.isFile() && name.endsWith(".cdb");
                    }
                });
                //读取全部卡片
                if (files != null) {
                    for (File file : files) {
                        count = readAllCards(file, cardDataHashMap);
                        Log.i("Irrlicht", "load " + count + " cdb:" + file);
                    }
                }
            }
        }
    }

    private static SQLiteDatabase openDatabase(String file) {
        return SQLiteDatabase.openDatabase(file, null,
                SQLiteDatabase.NO_LOCALIZED_COLLATORS | SQLiteDatabase.OPEN_READONLY);
    }

    public static boolean checkDataBase(File file) {
        if (!file.exists()) {
            return false;
        }
        Cursor reader = null;
        SQLiteDatabase db = null;
        boolean rs = false;
        try {
            db = openDatabase(file.getPath());
            reader = db.rawQuery("select datas.id, ot, alias, setcode, type, level, race, attribute, atk, def,category,name,\"desc\" from datas,texts  where datas.id = texts.id limit 1;", null);
            rs = reader != null;
        } catch (Throwable e) {
            //ignore
        } finally {
            IOUtils.close(reader);
        }
        if (!rs) {
            try {
                reader = db.rawQuery("select datas._id, ot, alias, setcode, type, level, race, attribute, atk, def,category,name,\"desc\" from datas,texts where datas._id = texts._id  limit 1;", null);
                rs = reader != null;
            } catch (Throwable e) {
                //ignore
            } finally {
                IOUtils.close(reader);
            }
        }
        IOUtils.close(db);
        return rs;
    }

    @WorkerThread
    protected int readAllCards(File file, SparseArray<Card> cardMap) {
        if (!file.exists()) {
            return 0;
        }
        int i = 0;
        Cursor reader = null;
        SQLiteDatabase db = null;
        try {
            db = openDatabase(file.getPath());
            try {
                reader = db.rawQuery("select datas.id, ot, alias, setcode, type, level, race, attribute, atk, def,category,name,\"desc\" from datas,texts where datas.id = texts.id;", null);
            } catch (Throwable e) {
                //ignore
                reader = db.rawQuery("select datas._id, ot, alias, setcode, type, level, race, attribute, atk, def,category,name,\"desc\" from datas,texts where datas._id = texts._id;", null);
            }
            if (reader != null && reader.moveToFirst()) {
                do {
                    Card cardData = new Card();
                    cardData.Code = reader.getInt(0);
                    cardData.Ot = reader.getInt(1);
                    cardData.Alias = reader.getInt(2);
                    cardData.Setcode = reader.getLong(3);
                    cardData.Type = reader.getLong(4);
                    int levelInfo = reader.getInt(5);
                    cardData.Level = levelInfo & 0xff;
                    cardData.LScale = (levelInfo >> 24) & 0xff;
                    cardData.RScale = (levelInfo >> 16) & 0xff;
                    cardData.Race = reader.getLong(6);
                    cardData.Attribute = reader.getInt(7);
                    cardData.Attack = reader.getInt(8);
                    cardData.Defense = reader.getInt(9);
                    cardData.Category = reader.getLong(10);
                    cardData.Name = reader.getString(11);
                    cardData.Desc = reader.getString(12);
                    //put
                    i++;
                    cardMap.put(cardData.Code, cardData);
                } while (reader.moveToNext());
            }
        } catch (Throwable e) {
            e.printStackTrace();
            Log.e("Irrlicht", "read cards " + file, e);
        } finally {
            IOUtils.close(reader);
            IOUtils.close(db);
        }
        return i;
    }
}
