package com.example.Maps013;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.Date;


import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.opengl.Visibility;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;

// http://stackoverflow.com/questions/32652477/determining-constant-velocity-using-androids-accelerometer
// https://github.com/alanszlosek/android-accelerometer-gps/blob/master/src/com/szlosek/whenmoving/MainService.java
// https://github.com/BoD/bikey
// http://www.analog.com/media/en/analog-dialogue/volume-44/number-2/articles/pedometer-design-3-axis-digital-acceler.pdf

// http://techqa.info/programming/question/20324356/how-to-calculate-exact-foot-step-count-using-accelerometer-in-android

// https://github.com/MichalDanielDobrzanski/WalkingSynth/blob/master/app/src/main/java/com/dobi/walkingsynth/accelerometer/AccelerometerProcessing.java

// https://github.com/bagilevi/android-pedometer

// https://developers.google.com/fit/android/data-types

// http://stackoverflow.com/questions/27058741/detect-user-activity-running-cycling-driving-using-android

// https://www.spaceotechnologies.com/integrate-android-accelerometer-detect-shake/

// http://stackoverflow.com/questions/2122333/how-to-count-the-number-of-steps-using-the-accelerometer?rq=1

// http://www.analog.com/media/en/technical-documentation/application-notes/47076299220991AN_900.pdf

// http://stackoverflow.com/questions/13264718/how-to-calculate-running-speed-using-accelerometer-sensor-in-android?rq=1

// shake detector http://jasonmcreynolds.com/?p=388

// http://stackoverflow.com/questions/2317428/android-i-want-to-shake-it

// http://www.java2s.com/Open-Source/Android_Free_Code/Hardware/accelerometer/index.htm

@SuppressLint("HandlerLeak")
public class StepCounterActivity extends Activity 
{

	private TextView tv_timer;
	private TextView tv_distance;
	private TextView tv_calories;
	private TextView tv_clock;
	private TextView tv_velocity;
	private TextView tv_step;
	private Button btn_start;
	private Button btn_stop;
    private TextView tv_gps;
	
	
	private long timer = 0;
	private  long startTimer = 0;
	private  long tempTime = 0;

	private Double distance = 0.0;
	private Double calories = 0.0;
	private Double velocity = 0.0;

	private int step_length = 0;  
	private int weight = 0;       
	private int total_step = 0;   

	private Thread thread;  

	
	boolean stop_tag = false;
	
    private BroadcastReceiver broadcastReceiver;

	Handler handler = new Handler() 
	{
		
		@Override               
		public void handleMessage(Message msg) 
		{
			super.handleMessage(msg);      

			countDistance();    

		
			if (timer != 0 && distance != 0.0) 
			{
				calories = weight * distance * 0.001;
				velocity = distance * 1000 / timer;
			} 
			else 
			{
				calories = 0.0;
				velocity = 0.0;
			}

			countStep();         

			tv_timer.setText(getFormatTime(timer));
			tv_distance.setText(formatDouble(distance));
			tv_calories.setText(formatDouble(calories));
			tv_velocity.setText(formatDouble(velocity));
			tv_step.setText(total_step + "");
			
			 if(broadcastReceiver == null)
			 {
		            broadcastReceiver = new BroadcastReceiver() 
		            {
		                @Override
		                public void onReceive(Context context, Intent intent) {

		                	//tv_gps.append("\n" +intent.getExtras().get("coordinates"));
		                	String str = (String) intent.getExtras().get("coordinates");
		                	String[] gps_parameters =  str.split(" ");
		                	
		                	//  i.putExtra("coordinates",location.getLongitude()+" "+location.getLatitude() +" "+location.getSpeed() +" "+location.getAltitude());
		                	//lat
		                	//longi
		                	//speed
		                	//altitude
		                	
		                	tv_gps.setText("" + intent.getExtras().get("coordinates"));	
		                	
		                	//tv_gps.setText(gps_parameters[3]);	
		                	
		                	
		                }
		            };
		     }
		     
			 registerReceiver(broadcastReceiver,new IntentFilter("location_update"));
			 
		
		}

	};

