package eu.neosurance.utils;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import eu.neosurance.sdk.NSR;

public class NSRShake implements SensorEventListener {

    //*** SHAKE
    public static SensorManager mSensorManager;
    public static Sensor mAccelerometer;
    public static NSRShake mShakeDetector;

    private static String jsonShakeLabel = null;
    private static JSONObject jsonShakePayload = null;

    protected static final String TAG_SHAKE = "NSR_NSRShake";

    private static final float SHAKE_THRESHOLD_GRAVITY = 2.7F;
    private static final int SHAKE_SLOP_TIME_MS = 500;
    private static final int SHAKE_COUNT_RESET_TIME_MS = 3000;

    public static boolean sem_shake = false;
    public static int sem_shake_time = 5000;

    private OnShakeListener mListener;
    private long mShakeTimestamp;
    private int mShakeCount;


    public void setOnShakeListener(OnShakeListener listener) {
        this.mListener = listener;
    }

    public interface OnShakeListener {
        public void onShake(int count);
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        //...
    }

    @Override
    public void onSensorChanged(SensorEvent event) {

        if (mListener != null) {
            float x = event.values[0];
            float y = event.values[1];
            float z = event.values[2];

            float gX = x / SensorManager.GRAVITY_EARTH;
            float gY = y / SensorManager.GRAVITY_EARTH;
            float gZ = z / SensorManager.GRAVITY_EARTH;

            double gForce = Math.sqrt(gX * gX + gY * gY + gZ * gZ);

            if (gForce > SHAKE_THRESHOLD_GRAVITY) {
                final long now = System.currentTimeMillis();

                if (mShakeTimestamp + SHAKE_SLOP_TIME_MS > now) {
                    return;
                }

                // reset the shake count after 3 seconds of no shakes
                if (mShakeTimestamp + SHAKE_COUNT_RESET_TIME_MS < now) {
                    mShakeCount = 0;
                }

                mShakeTimestamp = now;
                mShakeCount++;

                mListener.onShake(mShakeCount);
            }
        }
    }

    public static void setShakeLabelAndPayload(JSONObject jsonShake){

        if(jsonShake.length() > 0)
            try {
                jsonShakeLabel = ( (String)jsonShake.get("label") != null) ? (String)jsonShake.get("label") : "";
                jsonShakePayload = ( (JSONObject) jsonShake.get("payload") != null ) ? (JSONObject) jsonShake.get("payload") : new JSONObject();
            } catch (JSONException e) {
                e.printStackTrace();
            }
        else {
            jsonShakeLabel = "";
            jsonShakePayload = new JSONObject();
        }

    }

    public void setNSRShake(final Context ctx){

        //**** << ShakeDetector

        mSensorManager = (SensorManager) ctx.getSystemService(Context.SENSOR_SERVICE);
        mAccelerometer = mSensorManager
                .getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        mShakeDetector = new NSRShake();
        mShakeDetector.setOnShakeListener(new NSRShake.OnShakeListener() {
            @Override
            public void onShake(final int count) {

                if(NSRShake.sem_shake == false){
                    NSRShake.sem_shake = true;

                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            Log.d(TAG_SHAKE,"...on shake! >> count: " + count);

                            //NSR.getInstance(ctx).sendEvent("inAirport",new JSONObject());
                            NSR.getInstance(ctx).sendEvent(jsonShakeLabel,jsonShakePayload);

                            try {
                                Thread.sleep(NSRShake.sem_shake_time);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }

                            NSRShake.sem_shake = false;
                        }
                    }).start();

                }

            }
        });

        mSensorManager.registerListener(mShakeDetector, mAccelerometer,	SensorManager.SENSOR_DELAY_UI);

        //**** ShakeDetector >>

        //**** << NSRShake off
        //mSensorManager.unregisterListener(NSRShake.mShakeDetector);
    }

    public static void NSRShakeOnResume() {
        Log.d("NSRShakeOnResume", "NSRShakeOnResume onResume");
        mSensorManager.registerListener(mShakeDetector, mAccelerometer,	SensorManager.SENSOR_DELAY_UI);
    }

    public static void NSRShakeOnStop() {
        Log.d("NSRShakeOnResume", "NSRShakeOnResume onStop");
        //**** << NSRShake off
        mSensorManager.unregisterListener(mShakeDetector);
    }

}
