package com.example.bd;

import java.io.IOException;
import java.util.ArrayList;

import org.achartengine.ChartFactory;
import org.achartengine.GraphicalView;
import org.achartengine.chart.PointStyle;
import org.achartengine.chart.BarChart.Type;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;

import com.rscja.deviceapi.BDNavigation;
import com.rscja.deviceapi.BDNavigation.BDLocationListener;
import com.rscja.deviceapi.BDNavigation.BDProviderEnum;
import com.rscja.deviceapi.BDNavigation.BDStartModeEnum;
import com.rscja.deviceapi.BDNavigation.BDStatusListener;
import com.rscja.deviceapi.entity.BDLocation;
import com.rscja.deviceapi.entity.SatelliteEntity;
import com.rscja.deviceapi.exception.ConfigurationException;

import android.support.v4.app.Fragment;
import android.app.Activity;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.Paint.Align;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.os.Build;

/**
 * 北斗导航使用demo
 * 
 * 1、使用前请确认您的机器已安装此模块。
 * 2、要正常使用模块需要在\libs\armeabi\目录放置libDeviceAPI.so文件，同时在\libs\目录下放置DeviceAPIver20160728
 * .jar文件。 3、在操作设备前需要调用 <b>{@link #open()}</b> 打开设备，使用完后调用 <b>{@link #close()}
 * </b> 关闭设备 <br/>
 * 
 * 更多函数的使用方法请查看API说明文档
 * 
 * @author wushengjun
 * 更新于2016年8月9日
 */

public class MainActivity extends Activity {

	private final static String TAG = "MainActivity";

	private BDNavigation mInstance;
	private boolean isOpened = false;

	private TextView tvLongitude;
	private TextView tvLatitude;
	private TextView tvSatelliteCount;
	private TextView tvBDStatus;
	private TextView tvAltitude;
	private TextView tvTime;
	private RadioButton rbGPS;
	private RadioButton rbBD;
	private RadioButton rbGB;
	private RadioGroup rgNavSys;
	private LinearLayout llChart;
	private RadioButton rbCold;
	private RadioButton rbWarm;
	private RadioButton rbHot;
	private RadioGroup rgMode;
	
	
	private XYMultipleSeriesDataset mDataset;// 数据设置器
	private GraphicalView graphicalView;
	private XYMultipleSeriesRenderer renderer;// 描绘器
	private XYSeriesRenderer yRenderer;
	private XYSeriesRenderer usedRenderer;
	private XYSeries series;
	private XYSeries usedSeries;// 已用卫星

	BDLocationListener bdListener = new BDLocationListener() {

		@Override
		public void onLocationChanged(BDLocation arg0) {

			final BDLocation loc = arg0;
			runOnUiThread(new Runnable() {
				public void run() {

					updateLocal(loc);
				}
			});

		}

		@Override
		public void onDataResult(String arg0) {

		}
	};

	BDStatusListener bdStatusListener = new MyBDStatusListener();

	private class MyBDStatusListener implements BDStatusListener {

		int vCount = 0;
		int uCount = 0;

		ArrayList<SatelliteEntity> lstSatellite = new ArrayList<SatelliteEntity>();

		@Override
		public void onBDSatelliteViewChanged(int arg0) {
			vCount = arg0;

			runOnUiThread(new Runnable() {
				public void run() {

					tvSatelliteCount.setText(uCount + "/" + vCount);
				}
			});
		}

		@Override
		public void onBDSatelliteUsedChanged(int arg0) {
			uCount = arg0;

			runOnUiThread(new Runnable() {
				public void run() {

					tvSatelliteCount.setText(uCount + "/" + vCount);
				}
			});

		}

		@Override
		public void onBDSatelliteLocating() {

			runOnUiThread(new Runnable() {
				public void run() {

					tvBDStatus.setText(R.string.bd_msg_Locateing);
				}
			});

		}

		@Override
		public void onBDSatelliteFIX(int arg0) {
			uCount = arg0;

			Log.i(TAG, "onBDSatelliteFIX()");

			runOnUiThread(new Runnable() {
				public void run() {
					tvSatelliteCount.setText(uCount + "/" + vCount);
					tvBDStatus.setText(R.string.bd_msg_Locate_succ);
				}
			});

		}

		@Override
		public void onBDSatelliteChanged(ArrayList<SatelliteEntity> arg0) {

			lstSatellite = arg0;
			runOnUiThread(new Runnable() {
				public void run() {
					updateChart(lstSatellite);
				}
			});
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		init();

		try {
			// 获取条码操作实例
			mInstance = BDNavigation.getInstance();

		} catch (ConfigurationException e) {
			e.printStackTrace();

			return;
		}

		new InitTask().execute();

		rgNavSys.setOnCheckedChangeListener(new MyOnCheckedChangeListener());
		rgMode.setOnCheckedChangeListener(new MyModeOnCheckedChangeListener());
		initChart();
	}

