/*
        This software is distributed under the "New BSD License" agreement:

        Copyright (c) 2016 Bogdan-Florin Gheran, Gabriel Cramariuc, Ionela Rusu, Elena-Gina Craciun. All rights reserved.

        Redistribution and use in source and binary forms, with or without modification, are permitted provided
        that the following conditions are met:
        - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
        - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or
        other materials provided with the distribution.
        - Neither the name of the University Stefan cel Mare of Suceava nor the names of its contributors may be used to endorse
        or promote products derived from this software without specific prior written permission.

        THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
        ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
        THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Bogdan-Florin Gheran, Gabriel Cramariuc, Ionela Rusu, or Elena-Gina Craciun
        BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
        EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
        OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        SUCH DAMAGE.
 */
package com.example.circle.densitytapexperiment;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.util.Size;
import android.view.View;
import android.view.WindowManager;
import android.widget.EditText;

//
// Implements the main activity with sensor acquisition and processing.
//
public class MainActivity extends AppCompatActivity implements SensorEventListener {

    private SensorManager sensorManager;
    private Sensor accelerometer;
    private static float tiltZ = 0;                                                 // measures tilt on Z axis (in degrees, between 0 and 90)
    private static float accelerationX = 0, accelerationY = 0, accelerationZ = 0;   // measures the absolute acceleration on each axis
    private static float numMeasurements = 0;                                       // number of measurements from the sensor

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);
        ResetMeasurements();

        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

        this.startLockTask();   // lock hardware buttons
    }

    protected void onResume() {
        super.onResume();
        sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_FASTEST);
    }

    protected void onPause() {
        super.onPause();
        sensorManager.unregisterListener(this);
    }

    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }

    float[] gravity = new float[3];
    public void onSensorChanged(SensorEvent event) {
        // get linear acceleration, without gravity
        float alpha = 0.8f;
        gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
        gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
        gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];

        float gX = event.values[0] - gravity[0];
        float gY = event.values[1] - gravity[1];
        float gZ = event.values[2] - gravity[2];

        accelerationX += Math.abs(gX);
        accelerationY += Math.abs(gY);
        accelerationZ += Math.abs(gZ);

        // get tilt on the Z axis
        double norm_of_g = Math.sqrt(gravity[0] * gravity[0] + gravity[1] * gravity[1] + gravity[2] * gravity[2]);
        tiltZ = (float)Math.toDegrees(Math.acos(gravity[2] / norm_of_g));

        numMeasurements++;
    }

    public Size getScreenSize() {
        DisplayMetrics displaymetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        return new Size(displaymetrics.widthPixels, displaymetrics.heightPixels);
    }

    public static float getTiltZ() {
        return tiltZ;
    }

    public static float getAccelerationX() {
        return (numMeasurements == 0) ? 0.0f : accelerationX;
    }

    public static float getAccelerationY() {
        return (numMeasurements == 0) ? 0.0f : accelerationY;
    }

    public static float getAccelerationZ() {
        return (numMeasurements == 0) ? 0.0f : accelerationZ;
    }

    public static float getNumberOfAccelerationMeasurements() {
        return numMeasurements;
    }

    public static void ResetMeasurements() {
        accelerationX = 0;
        accelerationY = 0;
        accelerationZ = 0;
        tiltZ = 0;
        numMeasurements = 0;
    }

    @Override
    public void onBackPressed() {
        return;
    }

    public void CloseApp(View view) {
        this.stopLockTask();
        System.exit(0);
    }

    public void StartExperiment(View view) {
        findViewById(R.id.btnClose).setVisibility(View.INVISIBLE);
        findViewById(R.id.btnStartExperiment).setVisibility(View.INVISIBLE);
        findViewById(R.id.btnTraining).setVisibility(View.INVISIBLE);
        findViewById(R.id.textView).setVisibility(View.INVISIBLE);
        findViewById(R.id.participantNumber).setVisibility(View.INVISIBLE);
        String participantNo = ((EditText) findViewById(R.id.participantNumber)).getText().toString();
        ((ExperimentView) findViewById(R.id.experimentView)).startExperiment(participantNo, false);
    }

    public void StartTraining(View view) {
        findViewById(R.id.btnClose).setVisibility(View.INVISIBLE);
        findViewById(R.id.btnStartExperiment).setVisibility(View.INVISIBLE);
        findViewById(R.id.btnTraining).setVisibility(View.INVISIBLE);
        findViewById(R.id.textView).setVisibility(View.INVISIBLE);
        findViewById(R.id.participantNumber).setVisibility(View.INVISIBLE);
        String participantNo = ((EditText) findViewById(R.id.participantNumber)).getText().toString();
        ((ExperimentView) findViewById(R.id.experimentView)).startExperiment(participantNo, true);
    }

    public void StopExperiment() {
        findViewById(R.id.btnClose).setVisibility(View.VISIBLE);
        findViewById(R.id.btnStartExperiment).setVisibility(View.VISIBLE);
        findViewById(R.id.btnTraining).setVisibility(View.VISIBLE);
        findViewById(R.id.textView).setVisibility(View.VISIBLE);
        findViewById(R.id.participantNumber).setVisibility(View.VISIBLE);
    }
}
