package com.example.distmeasapp;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class ShortMeas extends Activity implements SensorEventListener {

	private static final int M_CAMERA = 0;
	private static final int M_SHORTMEAS = 1;
	private static final int M_LONGMEAS = 2;
	private static final int M_HELP = 3;
	private static final int M_EXIT = 4;
	private int buffersize = 10000, state, step;
	private double []T = new double[buffersize];
	private double []gravity = new double[3];
	private double []X = new double[buffersize];
	private double []Y = new double[buffersize];
	private double []Z = new double[buffersize];
	private double []Xg = new double[buffersize];
	private double []Yg = new double[buffersize];
	private double []Zg = new double[buffersize];
	private double []Vx = new double[buffersize];
	private double []Vy = new double[buffersize];
	private double []Vz = new double[buffersize];
	private double []Sx = new double[buffersize];
	private double []Sy = new double[buffersize];
	private double []Sz = new double[buffersize];
	private double distA, distB, VxMax, VyMax, VzMax;
	private double alpha = 0.8f; // konstanta pro low-pass filter
	private long res, temp;
	private String string2 = "";
	private long multiply = 1000000000; // nasobek pro ustaleni jednotky casu (ms)
	private SensorManager mSensorManager;
	private Sensor grav;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.short_meas);
		
		mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
		grav = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		menu.add(0, M_CAMERA,0, R.string.menu0);
		menu.add(0, M_SHORTMEAS,0, R.string.menu1);
		menu.add(0, M_LONGMEAS,0, R.string.menu2);
		menu.add(0, M_HELP,0, R.string.menu3);
		menu.add(0, M_EXIT,0, R.string.menu4);
		return true;
	}

	@Override
    public boolean onMenuItemSelected(int featureId, MenuItem item) {
    	switch(item.getItemId()) {
        case M_CAMERA:
        	startActivity(new Intent(this, CameraMeas.class));
        	return true;
        case M_SHORTMEAS:
        	startActivity(new Intent(this, ShortMeas.class));
        	return true;
        case M_LONGMEAS:
        	startActivity(new Intent(this, LongMeas.class));
        	return true;
        case M_HELP:
        	startActivity(new Intent(this, Help.class));
        	return true;
        case M_EXIT:
        	finish();
        	return true;
        default:
            return super.onOptionsItemSelected(item);
	    }
    }
	
	public void btnClicked(View view) {
		TextView view1 = (TextView) findViewById(R.id.TextView1);
		String s = "";
		Button textChange = (Button)findViewById(R.id.button1);

		if (state == 0) {
			state = 1; // zapnuti mereni
			step = 0;
			textChange.setText("Ukončit měření");
			Arrays.fill(Vx, 0);
			Arrays.fill(Vy, 0);
			Arrays.fill(Vz, 0);
			Arrays.fill(Sx, 0);
			Arrays.fill(Sy, 0);
			Arrays.fill(Sz, 0);
			distA = 0;
			distB = 0;
			VxMax = 0;
			VyMax = 0;
			VzMax = 0;
		} else {
			state = 0; // vypnuti mereni
			textChange.setText("Zahájit měření");
			String string = "";
			
			if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
				string = "krok\tX\tY\tZ\tXg\tYg\tZg\tVx\tVy\tVz\tSx\tSy\tSz\tT\r\n0\t"
					+ X[0] + "\t" + Y[0] + "\t" + Z[0] + "\t"
					+ Xg[0] + "\t" + Yg[0] + "\t" + Zg[0] + "\t"
					+ Vx[0] + "\t" + Vy[0] + "\t" + Vz[0] + "\t"
					+ Sx[0] + "\t" + Sy[0] + "\t" + Sz[0] + "\t"
					+ T[0] + ";\r\n";
			}
			else	Toast.makeText(this,"Paměťová karta není přístupná.",Toast.LENGTH_SHORT).show();
			
			for (int i = 1; i < step+1; i++) {
				if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
					string = string + i + "\t" + X[i]+ "\t" + Y[i]+ "\t" + Z[i] + "\t" + Xg[i]+ "\t" + Yg[i]+ "\t" + Zg[i] + "\t";
				// akcelerace -> rychlost
				Vx[i] = Vx[i-1] + (Xg[i] * T[i]);
				Vy[i] = Vy[i-1] + (Yg[i] * T[i]);
				Vz[i] = Vz[i-1] + (Zg[i] * T[i]);

				if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
					string = string + Vx[i]+ "\t" + Vy[i]+ "\t" + Vz[i] + "\t";
				
				// maximalni rychlost pohybu pro jednotlive osy
				if (Vx[i] > VxMax)	VxMax = Vx[i];
				if (Vy[i] > VyMax)	VyMax = Vy[i];
				if (Vz[i] > VzMax)	VzMax = Vz[i];
				
				// rychlost -> souradnice bodu
				Sx[i] = Sx[i-1] + 0.5 * (Vx[i-1] + Vx[i]) * T[i];
				Sy[i] = Sy[i-1] + 0.5 * (Vy[i-1] + Vy[i]) * T[i];
				Sz[i] = Sz[i-1] + 0.5 * (Vz[i-1] + Vz[i]) * T[i];
				
				if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
					string = string + Sx[i]+ "\t" + Sy[i]+ "\t" + Sz[i] + "\t" + T[i] + "\r\n";
				
				if (i>1)
					distA = distA + Math.sqrt((Sx[i]-Sx[i-1])*(Sx[i]-Sx[i-1])+(Sy[i]-Sy[i-1])*(Sy[i]-Sy[i-1])+(Sz[i]-Sz[i-1])*(Sz[i]-Sz[i-1]));
			}
			
			distB = Math.sqrt((Sx[1]-Sx[step])*(Sx[1]-Sx[step])+(Sy[1]-Sy[step])*(Sy[1]-Sy[step])+(Sz[1]-Sz[step])*(Sz[1]-Sz[step]));
			
			if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
				string = string
						+ "\r\n VxMax: " + VxMax
						+ "\r\n VyMax: " + VyMax
						+ "\r\n VzMax: " + VzMax
						+ "\r\n distA: " + distA
						+ "\r\n distB: " + distB
						+ "\r\n steps: " + step;
			}
			
			s = "Maximální rychlosti pro osy:" +
				"\nX: " + VxMax +
				"\nY: " + VyMax +
				"\nZ: " + VzMax +
				"\n\nVzdálenost:" +
				"\n- celková: " +	distA +
				"\n- vzdušnou čarou: " + distB +
				"\n\nVyužití bufferu: " + step + " z " + buffersize;
			view1.setText(s);
			distA = 0;
			distB = 0;
			
			// ulozeni vystupnich dat do souboru
			if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
				string = string + string2;
				getOutputExport(string);
			}

			// vykresleni krivek do grafu
		}
	}
	
	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {
		// TODO Auto-generated method stub
	}

	@Override
	public void onSensorChanged(SensorEvent event) {
		TextView view = (TextView) findViewById(R.id.TextView1);
		String s = "";
		
		if (event.sensor.getType() == Sensor.TYPE_GRAVITY) {
			// kod uprednostnovany pro verze OS Android v2.3 a vyssi
			gravity[0] = event.values[0];
			gravity[1] = event.values[1];
			gravity[2] = event.values[2];
		}
		
		if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
			if (grav == null) {
				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];
			}
			
			if (state == 1) {
				step = step + 1;
				if (step<buffersize) {

				    temp = System.nanoTime();
					T[step] = ((double) (temp - res)) / multiply;
					res = temp;
				    X[step] = event.values[0];
				    Y[step] = event.values[1];
				    Z[step] = event.values[2];
					Xg[step] = X[step] - gravity[0];
				    Yg[step] = Y[step] - gravity[1];
				    Zg[step] = Z[step] - gravity[2];
					
				    s = "Krok: " + step +
						"\nT: " + T[step] + " s" +
						"\nX: " + X[step] + " m/s^2" +
						"\nY: " + Y[step] + " m/s^2" +
						"\nZ: " + Z[step] + " m/s^2" +
						"\nXg: " + Xg[step] + " m/s^2" +
						"\nYg: " + Yg[step] + " m/s^2" +
						"\nZg: " + Zg[step] + " m/s^2" +
						"\nTime:" + System.nanoTime()/1000000;
				}
				else {
					s = "Krok: " + step +
						"\nBuffer byl přeplněn.";
					state = 0;
				}
				view.setText(s);
			} else {	// pocatecni stav

			    X[0] = event.values[0];
			    Y[0] = event.values[1];
			    Z[0] = event.values[2];
			    Xg[0] = X[0] - gravity[0];
				Yg[0] = Y[0] - gravity[1];
				Zg[0] = Z[0] - gravity[2];
				res = System.nanoTime();
				T[0] = 0;
			}
		}
	}
	
	@Override
	protected void onResume() {
	    super.onResume();
	    // registrace tridy jako sledovac orientace a akcelerace
	    mSensorManager.registerListener(this,
	    mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
	    mSensorManager.SENSOR_DELAY_NORMAL);
	    
	    mSensorManager.registerListener(this,
	    mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY),
	    mSensorManager.SENSOR_DELAY_NORMAL);

	  }

	  @Override
	protected void onPause() {
	    // odregistrace sledovace
	    super.onPause();
	    mSensorManager.unregisterListener(this);
	  }
	  
	public void getOutputExport(String string){
	        // osetreni, zda je pristupna pametova karta
	    	/*if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
	    		Toast.makeText(this,"Paměťová karta není přístupná.",Toast.LENGTH_SHORT).show();
	    		return;
	    	}*/
	        // Vytvoreni adresare pro exporty, pokud neexistuje
	        File folder = new File(Environment.getExternalStorageDirectory(), "DMA-export");
	    	
	        if (! folder.exists()){
	            if (! folder.mkdirs()) {
	    	    	Toast.makeText(this, "Nepodařilo se vytvořit adresář " + folder.getPath() + ".", Toast.LENGTH_SHORT ).show();
	    	    	return;
	            }
		        else Toast.makeText(this, "Vytvořen adresář "+Environment.getExternalStorageDirectory().getPath(), Toast.LENGTH_SHORT).show();
	        }

	        // vytvoreni textoveho souboru
	        String fileName = "export_SM_" + new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss").format(new Date()) + ".txt";
	        try
	        {
	            File textFile = new File(folder, fileName);
	            FileWriter writer = new FileWriter(textFile);
	            writer.append(string);
	            writer.flush();
	            writer.close();

	            Toast.makeText(this, "Export dat do souboru " + fileName + " proběhl úspěšně.", Toast.LENGTH_SHORT).show();
	            //zakomentovat
	        }
	        catch (FileNotFoundException e) {}
	        catch (IOException e) {}
	    }
}