package com.example.stepcounter;

import android.content.Intent;
import android.graphics.drawable.ColorDrawable;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;

import java.util.List;

public class MainActivity extends AppCompatActivity {
    private TextView steps = null;
    private TextView mph = null;

    private Button BtnStart, BtnStop, BtnClear;
    private SensorManager sensorManager;
    private Sensor accelerator;
    private int numSteps;
    private long lastUpdate;
    List list;

    private static final int ACCELERATOR_RING_SIZE = 50;
    private static final int VEL_RING_SIZE = 10;
    private static final float STEP_THRESHOLD = 50f;
    private static final int STEP_DELAY_NS = 250000000;
    private int acceleratorRingCounter = 0;
    private float[] accelRingX = new float[ACCELERATOR_RING_SIZE];
    private float[] accelRingY = new float[ACCELERATOR_RING_SIZE];
    private float[] accelRingZ = new float[ACCELERATOR_RING_SIZE];
    private int velRingCounter = 0;
    private float[] velRing = new float[VEL_RING_SIZE];
    private long lastStepTimeNs = 0;
    private float oldVelocityEstimate = 0;

    SensorEventListener sel = new SensorEventListener() {
        public void onAccuracyChanged(Sensor sensor, int accuracy) {}
        public void onSensorChanged(SensorEvent event) {
            // step event
            float[] values = event.values;
            float x = values[0];
            float y = values[1];
            float z = values[2];

            if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
              //  Toast.makeText(MainActivity.this, "Step detected", Toast.LENGTH_SHORT).show();
          //      StepDetector.updateAccel(event.timestamp, event.values[0], event.values[1], event.values[2]);
                float[] currentAccelerator = new float[3];
                currentAccelerator[0] = x;
                currentAccelerator[1] = y;
                currentAccelerator[2] = z;

                acceleratorRingCounter++;
                accelRingX[acceleratorRingCounter % ACCELERATOR_RING_SIZE] = currentAccelerator[0];
                accelRingY[acceleratorRingCounter % ACCELERATOR_RING_SIZE] = currentAccelerator[1];
                accelRingZ[acceleratorRingCounter % ACCELERATOR_RING_SIZE] = currentAccelerator[2];

                float[] valueX = new float[3];
                valueX[0] = SensorFilter.sum(accelRingX) / Math.min(acceleratorRingCounter, ACCELERATOR_RING_SIZE);
                valueX[1] = SensorFilter.sum(accelRingY) / Math.min(acceleratorRingCounter, ACCELERATOR_RING_SIZE);
                valueX[2] = SensorFilter.sum(accelRingZ) / Math.min(acceleratorRingCounter, ACCELERATOR_RING_SIZE);

                float normalization_factor = SensorFilter.norm(valueX);

                valueX[0] = valueX[0] / normalization_factor;
                valueX[1] = valueX[1] / normalization_factor;
                valueX[2] = valueX[2] / normalization_factor;

                float currentX = SensorFilter.dot(valueX, currentAccelerator) - normalization_factor;
                velRingCounter++;

                velRing[velRingCounter % VEL_RING_SIZE] = currentX;

                float velocityEstimate = SensorFilter.sum(velRing);

            //    mph.setText("" + (int) oldVelocityEstimate);
                if ( (int) velocityEstimate > 0) {
                    if ((int) oldVelocityEstimate < 2) {
                        numSteps++;
                        steps.setText("" + numSteps);
                    }
                }
                if (velocityEstimate > STEP_THRESHOLD && oldVelocityEstimate <= STEP_THRESHOLD && (event.timestamp - lastStepTimeNs > STEP_DELAY_NS)) {
                     lastStepTimeNs = event.timestamp;
                }
                oldVelocityEstimate = velocityEstimate;
            }


            // detect a shake
            float accelationSquareRoot = (x * x + y * y + z * z) / (SensorManager.GRAVITY_EARTH * SensorManager.GRAVITY_EARTH);
            long actualTime = event.timestamp;
            if (accelationSquareRoot >= 2)
            {
                if (actualTime - lastUpdate < 200) {
                    return;
                }
                lastUpdate = actualTime;
                Toast.makeText(MainActivity.this, "Device was shuffed", Toast.LENGTH_SHORT).show();
            }
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ActionBar actionBar = getSupportActionBar();

        // providing title for the ActionBar
        actionBar.setTitle("Steps | Clock");
        actionBar.setBackgroundDrawable(new ColorDrawable(0xff00ACED));

        lastUpdate = System.currentTimeMillis();
        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        accelerator = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

        steps = findViewById(R.id.steps);
        mph = findViewById(R.id.mph);

        BtnStart = findViewById(R.id.btn_start);
        BtnStop = findViewById(R.id.btn_stop);
        BtnClear = findViewById(R.id.btn_clear);
        list = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);

        BtnStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                sensorManager.registerListener(sel, (Sensor) list.get(0), SensorManager.SENSOR_DELAY_NORMAL);
            }
        });

        BtnStop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                sensorManager.unregisterListener(sel);
            }
        });

        BtnClear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                numSteps=0;
                steps.setText("" + 0);
            }
        });
    }
    @Override
    public boolean onCreateOptionsMenu( Menu menu ) {
        getMenuInflater().inflate(R.menu.main, menu);
        return super.onCreateOptionsMenu(menu);
    }

    public boolean onOptionsItemSelected( MenuItem item ) {
        if (item.getItemId() == R.id.clock) {
            Intent intent = new Intent(MainActivity.this, StopWatch.class);
            startActivity(intent);
        }
        return super.onOptionsItemSelected(item);
    }


}