package com.virtual.pollentia.WalkingTour.modelo;

/**
 * Created by Roger Gomez
 */

import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;

public class AdminSQLiteOpenHelper extends SQLiteOpenHelper {

    //variables globales
    private static String DB_PATH = "data/data/com.virtual.pollentia.pollentia_tour/databases/";
    private static String DB_NAME = "Pollentia";
    private static String TABLE_LOCATION = "rutas";
    private static String TABLE_VIDEOS = "videos";
    private static String TABLE_AUDIOS = "audios";
    private static String TABLE_TEXTS = "txt";
    private static String TABLE_IMAGES = "images";

    private final Context context;
    private SQLiteDatabase db;


    /**
     * Constructor de la clase
     * @param context, contexto de la activity que lo crea
     */

    public AdminSQLiteOpenHelper(Context context) {

        super(context, DB_NAME, null, 1);
        this.context = context;

    }


    /**
     * Función para la creación de la BD en caso de que no exista.
     * @throws IOException
     */
    public void create() throws IOException {
        boolean dbExist = checkDataBase();

        if (dbExist) {

            //do nothing - database already exist
        } else {

            //creamos una base de datos vaciía para rellenarla.
            this.getReadableDatabase();

            try {

                copyDataBase();

            } catch (IOException e) {

                throw new Error("Error copiando la base de datos");

            }
        }

    }

    /**
     * Comprueba si existe la base de datos.
     * @return booleano que indica si existe o no la BD.
     */
    private boolean checkDataBase() {
        SQLiteDatabase checkDB = null;

        try {


            String path = DB_PATH + DB_NAME;
            checkDB = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);

        } catch (SQLiteException e) {

            // no existe la BD
            e.printStackTrace();

        }

        if (checkDB != null) {

            checkDB.close();

        }