	private void initChart() {
		// 这个类用来放置曲线上的所有点，是一个点的集合，根据这些点画出曲线
		series = new XYSeries("");
		usedSeries = new XYSeries("");

		// 创建一个数据集的实例，这个数据集将被用来创建图表
		mDataset = new XYMultipleSeriesDataset();

		renderer = getBarRenderer();

		mDataset.addSeries(series);
		mDataset.addSeries(usedSeries);

		// 以下都是曲线的样式和属性等等的设置，renderer相当于一个用来给图表做渲染的句柄
		int color = Color.GREEN;
		PointStyle style = PointStyle.POINT;

		Log.v("MY", "dataset.getSeriesCount()=" + mDataset.getSeriesCount()
				+ " renderer" + renderer.getSeriesRendererCount());

		graphicalView = ChartFactory.getBarChartView(MainActivity.this,
				mDataset, renderer, Type.DEFAULT);

		llChart.addView(graphicalView);

	}
	
	
	// 柱状图渲染器
		public XYMultipleSeriesRenderer getBarRenderer() {

			renderer = new XYMultipleSeriesRenderer();

			yRenderer = new XYSeriesRenderer();
			yRenderer.setDisplayChartValues(true);
			yRenderer.setChartValuesTextAlign(Align.CENTER);
			yRenderer.setColor(Color.LTGRAY); // 設定Series顏色
			yRenderer.setChartValuesTextSize(16);
			renderer.addSeriesRenderer(yRenderer);

			usedRenderer = new XYSeriesRenderer();
			usedRenderer.setDisplayChartValues(true);
			usedRenderer.setChartValuesTextSize(16);
			usedRenderer.setChartValuesTextAlign(Align.CENTER);
			usedRenderer.setColor(Color.YELLOW); // 設定Series顏色
			renderer.addSeriesRenderer(usedRenderer);

			// renderer.setMarginsColor(Color.WHITE); // 設定圖外圍背景顏色
			renderer.setTextTypeface(null, Typeface.BOLD); // 設定文字style

			renderer.setShowGrid(true); // 設定網格
			renderer.setGridColor(Color.GRAY); // 設定網格顏色

			renderer.setChartTitle(getString(R.string.gps_msg_title_satellite_signal)); // 設定標頭文字
			renderer.setLabelsColor(Color.WHITE); // 設定標頭文字顏色
			renderer.setChartTitleTextSize(20); // 設定標頭文字大小
			renderer.setLabelsTextSize(15);
			renderer.setAxesColor(Color.WHITE); // 設定雙軸顏色
			renderer.setBarSpacing(0.5); // 設定bar間的距離

			renderer.setXLabelsColor(Color.WHITE); // 設定X軸文字顏色
			renderer.setYLabelsColor(0, Color.GREEN); // 設定Y軸文字顏色
			renderer.setXLabelsAlign(Align.CENTER); // 設定X軸文字置中
			renderer.setYLabelsAlign(Align.CENTER); // 設定Y軸文字置中

			renderer.setXLabels(0); // 設定X軸不顯示數字, 改以程式設定文字
			renderer.setYAxisMin(0); // 設定Y軸文最小值
			renderer.setXAxisMax(6.5);
			renderer.setXAxisMin(0.5);
			renderer.setYLabels(0);
			renderer.setYAxisMin(0);
			renderer.setYAxisMax(80);
			renderer.setShowLegend(false);
			renderer.setClickEnabled(false);
			renderer.setPanEnabled(false); // 屏蔽移动
			renderer.setZoomEnabled(false); // 屏蔽缩放
			renderer.setBarWidth(40);

			return renderer;
		}

		private synchronized void updateChart(ArrayList<SatelliteEntity> maps) {

			Log.i(TAG, "updateChart() maps.size()=" + maps.size());

			// 移除数据集中旧的点集
			mDataset.removeSeries(series);
			mDataset.removeSeries(usedSeries);

			series.clear();
			usedSeries.clear();

			if (maps.size() == 0) {
				renderer.clearTextLabels();
			}

			float maxY = 20;// Y轴最大值
			float maxX = 6.5f;// X轴最大值

			String sNum;
			double signal;

//			Collections.reverse(maps);

			int size = maps.size() > 8 ? 8 : maps.size();

			for (int i = 0; i < size; i++) {

				sNum = maps.get(i).getNumber();

				signal = toDouble(maps.get(i).getSignal());

				renderer.addXTextLabel(i + 1, sNum + "#");

				series.add(i + 1.4, signal);

				if (signal > maxY) {
					maxY = (float) signal;

				}

				// Log.v(TAG, sNum + "#" + signal);

			}

			if (size > maxX) {
				maxX = (float) (size + 0.5);
			}

			renderer.setRange(new double[] { 0.5, maxX, 0, maxY + 5 });

			mDataset.addSeries(series);

			mDataset.addSeries(usedSeries);

			// 视图更新，没有这一步，曲线不会呈现动态
			// 如果在非UI主线程中，需要调用postInvalidate()，具体参考api
			graphicalView.invalidate();
		}

