package com.seikoinstruments.sdk.thermalprinter.sample;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.seikoinstruments.sdk.thermalprinter.sample.R;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;


public class BluetoothDeviceActivity extends Activity {

    private static final int REQUEST_ENABLE_BLUETOOTH = 1;
    private static final int DIALOG_BLUETOOTH_NO_SUPPORT = 101;
    private static final int DIALOG_BLUETOOTH_SCAN_DEVICES = 102;

    public static final int MESSAGE_DISCOVER_NEW_DEVICE = 1;

    private static final String BLUETOOTH_DEVICE_NAME = "name";
    private static final String BLUETOOTH_DEVICE_ADDRESS = "address";


    private BluetoothAdapter mBluetoothAdapter = null;

    List<Map<String, String>> mPairedDevicesList;


    private final BroadcastReceiver _broadcastReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if(BluetoothDevice.ACTION_FOUND.equals(action)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if(device != null) {
                    final String deviceName = device.getName();
                    final String deviceAddress = device.getAddress();
                    final boolean duplicate = checkDuplicateBluetoothDevice(deviceName, deviceAddress);
                    if(!duplicate) {
                        BluetoothDeviceListItem deviceItem = new BluetoothDeviceListItem(deviceName, deviceAddress);
                        _deviceListAdapter.add(deviceItem);
                    }
                }
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                final Button btnScanDevices = (Button)findViewById(R.id.button_scan_devices);
                btnScanDevices.setText(R.string.scan_devices);
                btnScanDevices.setEnabled(true);

                closeDialog(DIALOG_BLUETOOTH_SCAN_DEVICES);
            }
        }
    };

    private BluetoothDeviceListArrayAdapter _deviceListAdapter;


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

        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        // 「Devices」List
        ListView lstPairedDevices = (ListView)findViewById(R.id.list_paired_devices);
        List<BluetoothDeviceListItem> deviceList = new ArrayList<BluetoothDeviceListItem>();
        _deviceListAdapter = new BluetoothDeviceListArrayAdapter(getApplicationContext(), deviceList);
        lstPairedDevices.setAdapter(_deviceListAdapter);
        lstPairedDevices.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                ListView listView = (ListView) parent;
                final BluetoothDeviceListItem item = (BluetoothDeviceListItem)listView.getItemAtPosition(position);

                Intent result = new Intent();
                result.putExtra(BLUETOOTH_DEVICE_NAME, item.getDeviceName());
                result.putExtra(BLUETOOTH_DEVICE_ADDRESS, item.getDeviceAddress());
                setResult(RESULT_OK, result);

                finish();
            }
        });

        // 「Scan devices」Button
        Button btnScanDevices = (Button)findViewById(R.id.button_scan_devices);
        btnScanDevices.setOnClickListener(new OnClickListener() {
            public void onClick(View view) {
                _deviceListAdapter.clear();
                findPairedDevices();
                discoverDevices();
            }
        });

        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        registerReceiver(_broadcastReceiver, filter);

        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        registerReceiver(_broadcastReceiver, filter);
    }


    @Override
    public void onStart() {
        super.onStart();

        _deviceListAdapter.clear();

        checkBluetooth();
    }


    @Override
    public void onDestroy() {
        super.onDestroy();

        if(mBluetoothAdapter != null) {
            mBluetoothAdapter.cancelDiscovery();
        }

        unregisterReceiver(_broadcastReceiver);
    }


    private void checkBluetooth() {
        if(mBluetoothAdapter == null) {
            showDialog(DIALOG_BLUETOOTH_NO_SUPPORT);
            return;
        }

        if(!mBluetoothAdapter.isEnabled()) {
            // Bluetooth ON
            Intent enableBluetoothIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBluetoothIntent, REQUEST_ENABLE_BLUETOOTH);

        } else {
            findPairedDevices();
        }
    }


    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == REQUEST_ENABLE_BLUETOOTH) {
            if(resultCode == RESULT_OK) {
                Toast.makeText(getApplicationContext(), R.string.enabled_bluetooth, Toast.LENGTH_LONG);
                findPairedDevices();
            }
        }

    }


    private void findPairedDevices() {
        Set<BluetoothDevice> paired_devices = mBluetoothAdapter.getBondedDevices();
        for(BluetoothDevice device : paired_devices) {
            final String deviceName = device.getName();
            final String deviceAddress = device.getAddress();
            final boolean duplicate = checkDuplicateBluetoothDevice(deviceName, deviceAddress);
            Log.d("BluetoothSetting", "Paired Device Duplicate : " + duplicate);
            if(!duplicate) {
                BluetoothDeviceListItem deviceItem = new BluetoothDeviceListItem(deviceName, deviceAddress);
                _deviceListAdapter.add(deviceItem);
            }
        }
    }


    private void discoverDevices() {
        mBluetoothAdapter.cancelDiscovery();
        mBluetoothAdapter.startDiscovery();

        showDialog(DIALOG_BLUETOOTH_SCAN_DEVICES);
    }


    @Override
    protected Dialog onCreateDialog(int id) {
        Dialog dialog = super.onCreateDialog(id);
        switch(id) {
            case DIALOG_BLUETOOTH_NO_SUPPORT:
                dialog = createDialogBluetoothNoSupport();
                break;

            case DIALOG_BLUETOOTH_SCAN_DEVICES:
                dialog = createProgressDialogScanDevices();
                break;
        }

        return dialog;
    }


    private Dialog createDialogBluetoothNoSupport() {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
        alertDialog.setTitle(R.string.bluetooth);
        alertDialog.setMessage(R.string.bluetooth_not_supported);
        alertDialog.setPositiveButton(R.string.ok,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                    }
                });

        return alertDialog.create();
    }


    private Dialog createProgressDialogScanDevices() {
        ProgressDialog progressDialog = new ProgressDialog(this);
        progressDialog.setTitle(R.string.bluetooth);
        progressDialog.setMessage(getText(R.string.scanning_devices));
        progressDialog.setIndeterminate(false);
        progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);

        return progressDialog;
    }


    private void closeDialog(int id) {
        try {
            dismissDialog(id);
        } catch(Exception e) {
        }
    }


    private boolean checkDuplicateBluetoothDevice(final String name, final String address) {
        if((name == null)
                || (address == null)) {
            return true;
        }

        final int deviceCount = _deviceListAdapter.getCount();
        for(int index = 0; index < deviceCount; index++) {
            BluetoothDeviceListItem item = _deviceListAdapter.getItem(index);
            if(address.equals(item.getDeviceAddress())) {
                return true;
            }
        }

        return false;
    }

}
