package com.kekenzy.sports;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;


import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.Toast;

import com.kekenzy.model.sqlite.bean.MapPosBean;
import com.kekenzy.model.sqlite.bean.RunningBean;
import com.kekenzy.model.sqlite.biz.RunningDBManager;
import com.kekenzy.viewer.ListRunningItemAdapter;

public class RunningRecoderActivity extends Activity implements OnClickListener, LocationListener{

	static final int MIL_TIME = 1;
    static final long DELAY_TIME = 1000/MIL_TIME; // TimerTaskのDelay時間(ミリ秒)
    static final long PERIOD_TIME = 1000/MIL_TIME; // TimerTaskのPeriod時間(ミリ秒)

	static final long MIN_TIME = 0; // 通知の最小時間
    static final float MIN_DISTANCE = 0; // 通知の最短距離

    static final String TAG = "RunningRecoderActivity";

    Timer mTimer = null;
	private SimpleCursorAdapter mAdapter;

    private Handler mHandler = new Handler();

    public static final int[] LIST_COLUMN = { R.id.tId, R.id.tRunDate, R.id.tTime, R.id.tDistance, };

    Button bStartStop;
    Button bReset;
    Button bSave;
    Button bMap;
    Button bMap2;

    TextView tRecordTime;

    TextView tLatitude;
    TextView tLongitude;
    TextView tPlaceName;

    int mLapTime = 0;
    double dDistance = 0;

	double lastLatitude;
	double lastLongitude;
//    Chronometer chronometer;

	long run_id;

    // 地名検索用
    Geocoder mGeoCoder;

    // 位置情報を取得するためのマネージャ
    LocationManager mLocationManager;

    Location mLocation;

    // DBマネージャ
    private RunningDBManager mDb;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);


        bStartStop = (Button)findViewById(R.id.bStartStopRecord);
        bStartStop.setOnClickListener(this);

        bReset = (Button)findViewById(R.id.bResetRecord);
        bReset.setOnClickListener(this);

        bSave = (Button)findViewById(R.id.bSave);
        bSave.setOnClickListener(this);

        bMap = (Button)findViewById(R.id.bMap);
        bMap.setOnClickListener(this);

        bMap2 = (Button)findViewById(R.id.bMap2);
        bMap2.setOnClickListener(this);

        bReset.setEnabled(false);
        bSave.setEnabled(false);

        tRecordTime = (TextView)findViewById(R.id.tRecordTime);

        tLatitude = (TextView)findViewById(R.id.tLatitude);
        tLongitude = (TextView)findViewById(R.id.tLongitude);
        tPlaceName = (TextView)findViewById(R.id.tPraceName);

//        chronometer = (Chronometer) findViewById(R.id.chronometer_id);
//        chronometer.setFormat("time %s");
//        // 最初にリセット
//        chronometer.setBase(SystemClock.elapsedRealtime());

        // 位置情報取得クラス生成
        mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
//		mLocationManager.addGpsStatusListener(this);

        mGeoCoder = new Geocoder(getApplicationContext(), Locale.JAPAN);

    }

    void showToast(String msg){
        Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
    }

    @Override
    public void onLocationChanged(Location location) {
        mLocation = location;

		double latitude = mLocation.getLatitude();
		double longitude = mLocation.getLongitude();
		if (lastLatitude != 0 && lastLongitude != 0){
			dDistance = dDistance + getDistance(lastLatitude, lastLongitude, latitude, longitude);
		}
		setLocationNameFromGeo(latitude,longitude);
		locationSet(latitude, longitude);

		lastLatitude = latitude;
		lastLongitude = longitude;

		// 位置情報をDBに保存
        saveLocation(location);

//		showToast("ロケーション変更！！" + Double.toString(latitude) + "/" + Double.toString(longitude));
    }

    @Override
    public void onProviderDisabled(String s) {
        // TODO 自動生成されたメソッド・スタブ

    }

    @Override
    public void onProviderEnabled(String s) {
        // TODO 自動生成されたメソッド・スタブ

    }

    @Override
    public void onStatusChanged(String s, int i, Bundle bundle) {
        // TODO 自動生成されたメソッド・スタブ

    }