        return checkDB != null ? true : false;
    }

    /**
     * Copia la BD  de assets a la nueva BD creada
     * @throws IOException
     */
    private void copyDataBase() throws IOException {
        //abre la BD de entradacomo un input stream
        InputStream myInput = context.getAssets().open(DB_NAME);

        // ruta de la nueva bd creada
        String outFileName = DB_PATH + DB_NAME;

        //Abre la bd de salida como ouput
        OutputStream myOutput = new FileOutputStream(outFileName);

        //transfiere los datos des de inputfile a outputfile
        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }

        //cierra loss streams
        myOutput.flush();
        myOutput.close();
        myInput.close();
    }

    /**
     * Abre la bd.
     * @return booleano que indica si se abrió o no la BD.
     */
    public boolean open() {

        try {
            String myPath = DB_PATH + DB_NAME;
            db = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
            return true;

        } catch (SQLException sqle) {
            db = null;
            return false;
        }

    }

    /**
     * Cierra la BD.
     */
    @Override
    public synchronized void close() {

        if (db != null)
            db.close();

        super.close();

    }

    @Override
    public void onCreate(SQLiteDatabase db) {

    }

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

    }


    /**
     * Devuelve una lista de puntos de la BD.
     * @return
     */
    public ArrayList<PuntoGps> getLocations() {
        ArrayList<PuntoGps> locations = null;
        try {

            //selecciona de la tabla de puntos todos  los puntos
            String query = "SELECT * FROM " + TABLE_LOCATION;
            open();
            Cursor cursor = db.rawQuery(query, null);

            locations = new ArrayList<PuntoGps>();
            Double lat = -1.0;
            Double lon = -1.0;
            String wptDescription = "";
            int grade = -1;
            int id = 0;
            if (cursor.moveToFirst()) {
                do {

                    id = cursor.getInt(0);
                    lon = Double.parseDouble(cursor.getString(1));
                    lat = Double.parseDouble(cursor.getString(2));
                    grade = cursor.getInt(3);
                    wptDescription = cursor.getString(4);
                    if(wptDescription==null) {
                        wptDescription = "";
                    }
                    PuntoGps posicion = new PuntoGps(id, lat, lon, grade, wptDescription);

                    locations.add(posicion);

                } while (cursor.moveToNext());
            }
        } catch (Exception e) {
            // sql error
        }
        close();
        return locations;
    }

    /**
     * Devuelve el siguiente punto de la ruta en caso de que exista o -1 en caso contrario.
     * @param idPuntoActual, id del punto actual.
     * @param sentido, indica el sentido de la marcha.
     * @return int que es la id del siguiente punto.
     */
    public int getNextPoint(int idPuntoActual,int sentido) {

        if(sentido==1)
            idPuntoActual+=1;
        else
            idPuntoActual-=1;

        int next = -1;
        try {

            //selecciona de la tabla de puntos un punto en concreto para verificar si existe
            String query = "SELECT * FROM " + TABLE_LOCATION + " WHERE id=" + idPuntoActual;
            open();
            Cursor cursor = db.rawQuery(query, null);


            if (cursor.moveToFirst()) {
                do {
                    next = cursor.getInt(0);


                } while (cursor.moveToNext());
            }
        } catch (Exception e) {
            // sql error
        }
        close();
        return next;
    }

    /**
     * Devuelve el video asociado a un punto de la ruta.
     * @param id, id del punto de la ruta.
     * @return string con la ruta del video.
     */
    public String getVideo(int id) {
        String video="";
        try {

            //selecciona de la tabla de videos el de un punto en concreto
            String query = "SELECT * FROM " + TABLE_VIDEOS + " WHERE id_punto=" + id;
            open();
            Cursor cursor = db.rawQuery(query, null);


            if (cursor.moveToFirst()) {
                do {
                    video = cursor.getString(2);


                } while (cursor.moveToNext());
            }
        } catch (Exception e) {
           video="";
        }
        close();
        return video;
    }

    /**
     * Devuelve las rutas de las imagenes de un punto.
     * @param id, id del punto de la ruta.
     * @return ArrayList con todas las rutas de las imagenes de un punto.
     */
    public ArrayList<String> getPhotos(int id) {
        ArrayList<String> photos=new ArrayList<>();

        try {

            //selecciona de la tabla de imagenes las imagenes de un punto en concreto
            String query = "SELECT * FROM " + TABLE_IMAGES + " WHERE id_punto=" + id;
            open();
            Cursor cursor = db.rawQuery(query, null);


            if (cursor.moveToFirst()) {
                do {
                    photos.add(cursor.getString(2));


                } while (cursor.moveToNext());
            }
            else{
                photos=null;
            }
        } catch (Exception e) {
            photos=null;
        }
        close();
        return photos;
    }

    /**
     * Devuelve una lista con los textos de las imagenes.
     * @param id ,id del punto de la ruta.
     * @return ArrayList con todos los tetxos de las imagenes de un punto.
     */

    public ArrayList<String> getPhotosText(int id) {
        ArrayList<String> textPhotos=new ArrayList<>();

        try {

            //selecciona de la tabla de imagenes los textos de un punto en concreto
            String query = "SELECT * FROM " + TABLE_IMAGES + " WHERE id_punto=" + id;
            open();
            Cursor cursor = db.rawQuery(query, null);


            if (cursor.moveToFirst()) {
                do {
                    textPhotos.add(cursor.getString(3));


                } while (cursor.moveToNext());
            }
            else{
                textPhotos=null;
            }
        } catch (Exception e) {
            textPhotos=null;
        }
        close();
        return textPhotos;
    }

    /**
     * Devuelve el texto asociado a un punto.
     * @param id, id del punto de la ruta.
     * @return devuelve un string con el texto de la ruta
     */

    public String getText(int id) {
        String texto="";

        try {

            //selecciona de la tabla de textos los de un punto en concreto
            String query = "SELECT * FROM " + TABLE_TEXTS + " WHERE id_punto=" + id;
            open();
            Cursor cursor = db.rawQuery(query, null);


            if (cursor.moveToFirst()) {
                do {
                    texto=cursor.getString(2);


                } while (cursor.moveToNext());
            }
        } catch (Exception e) {
            texto="";
        }
        close();
        return texto;
    }

    /**
     * Devuelve el audio asociado a un punto
     * @param id id del punto de la ruta.
     * @return devuelve un string con el nombre del fichero de audio
     */
    public String getAudio(int id) {
        String audio="";
        try {

            //selecciona de la tabla de videos el de un punto en concreto
            String query = "SELECT * FROM " + TABLE_AUDIOS + " WHERE id_punto=" + id;
            open();
            Cursor cursor = db.rawQuery(query, null);


            if (cursor.moveToFirst()) {
                do {
                    audio = cursor.getString(2);


                } while (cursor.moveToNext());
            }
        } catch (Exception e) {
            audio="";
        }
        close();
        return audio;
    }
}



