package hr.fer.labust.diverapp.fragment;

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.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;

import java.util.Set;

import hr.fer.labust.diverapp.BluetoothService;
import hr.fer.labust.diverapp.MainActivity;
import hr.fer.labust.diverapp.R;
import hr.fer.labust.diverapp.adapter.BluetoothListAdapter;

public class BluetoothFragment extends Fragment {
    private View mView;
    private Context mContext;
    private BluetoothService mBluetoothService;

    private TextView mBluetoothAdapterName;
    private Button mSearchButton;
    private Button mDiscoverableButton;
    private ToggleButton mSwitchButton;
    private CheckBox mServerCheckbox;

    private BluetoothListAdapter mBluetoothListAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        MainActivity activity = (MainActivity)getActivity();
        mContext = activity.getBaseContext();
        mBluetoothService = activity.getBluetoothService();
        mBluetoothListAdapter = new BluetoothListAdapter(mContext, mBluetoothService);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if (mView == null) {
            mView = inflater.inflate(R.layout.fragment_bluetooth, container, false);
            setLayout();
        }
        else {
            ViewGroup parent = (ViewGroup)mView.getParent();

            if (parent != null) {
                parent.removeView(mView);
            }
        }

        setUI(mBluetoothService.isEnabled());
        return mView;
    }

    private void setLayout() {
        mSwitchButton = (ToggleButton)mView.findViewById(R.id.bluetooth_toggle_button);
        mSwitchButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    if (!mBluetoothService.isEnabled())
                        mBluetoothService.enable();
                }
                else {
                    if (mBluetoothService.isEnabled())
                        mBluetoothService.disable();
                }
            }
        });

        mBluetoothAdapterName = (TextView)mView.findViewById(R.id.bluetooth_name);
        ListView mRemoteBluetoothDevicesList = (ListView)mView.findViewById(R.id.bluetooth_devices_list);
        mRemoteBluetoothDevicesList.setAdapter(mBluetoothListAdapter);

        mServerCheckbox = (CheckBox)mView.findViewById(R.id.bluetooth_remote_checkbox);
        mServerCheckbox.setPadding(mServerCheckbox.getPaddingLeft(), mServerCheckbox.getPaddingTop(), mServerCheckbox.getPaddingRight(), mServerCheckbox.getPaddingBottom() + 10);
        mServerCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    mBluetoothService.startServer();
                }
                else {
                    mBluetoothService.closeServer();
                }
            }
        });

        mSearchButton = (Button)mView.findViewById(R.id.bluetooth_search_button);
        mSearchButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String buttonText = ((TextView)v).getText().toString();
                if (buttonText.equals(getString(R.string.search_for_devices))) {
                    mBluetoothListAdapter.clear();

                    Set<BluetoothDevice> BondedDevices = mBluetoothService.getBondedDevices();
                    Set<BluetoothDevice> ConnectedDevices = mBluetoothService.getConnectedDevices();

                    for (BluetoothDevice d: BondedDevices) {
                        mBluetoothListAdapter.add(d);
                    }

                    for (BluetoothDevice d: ConnectedDevices) {
                        mBluetoothListAdapter.add(d);
                    }

                    mBluetoothListAdapter.notifyDataSetChanged();
                    mBluetoothService.startDiscovery();
                }
                else {
                    mBluetoothService.cancelDiscovery();
                    ((TextView)v).setText(getString(R.string.search_for_devices));
                }
            }
        });

        mDiscoverableButton = (Button)mView.findViewById(R.id.bluetooth_discoverable_button);
        mDiscoverableButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                makeDiscoverable();
            }
        });
    }

    private void makeDiscoverable() {
        Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
        enableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 0);
        startActivity(enableIntent);
    }

    private void setUI(boolean bluetoothEnabled) {
        mSwitchButton.setChecked(bluetoothEnabled);

        if (bluetoothEnabled) {
            mBluetoothAdapterName.setText(mBluetoothService.getName());
            mSearchButton.setEnabled(true);
            mDiscoverableButton.setEnabled(true);
            mServerCheckbox.setEnabled(true);
            mServerCheckbox.setChecked(mBluetoothService.isServerRunning());

            mBluetoothListAdapter.clear();
            Set<BluetoothDevice> BondedDevices = mBluetoothService.getBondedDevices();

            for (BluetoothDevice d: BondedDevices) {
                mBluetoothListAdapter.add(d);
            }

            Set<BluetoothDevice> ConnectedDevices = mBluetoothService.getConnectedDevices();
            for (BluetoothDevice d: ConnectedDevices) {
                mBluetoothListAdapter.add(d);
            }

            mBluetoothListAdapter.notifyDataSetChanged();
        }
        else {
            mBluetoothAdapterName.setText("");
            mSearchButton.setEnabled(false);
            mDiscoverableButton.setEnabled(false);
            mBluetoothListAdapter.clear();
            mServerCheckbox.setChecked(false);
            mServerCheckbox.setEnabled(false);
        }
    }

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

        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothDevice.ACTION_FOUND);
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        getActivity().registerReceiver(mReceiver, filter);
    }

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

        getActivity().unregisterReceiver(mReceiver);
    }

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(BluetoothDevice.ACTION_FOUND)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (device.getBondState() != device.BOND_BONDED) {
                    mBluetoothListAdapter.add(device);
                    mBluetoothListAdapter.notifyDataSetChanged();
                }
            }
            else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_STARTED)) {
                mSearchButton.setText(getString(R.string.cancel_search));
            }
            else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
                mSearchButton.setText(getString(R.string.search_for_devices));
            }
            else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
                int extra = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
                if (extra == BluetoothAdapter.STATE_ON) {
                    setUI(true);
                }
                else if (extra == BluetoothAdapter.STATE_TURNING_OFF) {
                    mBluetoothService.disconnectAll();
                    mBluetoothService.closeServer();
                }
                else if (extra == BluetoothAdapter.STATE_OFF) {
                    setUI(false);
                }
            }
        }
    };

    public void connectionStateChanged(BluetoothDevice device) {
        mBluetoothListAdapter.add(device);
        mBluetoothListAdapter.notifyDataSetChanged();
    }

    public void serverStateChanged() {
        mServerCheckbox.setChecked(mBluetoothService.isServerRunning());
    }
}