package com.decoding.twodtg.barcodereader2dtg;

import android.Manifest;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import java.util.SortedMap;

import static android.view.View.INVISIBLE;

public class BltDiscoveryActivity extends Activity
{
  private ArrayList<BluetoothDevice> devices = new ArrayList<BluetoothDevice>();
  private ArrayList<String> deviceNames = new ArrayList<String>();
  private Button discovery;
  private Button stop;
  private ListView list;
  private TextView charSetCaption;
  private ArrayAdapter<String> devAdapter;
  private Communications device;
  private ProgressBar progress;
  private Spinner charSets;
  private CheckBox sendReturn;
  private CheckBox connected;
  private String[] nameCharsets;
  private boolean toKeybrd = false;

  private void Init()
  {
    // Register for broadcasts when a device is discovered
    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
    this.registerReceiver(mReceiver, filter);

    // Register for broadcasts when discovery has finished
    filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
    this.registerReceiver(mReceiver, filter);

    devAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, deviceNames);

    final Activity a = this;
    list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
      @Override
      public void onItemClick(AdapterView<?> parent, View itemClicked, int position, long id) {
        device.setRemoteAddress(devices.get(position).getAddress(), a);
        finish();
      }
    });

    Bundle b = getIntent().getExtras();
    if(b != null)
      if(b.getBoolean("isKEYBRD"))
      {
        sendReturn.setVisibility(INVISIBLE);
        charSets.setEnabled(false);
        toKeybrd = true;
      }
      else
      {
        charSets.setEnabled(true);
      }

    sendReturn.setChecked(Communications.ReadSendReturn(this));
    if(toKeybrd)
      sendReturn.setChecked(false);
    connected.setChecked(Communications.ReadConnectedSession(this));

    SortedMap<String, Charset> listCharsets = Charset.availableCharsets();
    nameCharsets = new String[listCharsets.size()];
    Object[] tmpCs = listCharsets.values().toArray();
    for(int i = 0; i < listCharsets.size(); i++)
      nameCharsets[i] = ((Charset) (tmpCs[i])).name();

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
        android.R.layout.simple_spinner_item, nameCharsets);
    charSets.setAdapter(adapter);

    charSets.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
    {
      @Override
      public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3)
      {
        if(toKeybrd) return;
        String cs = charSets.getItemAtPosition(arg2).toString();
        device.setCharset(cs, a);
      }

      @Override
      public void onNothingSelected(AdapterView<?> arg0)
      {
      }
    });

    String charset = Communications.ReadCharsetName(this);
    if(toKeybrd)
      charset = "UTF-16";
    if(charset != null)
    {
      for(int i = 0; i < nameCharsets.length; i++)
        if(charset.equals(nameCharsets[i]))
        {
          charSets.setSelection(i);
          break;
        }
    }

    if(Build.VERSION.SDK_INT >= 23)
    {
      list.setAdapter(devAdapter);
      discovery.setVisibility(INVISIBLE);
      stop.setVisibility(INVISIBLE);
      if(OnDevice())
      {
        Set<BluetoothDevice> pairedDevices = ((BltSerial)device).mBluetoothAdapter.getBondedDevices();
        Iterator<BluetoothDevice> iterator = pairedDevices.iterator();
        while (iterator.hasNext())
        {
          FindDevice(iterator.next());
        }
      }
    }
  }

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

    discovery = (Button) this.findViewById(R.id.buttonStartDiscovery);
    stop = (Button) this.findViewById(R.id.buttonStopDiscovery);
    list = (ListView) this.findViewById(R.id.ListDevices);
    progress = (ProgressBar)this.findViewById(R.id.progressBar);
    charSets = (Spinner)this.findViewById(R.id.spinnerCharSet);
    sendReturn = (CheckBox)this.findViewById(R.id.checkBoxReturn);
    charSetCaption = (TextView)this.findViewById(R.id.textView21);
    connected = (CheckBox)this.findViewById(R.id.checkBoxConnectedSession);

    Init();
   }

  private boolean OnDevice()
  {
    if(device == null)
    {
      try
      {
        device = Communications.GetBltSerial(getBaseContext());
      } catch(Communications.ConnectionException e)
      {
        Utils.MessageBoxError(this, e.getMessage());
        return false;
      }
    }
    return true;
  }

  @Override
  protected void onDestroy()
  {
    super.onDestroy();
    unregisterReceiver(mReceiver);
  }

  public void DiscoveryBltClick(View v)
  {
    try
    {
      if(!OnDevice()) return;
      //ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 1001);
      startDiscovery();
    }catch(Exception e)
    {
      Utils.Failed(e);
    }
  }

  @Override
  public void onRequestPermissionsResult (int requestCode, String[] permissions, int[] grantResults)
  {
    Utils.Trace("onRequestPermissionsResult");
    startDiscovery();
  }

  private void startDiscovery()
  {
    try
    {
      discovery.setEnabled(false);
      stop.setEnabled(true);
      devices.clear();
      deviceNames.clear();
      list.setAdapter(devAdapter);
      device.Discovery(this);
      progress.setVisibility(ProgressBar.VISIBLE);
    }catch(Exception e)
    {
      DiscoveryEnd();
      Utils.Failed(e);
    }
  }

  public void StopClick(View v)
  {
    DiscoveryEnd();
    if(device != null)
      device.StopDiscovery();
  }

  private void FindDevice(BluetoothDevice device)
  {
    devices.add(device);
    deviceNames.add(device.getName());
    devAdapter.notifyDataSetChanged();
  }

  private void DiscoveryEnd()
  {
    setProgressBarIndeterminateVisibility(false);
    discovery.setEnabled(true);
    stop.setEnabled(false);
    progress.setVisibility(INVISIBLE);
  }

  public void onSendReturnClick(View v)
  {
    boolean rt = sendReturn.isChecked();
    device.setSendReturn(rt, this);
  }

  public void onConnectedClick(View v)
  {
    boolean rt = connected.isChecked();
    device.setConnectedSession(rt, this);
  }

  /**
   * The BroadcastReceiver that listens for discovered devices and changes the title when
   * discovery is finished
   */
  private final BroadcastReceiver mReceiver = new BroadcastReceiver()
  {
    @Override
    public void onReceive(Context context, Intent intent) {
      String action = intent.getAction();

      // When discovery finds a device
      if (BluetoothDevice.ACTION_FOUND.equals(action))
      {
        // Get the BluetoothDevice object from the Intent
        BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
        // If it's already paired, skip it, because it's been listed already
        //if (device.getBondState() != BluetoothDevice.BOND_BONDED)
          FindDevice(device);
        // When discovery is finished, change the Activity title
      }
      else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action))
      {
        DiscoveryEnd();
      }
    }
  };
}