//	private String getDiffTime( long fromTime, long toTime ){
//		long tmpTime = toTime - fromTime;
//		int days = (int) (tmpTime / 86400000);
//		int time =  (int) (( tmpTime / 60000 ) % 1440);
//		int hour = time / 60;
//		int min = time % 60;
//		int sec =  (int) (( tmpTime / 1000 ) % 60);
//
//		String lastTime = getString(R.string.LAST) + Integer.toString(days)
//						+ getString(R.string.DAY) + getString(R.string.AND)
//						+ Integer.toString(hour) + getString(R.string.HOUR)
//						+ Integer.toString(min) + getString(R.string.MIN)
//						+ Integer.toString(sec) + getString(R.string.SEC);
//		Toast.makeText(this, lastTime, Toast.LENGTH_LONG).show();
//		return lastTime;
//	}

    boolean bStartOn = false;
    boolean bStartExe = false;
    long nowTime;

    @Override
    public void onClick(View v) {

        Button btn = (Button)v;

        switch (btn.getId()){
        case R.id.bStartStopRecord:
            if (bStartOn == false) {
//                if (!mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
//                    showToast("GPSが有効でないです。有効にしてください");
//                    break;
//                }

            	// 一時停止中
                if (bStartExe) {
//                    chronometer.start();


                // タイマー初期化
                } else {
                    clearTimer();
//                	chronometer.setBase(SystemClock.elapsedRealtime());
//                    chronometer.start();
                    bStartExe = true;
                }

                startTimer();
                bStartStop.setText(R.string.STOP_RECORD);
                bStartOn = true;

            } else {
            	stopTimer();
//				nowTime = chronometer.setBase(S);
//                chronometer.stop();
                bStartStop.setText(R.string.RESTART_RECORD);
                bStartOn = false;

            }
            bReset.setEnabled(true);
            bSave.setEnabled(true);
            break;

        case R.id.bResetRecord:
        	stopTimer();
        	clearTimer();
        	dDistance = 0;
//            chronometer.stop();
//            chronometer.setBase(SystemClock.elapsedRealtime());
            bStartStop.setText(R.string.START_RECORD);
            bStartOn = false;
            bStartExe = false;
            bReset.setEnabled(false);
            bSave.setEnabled(false);
            break;

        case R.id.bSave:
        	saveRunningRecord();
        	viewList();
        	break;

        case R.id.bMap:
    		// 位置情報をDBに保存
            saveLocation(mLocation);

        	callMapView();
        	break;

        case R.id.bMap2:
        	Intent intent = new Intent();
            intent.setAction(Intent.ACTION_VIEW);
            intent.setClassName("com.google.android.apps.maps","com.google.android.maps.MapsActivity");
            intent.setData(Uri.parse("http://maps.google.com/maps?myl= saddr=33.589684,130.42336&daddr=33.590073,130.4236&dirflg=w"));
            startActivity(intent);
            break;
        }

    }

    private void callMapView(){
		Intent intent = new Intent( getApplicationContext(), RunningMapActivity.class );
		intent.putExtra( RunningMapActivity.INTENT_PARAM_LAT, lastLatitude );
		intent.putExtra( RunningMapActivity.INTENT_PARAM_LON, lastLongitude );
		startActivity( intent );

    }

    private void startTimer(){
        if (mTimer == null) {
            mTimer = new Timer(true);
        }

        mTimer.scheduleAtFixedRate(new TimerTask(){

            @Override
            public void run() {
                // TODO 自動生成されたメソッド・スタブ
                mHandler.post(new Runnable(){
                    @Override
                    public void run() {
                        mLapTime++;
                    	tRecordTime.setText(getFormatTime(mLapTime));
                    }
                });

            }

            }, DELAY_TIME, PERIOD_TIME);
    }

    private String getFormatTime(int time){
    	String hour = String.format("%1$02d", time/(3600*MIL_TIME));
    	String min = String.format("%1$02d", (time/(60*MIL_TIME)) % (60*MIL_TIME));
    	String sec =  String.format("%1$02d", time % (60*MIL_TIME) / MIL_TIME);
//    	int msec =  time % MIL_TIME;

    	return (hour + ":" + min + ":" + sec);
    }

    private void stopTimer(){
        if (mTimer != null) {
            mTimer.cancel();
            mTimer = null;
        }
    }
    private void clearTimer(){
        mLapTime = 0;
    	tRecordTime.setText("00:00:00");
    }

    private void saveRunningRecord(){
        RunningBean rBean = new RunningBean();
        rBean.setRunDate(getNowDateTime());
        rBean.setDistance(dDistance);
        rBean.setTime(getFormatTime(mLapTime));


        // DBへInsert処理
        run_id = mDb.insertRun(rBean);
    }

    /**
     * 位置情報をDBに保存
     *
     * @param location
     */
    private void saveLocation(Location location) {
    	MapPosBean mBean = new MapPosBean();
    	mBean.setRunID(run_id);
    	mBean.setLatitude(location.getLatitude());
    	mBean.setLongitude(location.getLongitude());
    	mBean.setTime(System.currentTimeMillis());

        mDb.insertMapPos(mBean);
    }


    private String getNowDateTime(){
    	Calendar cal1 = Calendar.getInstance();  //(1)オブジェクトの生成

    	int year = cal1.get(Calendar.YEAR);        //(2)現在の年を取得
    	int month = cal1.get(Calendar.MONTH) + 1;  //(3)現在の月を取得
    	int day = cal1.get(Calendar.DATE);         //(4)現在の日を取得
    	int hour = cal1.get(Calendar.HOUR_OF_DAY); //(5)現在の時を取得
    	int minute = cal1.get(Calendar.MINUTE);    //(6)現在の分を取得
    	int second = cal1.get(Calendar.SECOND);    //(7)現在の秒を取得
    	return year + "/" + month + "/" + day + " " + hour + ":" + minute + ":" + second;
    }
    private void viewList(){
        Cursor c = mDb.fetchAllRun();
    	mAdapter = new ListRunningItemAdapter(
    			this, R.layout.list_run_item, c, mDb.RunningTbColumn(),LIST_COLUMN);

    	ListView runningList = (ListView) findViewById(R.id.listView);
    	runningList.setAdapter(mAdapter);


    }

    private void locationSet(double latitude, double longitude){
        Log.d(TAG, "showlocation lati=" + latitude + " lon=" + longitude);
        tLatitude.setText(Double.toString(latitude));
        tLongitude.setText(Double.toString(longitude));
    }

    @Override
    protected void onResume() {
        super.onResume();
        // 現在の状況に最適なプロバイダを取得する
		String provider;
		provider = mLocationManager.getBestProvider(new Criteria(), true);

		if (provider == null) {
			Toast.makeText(this, R.string.MSG_PROVIDER_ERR, Toast.LENGTH_LONG).show();
//			finish();
		} else {
			mLocationManager.requestLocationUpdates(provider, MIN_TIME, MIN_DISTANCE, this);
		}

/*        if (mLocationManager != null) {
            mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                    MIN_TIME, MIN_DISTANCE, this);

        }
*/
        // 最後に取得した場所があれば表示する
/*        Location loc = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        if (loc != null) {
            onLocationChanged(loc);
        }
*/

        mDb = new RunningDBManager(getApplicationContext());
    }

    @Override
    protected void onPause() {
        super.onPause();
        mLocationManager.removeUpdates(this);
        mDb.close();
    }

    private void setLocationNameFromGeo(double latitude, double longitude) {

        StringBuffer buffer = new StringBuffer();

        // Geocoderで維持情報から地名検索
        try {
            List<Address> addres = mGeoCoder.getFromLocation(latitude,
                    longitude, 1);

            for (Address add : addres) {

                // 地名取得し文字列に連結
                int index = add.getMaxAddressLineIndex();
                for (int i = 0; i <= index; i++) {
                    if (i >= 1) {
                        buffer.append(add.getAddressLine(i));
                        buffer.append(" ");
//                        address = address + add.getAddressLine(i);
                    }
                }
            }
        } catch (IOException e) {
            // TODO 自動生成された catch ブロック
            e.printStackTrace();
        }

        tPlaceName.setText(buffer.toString());
//        textChangeFlg = false;
    }



    //長半径(WGS84)
    private final double a = 6378137D;

    //扁平率(WGS84)
    private final double f = 1D / 298.257222101D;

    public double getDistance(double latStart, double lonStart, double latEnd, double lonEnd) {
        //緯度経度をラジアンに変換
        double radLatStart = latStart * Math.PI/180D;
        double radLonStart = lonStart * Math.PI/180D;
        double radLatEnd = latEnd * Math.PI/180D;
        double radLonEnd = lonEnd * Math.PI/180D;

        //二点間の平均緯度（ラジアン）
        double avgLat = (radLatStart + radLatEnd) / 2D;

        //扁平率の逆数
        double F = 1D / f;

        //第一離心率
        double e = (Math.sqrt(2 * F - 1)) / F;

        double W = Math.sqrt(1 - Math.pow(e, 2) * Math.pow(Math.sin(avgLat), 2));

        //子午線曲率半径
        double M = (a*(1 - Math.pow(e, 2))) / Math.pow(W, 3);

        //卯酉線曲率半径
        double N = a / W;

        //2点間の緯度差(ラジアン)
        double dLat = radLatStart - radLatEnd;

        //2点間の経度差(ラジアン)
        double dLon = radLonStart - radLonEnd;

        //2点間の距離（メートル）
        double d = Math.sqrt(Math.pow(M*dLat, 2) + Math.pow(N * Math.cos(avgLat) * dLon, 2));

        return d;
    }


//	@Override
//	public void onGpsStatusChanged(int event) {
//		// TODO 自動生成されたメソッド・スタブ
//
//	}
}
