package com.example.unodtantos.appqueology2.controlador;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.Toast;

import com.example.unodtantos.appqueology2.R;
import com.example.unodtantos.appqueology2.modelo.Nodo;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Created by unodtantos on 17/03/2015.
 */
public class DatosNodoCentral extends Activity {

    /*--------------------------------------------------------------------------------------------*/

    // <editor-fold defaultstate="collapsed" desc="Atributos de la clase">

    private static final int OK_RESULT_CODE = 1;

    private Controlador controlador;
    private String nombre_ue_inicial;
    private String nombre_bd;
    private Typeface font;

    private TextView nom_t;
    private TextView datacion_t;
    private TextView tipo_t;
    private TextView des_t;
    private RadioButton neg;
    private RadioButton est;
    private RadioButton estrato;
    private EditText e_nom;
    private EditText e_dat_1;
    private EditText e_dat_2;
    private EditText e_des;
    private Button btn_camara;
    private TextView txtv_cargando_punto;
    private ImageView imgView;
    private Button btn;

    private Nodo n;
    private String latitud;
    private String longitud;
    private String nombre_inicial;
    private int contador;
    private Timer timer;
    private TimerTask timerTask;
    private GPSTracker gps;
    private Location location;
    private String date2;
    private String photoCode;
    private Uri uri;
    private String date;
    private Context context;
    final Handler handler = new Handler();
    final String ruta_fotos = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + "/misfotos/";
    private File file = new File(ruta_fotos);

    // </editor-fold>

    /*--------------------------------------------------------------------------------------------*/

    // <editor-fold defaultstate="collapsed" desc="Constructor de la Activity">

    /**
     * Constructor de la clase.
     * @param savedInstanceState
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_datos_ue_central);

        inicializacionVariables();
        recogerValoresIntent();
        cargarElementos();
        cargarAspectoElementos();
        this.n = cargarValores();
    }

    // </editor-fold>

    /*--------------------------------------------------------------------------------------------*/

    // <editor-fold defaultstate="collapsed" desc="Inicializacion">

    /**
     * Método que se encarga de inicializar las variables necesarias para el correcto funcionamiento
     * de la clase.
     */
    public void inicializacionVariables(){

        this.controlador = (Controlador) getApplicationContext();
        this.font = Typeface.createFromAsset(getAssets(), "gloriahallelujah.ttf");
        this.context = this;
        this.latitud = "";
        this.longitud = "";
        this.nombre_inicial = "";
        this.contador = 0;
        this.location = null;
        this.photoCode = "";
        this.date = "";
    }

    /**
     * Método que se encarga de recoger los valores del Intent.
     */
    public void recogerValoresIntent() {

        this.nombre_ue_inicial = getIntent().getStringExtra("nombre_ue");
        this.nombre_bd = getIntent().getStringExtra("nombre_bd");
    }

    /**
     * Método que se encarga de cargar cada uno de los elementos que componen la vista.
     */
    private void cargarElementos(){

        this.nom_t = (TextView) findViewById(R.id.textView9);
        this.datacion_t = (TextView) findViewById(R.id.textView11);
        this.tipo_t = (TextView) findViewById(R.id.textView12);
        this.des_t = (TextView) findViewById(R.id.textView13);
        this.neg = (RadioButton) findViewById(R.id.radioBtn_negativa);
        this.est = (RadioButton) findViewById(R.id.radioBtn_estructura);
        this.estrato = (RadioButton) findViewById(R.id.radioBtn_estrato);
        this.e_nom = (EditText) findViewById(R.id.etxt_nombre);
        this.e_dat_1 = (EditText) findViewById(R.id.etxt_datacion_1);
        this.e_dat_2 = (EditText) findViewById(R.id.etxt_datacion_2);
        this.e_des = (EditText) findViewById(R.id.etxt_descripcion);
        this.btn_camara = (Button) findViewById(R.id.btn_camara_datos_ue);
        this.txtv_cargando_punto = (TextView) findViewById(R.id.txtv_cargando_punto);
        this.imgView = (ImageView) findViewById(R.id.imageView2);
        this.btn = (Button) findViewById(R.id.btn_guardar_nueva_ue);
    }

    /**
     * Método que se encarga de darle el aspecto esperado a cada elemento de la vista.
     */
    private void cargarAspectoElementos(){

        this.nom_t.setTypeface(this.font);
        this.datacion_t.setTypeface(this.font);
        this.tipo_t.setTypeface(this.font);
        this.des_t.setTypeface(this.font);
        this.neg.setTypeface(this.font);
        this.est.setTypeface(this.font);
        this.estrato.setTypeface(this.font);
        this.e_nom.setTypeface(this.font);
        this.e_dat_1.setTypeface(this.font);
        this.e_dat_2.setTypeface(this.font);
        this.e_des.setTypeface(this.font);
        this.txtv_cargando_punto.setTypeface(this.font);
        this.btn.setTypeface(this.font);
    }