	private class MyOnCheckedChangeListener implements OnCheckedChangeListener {

		@Override
		public void onCheckedChanged(RadioGroup group, int checkedId) {

			if (checkedId == rbBD.getId()) {

				mInstance.changeBDProvider(BDProviderEnum.BD);
			} else if (checkedId == rbGPS.getId()) {
				mInstance.changeBDProvider(BDProviderEnum.GPS);
			} else {
				mInstance.changeBDProvider(BDProviderEnum.GPSandBD);
			}

		}

	}

	private class MyModeOnCheckedChangeListener implements
			OnCheckedChangeListener {

		@Override
		public void onCheckedChanged(RadioGroup group, int checkedId) {

			if(mInstance == null) return;
			
			if (checkedId == R.id.rbCold) {

				mInstance.changeBDStartMode(BDStartModeEnum.COLD);

			} else if (checkedId == rbWarm.getId()) {
				mInstance.changeBDStartMode(BDStartModeEnum.WARM);
			} else {
				mInstance.changeBDStartMode(BDStartModeEnum.HOT);
			}

			if (rbBD.isChecked()) {
				mInstance.changeBDProvider(BDProviderEnum.BD);
			} else if (rbGPS.isChecked()) {
				mInstance.changeBDProvider(BDProviderEnum.GPS);
			} else {
				mInstance.changeBDProvider(BDProviderEnum.GPSandBD);
			}

		}

	}

	private void init() {

		tvLongitude = (TextView) findViewById(R.id.tvLongitude);
		tvLatitude = (TextView) findViewById(R.id.tvLatitude);
		tvSatelliteCount = (TextView) findViewById(R.id.tvSatelliteCount);
		tvBDStatus = (TextView) findViewById(R.id.tvBDStatus);
		tvAltitude = (TextView) findViewById(R.id.tvAltitude);
		tvTime = (TextView) findViewById(R.id.tvTime);
		rbGPS = (RadioButton) findViewById(R.id.rbGPS);
		rbBD = (RadioButton) findViewById(R.id.rbBD);
		rbGB = (RadioButton) findViewById(R.id.rbGB);
		rgNavSys = (RadioGroup) findViewById(R.id.rgNavSys);
		llChart= (LinearLayout) findViewById(R.id.llChart);
		rbCold = (RadioButton) findViewById(R.id.rbCold);
		rbWarm = (RadioButton) findViewById(R.id.rbWarm);
		rbHot = (RadioButton) findViewById(R.id.rbHot);
		rgMode = (RadioGroup) findViewById(R.id.rgMode);
	}

	private void updateLocal(BDLocation loc) {
		if (loc == null) {
			tvLatitude.setText("UNKNOWN");
			tvLongitude.setText("UNKNOWN");
			tvTime.setText("");
			return;
		}

		tvLatitude.setText(loc.getLat() + "");
		tvLongitude.setText(loc.getLon() + "");
		tvAltitude.setText(loc.getAltitude() + "");
		tvTime.setText(mInstance.getTimeToFirstFix() / 1000 + " s");
	}

	/**
	 * 设备上电异步类
	 * 
	 * @author liuruifeng 
	 */
	public class InitTask extends AsyncTask<String, Integer, Boolean> {

		@Override
		protected Boolean doInBackground(String... params) {
			boolean bresult = false;

			try {
				bresult = mInstance.open();

			} catch (SecurityException e) {
				Toast.makeText(MainActivity.this, "Requires root permission",
						Toast.LENGTH_SHORT).show();

				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}

			return bresult;
		}

		@Override
		protected void onPostExecute(Boolean result) {
			super.onPostExecute(result);
			isOpened = result;
			if (result) {
				mInstance.addBDStatusListener(bdStatusListener);

				mInstance.addBDLocationListener(BDProviderEnum.GPSandBD,
						bdListener);
			}
		}

	}

	@Override
	protected void onDestroy() {

		if (mInstance != null) {
			mInstance.close();
		}

		super.onDestroy();
	}

	
	/**
	 * 字符转double
	 * 
	 * @param obj
	 * @return 转换异常返回 0
	 */
	public static double toDouble(String obj) {
		try {
			return Double.parseDouble(obj);
		} catch (Exception e) {
		}
		return 0;
	}
}
