package com.example.sensors;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorListener;
import android.hardware.SensorManager;
import android.widget.TextView;

public final class Sensual {
	private Sensual(){}

	public static interface SixAxis{
		public void eval(float x, float y, float z, float a, float b, float c);
	}
	public static interface Axis{
		public void eval(float x, float y, float z);
	}
	public static interface Value{
		public void eval(float val);
	}
	
	public static void initAccel(final Axis gforce, final SensorManager sensorMan){
		sensorMan.registerListener(new SensorListener(){
			private final float alpha = 0.8f;
			private float gravityX,
			      		  gravityY,
			      		  gravityZ;

			public void onAccuracyChanged(int arg0, int arg1) {
			}
			public void onSensorChanged(int arg0, float[] arg1) {
				// Isolate the force of gravity with the low-pass filter.
				gravityX = alpha * gravityX + (1 - alpha) * arg1[0];
				gravityY = alpha * gravityY + (1 - alpha) * arg1[1];
				gravityZ = alpha * gravityZ + (1 - alpha) * arg1[2];
				
				// Remove the gravity contribution with the high-pass filter.
				if (gforce != null)
					gforce.eval(arg1[0] - gravityX, arg1[1] - gravityY, arg1[2] - gravityZ);
			}
		}, Sensor.TYPE_ACCELEROMETER);
	}
	
	public static void initLinear(final Axis gforce, final SensorManager sensorMan){
		sensorMan.registerListener(new SensorListener(){
			public void onAccuracyChanged(int arg0, int arg1) {
			}
			public void onSensorChanged(int arg0, float[] arg1) {
				if (gforce != null)
					gforce.eval(arg1[0], arg1[1], arg1[2]);
			}
		}, Sensor.TYPE_LINEAR_ACCELERATION);
	}
	
	public static void initGravity(final Axis axis, final SensorManager sensorMan){
		sensorMan.registerListener(new SensorListener(){

			public void onAccuracyChanged(int arg0, int arg1) {
			}
			public void onSensorChanged(int arg0, float[] arg1) {
				axis.eval(arg1[0], arg1[1], arg1[2]);
			}
		}, Sensor.TYPE_GRAVITY);
	}
		
	public static void initRotation(final Axis axis, final SensorManager sensorMan){
		sensorMan.registerListener(new SensorListener(){

			public void onAccuracyChanged(int arg0, int arg1) {
			}
			public void onSensorChanged(int arg0, float[] arg1) {
				axis.eval(arg1[0], arg1[1], arg1[2]);
			}
		}, Sensor.TYPE_ROTATION_VECTOR);
	}
	
	public static void initCompass(final Axis axis, final SensorManager sensorMan){
		sensorMan.registerListener(new SensorListener(){
			public void onAccuracyChanged(int arg0, int arg1) {
			}
			public void onSensorChanged(int arg0, float[] arg1) {
				axis.eval(arg1[0], arg1[1], arg1[2]);
			}
		}, Sensor.TYPE_MAGNETIC_FIELD);
	}
	
	public static void initGyro(final Axis axis, final SensorManager sensorMan){
		sensorMan.registerListener(new SensorListener(){
			public void onAccuracyChanged(int arg0, int arg1) {
			}
			public void onSensorChanged(int arg0, float[] arg1) {
				axis.eval(arg1[0], arg1[1], arg1[2]);
			}
		}, Sensor.TYPE_GYROSCOPE);
	}
	
	public static void initThermometer(final Value val, final SensorManager sensorMan){
		sensorMan.registerListener(new SensorListener(){
			public void onAccuracyChanged(int arg0, int arg1) {
			}
			public void onSensorChanged(int arg0, float[] arg1) {
				val.eval(arg1[0]);
			}
		}, Sensor.TYPE_AMBIENT_TEMPERATURE);
	}
	
	public static void initBarometer(final Value val, final SensorManager sensorMan){
		sensorMan.registerListener(new SensorListener(){
			public void onAccuracyChanged(int arg0, int arg1) {
			}
			public void onSensorChanged(int arg0, float[] arg1) {
				val.eval(arg1[0]);
			}
		}, Sensor.TYPE_PRESSURE);
	}
	
	public static void initHygrometer(final Value val, final SensorManager sensorMan){
		sensorMan.registerListener(new SensorListener(){
			public void onAccuracyChanged(int arg0, int arg1) {
			}
			public void onSensorChanged(int arg0, float[] arg1) {
				val.eval(arg1[0]);
			}
		}, Sensor.TYPE_RELATIVE_HUMIDITY);
	}
	
	public static void initLumens(final Value val, final SensorManager sensorMan){
		sensorMan.registerListener(new SensorListener(){
			public void onAccuracyChanged(int arg0, int arg1) {
			}
			public void onSensorChanged(int arg0, float[] arg1) {
				val.eval(arg1[0]);
			}
		}, Sensor.TYPE_LIGHT);
	}
	
	public static void initProximity(final Value val, final SensorManager sensorMan){
		sensorMan.registerListener(new SensorListener(){
			public void onAccuracyChanged(int arg0, int arg1) {
			}
			public void onSensorChanged(int arg0, float[] arg1) {
				val.eval(arg1[0]);
			}
		}, Sensor.TYPE_PROXIMITY);
	}
}