    /**
     * Método que se encarga de rellenar los campos de la vista que nos ocupa en función
     * de los valores que la UE a tratar tiene guardados en la BBDD.
     * @return
     */
    private Nodo cargarValores(){

        this.n = controlador.obtenerDatosUe(nombre_bd, nombre_ue_inicial);

        this.nombre_inicial = n.getNombre();

        this.e_nom.setText(n.getNombre());
        this.e_dat_1.setText(n.getDatacion1());
        this.e_dat_2.setText(n.getDatacion2());
        this.e_des.setText(n.getDescripcion());

        if(n.getTipoUe().equals("negativa")){
            this.neg.setChecked(true);
        }
        if(n.getTipoUe().equals("estructura")){
            this.est.setChecked(true);
        }
        if(n.getTipoUe().equals("estrato")){
            this.estrato.setChecked(true);
        }
        if(!n.getNombreFoto().isEmpty()){
            this.imgView.setImageURI(Uri.parse(n.getUrlFoto()));
        }

        return n;
    }

    // </editor-fold>

    /*--------------------------------------------------------------------------------------------*/

    // <editor-fold defaultstate="collapsed" desc="Capturando Eventos">

    /**
     * Método que se encarga de capturar el evento onClick del botón que permite sacar la foto y
     * asociarla a una UE.
     * @param view
     */
    public void onClickBtnSacarFotoDatosUe(View view){

        gps = new GPSTracker(DatosNodoCentral.this, nombre_bd);

        if(!gps.canGetLocation()) {
            gps.alertHabilitarServicios();
        }else {
            if(location == null){
                startTimerLocation();
                btn_camara.setVisibility(View.INVISIBLE);

            } else {
                gps.stopUsingGPS();
                camara();
            }
        }
    }

    /**
     * Método que se encarga de capturar el evento del ImageView en miniatura que permitirá ver la
     * imagen en pantalla completa.
     * @param view
     */
    public void onClickImagenDatosUe(View view){
        if (this.imgView.getDrawable() != null) {
            Intent intent = new Intent(context, ImagenUe.class);
            intent.putExtra("url",n.getUrlFoto().toString());
            context.startActivity(intent);
        }
    }

    /**
     * Método que permite capturar el evento onClick del botón que permite almacenar los datos
     * de la UE en cuestión en la base de datos apropiada.
     * @param view
     */
    public void onClickBtnGuardarDatosUe(View view){
        returnParams();
    }

    // </editor-fold>

    /*--------------------------------------------------------------------------------------------*/

    // <editor-fold defaultstate="collapsed" desc="Sacar foto">

