/**
 * Copyright (C) 2012 - Florindo Smilari (spherIC)
 */
package ch.spherIC.recurvebowsight.database.dao;

import android.content.ContentValues;

import android.database.Cursor;

import android.database.sqlite.SQLiteDatabase;

import ch.spherIC.recurvebowsight.database.RBSDatabaseHelper;
import ch.spherIC.recurvebowsight.model.IEntity;

import java.util.ArrayList;
import java.util.List;


/**
 * DAO-Vaterklasse.
 *
 * @author  FC Smilari
 */
public abstract class DAO<E extends IEntity> {


    /**
     * Konstruktor.
     */
    public DAO() {
        super();
    }


    /**
     * @return  the db
     */
    protected SQLiteDatabase getDb() {
        return RBSDatabaseHelper.getInstance().getWritableDatabase();
    }

    protected abstract E cursorToEntity(final Cursor cursor);

    protected abstract ContentValues getContentValues(E entity);

    protected abstract String getTableName();

    protected abstract String getIdColumn();


    /**
     * Lädt das Entität über eine Id.
     *
     * @param   id
     *
     * @return  E
     */
    public E loadById(final long id) {
        E entity;
        Cursor cursor = getDb().query(getTableName(), null, getIdColumn() + " = " + id, null, null, null, null);
        cursor.moveToFirst();
        entity = cursorToEntity(cursor);
        cursor.close();
        return entity;
    }

    /**
     * Lädt alle Entitäten.
     *
     * @return
     */
    public List<E> loadAll() {
        List<E> entities = new ArrayList<E>();
        Cursor cursor = getDb().query(getTableName(), null, null, null, null, null, getOrderBy());
        cursor.moveToFirst();

        while (!cursor.isAfterLast()) {
            E entity = cursorToEntity(cursor);
            entities.add(entity);
            cursor.moveToNext();
        }

        cursor.close();
        return entities;
    }

    /**
     * Fügt eine Entität in die DB ein.
     *
     * @param   entity
     *
     * @return
     */
    public E insert(final E entity) {
        ContentValues values = getContentValues(entity);
        long insertId = getDb().insert(getTableName(), null, values);
        return loadById(insertId);
    }

    /**
     * Updated eine Entität in der DB ein.
     *
     * @param   entity
     *
     * @return
     */
    public E update(final E entity) {
        ContentValues values = getContentValues(entity);
        getDb().update(getTableName(), values, getIdColumn() + " = " + entity.getId(), null);
        return loadById(entity.getId());
    }

    /**
     * Löschet eine Entität aus der DB.
     *
     * @param  entity
     */
    public void delete(final E entity) {
        getDb().delete(getTableName(), getIdColumn() + " = " + entity.getId(), null);
    }

    protected String getOrderBy() {
        return null;
    }
}