	@Override
	protected void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		//requestWindowFeature(Window.FEATURE_NO_TITLE);
		this.setContentView(R.layout.main03);  
		
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

		if (SettingsActivity.sharedPreferences == null) 
		{
			SettingsActivity.sharedPreferences = this.getSharedPreferences(	SettingsActivity.SETP_SHARED_PREFERENCES,Context.MODE_PRIVATE);
		}


		if (thread == null)
		{

			thread = new Thread() 
			{
				
					@Override
					public void run()
					{
						super.run();
						int temp = 0;
						while (true) 
						{
								try 
								{
									Thread.sleep(300); // 300
								} 
								catch (InterruptedException e) 
								{
									e.printStackTrace();
								}
								
								if (StepCounterService.FLAG) 
								{
									Message msg = new Message();
									if (temp != StepDetector.CURRENT_SETP) 
									{
										temp = StepDetector.CURRENT_SETP;
									}
									
									if (startTimer != System.currentTimeMillis()) 
									{
										timer = tempTime + System.currentTimeMillis() - startTimer;
									}
									handler.sendMessage(msg);
								}
						}
					}
			};
			
			thread.start();
		}
		
		
		/************* pour la clock ********************/
		Thread t = new Thread() 
		{

		        @Override
		        public void run() 
		        {
		            try 
		            {
		                while (!isInterrupted())
		                {
		                    Thread.sleep(1000);
		                    runOnUiThread(new Runnable() 
		                    {
			                        @Override
			                        public void run()
			                        {
			                            updateClock();
			                        }
		                    });
		                }
		            } 
		            catch (InterruptedException e) 
		            {
		            }
		        }
		    };