    public void camara(){
        String path = file.getPath();

        if (!file.exists()) {
            Boolean c = file.mkdirs();
        }

        String file = ruta_fotos + getCode() + ".jpg";
        File mi_foto = new File( file );

        try {
            mi_foto.createNewFile();
        } catch (IOException ex) {
        }
        uri = Uri.fromFile(mi_foto);
        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //Abre la camara para tomar la foto
        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); //Guarda imagen
        startActivityForResult(cameraIntent, 0); //Retorna a la actividad
    }

    @SuppressLint("SimpleDateFormat")
    private String getCode() {

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyymmddhhmmss");
        SimpleDateFormat dateFormat2 = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss");
        this.date = dateFormat.format(new Date());
        date2 = dateFormat2.format(new Date());
        this.photoCode = "pic_" + date;
        return photoCode;
    }

    // </editor-fold>

    /*--------------------------------------------------------------------------------------------*/

    // <editor-fold defaultstate="collapsed" desc="GPS">

    /**
     * Método que obtiene las coordenadas del GPS.
     */
    public void getCoordenadas(){

        if (location == null) {
            location = gps.getLocation();
            contador++;
            this.txtv_cargando_punto.setText("Cargando punto... " + contador);
            if(contador==60){
                this.txtv_cargando_punto.setText("Lo siento, hay un problema con el GPS");
                stopTimerTask();
            }
        }else {
            stopTimerTask();
            double lat = location.getLatitude();
            double lon = location.getLongitude();
            latitud = String.valueOf(lat);
            longitud = String.valueOf(lon);
            btn_camara.setVisibility(View.VISIBLE);
            this.txtv_cargando_punto.setText("Punto localizado, puedes sacar la foto.");
        }
    }

    /**
     * Método que trabaja en segundo plano y que trata de obtener un punto GPS en un tiempo
     * determinado.
     */
    public void startTimerLocation() {

        timer = new Timer();
        initializeTimerTask();
        timer.schedule(timerTask, 1000, 1000);
    }

    /**
     * Método que inicializa el TimerTask.
     */
    public void initializeTimerTask() {

        timerTask = new TimerTask() {
            public void run() {
                handler.post(new Runnable() {
                    public void run() {
                        getCoordenadas();

                    }
                });
            }
        };
    }

    /**
     * Método que para el TimerTask.
     */
    public void stopTimerTask() {
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
    }

    // </editor-fold>

    /*--------------------------------------------------------------------------------------------*/

    // <editor-fold defaultstate="collapsed" desc="Return parametros">

    /**
     * Método que carga los valores necesarios para ser devueltos al método startResultActivity de
     * la vista Área de Trabajo.
     */
    private void returnParams() {

        String nombre_ue = e_nom.getText().toString();

        if(nombre_ue.isEmpty()){
            Toast.makeText(getApplicationContext(), "No se realizará ninguna acción, ya que has dejado el campo de nombre en blanco para una UE que ya existía.", Toast.LENGTH_LONG).show();
        }else{
            if(!nombre_ue_inicial.equals(nombre_ue)){
                Boolean encontrado = controlador.comprobarExiteUe(nombre_bd,nombre_ue);
                if(encontrado){
                    Toast.makeText(getApplicationContext(), "Lo siento, esa UE ya existe, no puede realizarse el cambio, trata de intentarlo con otro nombre de UE.", Toast.LENGTH_LONG).show();
                }else{
                    this.n = actualizarNodo(nombre_ue);

                    Intent intent = new Intent();
                    intent.putExtra("datos_ue",this.n);
                    setResult(OK_RESULT_CODE,intent);
                    finish();
                }
            }else{

                this.n = actualizarNodo(nombre_ue);

                Intent intent = new Intent();
                intent.putExtra("datos_ue",this.n);
                setResult(OK_RESULT_CODE,intent);
                finish();
            }
        }
    }

    // </editor-fold>

    /*--------------------------------------------------------------------------------------------*/

    // <editor-fold defaultstate="collapsed" desc="Actualizar datos">

    /**
     * Método que se encarga de guardar en un objeto del tipo Nodo los valores correspondientes
     * a la UE cargada.
     * @param nombre_ue
     * @return
     */
    private Nodo actualizarNodo(String nombre_ue){

        this.n.setNombre(nombre_ue);
        this.n.setDatacion1(e_dat_1.getText().toString());
        this.n.setDatacion2(e_dat_2.getText().toString());
        if(this.neg.isChecked()==true){
            this.n.setTipoUe("negativa");
        }
        if(this.est.isChecked()==true){
            this.n.setTipoUe("estructura");
        }
        if(this.estrato.isChecked()==true){
            this.n.setTipoUe("estrato");
        }
        this.n.setDescripcion(e_des.getText().toString());

        if(!longitud.isEmpty()){
            String punto = longitud + ", " + latitud;
            this.n.setLocalizacion(punto);
        }

        Nodo n2  = new Nodo();
        n2 = controlador.comprobarSiFoto(nombre_bd, n.getId());
        if(!n2.getNombreFoto().isEmpty()){
            this.n.setNombreFoto(n2.getNombreFoto());
            this.n.setFechaFoto(n2.getFechaFoto());
            this.n.setUrlFoto(n2.getUrlFoto());
        }

        if(!n2.getLocalizacion().isEmpty()){
            this.n.setLocalizacion(n2.getLocalizacion());
        }

        return this.n;
    }

    // </editor-fold>

    /*--------------------------------------------------------------------------------------------*/

    // <editor-fold defaultstate="collapsed" desc="onActivityResult">

    /**
     * Método que se encarga de recoger los valores obtenidos por el servicio de la Cámara.
     * @param requestCode
     * @param resultCode
     * @param data
     */
    @Override
    protected void onActivityResult(int requestCode,int resultCode, Intent data) {

        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 0) {
            if (RESULT_OK == resultCode) {
                if(uri == null){
                    uri = gps.getUri();
                    photoCode = gps.getPhotoCode();
                    date2 = gps.getDate();
                }
                if(!photoCode.isEmpty()){
                    n.setNombreFoto(photoCode);
                    n.setFechaFoto(date2);
                    n.setUrlFoto(String.valueOf(uri));
                }
                File imgFile = new File(String.valueOf(uri));
                if(imgFile.exists()) {
                    this.imgView.setImageURI(Uri.fromFile(imgFile));
                }
                this.imgView.setImageURI(Uri.parse(uri.toString()));
            }
        }
    }

    // </editor-fold>

    /*--------------------------------------------------------------------------------------------*/

    // <editor-fold defaultstate="collapsed" desc="onBackPressed">

    /**
     * Método que configura el botón "back" del dispositivo.
     */
    @Override
    public void onBackPressed(){
        Intent intent = new Intent();
        intent.putExtra("datos_ue", this.n);
        setResult(OK_RESULT_CODE, intent);
        finish();
    }

    // </editor-fold>

    /*--------------------------------------------------------------------------------------------*/
}
