package com.atid.app.atx.ble.deviceoption;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanRecord;
import android.bluetooth.le.ScanResult;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.ProgressBar;

import com.atid.app.atx.ble.deviceoption.adapter.DeviceListBluetoothAdapter;
import com.atid.app.atx.ble.deviceoption.data.DeviceItem;
import com.atid.app.atx.ble.deviceoption.data.GlobalData;
import com.atid.lib.transport.types.ConnectType;
import com.atid.lib.util.StringUtil;
import com.atid.lib.util.diagnotics.ATLog;

import java.util.List;


public class SelectDeviceActivity extends Activity implements OnClickListener, OnItemClickListener {

	private static final String TAG = SelectDeviceActivity.class.getSimpleName();
	private static final int INFO = ATLog.L2;

	private static final int BLE_SCAN_TIMEOUT = 12000;

	public static final int ID = 0x12101000;
	public static final String ITEM = "item";

	// ------------------------------------------------------------------------
	// Member Variable
	// ------------------------------------------------------------------------
	private ProgressBar progBLE;
	private ListView lstBtNewDevices;

	private Button btnScan;

	private DeviceListBluetoothAdapter adpNewBLEDevices;
	private BluetoothLeScanner mLeScanner;

	private BluetoothAdapter mBluetoothAdapter;

	private volatile boolean mIsBleScanning;
	private volatile int mBleDeviceScanCount;
	private Handler mScanDoneHanlder;

	// ------------------------------------------------------------------------
	// Override Event Methods
	// ------------------------------------------------------------------------

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_select_device);
		getActionBar().setDisplayHomeAsUpEnabled(true);

		// Initialize Widgets
		initActivity();

		IntentFilter filter = null;
		// Initialize Bluetooth
		if (GlobalData.isSupportBluetooth) {
			mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
			mLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
		}

		mIsBleScanning = false;
		mBleDeviceScanCount = 0;
		mScanDoneHanlder = new Handler();

		ATLog.i(TAG, INFO, "INFO. onCreate()");
	}

	@Override
	protected void onDestroy() {

		ATLog.i(TAG, INFO, "INFO. onDestroy()");
		super.onDestroy();
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		switch (item.getItemId()) {
			case android.R.id.home:
				exitActivity();
				ATLog.i(TAG, INFO, "INFO. onOptionsItemSelected(home)");
				return true;
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	public void onBackPressed() {

		exitActivity();
		ATLog.i(TAG, INFO, "INFO. onBackPressed()");

		super.onBackPressed();
	}


	@Override
	public void onClick(View v) {

		switch (v.getId()) {
			case R.id.scan_device:
				if (isDiscover())
					stopDiscover();
				else {
					adpNewBLEDevices.clear();

					startDiscover();
				}
				ATLog.i(TAG, INFO, "INFO. onClick(scan_device)");
				break;
		}
	}

	@Override
	public void onItemClick(AdapterView<?> parentView, View view, int position, long id) {

		Intent intent = null;

		switch (parentView.getId()) {

			case R.id.new_ble_device:
				intent = new Intent();
				intent.putExtra(ITEM, adpNewBLEDevices.getItem(position));
				exitActivity(intent);
				ATLog.i(TAG, INFO, "INFO. onItemClick(new_bluetooth_device, %d)", position);
				return;
		}
	}

	// ------------------------------------------------------------------------
	// Internal Widgets Control Methods
	// ------------------------------------------------------------------------

	private void initActivity() {

		progBLE = (ProgressBar) findViewById(R.id.prog_ble);

		lstBtNewDevices = (ListView) findViewById(R.id.new_ble_device);
		adpNewBLEDevices = new DeviceListBluetoothAdapter(this);
		lstBtNewDevices.setAdapter(adpNewBLEDevices);
		lstBtNewDevices.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
		lstBtNewDevices.setOnItemClickListener(this);

		btnScan = (Button) findViewById(R.id.scan_device);
		btnScan.setOnClickListener(this);

		ATLog.i(TAG, INFO, "INFO. initActivity()");
	}

	private void exitActivity() {
		exitActivity(null);
	}

	private void exitActivity(Intent intent) {

		if (mIsBleScanning)
			stopDiscover();

		if (intent == null)
			setResult(Activity.RESULT_CANCELED);
		else
			setResult(Activity.RESULT_OK, intent);
		finish();

		ATLog.i(TAG, INFO, "INFO. exitActivity()");
	}

	// ------------------------------------------------------------------------
	// Device Discovering Methods
	// ------------------------------------------------------------------------

	private boolean isDiscover() {
		return mIsBleScanning;
	}

	private void startDiscover() {

		btnScan.setEnabled(false);

		if (mIsBleScanning)
			return;

		mBleDeviceScanCount = 0;

		try {
			mLeScanner.startScan(mScanCallback);
		} catch (Exception e) {
			ATLog.e(TAG, e,"ERROR. startDiscover() - Failed to start ble device scanning");
			return;
		}

		btnScan.setText(R.string.action_stop);
		btnScan.setEnabled(true);

		mIsBleScanning = true;
		if (mIsBleScanning) {
			progBLE.setVisibility(View.VISIBLE);

			mScanDoneHanlder.postDelayed(new Runnable(){
				@Override
				public void run() {

					if (mIsBleScanning)
						stopDiscover();

					btnScan.setText(R.string.action_scan_device);
					btnScan.setEnabled(true);

					progBLE.setVisibility(View.GONE);
				}
			}, BLE_SCAN_TIMEOUT);
		}

		ATLog.i(TAG, INFO, "INFO. startDiscover()");
	}

	private void stopDiscover() {

		btnScan.setEnabled(false);

		try {
			mLeScanner.stopScan(mScanCallback);
		} catch (Exception e) {
			ATLog.e(TAG, e,"ERROR. stopDiscover() - Failed to stop ble device scanning");
			return;
		}

		if (mScanDoneHanlder != null) {
			mScanDoneHanlder.removeCallbacksAndMessages(null);
		}

		btnScan.setText(R.string.action_scan_device);
		btnScan.setEnabled(true);

		progBLE.setVisibility(View.GONE);

		mIsBleScanning = false;

		ATLog.i(TAG, INFO, "INFO. stopDiscover()");
	}

	// ------------------------------------------------------------------------
	// Ble Device Discovering Methods
	// ------------------------------------------------------------------------
	private final ScanCallback mScanCallback = new ScanCallback() {
		@Override
		public void onScanResult(int callbackType, ScanResult result) {
			mBleDeviceScanCount++;

			if (!StringUtil.isNullOrEmpty(result.getDevice().getName())) {
				addNewBLEDevice(result.getDevice(), result.getRssi(), result.getScanRecord());
			}
		}

		@Override
		public void onBatchScanResults(List<ScanResult> results) {

			ATLog.i(TAG, INFO, "INFO. $mScanCallback.onBatchScanResults()");
		}

		@Override
		public void onScanFailed(int errorCode) {
			ATLog.e(TAG, "ERROR. $mScanCallback.onScanFailed(%d)", errorCode);
		}

	};

	private void addNewBLEDevice(BluetoothDevice device , final int rssi, ScanRecord scanRecode) {
		if (device == null)
			return;

		String name = device.getName();
		String address = device.getAddress();

		if (DeviceItem.contains(name)) {
			adpNewBLEDevices.add(ConnectType.BluetoothLe, name, address);
		}


		ATLog.i(TAG, INFO, "INFO. addNewBLEDevice([%s]:[%s])", name, address);


	}
}
