public class CreatureDao {
    private CommonDatabase<Creature> db;
    private Mapper<Creature> rowMapper;

    public CreatureDao(CommonDatabase<Creature> database,
            Mapper<Creature> mapper) {
        db = database;
        rowMapper = mapper;
    }

    public Creature create(Creature creature) {
        return db.insert(creature, CommonDatabase.INFO_TABLE_NAME);
    }

    public Creature update(Creature creature) {
        db.update(CommonDatabase.INFO_TABLE_NAME, creature, "CI_ID = "
                + creature.id, null);
        return creature;
    }

    public void delete(Creature creature) {
        db.delete(CommonDatabase.INFO_TABLE_NAME, "CI_ID = " + creature.id,
                null);
    }

    public boolean isDatabaseEmpty() {
        List<Creature> c = db.queryList(rowMapper,
                CommonDatabase.INFO_TABLE_NAME, null, null, null, null, null,
                null);
        if (c == null) {
            return true;
        }
        return false;
    }

//    public void seedData() {
//        // TODO: debug guard
//        db.seedData();
//    }
//
//    public void purgeData() {
//        // TODO: debug guard
//        db.deleteDatabase();
//    }

    public List<Creature> getAll() {
        return db
                .queryList(
                        rowMapper,
                        "CREATURE_INFO join CREATURE_TYPE on (CREATURE_INFO.CT_ID = CREATURE_TYPE.CT_ID)",
                        null, null, null, null, null, null);
    }

    public int getNumberOfAlive() {
        return db.getResultCount(CommonDatabase.INFO_TABLE_NAME, null,
                "CI_ALIVE = 1", null, null, null, null);
    }