	    t.start();
		
	}
	
	private void updateClock() 
	{
	    Date clock = Calendar.getInstance().getTime();

	    String time = "hh:mm:ss"; // 12:00
	    tv_clock.setText(DateFormat.format(time, clock));

	   // String date = "dd MMMMM yyyy"; // 01 January 2013
	    //tvDate.setText(DateFormat.format(date, noteTS));
	}

	@Override
	protected void onResume()
	{
		super.onResume();

		Log.i("APP", "on resuame.");
		
		
		
		addView();
		init();
		
		
		

	}

	@Override
	protected void onDestroy() 
	{
		// TODO Auto-generated method stub
		super.onDestroy();
		
		if(broadcastReceiver != null){
            unregisterReceiver(broadcastReceiver);
        }
		
	}

	
	private void addView() 
	{

		tv_timer = (TextView) this.findViewById(R.id.tv_timer);
		tv_distance = (TextView) this.findViewById(R.id.tv_distance);
		tv_calories = (TextView) this.findViewById(R.id.tv_calories);
		tv_clock = (TextView) this.findViewById(R.id.tv_clock);
		tv_velocity = (TextView) this.findViewById(R.id.tv_velocity);
		tv_step = (TextView)findViewById(R.id.tv_step);
		btn_start = (Button) this.findViewById(R.id.start);
		btn_stop = (Button) this.findViewById(R.id.stop);
		tv_gps = (TextView) findViewById(R.id.tv_gps);   

		Intent service = new Intent(this, StepCounterService.class);
		stopService(service);
		
		Intent gps_service = new Intent(this, GPS_Service.class);
		stopService(gps_service);
		
		StepDetector.CURRENT_SETP = 0;
		tempTime = timer = 0;
		
		tv_timer.setText(getFormatTime(timer));     
		tv_distance.setText(formatDouble(0.0));
		tv_calories.setText(formatDouble(0.0));
		tv_velocity.setText(formatDouble(0.0));
		tv_step.setText("0");
		handler.removeCallbacks(thread);

	}


	private void init() 
	{

		step_length = SettingsActivity.sharedPreferences.getInt(SettingsActivity.STEP_LENGTH_VALUE, 70);
		weight = SettingsActivity.sharedPreferences.getInt(SettingsActivity.WEIGHT_VALUE, 50);

		countDistance();
		countStep();
		
		if ((timer += tempTime) != 0 && distance != 0.0)
		{ 
			calories = weight * distance * 0.001;
			velocity = distance * 1000 / timer;
		} 
		else 
		{
			calories = 0.0;
			velocity = 0.0;
		}

		tv_timer.setText(getFormatTime(timer + tempTime));
		tv_distance.setText(formatDouble(distance));
		tv_calories.setText(formatDouble(calories));
		tv_velocity.setText(formatDouble(velocity));
		tv_step.setText(total_step + "");

		btn_start.setEnabled(!StepCounterService.FLAG);
		btn_stop.setEnabled(StepCounterService.FLAG);

		if (StepCounterService.FLAG)
		{
			btn_stop.setText(getString(R.string.pause));
		} 
		else if (StepDetector.CURRENT_SETP > 0)
		{
			btn_stop.setEnabled(true);
			btn_stop.setText(getString(R.string.cancel));
		}

		//setDate();
	}

	
	private void setDate()
	{
		Calendar mCalendar = Calendar.getInstance();
		int weekDay = mCalendar.get(Calendar.DAY_OF_WEEK);
		int month = mCalendar.get(Calendar.MONTH) + 1;
		int day = mCalendar.get(Calendar.DAY_OF_MONTH);

//		tv_date.setText(month + getString(R.string.month) + day
//				+ getString(R.string.day));

		String week_day_str = new String();
		switch (weekDay) {
		case Calendar.SUNDAY:
			week_day_str = getString(R.string.sunday);
			break;

		case Calendar.MONDAY:
			week_day_str = getString(R.string.monday);
			break;

		case Calendar.TUESDAY:
			week_day_str = getString(R.string.tuesday);
			break;

		case Calendar.WEDNESDAY:
			week_day_str = getString(R.string.wednesday);
			break;

		case Calendar.THURSDAY:
			week_day_str = getString(R.string.thursday);
			break;

		case Calendar.FRIDAY:
			week_day_str = getString(R.string.friday);
			break;

		case Calendar.SATURDAY:
			week_day_str = getString(R.string.saturday);
			break;
		}
//		tv_week_day.setText(week_day_str);
	}

	private String formatDouble(Double doubles)
	{
		DecimalFormat format = new DecimalFormat("####.##");
		String distanceStr = format.format(doubles);
		return distanceStr.equals(getString(R.string.zero)) ? getString(R.string.double_zero): distanceStr;
	}

	public void onClick(View view) 
	{
		Intent service = new Intent(this, StepCounterService.class);
		
		Intent GPS_service = new Intent(this, GPS_Service.class);
		
		switch (view.getId())
		{
			case R.id.start:
				
				stop_tag = false;
				
				startService(service);
				
				startService(GPS_service);
				
				
				btn_start.setEnabled(false);
				btn_stop.setEnabled(true);
				btn_stop.setText(getString(R.string.pause));
				startTimer = System.currentTimeMillis();
				tempTime = timer;
				break;
	
			case R.id.stop:
				stopService(service);
				
				stopService(GPS_service);
				
				
				stop_tag = true;
				
				if (StepCounterService.FLAG && StepDetector.CURRENT_SETP > 0)
				{
					btn_stop.setText(getString(R.string.cancel));
				} 
				else 
				{
					
					
							AlertDialog.Builder b = new AlertDialog.Builder(this)
						    .setTitle("Warning !")
						    .setCancelable(false)
						    .setMessage("Do you really want to clear datas ?")
						    .setIcon(R.drawable.ic_launcher)
						    
						    .setNegativeButton("No", new OnClickListener()
						    {
							    	@Override
							    	public void onClick(DialogInterface dialog, int which)
							    	{
							    		dialog.dismiss();
							    	}
						    })
						    
						    .setPositiveButton("Yes", new OnClickListener() 
						    {
								   @Override
								   public void onClick(DialogInterface dialog, int which)
								   {
									    StepDetector.CURRENT_SETP = 0;
										tempTime = timer = 0;
						
										btn_stop.setText(getString(R.string.pause));
										btn_stop.setEnabled(false);
						
										tv_timer.setText(getFormatTime(timer));     
						
										tv_step.setText("0");
										tv_distance.setText(formatDouble(0.0));
										tv_calories.setText(formatDouble(0.0));
										tv_velocity.setText(formatDouble(0.0));
						
										handler.removeCallbacks(thread);
									    dialog.dismiss();
							   }
						    });
							
						  b.show();
/*					
					
					StepDetector.CURRENT_SETP = 0;
					tempTime = timer = 0;
	
					btn_stop.setText(getString(R.string.pause));
					btn_stop.setEnabled(false);
	
					tv_timer.setText(getFormatTime(timer));     
	
					tv_step.setText("0");
					tv_distance.setText(formatDouble(0.0));
					tv_calories.setText(formatDouble(0.0));
					tv_velocity.setText(formatDouble(0.0));
	
					handler.removeCallbacks(thread);
*/					
				}
				
				btn_start.setEnabled(true);
				break;	
		}
	}

	
	private String getFormatTime(long time) 
	{
		time = time / 1000;
		long second = time % 60;
		long minute = (time % 3600) / 60;
		long hour = time / 3600;

		
		// String strMillisecond = "" + (millisecond / 10);
		
		String strSecond = ("00" + second)
				.substring(("00" + second).length() - 2);
	
		String strMinute = ("00" + minute)
				.substring(("00" + minute).length() - 2);
	
		String strHour = ("00" + hour).substring(("00" + hour).length() - 2);

		return strHour + ":" + strMinute + ":" + strSecond;
		// + strMillisecond;
	}


	
	private void countDistance()
	{
		if (StepDetector.CURRENT_SETP % 2 == 0)
		{
			distance = (StepDetector.CURRENT_SETP / 2) * 3 * step_length * 0.01;
		} 
		else 
		{
			distance = ((StepDetector.CURRENT_SETP / 2) * 3 + 1) * step_length * 0.01;
		}
	}


	private void countStep() 
	{
		if (StepDetector.CURRENT_SETP % 2 == 0) 
		{
			total_step = StepDetector.CURRENT_SETP;
		} 
		else
		{
			total_step = StepDetector.CURRENT_SETP +1;
		}

		total_step = StepDetector.CURRENT_SETP;
	}

	@Override
	public void onBackPressed()
	{
		
		//super.onBackPressed();
		//Toast.makeText(getApplicationContext(), "Quitter podometre", Toast.LENGTH_LONG).show();
		//finish();
		
					AlertDialog.Builder b = new AlertDialog.Builder(this)
				    .setTitle("Warning !")
				    .setCancelable(false)
				    .setMessage("Do you really want to close podometre?")
				    .setIcon(R.drawable.ic_launcher)
				    
				    .setNegativeButton("No", new OnClickListener()
				    {
					    	@Override
					    	public void onClick(DialogInterface dialog, int which)
					    	{
					    		dialog.dismiss();
					    	}
				    })
				    
				    .setPositiveButton("Yes", new OnClickListener() 
				    {
						   @Override
						   public void onClick(DialogInterface dialog, int which)
						   {
							   StepCounterActivity.this.finish();
							   dialog.dismiss();
					   }
				    });
					
				  b.show();
		
	}
	
	
	/*******************************************************************************************/

	@Override
	public boolean onCreateOptionsMenu(Menu menu) 
	{
			getMenuInflater().inflate(R.menu.podometre_menu, menu);
			return true;
	}
	
	@Override
    public boolean onOptionsItemSelected(MenuItem item) 
	{
		
			Intent Intent;
		 
	        switch (item.getItemId())
	        {
	        
	        	case R.id.menu_settings:
	        		Intent = new Intent(StepCounterActivity.this, SettingsActivity.class);
	        		startActivity(Intent);
	        		return true;
	        
	        	case R.id.menu_save:
	        		//Intent = new Intent(StepCounterActivity.this, test_DB.class); // SaveActivity
	        		//startActivity(Intent);
	        		return true;
		          
		  		default:
		          return super.onOptionsItemSelected(item);
             }
    }
	
	/*******************************************************************************************/
	

}