    public Creature findById(long id) {
        return db
                .queryUnique(
                        rowMapper,
                        "CREATURE_INFO join CREATURE_TYPE on (CREATURE_INFO.CT_ID = CREATURE_TYPE.CT_ID)",
                        null, "CI_ID = " + id, null, null, null, null);
    }
} public class CreatureDatabase<T extends CommonModel> implements
        CommonDatabase<T> {

    public static final String INFO_TABLE_NAME = "CREATURE_INFO";
    public static final String STATE_TABLE_NAME = "CREATURE_STATE";
    public static final String EVOLUTION_TABLE_NAME = "CREATURE_EVOLUTION";
    public static final String TYPE_TABLE_NAME = "CREATURE_TYPE";
    public static final String RAISE_TYPE_TABLE_NAME = "CREATURE_RAISE_TYPE";
    public static final String ACTION_TABLE_NAME = "CREATURE_ACTION";
    public static final String DEBUFF_TABLE_NAME = "CREATURE_DEBUFF";
    public static final String MEDICINE_TABLE_NAME = "MEDICINE";
    public static final String SICKNESS_TABLE_NAME = "SICKNESS";
    public static final String EXPERIENCE_ACTION_TABLE_NAME = "EXPERIENCE_ACTION";
    public static final String EXPERIENCE_DEBUFF_TABLE_NAME = "EXPERIENCE_DEBUFF";

    private final DatabaseHelper databaseHelper;

    public CreatureDatabase(Context context) {
        databaseHelper = new DatabaseHelper(context);
        // TODO: remove this call to getWritableDatabase before production
        databaseHelper.getWritableDatabase();
        //seedData();
    }

    public T queryUnique(Mapper<T> rowMapper, String table,
            String[] projectionIn, String selection, String[] selectionArgs,
            String groupBy, String having, String sortOrder) {
        Cursor c = query(table, projectionIn, selection, selectionArgs,
                groupBy, having, sortOrder);
        T toReturn = rowMapper.mapRow(c);
        c.close();
        return toReturn;
    }

    public List<T> queryList(Mapper<T> rowMapper, String table,
            String[] projectionIn, String selection, String[] selectionArgs,
            String groupBy, String having, String sortOrder) {
        Cursor c = query(table, projectionIn, selection, selectionArgs,
                groupBy, having, sortOrder);
        List<T> toReturn = new ArrayList<T>(c.getCount());
        while (!c.isAfterLast()) {
            toReturn.add(rowMapper.mapRow(c));
            c.moveToNext();
        }
        c.close();
        return toReturn;
    }

    public int getResultCount(String table, String[] projectionIn,
            String selection, String[] selectionArgs, String groupBy,
            String having, String sortOrder) {
        return query(table, projectionIn, selection, selectionArgs, groupBy,
                having, sortOrder).getCount();
    }

    private Cursor query(String table, String[] projectionIn, String selection,
            String[] selectionArgs, String groupBy, String having,
            String sortOrder) {
        SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
        builder.setTables(table);
        Cursor c = builder.query(databaseHelper.getReadableDatabase(),
                projectionIn, selection, selectionArgs, groupBy, having,
                sortOrder);
        if (c == null) {
            return null;
        } else if (!c.moveToFirst()) {
            c.close();
            return null;
        }
        return c;
    }

    public T insert(T toCreate, String table) {
        long res = databaseHelper.getWritableDatabase().insert(table, null,
                ContentValueUtils.buildContentValues(toCreate));
        toCreate.id = res;
        return toCreate;
    }

    public void update(String table, T toUpdate, String whereClause,
            String[] whereArgs) {
        databaseHelper.getWritableDatabase().update(table,
                ContentValueUtils.buildContentValues(toUpdate), whereClause, whereArgs);
    }

    public void delete(String table, String whereClause, String[] whereArgs) {
        databaseHelper.getWritableDatabase().delete(table, whereClause,
                whereArgs);
    }

    /**
     * For testing purposes during development!
     */
    public void deleteDatabase() {
        // TODO: debug guard
        databaseHelper.deleteDatabase();
    }

    /**
     * This is a basic method for use by developers during development.
     */
    public void seedData() {
        // TODO: This needs to be set up with the actual data for the
        // game
        // seed data for constants, i.e. medicine, sickness, etc.
        // TODO: debug guard
        SQLiteDatabase db = databaseHelper.getWritableDatabase();
        ContentValues vals;
        
        for (int i = 0; i < 5; i++) {
            vals = new ContentValues();
            vals.put("M_ID", i);
            vals.put("M_NAME", "MEDICINE" + i);
            db.insert(MEDICINE_TABLE_NAME, null, vals);
        }

        for (int i = 0; i < 5; i++) {
            vals = new ContentValues();
            vals.put("S_ID", i);
            vals.put("M_ID", i);
            vals.put("S_NAME", "SICKNESS" + i);
            db.insert(SICKNESS_TABLE_NAME, null, vals);
        }

        vals = new ContentValues();
        vals.put("CRT_ID", 1);
        vals.put("CRT_NAME", "HEALTHY");
        vals.put("CRT_MULTIPLIER", "1.00");
        db.insert(RAISE_TYPE_TABLE_NAME, null, vals);

        vals = new ContentValues();
        vals.put("CT_ID", 1);
        vals.put("CT_NAME", "DEFAULT");
        db.insert(TYPE_TABLE_NAME, null, vals);

        vals = new ContentValues();
        vals.put("CE_ID", 1);
        vals.put("CT_ID", 1);
        vals.put("CE_NAME", "Name");
        vals.put("CE_MAX_HEALTH", 100);
        vals.put("CE_MAX_BOWEL", 100);
        vals.put("CE_MAX_DISCIPLINE", 100);
        vals.put("CE_MAX_HUNGER", 100);
        vals.put("CE_MAX_HAPPY", 100);
        vals.put("CE_CURRENT_XP", (int)(Math.random()*((500 + 20000) + 1)));
        db.insert(EVOLUTION_TABLE_NAME, null, vals);
        
        vals = new ContentValues();
        vals.put("CA_ID", 1);
        vals.put("CA_NAME", "Action1");
        db.insert(ACTION_TABLE_NAME, null, vals);
        
        vals = new ContentValues();
        vals.put("CD_ID", 1);
        vals.put("CD_NAME", "Debuff1");
        db.insert(DEBUFF_TABLE_NAME, null, vals);
        
        vals = new ContentValues();
        vals.put("EA_ID", 1);
        vals.put("CT_ID", 1);
        vals.put("CA_ID", 1);
        vals.put("EA_MODIFIER", 1.5);
        db.insert(EXPERIENCE_ACTION_TABLE_NAME, null, vals);
        
        vals = new ContentValues();
        vals.put("ED_ID", 1);
        vals.put("CT_ID", 1);
        vals.put("CD_ID", 1);
        vals.put("ED_MODIFIER", 0.8);
        db.insert(EXPERIENCE_DEBUFF_TABLE_NAME, null, vals);
    }

    private static class DatabaseHelper extends SQLiteOpenHelper {

        private static final String FOREIGN_KEYS_ON = "PRAGMA foreign_keys=ON;";
        private static final String DB_NAME = "RAD_CREATURES.db";
        private static final int DB_VERSION = 2;

        private static final String CREATE_INFO = "" + "CREATE TABLE "
                + INFO_TABLE_NAME + " (" + "CI_ID INTEGER PRIMARY KEY, "
                + "CT_ID INTEGER, " + "CE_ID INTEGER, "
                + "CI_NAME VARCHAR2(50), " + "CI_BIRTH_DATE INTEGER, "
                + "CI_DEATH_DATE INTEGER, " + "CI_ALIVE BOOLEAN, "
                + "CI_GENDER BOOLEAN, "
                + "FOREIGN KEY(CT_ID) REFERENCES " +  TYPE_TABLE_NAME + "(CT_ID), "
                + "FOREIGN KEY(CE_ID) REFERENCES " + EVOLUTION_TABLE_NAME + "(CE_ID) "
                + ");";
        private static final String CREATE_STATE = ""
                + "CREATE TABLE "
                + STATE_TABLE_NAME
                + " ("
                + "CS_ID INTEGER PRIMARY KEY, "
                + "CI_ID INTEGER, "
                + "CRT_ID INTEGER, "
                + "S_ID INTEGER, "
                + "CS_HEALTH INTEGER, "
                + "CS_BOWEL INTEGER, "
                + "CS_DISCIPLINE INTEGER, "
                + "CS_HUNGER INTEGER, "
                + "CS_HAPPY INTEGER, "
                + "CS_SICK BOOLEAN, "
                + "CS_EXPERIENCE INTEGER, "
                + "FOREIGN KEY(CI_ID) REFERENCES " + INFO_TABLE_NAME + "(CI_ID), "
                + "FOREIGN KEY(CRT_ID) REFERENCES " + RAISE_TYPE_TABLE_NAME + "(CRT_ID), "
                + "FOREIGN KEY(S_ID) REFERENCES " + SICKNESS_TABLE_NAME + "(S_ID) " + ");";
        private static final String CREATE_EVOLUTION = "" + "CREATE TABLE "
                + EVOLUTION_TABLE_NAME + " (" + "CE_ID INTEGER PRIMARY KEY, "
                + "CT_ID INTEGER, " + "CE_NAME VARCHAR2(100), "
                + "CE_MAX_HEALTH INTEGER, " + "CE_MAX_BOWEL INTEGER, "
                + "CE_MAX_DISCIPLINE INTEGER, " + "CE_MAX_HUNGER INTEGER, "
                + "CE_MAX_HAPPY INTEGER, " + "CE_MAX_EXPERIENCE INTEGER, "
                + "FOREIGN KEY(CT_ID) REFERENCES " + TYPE_TABLE_NAME + "(CT_ID) " + ");";
        private static final String CREATE_CREATURE_TYPE = "" + "CREATE TABLE "
                + TYPE_TABLE_NAME + " (" + "CT_ID INTEGER PRIMARY KEY, "
                + "CT_NAME VARCHAR2(100) " + ");";
        private static final String CREATE_CREATURE_RAISE_STATE = ""
                + "CREATE TABLE " + RAISE_TYPE_TABLE_NAME + " ("
                + "CRT_ID INTEGER PRIMARY KEY, " + "CRT_NAME TEXT, "
                + "CRT_MULTIPLIER REAL " + ");";
        private static final String CREATE_MEDICINE = "" + "CREATE TABLE "
                + MEDICINE_TABLE_NAME + " (" + "M_ID INTEGER PRIMARY KEY, "
                + "M_NAME TEXT " + ");";
        private static final String CREATE_SICKNESS = "" + "CREATE TABLE "
                + SICKNESS_TABLE_NAME + " (" + "S_ID INTEGER PRIMARY KEY, "
                + "M_ID INTEGER, " + "S_NAME TEXT, "
                + "FOREIGN KEY (M_ID) REFERENCES " + MEDICINE_TABLE_NAME + "(M_ID) " + ");";
        private static final String CREATE_CREATURE_ACTION = "" + "CREATE TABLE "
                + ACTION_TABLE_NAME + " (" + "CA_ID INTEGER PRIMARY KEY, "
                + "CA_NAME TEXT " + ");";
        private static final String CREATE_CREATURE_DEBUFF = "" + "CREATE TABLE "
                + DEBUFF_TABLE_NAME + " (" + "CD_ID INTEGER PRIMARY KEY, "
                + "CD_NAME TEXT " + ");";
        private static final String CREATE_EXPERIENCE_ACTION = "" + "CREATE TABLE "
                + EXPERIENCE_ACTION_TABLE_NAME + " (" + "EA_ID INTEGER PRIMARY KEY, "
                + "CT_ID INTEGER, " + "CA_ID INTEGER, " + "EA_MODIFIER REAL, "
                + "FOREIGN KEY (CT_ID) REFERENCES " + TYPE_TABLE_NAME + "(CT_ID), "
                + "FOREIGN KEY (CA_ID) REFERENCES " + ACTION_TABLE_NAME + "(CA_ID) "+ ");";

        private static final String CREATE_EXPERIENCE_DEBUFF = "" + "CREATE TABLE "
                + EXPERIENCE_DEBUFF_TABLE_NAME + " (" + "ED_ID INTEGER PRIMARY KEY, "
                + "CT_ID INTEGER, " + "CD_ID INTEGER, " + "ED_MODIFIER REAL, "
                + "FOREIGN KEY (CT_ID) REFERENCES " + TYPE_TABLE_NAME + "(CT_ID), "
                + "FOREIGN KEY (CD_ID) REFERENCES " + DEBUFF_TABLE_NAME + "(CD_ID) "+ ");";

        private Context mContext;

        public DatabaseHelper(Context context) {
            super(context, DB_NAME, null, DB_VERSION);
            mContext = context;
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(CREATE_MEDICINE);
            db.execSQL(CREATE_SICKNESS);
            db.execSQL(CREATE_CREATURE_RAISE_STATE);
            db.execSQL(CREATE_CREATURE_TYPE);
            db.execSQL(CREATE_INFO);
            db.execSQL(CREATE_STATE);
            db.execSQL(CREATE_EVOLUTION);
            db.execSQL(CREATE_CREATURE_ACTION);
            db.execSQL(CREATE_CREATURE_DEBUFF);
            db.execSQL(CREATE_EXPERIENCE_ACTION);
            db.execSQL(CREATE_EXPERIENCE_DEBUFF);
            // turn on foreign keys
            db.execSQL(FOREIGN_KEYS_ON);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        }

        @Override
        public void onOpen(SQLiteDatabase db) {
            db.execSQL(FOREIGN_KEYS_ON);
        }
        
        public void deleteDatabase() {
            mContext.deleteDatabase(DB_NAME);
        }

    }
} public class CreatureEvolutionDao {
    private CommonDatabase<CreatureEvolution> db;
    Mapper<CreatureEvolution> rowMapper;

    public CreatureEvolutionDao(CommonDatabase<CreatureEvolution> database,
            Mapper<CreatureEvolution> mapper) {
        db = database;
        rowMapper = mapper;
    }

    public CreatureEvolution create(CreatureEvolution evo) {
        return db.insert(evo, CommonDatabase.EVOLUTION_TABLE_NAME);
    }

    public CreatureEvolution update(CreatureEvolution evo) {
        db.update(CommonDatabase.EVOLUTION_TABLE_NAME, evo, "CE_ID = "
                + evo.id, null);
        return evo;
    }

    public void delete(CreatureEvolution evo) {
        db.delete(CommonDatabase.EVOLUTION_TABLE_NAME, "CE_ID = " + evo.id,
                null);
    }

    public List<CreatureEvolution> getAll() {
        return db
                .queryList(
                        rowMapper,
                        "CREATURE_EVOLUTION join CREATURE_TYPE on (CREATURE_EVOLUTION.CT_ID = CREATURE_TYPE.CT_ID)",
                        null, null, null, null, null, null);
    }

    public CreatureEvolution findById(long id) {
        return db
                .queryUnique(
                        rowMapper,
                        "CREATURE_EVOLUTION join CREATURE_TYPE on (CREATURE_EVOLUTION.CT_ID = CREATURE_TYPE.CT_ID)",
                        null, "CE_ID = " + id, null, null, null, null);
    }
} public class CreatureRaiseTypeDao {
    private CommonDatabase<CreatureRaiseType> db;
    private Mapper<CreatureRaiseType> rowMapper;

    public CreatureRaiseTypeDao(CommonDatabase<CreatureRaiseType> database,
            Mapper<CreatureRaiseType> mapper) {
        db = database;
        rowMapper = mapper;
    }

    public CreatureRaiseType create(CreatureRaiseType crt) {
        return db.insert(crt, CommonDatabase.RAISE_TYPE_TABLE_NAME);
    }

    public CreatureRaiseType update(CreatureRaiseType crt) {
        db.update(CommonDatabase.RAISE_TYPE_TABLE_NAME, crt, "CRT_ID = "
                + crt.id, null);
        return crt;
    }

    public void delete(CreatureRaiseType crt) {
        db.delete(CommonDatabase.RAISE_TYPE_TABLE_NAME, "CRT_ID = " + crt.id,
                null);
    }

    public List<CreatureRaiseType> getAll() {
        return db.queryList(rowMapper, CommonDatabase.RAISE_TYPE_TABLE_NAME,
                null, null, null, null, null, null);
    }

    public CreatureRaiseType findById(long id) {
        return db.queryUnique(rowMapper,
                CommonDatabase.RAISE_TYPE_TABLE_NAME, null, "CRT_ID = " + id,
                null, null, null, null);
    }
} public class CreatureStateDao {
    private CommonDatabase<CreatureState> db;
    private Mapper<CreatureState> rowMapper;
    private static final String SELECT_JOIN = CommonDatabase.STATE_TABLE_NAME
            + " join " + CommonDatabase.RAISE_TYPE_TABLE_NAME + " on ( "
            + CommonDatabase.STATE_TABLE_NAME + ".CRT_ID = "
            + CommonDatabase.RAISE_TYPE_TABLE_NAME + ".CRT_ID ) join "
            + CommonDatabase.INFO_TABLE_NAME + " on ( "
            + CommonDatabase.STATE_TABLE_NAME + ".CI_ID = "
            + CommonDatabase.INFO_TABLE_NAME + ".CI_ID ) join "
            + CommonDatabase.SICKNESS_TABLE_NAME + " on ( "
            + CommonDatabase.STATE_TABLE_NAME + ".S_ID = "
            + CommonDatabase.SICKNESS_TABLE_NAME + ".S_ID ) join "
            + CommonDatabase.TYPE_TABLE_NAME + " on ( "
            + CommonDatabase.INFO_TABLE_NAME + ".CT_ID = "
            + CommonDatabase.TYPE_TABLE_NAME + ".CT_ID ) join "
            + CommonDatabase.MEDICINE_TABLE_NAME + " on ( "
            + CommonDatabase.SICKNESS_TABLE_NAME + ".M_ID = "
            + CommonDatabase.MEDICINE_TABLE_NAME + ".M_ID )";

    public CreatureStateDao(CommonDatabase<CreatureState> database,
            Mapper<CreatureState> mapper) {
        db = database;
        rowMapper = mapper;
    }

    public CreatureState create(CreatureState state) {
        return db.insert(state, CommonDatabase.STATE_TABLE_NAME);
    }

    public CreatureState update(CreatureState state) {
        db.update(CommonDatabase.STATE_TABLE_NAME, state, "CS_ID = "
                + state.id, null);
        return state;
    }

    public void delete(CreatureState state) {
        db.delete(CommonDatabase.STATE_TABLE_NAME, "CS_ID = " + state.id,
                null);
    }

    public List<CreatureState> getAll() {
        return db.queryList(rowMapper, SELECT_JOIN, null, null, null, null,
                null, null);
    }

    public CreatureState findById(long id) {
        return db.queryUnique(rowMapper, SELECT_JOIN, null, "CS_ID = " + id,
                null, null, null, null);
    }
} public class ExperienceActionDao {
    private CommonDatabase<ExperienceAction> db;
    private Mapper<ExperienceAction> rowMapper;
    
    public ExperienceActionDao(CommonDatabase<ExperienceAction> database,
            Mapper<ExperienceAction> mapper) {
        db = database;
        rowMapper = mapper;
    }
    
    public ExperienceAction create(ExperienceAction exp) {
        return db.insert(exp, CommonDatabase.EXPERIENCE_ACTION_TABLE_NAME);
    }
    
    public ExperienceAction update(ExperienceAction exp) {
        db.update(CommonDatabase.EXPERIENCE_ACTION_TABLE_NAME, 
                exp, 
                "EA_ID = " + exp.id, 
                null);
        return exp;
    }
    
    public void delete(ExperienceAction exp) {
        db.delete(CommonDatabase.EXPERIENCE_ACTION_TABLE_NAME, 
                "EA_ID = " + exp.id, 
                null);
    }
    
    public List<ExperienceAction> getAll() {
        return db.queryList(rowMapper, CommonDatabase.EXPERIENCE_ACTION_TABLE_NAME + " join "
                + CommonDatabase.TYPE_TABLE_NAME + " on ("
                + CommonDatabase.EXPERIENCE_ACTION_TABLE_NAME + ".CT_ID = "
                + CommonDatabase.TYPE_TABLE_NAME + ".CT_ID )" + " join "
                + CommonDatabase.ACTION_TABLE_NAME + " on ("
                + CommonDatabase.EXPERIENCE_ACTION_TABLE_NAME + ".CA_ID = "
                + CommonDatabase.ACTION_TABLE_NAME + ".CA_ID )", null, null,
                null, null, null, null);
    }
    
    public ExperienceAction findExperienceById(long id) {
        return db.queryUnique(rowMapper, CommonDatabase.EXPERIENCE_ACTION_TABLE_NAME, null, 
                "EA_ID = " + id, null, null, null, null);
    }
} public class MedicineDao {
    private CommonDatabase<Medicine> db;
    private Mapper<Medicine> rowMapper;

    public MedicineDao(CommonDatabase<Medicine> database,
            Mapper<Medicine> mapper) {
        db = database;
        rowMapper = mapper;
    }

    public Medicine create(Medicine m) {
        return db.insert(m, CommonDatabase.MEDICINE_TABLE_NAME);
    }

    public Medicine update(Medicine m) {
        db.update(CommonDatabase.MEDICINE_TABLE_NAME, m, "M_ID = " + m.id,
                null);
        return m;
    }

    public List<Medicine> getAll() {
        return db.queryList(rowMapper, CommonDatabase.MEDICINE_TABLE_NAME,
                null, null, null, null, null, null);
    }

    public Medicine findById(long id) {
        return db.queryUnique(rowMapper, CommonDatabase.MEDICINE_TABLE_NAME,
                null, "M_ID = " + id, null, null, null, null);
    }
} public class SicknessDao {
    private CommonDatabase<Sickness> db;
    private Mapper<Sickness> rowMapper;

    public SicknessDao(CommonDatabase<Sickness> database,
            Mapper<Sickness> mapper) {
        db = database;
        rowMapper = mapper;
    }

    /*
     * Sickness
     */
    public Sickness create(Sickness sickness) {
        return db.insert(sickness, CommonDatabase.SICKNESS_TABLE_NAME);
    }

    public Sickness update(Sickness sickness) {
        db.update(CommonDatabase.SICKNESS_TABLE_NAME,
                sickness, "S_ID = " + sickness.id, null);
        return sickness;
    }

    public void delete(Sickness sickness) {
        db.delete(CommonDatabase.SICKNESS_TABLE_NAME,
                "S_ID = " + sickness.id, null);
    }

    public List<Sickness> getAll() {
        return db.queryList(rowMapper, CommonDatabase.SICKNESS_TABLE_NAME + " join "
                + CommonDatabase.MEDICINE_TABLE_NAME + " on ("
                + CommonDatabase.SICKNESS_TABLE_NAME + ".M_ID = "
                + CommonDatabase.MEDICINE_TABLE_NAME + ".M_ID )", null, null,
                null, null, null, null);
    }

    public Sickness findById(long id) {
        return db.queryUnique(rowMapper, CommonDatabase.SICKNESS_TABLE_NAME + " join "
                + CommonDatabase.MEDICINE_TABLE_NAME + " on ("
                + CommonDatabase.SICKNESS_TABLE_NAME + ".M_ID = "
                + CommonDatabase.MEDICINE_TABLE_NAME + ".M_ID )", null,
                "S_ID = " + id, null, null, null, null);
    }
} public class CreatureEvolutionMapper extends Mapper<CreatureEvolution> {

    public CreatureEvolution mapRow(Object obj) {
        if (obj instanceof Cursor) {
            Cursor c = (Cursor)obj;
            CreatureEvolution evo = new CreatureEvolution();
            evo.id = c.getLong(c.getColumnIndex("CE_ID"));
            CreatureType t = new CreatureType();
            t.id = c.getLong(c.getColumnIndex("CT_ID"));
            t.name = c.getString(c.getColumnIndex("CT_NAME"));
            evo.type = t;
            evo.name = c.getString(c.getColumnIndex("CE_NAME"));
            evo.maxHealth = c.getInt(c.getColumnIndex("CE_MAX_HEALTH"));
            evo.maxBowel = c.getInt(c.getColumnIndex("CE_MAX_BOWEL"));
            evo.maxDiscipline = c.getInt(c.getColumnIndex("CE_MAX_DISCIPLINE"));
            evo.maxHunger = c.getInt(c.getColumnIndex("CE_MAX_HUNGER"));
            evo.maxHappy = c.getInt(c.getColumnIndex("CE_MAX_HAPPY"));
            evo.currentXp = c.getInt(c.getColumnIndex("CE_CURRENT_XP"));
            return evo;
        }
        return null;
    }
} public class CreatureMapper extends Mapper<Creature> {

    /**
     * Map a Cursor object from the DB to a Creature object
     * 
     * @param cursor
     *            Result from the DB query
     * @return The row-mapped Creature object
     */
    public Creature mapRow(Object obj) {
        if (obj instanceof Cursor) {
            Cursor cursor = (Cursor) obj;
            // assume only one row here
            Creature c = new Creature();
            c.id = cursor.getLong(cursor.getColumnIndex("CI_ID"));
            c.name = cursor.getString(cursor.getColumnIndex("CI_NAME"));
            CreatureType type = new CreatureType();
            type.id = cursor.getInt(cursor.getColumnIndex("CT_ID"));
            type.name = cursor.getString(cursor.getColumnIndex("CT_NAME"));
            c.type = type;
            c.birthDate = new Date(cursor.getLong(cursor
                    .getColumnIndex("CI_BIRTH_DATE")));
            try {
                c.deathDate = new Date(cursor.getLong(cursor
                        .getColumnIndex("CI_DEATH_DATE")));
            } catch (Exception e) {
                c.deathDate = null;
            }
            c.alive = (cursor.getInt(cursor.getColumnIndex("CI_ALIVE")) == 0) ? false
                    : true;
            c.gender = Gender.fromDbValue(cursor.getString(cursor
                    .getColumnIndex("CI_GENDER")));
            return c;
        }
        return null;
    }
} public class CreatureRaiseTypeMapper extends Mapper<CreatureRaiseType> {

    public CreatureRaiseType mapRow(Object obj) {
        if (obj instanceof Cursor) {
            Cursor c = (Cursor)obj;
            CreatureRaiseType crt = new CreatureRaiseType();
            crt.id = c.getLong(c.getColumnIndex("CRT_ID"));
            crt.name = c.getString(c.getColumnIndex("CRT_NAME"));
            crt.multiplier = c.getDouble(c.getColumnIndex("CRT_MULTIPLIER"));
            return crt;
        }
        return null;
    }
} public class CreatureStateMapper extends Mapper<CreatureState> {
    CreatureMapper creatureMapper = new CreatureMapper();
    CreatureRaiseTypeMapper creatureRaiseTypeMapper = new CreatureRaiseTypeMapper();
    SicknessMapper sicknessMapper = new SicknessMapper();

    public CreatureState mapRow(Object obj) {
        if (obj instanceof Cursor) {
            Cursor c = (Cursor)obj;
            CreatureState state = new CreatureState();
            state.id = c.getLong(c.getColumnIndex("CS_ID"));
            state.creature = creatureMapper.mapRow(c);
            state.raiseType = creatureRaiseTypeMapper.mapRow(c);
            state.sickness = sicknessMapper.mapRow(c);
            state.health = c.getInt(c.getColumnIndex("CS_HEALTH"));
            state.bowel = c.getInt(c.getColumnIndex("CS_BOWEL"));
            state.discipline = c.getInt(c.getColumnIndex("CS_DISCIPLINE"));
            state.hunger = c.getInt(c.getColumnIndex("CS_HUNGER"));
            state.happy = c.getInt(c.getColumnIndex("CS_HAPPY"));
            state.sick = (c.getInt(c.getColumnIndex("CS_SICK")) == 1) ? true
                    : false;
            state.experience = c.getInt(c.getColumnIndex("CS_EXPERIENCE"));
            return state;
        }
        return null;
    }
} public class ExperienceActionMapper extends Mapper<ExperienceAction> {

    @Override
    public ExperienceAction mapRow(Object obj) {
        if (obj instanceof Cursor) {
            Cursor c = (Cursor)obj;
            ExperienceAction exp = new ExperienceAction();
            exp.id = c.getLong(c.getColumnIndex("EA_ID"));
            
            CreatureType type = new CreatureType();
            type.id = c.getLong(c.getColumnIndex("CT_ID"));
            type.name = c.getString(c.getColumnIndex("CT_NAME"));
            exp.type = type;
            
            CreatureAction action = new CreatureAction();
            action.id = c.getLong(c.getColumnIndex("CA_ID"));
            action.name = c.getString(c.getColumnIndex("CA_NAME"));
            exp.action = action;
            
            exp.modifier = c.getDouble(c.getColumnIndex("EA_MODIFIER"));
            
            return exp;
        }
        return null;
    }
} public class MedicineMapper extends Mapper<Medicine> {

    public Medicine mapRow(Object obj) {
        if (obj instanceof Cursor) {
            Cursor c = (Cursor)obj;
            Medicine m = new Medicine();
            m.id = c.getLong(c.getColumnIndex("M_ID"));
            m.name = c.getString(c.getColumnIndex("M_NAME"));
            return m;
        }
        return null;
    }
} public class SicknessMapper extends Mapper<Sickness> {
    MedicineMapper medicineMapper = new MedicineMapper();

    public Sickness mapRow(Object obj) {
        if (obj instanceof Cursor) {
            Cursor c = (Cursor)obj;
            Sickness s = new Sickness();
            s.id = c.getLong(c.getColumnIndex("S_ID"));
            s.medicine = medicineMapper.mapRow(c);
            s.name = c.getString(c.getColumnIndex("S_NAME"));
            return s;
        }
        return null;
    }
} public class Creature extends CommonModel {

    public String name;
    public CreatureType type;
    public Date birthDate;
    public Date deathDate;
    public CreatureState state;
    public boolean alive;
    public Gender gender;

    /**
     * A convenience method for testing
     * 
     * @return A basic creature object
     */
    public static Creature createDefaultCreature() {
        CreatureType type = new CreatureType();
        type.id = 1;
        type.name = "Default";

        Creature c = new Creature();
        c.name = "Default Creature";
        c.type = type;
        c.birthDate = new Date();
        c.state = new CreatureState();
        c.alive = true;
        c.gender = Gender.FEMALE;
        return c;
    }

    /**
     * Create A Creature Simple function to call when a person leaves the
     * creature-creation screen, and gets used to save the creature.
     * 
     * @author Hannes Vermeire
     * @return The creature.
     */
    public static Creature createCreature(String name, Gender gender,
            CreatureType type) {
        Creature c = new Creature();
        c.name = name;
        c.type = type;
        c.birthDate = new Date();
        c.gender = gender;
        c.state = new CreatureState();
        c.alive = true;
        c.gender = gender;
        return c;
    }

} public class CreatureEvolution extends CommonModel {

    public CreatureType type;
    public String name;
    public int maxHealth;
    public int maxBowel;
    public int maxDiscipline;
    public int maxHunger;
    public int maxHappy;
    public int currentXp;
} public class CreatureRaiseType extends CommonModel {

    public String name;
    public double multiplier;
} public class CreatureState extends CommonModel {

    public Creature creature;
    public CreatureRaiseType raiseType;
    public Sickness sickness;
    public int health;
    public int bowel;
    public int discipline;
    public int hunger;
    public int happy;
    public boolean sick;
    public int experience;
} public class ExperienceAction extends CommonModel {
    public CreatureType type;
    public CreatureAction action;
    public double modifier;
} public class Medicine extends CommonModel {

    public String name;
} public class Sickness extends CommonModel{

    public Medicine medicine;
    public String name;
}
import android.content.Context;
import android.os.Bundle;
import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
import com.redditandroiddevelopers.tamagotchi.dao.CreatureDao;
import com.redditandroiddevelopers.tamagotchi.dao.CreatureDatabase;
import com.redditandroiddevelopers.tamagotchi.dao.CreatureEvolutionDao;
import com.redditandroiddevelopers.tamagotchi.dao.CreatureRaiseTypeDao;
import com.redditandroiddevelopers.tamagotchi.dao.CreatureStateDao;
import com.redditandroiddevelopers.tamagotchi.dao.ExperienceActionDao;
import com.redditandroiddevelopers.tamagotchi.dao.MedicineDao;
import com.redditandroiddevelopers.tamagotchi.dao.SicknessDao;
import com.redditandroiddevelopers.tamagotchi.mappers.CreatureEvolutionMapper;
import com.redditandroiddevelopers.tamagotchi.mappers.CreatureMapper;
import com.redditandroiddevelopers.tamagotchi.mappers.CreatureRaiseTypeMapper;
import com.redditandroiddevelopers.tamagotchi.mappers.CreatureStateMapper;
import com.redditandroiddevelopers.tamagotchi.mappers.ExperienceActionMapper;
import com.redditandroiddevelopers.tamagotchi.mappers.MedicineMapper;
import com.redditandroiddevelopers.tamagotchi.mappers.SicknessMapper;
import com.redditandroiddevelopers.tamagotchi.model.Creature;
import com.redditandroiddevelopers.tamagotchi.model.CreatureEvolution;
import com.redditandroiddevelopers.tamagotchi.model.CreatureRaiseType;
import com.redditandroiddevelopers.tamagotchi.model.CreatureState;
import com.redditandroiddevelopers.tamagotchi.model.ExperienceAction;
import com.redditandroiddevelopers.tamagotchi.model.Medicine;
import com.redditandroiddevelopers.tamagotchi.model.Sickness;

package com.redditandroiddevelopers.tamagotchi;



public class MainActivity extends AndroidApplication {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration();
        cfg.useGL20 = false;

        TamagotchiConfiguration tcfg = new TamagotchiConfiguration();
        initializeDatabase(tcfg);
        initialize(new TamagotchiGame(tcfg), cfg);

    }

    private void initializeDatabase(TamagotchiConfiguration config) {
        final Context context = getBaseContext();
        config.creatureDao = new CreatureDao(new CreatureDatabase<Creature>(